|
|
1.1 ! root 1: /* un_rep.cpp */ ! 2: ! 3: /* Synchronet QWK replay (REP) packet unpacking routine */ ! 4: ! 5: /* $Id: un_rep.cpp,v 1.36 2006/01/31 02:51:59 rswindell Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #include "sbbs.h" ! 39: #include "qwk.h" ! 40: ! 41: /****************************************************************************/ ! 42: /* Unpacks .REP packet, 'repname' is the path and filename of the packet */ ! 43: /****************************************************************************/ ! 44: bool sbbs_t::unpack_rep(char* repfile) ! 45: { ! 46: char str[MAX_PATH+1],fname[MAX_PATH+1] ! 47: ,*AttemptedToUploadREPpacket="Attempted to upload REP packet"; ! 48: char tmp[512]; ! 49: char from[26]; ! 50: char to[26]; ! 51: char inbox[MAX_PATH+1]; ! 52: char block[QWK_BLOCK_LEN]; ! 53: int file; ! 54: uint i,j,k,lastsub=INVALID_SUB; ! 55: long l,size,misc; ! 56: ulong n; ! 57: ulong ex; ! 58: node_t node; ! 59: FILE* rep; ! 60: DIR* dir; ! 61: DIRENT* dirent; ! 62: BOOL twit_list; ! 63: ! 64: sprintf(fname,"%stwitlist.cfg",cfg.ctrl_dir); ! 65: twit_list=fexist(fname); ! 66: ! 67: if(repfile!=NULL) ! 68: strcpy(str,repfile); ! 69: else ! 70: sprintf(str,"%s%s.rep",cfg.temp_dir,cfg.sys_id); ! 71: if(!fexistcase(str)) { ! 72: bputs(text[QWKReplyNotReceived]); ! 73: logline("U!",AttemptedToUploadREPpacket); ! 74: logline(nulstr,"REP file not received"); ! 75: return(false); ! 76: } ! 77: for(k=0;k<cfg.total_fextrs;k++) ! 78: if(!stricmp(cfg.fextr[k]->ext,useron.tmpext) && chk_ar(cfg.fextr[k]->ar,&useron)) ! 79: break; ! 80: if(k>=cfg.total_fextrs) ! 81: k=0; ! 82: ex=EX_OUTL|EX_OUTR; ! 83: if(online!=ON_REMOTE) ! 84: ex|=EX_OFFLINE; ! 85: i=external(cmdstr(cfg.fextr[k]->cmd,str,ALLFILES,NULL),ex); ! 86: if(i) { ! 87: bputs(text[QWKExtractionFailed]); ! 88: logline("U!",AttemptedToUploadREPpacket); ! 89: logline(nulstr,"Extraction failed"); ! 90: return(false); ! 91: } ! 92: sprintf(str,"%s%s.msg",cfg.temp_dir,cfg.sys_id); ! 93: if(!fexistcase(str)) { ! 94: bputs(text[QWKReplyNotReceived]); ! 95: logline("U!",AttemptedToUploadREPpacket); ! 96: logline(nulstr,"MSG file not received"); ! 97: return(false); ! 98: } ! 99: if((rep=fnopen(&file,str,O_RDONLY))==NULL) { ! 100: errormsg(WHERE,ERR_OPEN,str,O_RDONLY); ! 101: return(false); ! 102: } ! 103: size=filelength(file); ! 104: fread(block,QWK_BLOCK_LEN,1,rep); ! 105: if(strnicmp((char *)block,cfg.sys_id,strlen(cfg.sys_id))) { ! 106: fclose(rep); ! 107: bputs(text[QWKReplyNotReceived]); ! 108: logline("U!",AttemptedToUploadREPpacket); ! 109: logline(nulstr,"Incorrect BBSID"); ! 110: return(false); ! 111: } ! 112: logline("U+","Uploaded REP packet"); ! 113: /********************/ ! 114: /* Process messages */ ! 115: /********************/ ! 116: bputs(text[QWKUnpacking]); ! 117: ! 118: for(l=QWK_BLOCK_LEN;l<size;l+=i*QWK_BLOCK_LEN) { ! 119: if(terminated) { ! 120: bprintf("!Terminated"); ! 121: break; ! 122: } ! 123: ! 124: lncntr=0; /* defeat pause */ ! 125: if(fseek(rep,l,SEEK_SET)!=0) { ! 126: sprintf(str,"%s.msg", cfg.sys_id); ! 127: errormsg(WHERE,ERR_SEEK,str,l); ! 128: break; ! 129: } ! 130: if(fread(block,1,QWK_BLOCK_LEN,rep)!=QWK_BLOCK_LEN) { ! 131: sprintf(str,"%s.msg", cfg.sys_id); ! 132: errormsg(WHERE,ERR_READ,str,ftell(rep)); ! 133: break; ! 134: } ! 135: sprintf(tmp,"%.6s",block+116); ! 136: i=atoi(tmp); /* i = number of blocks */ ! 137: if(i<2) { ! 138: sprintf(str,"%s.msg blocks (read '%s' at offset %ld)", cfg.sys_id, tmp, l); ! 139: errormsg(WHERE,ERR_CHK,str,i); ! 140: i=1; ! 141: continue; ! 142: } ! 143: if(atoi(block+1)==0) { /**********/ ! 144: if(useron.rest&FLAG('E')) { /* E-mail */ ! 145: bputs(text[R_Email]); /**********/ ! 146: continue; ! 147: } ! 148: ! 149: sprintf(str,"%25.25s",block+21); ! 150: truncsp(str); ! 151: if(!stricmp(str,"NETMAIL")) { /* QWK to FidoNet NetMail */ ! 152: qwktonetmail(rep,block,NULL,0); ! 153: continue; ! 154: } ! 155: if(strchr(str,'@')) { ! 156: qwktonetmail(rep,block,str,0); ! 157: continue; ! 158: } ! 159: if(!stricmp(str,"SBBS")) { /* to SBBS, config stuff */ ! 160: qwkcfgline(block+71,INVALID_SUB); ! 161: continue; ! 162: } ! 163: ! 164: if(useron.etoday>=cfg.level_emailperday[useron.level] ! 165: && !(useron.rest&FLAG('Q'))) { ! 166: bputs(text[TooManyEmailsToday]); ! 167: continue; ! 168: } ! 169: j=atoi(str); ! 170: if(j && j>lastuser(&cfg)) ! 171: j=0; ! 172: if(!j) ! 173: j=matchuser(&cfg,str,TRUE /* sysop_alias */); ! 174: if(!j) { ! 175: bputs(text[UnknownUser]); ! 176: continue; ! 177: } ! 178: if(j==1 && useron.rest&FLAG('S')) { ! 179: bprintf(text[R_Feedback],cfg.sys_op); ! 180: continue; ! 181: } ! 182: ! 183: getuserrec(&cfg,j,U_MISC,8,str); ! 184: misc=ahtoul(str); ! 185: if(misc&NETMAIL && cfg.sys_misc&SM_FWDTONET) { ! 186: getuserrec(&cfg,j,U_NETMAIL,LEN_NETMAIL,str); ! 187: qwktonetmail(rep,block,str,0); ! 188: continue; ! 189: } ! 190: ! 191: sprintf(smb.file,"%smail",cfg.data_dir); ! 192: smb.retry_time=cfg.smb_retry_time; ! 193: ! 194: if(lastsub!=INVALID_SUB) { ! 195: smb_close(&smb); ! 196: lastsub=INVALID_SUB; ! 197: } ! 198: ! 199: smb.subnum=INVALID_SUB; ! 200: if((k=smb_open(&smb))!=0) { ! 201: errormsg(WHERE,ERR_OPEN,smb.file,k,smb.last_error); ! 202: continue; ! 203: } ! 204: ! 205: if(!filelength(fileno(smb.shd_fp))) { ! 206: smb.status.max_crcs=cfg.mail_maxcrcs; ! 207: smb.status.max_msgs=0; ! 208: smb.status.max_age=cfg.mail_maxage; ! 209: smb.status.attr=SMB_EMAIL; ! 210: if((k=smb_create(&smb))!=0) { ! 211: smb_close(&smb); ! 212: errormsg(WHERE,ERR_CREATE,smb.file,k); ! 213: continue; ! 214: } ! 215: } ! 216: ! 217: if((k=smb_locksmbhdr(&smb))!=0) { ! 218: smb_close(&smb); ! 219: errormsg(WHERE,ERR_LOCK,smb.file,k); ! 220: continue; ! 221: } ! 222: ! 223: if((k=smb_getstatus(&smb))!=0) { ! 224: smb_close(&smb); ! 225: errormsg(WHERE,ERR_READ,smb.file,k); ! 226: continue; ! 227: } ! 228: ! 229: smb_unlocksmbhdr(&smb); ! 230: ! 231: if(!qwktomsg(rep,block,0,INVALID_SUB,j)) { ! 232: smb_close(&smb); ! 233: continue; ! 234: } ! 235: smb_close(&smb); ! 236: ! 237: if(j==1) { ! 238: useron.fbacks++; ! 239: logon_fbacks++; ! 240: putuserrec(&cfg,useron.number,U_FBACKS,5 ! 241: ,ultoa(useron.fbacks,tmp,10)); ! 242: } ! 243: else { ! 244: useron.emails++; ! 245: logon_emails++; ! 246: putuserrec(&cfg,useron.number,U_EMAILS,5 ! 247: ,ultoa(useron.emails,tmp,10)); ! 248: } ! 249: useron.etoday++; ! 250: putuserrec(&cfg,useron.number,U_ETODAY,5 ! 251: ,ultoa(useron.etoday,tmp,10)); ! 252: bprintf(text[Emailed],username(&cfg,j,tmp),j); ! 253: sprintf(str,"%s sent e-mail to %s #%d" ! 254: ,useron.alias,username(&cfg,j,tmp),j); ! 255: logline("E+",str); ! 256: if(useron.rest&FLAG('Q')) { ! 257: sprintf(tmp,"%-25.25s",block+46); ! 258: truncsp(tmp); ! 259: } ! 260: else ! 261: strcpy(tmp,useron.alias); ! 262: for(k=1;k<=cfg.sys_nodes;k++) { /* Tell user, if online */ ! 263: getnodedat(k,&node,0); ! 264: if(node.useron==j && !(node.misc&NODE_POFF) ! 265: && (node.status==NODE_INUSE ! 266: || node.status==NODE_QUIET)) { ! 267: sprintf(str,text[EmailNodeMsg] ! 268: ,cfg.node_num,tmp); ! 269: putnmsg(&cfg,k,str); ! 270: break; ! 271: } ! 272: } ! 273: if(k>cfg.sys_nodes) { ! 274: sprintf(str,text[UserSentYouMail],tmp); ! 275: putsmsg(&cfg,j,str); ! 276: } ! 277: } /* end of email */ ! 278: ! 279: /**************************/ ! 280: else { /* message on a sub-board */ ! 281: /**************************/ ! 282: n=atol((char *)block+1); /* conference number */ ! 283: for(j=0;j<usrgrps;j++) { ! 284: for(k=0;k<usrsubs[j];k++) ! 285: if(cfg.sub[usrsub[j][k]]->qwkconf==n) ! 286: break; ! 287: if(k<usrsubs[j]) ! 288: break; ! 289: } ! 290: ! 291: if(j>=usrgrps) { ! 292: if(n<1000) { /* version 1 method, start at 101 */ ! 293: j=n/100; ! 294: k=n-(j*100); ! 295: } ! 296: else { /* version 2 method, start at 1001 */ ! 297: j=n/1000; ! 298: k=n-(j*1000); ! 299: } ! 300: j--; /* j is group */ ! 301: k--; /* k is sub */ ! 302: if(j>=usrgrps || k>=usrsubs[j] || cfg.sub[usrsub[j][k]]->qwkconf) { ! 303: bprintf(text[QWKInvalidConferenceN],n); ! 304: sprintf(str,"%s: Invalid conference number %lu",useron.alias,n); ! 305: logline("P!",str); ! 306: continue; ! 307: } ! 308: } ! 309: ! 310: n=usrsub[j][k]; ! 311: ! 312: /* if posting, add to new-scan config for QWKnet nodes automatically */ ! 313: if(useron.rest&FLAG('Q')) ! 314: subscan[n].cfg|=SUB_CFG_NSCAN; ! 315: ! 316: sprintf(str,"%-25.25s","SBBS"); ! 317: if(!strnicmp((char *)block+21,str,25)) { /* to SBBS, config stuff */ ! 318: qwkcfgline((char *)block+71,n); ! 319: continue; ! 320: } ! 321: ! 322: if(!SYSOP && cfg.sub[n]->misc&SUB_QNET) { /* QWK Netted */ ! 323: sprintf(str,"%-25.25s","DROP"); /* Drop from new-scan? */ ! 324: if(!strnicmp((char *)block+71,str,25)) /* don't allow post */ ! 325: continue; ! 326: sprintf(str,"%-25.25s","ADD"); /* Add to new-scan? */ ! 327: if(!strnicmp((char *)block+71,str,25)) /* don't allow post */ ! 328: continue; ! 329: } ! 330: ! 331: if(useron.rest&FLAG('Q') && !(cfg.sub[n]->misc&SUB_QNET)) { ! 332: bputs(text[CantPostOnSub]); ! 333: logline("P!","Attempted to post on non-QWKnet sub"); ! 334: continue; ! 335: } ! 336: ! 337: if(useron.rest&FLAG('P')) { ! 338: bputs(text[R_Post]); ! 339: logline("P!","Post attempted"); ! 340: continue; ! 341: } ! 342: ! 343: if(useron.ptoday>=cfg.level_postsperday[useron.level] ! 344: && !(useron.rest&FLAG('Q'))) { ! 345: bputs(text[TooManyPostsToday]); ! 346: continue; ! 347: } ! 348: ! 349: if(useron.rest&FLAG('N') ! 350: && cfg.sub[n]->misc&(SUB_FIDO|SUB_PNET|SUB_QNET|SUB_INET)) { ! 351: bputs(text[CantPostOnSub]); ! 352: logline("P!","Networked post attempted"); ! 353: continue; ! 354: } ! 355: ! 356: if(!chk_ar(cfg.sub[n]->post_ar,&useron)) { ! 357: bputs(text[CantPostOnSub]); ! 358: logline("P!","Post attempted"); ! 359: continue; ! 360: } ! 361: ! 362: if((block[0]=='*' || block[0]=='+') ! 363: && !(cfg.sub[n]->misc&SUB_PRIV)) { ! 364: bputs(text[PrivatePostsNotAllowed]); ! 365: logline("P!","Private post attempt"); ! 366: continue; ! 367: } ! 368: ! 369: if(block[0]=='*' || block[0]=='+' /* Private post */ ! 370: || cfg.sub[n]->misc&SUB_PONLY) { ! 371: sprintf(str,"%-25.25s",nulstr); ! 372: sprintf(tmp,"%-25.25s","ALL"); ! 373: if(!strnicmp((char *)block+21,str,25) ! 374: || !strnicmp((char *)block+21,tmp,25)) { /* to blank */ ! 375: bputs(text[NoToUser]); /* or all */ ! 376: continue; ! 377: } ! 378: } ! 379: ! 380: if(!SYSOP && !(useron.rest&FLAG('Q'))) { ! 381: sprintf(str,"%-25.25s","SYSOP"); ! 382: if(!strnicmp((char *)block+21,str,25)) { ! 383: sprintf(str,"%-25.25s",username(&cfg,1,tmp)); ! 384: memcpy((char *)block+21,str,25); /* change from sysop */ ! 385: } /* to user name */ ! 386: } ! 387: ! 388: /* TWIT FILTER */ ! 389: if(twit_list) { ! 390: sprintf(fname,"%stwitlist.cfg",cfg.ctrl_dir); ! 391: sprintf(from,"%25.25s",block+46); /* From user */ ! 392: truncsp(from); ! 393: sprintf(to,"%25.25s",block+21); /* To user */ ! 394: truncsp(to); ! 395: ! 396: if(findstr(from,fname) || findstr(to,fname)) { ! 397: sprintf(str,"Filtering post from %s to %s on %s %s" ! 398: ,from ! 399: ,to ! 400: ,cfg.grp[cfg.sub[n]->grp]->sname,cfg.sub[n]->lname); ! 401: logline("P!",str); ! 402: continue; ! 403: } ! 404: } ! 405: ! 406: if(n!=lastsub) { ! 407: if(lastsub!=INVALID_SUB) ! 408: smb_close(&smb); ! 409: lastsub=INVALID_SUB; ! 410: sprintf(smb.file,"%s%s",cfg.sub[n]->data_dir,cfg.sub[n]->code); ! 411: smb.retry_time=cfg.smb_retry_time; ! 412: smb.subnum=n; ! 413: if((j=smb_open(&smb))!=0) { ! 414: errormsg(WHERE,ERR_OPEN,smb.file,j,smb.last_error); ! 415: continue; ! 416: } ! 417: ! 418: if(!filelength(fileno(smb.shd_fp))) { ! 419: smb.status.max_crcs=cfg.sub[n]->maxcrcs; ! 420: smb.status.max_msgs=cfg.sub[n]->maxmsgs; ! 421: smb.status.max_age=cfg.sub[n]->maxage; ! 422: smb.status.attr=cfg.sub[n]->misc&SUB_HYPER ? SMB_HYPERALLOC:0; ! 423: if((j=smb_create(&smb))!=0) { ! 424: smb_close(&smb); ! 425: lastsub=INVALID_SUB; ! 426: errormsg(WHERE,ERR_CREATE,smb.file,j); ! 427: continue; ! 428: } ! 429: } ! 430: ! 431: if((j=smb_locksmbhdr(&smb))!=0) { ! 432: smb_close(&smb); ! 433: lastsub=INVALID_SUB; ! 434: errormsg(WHERE,ERR_LOCK,smb.file,j); ! 435: continue; ! 436: } ! 437: if((j=smb_getstatus(&smb))!=0) { ! 438: smb_close(&smb); ! 439: lastsub=INVALID_SUB; ! 440: errormsg(WHERE,ERR_READ,smb.file,j); ! 441: continue; ! 442: } ! 443: smb_unlocksmbhdr(&smb); ! 444: lastsub=n; ! 445: } ! 446: ! 447: if(!qwktomsg(rep,block,0,n,0)) ! 448: continue; ! 449: ! 450: logon_posts++; ! 451: user_posted_msg(&cfg, &useron, 1); ! 452: bprintf(text[Posted],cfg.grp[cfg.sub[n]->grp]->sname ! 453: ,cfg.sub[n]->lname); ! 454: sprintf(str,"%s posted on %s %s" ! 455: ,useron.alias,cfg.grp[cfg.sub[n]->grp]->sname,cfg.sub[n]->lname); ! 456: signal_sub_sem(&cfg,n); ! 457: logline("P+",str); ! 458: if(!(useron.rest&FLAG('Q'))) ! 459: user_event(EVENT_POST); ! 460: } /* end of public message */ ! 461: } ! 462: ! 463: update_qwkroute(NULL); /* Write ROUTE.DAT */ ! 464: ! 465: if(lastsub!=INVALID_SUB) ! 466: smb_close(&smb); ! 467: fclose(rep); ! 468: ! 469: if(useron.rest&FLAG('Q')) { /* QWK Net Node */ ! 470: sprintf(str,"%s%s.msg",cfg.temp_dir,cfg.sys_id); ! 471: if(fexistcase(str)) ! 472: remove(str); ! 473: sprintf(str,"%s%s.rep",cfg.temp_dir,cfg.sys_id); ! 474: if(fexistcase(str)) ! 475: remove(str); ! 476: sprintf(str,"%sATTXREF.DAT",cfg.temp_dir); ! 477: if(fexistcase(str)) ! 478: remove(str); ! 479: ! 480: dir=opendir(cfg.temp_dir); ! 481: while(dir!=NULL && (dirent=readdir(dir))!=NULL) { /* Extra files */ ! 482: // Move files ! 483: sprintf(str,"%s%s",cfg.temp_dir,dirent->d_name); ! 484: if(isdir(str)) ! 485: continue; ! 486: ! 487: // Create directory if necessary ! 488: sprintf(inbox,"%sqnet/%s.in",cfg.data_dir,useron.alias); ! 489: MKDIR(inbox); ! 490: ! 491: sprintf(fname,"%s/%s",inbox,dirent->d_name); ! 492: mv(str,fname,1); ! 493: sprintf(str,text[ReceivedFileViaQWK],dirent->d_name,useron.alias); ! 494: putsmsg(&cfg,1,str); ! 495: } ! 496: if(dir!=NULL) ! 497: closedir(dir); ! 498: sprintf(str,"%sqnet-rep.now",cfg.data_dir); ! 499: ftouch(str); ! 500: } ! 501: ! 502: bputs(text[QWKUnpacked]); ! 503: CRLF; ! 504: /**********************************************/ ! 505: /* Hang-up now if that's what the user wanted */ ! 506: /**********************************************/ ! 507: autohangup(); ! 508: ! 509: return(true); ! 510: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.