|
|
1.1 root 1: /* un_rep.cpp */
2:
3: /* Synchronet QWK replay (REP) packet unpacking routine */
4:
1.1.1.2 ! root 5: /* $Id: un_rep.cpp,v 1.34 2004/12/29 04:40:38 rswindell Exp $ */
1.1 root 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: * *
1.1.1.2 ! root 11: * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html *
1.1 root 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: {
1.1.1.2 ! root 46: char str[MAX_PATH+1],fname[MAX_PATH+1]
1.1 root 47: ,*AttemptedToUploadREPpacket="Attempted to upload REP packet";
48: char tmp[512];
1.1.1.2 ! root 49: char from[26];
! 50: char to[26];
! 51: char inbox[MAX_PATH+1];
! 52: char block[QWK_BLOCK_LEN];
1.1 root 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;
1.1.1.2 ! root 62: BOOL twit_list;
! 63:
! 64: sprintf(fname,"%stwitlist.cfg",cfg.ctrl_dir);
! 65: twit_list=fexist(fname);
1.1 root 66:
67: if(repfile!=NULL)
68: strcpy(str,repfile);
69: else
70: sprintf(str,"%s%s.rep",cfg.temp_dir,cfg.sys_id);
1.1.1.2 ! root 71: if(!fexistcase(str)) {
1.1 root 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;
1.1.1.2 ! root 83: if(online!=ON_REMOTE)
1.1 root 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);
1.1.1.2 ! root 93: if(!fexistcase(str)) {
1.1 root 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);
1.1.1.2 ! root 104: fread(block,QWK_BLOCK_LEN,1,rep);
1.1 root 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:
1.1.1.2 ! root 118: for(l=QWK_BLOCK_LEN;l<size;l+=i*QWK_BLOCK_LEN) {
! 119: if(terminated) {
! 120: bprintf("!Terminated");
! 121: break;
! 122: }
! 123:
1.1 root 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: }
1.1.1.2 ! root 130: if(fread(block,1,QWK_BLOCK_LEN,rep)!=QWK_BLOCK_LEN) {
1.1 root 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);
1.1.1.2 ! root 136: i=atoi(tmp); /* i = number of blocks */
1.1 root 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;
1.1.1.2 ! root 141: continue;
! 142: }
1.1 root 143: if(atoi(block+1)==0) { /**********/
144: if(useron.rest&FLAG('E')) { /* E-mail */
145: bputs(text[R_Email]); /**********/
1.1.1.2 ! root 146: continue;
! 147: }
1.1 root 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);
1.1.1.2 ! root 153: continue;
! 154: }
1.1 root 155: if(strchr(str,'@')) {
156: qwktonetmail(rep,block,str,0);
1.1.1.2 ! root 157: continue;
! 158: }
1.1 root 159: if(!stricmp(str,"SBBS")) { /* to SBBS, config stuff */
160: qwkcfgline(block+71,INVALID_SUB);
1.1.1.2 ! root 161: continue;
! 162: }
1.1 root 163:
164: if(useron.etoday>=cfg.level_emailperday[useron.level]
165: && !(useron.rest&FLAG('Q'))) {
166: bputs(text[TooManyEmailsToday]);
1.1.1.2 ! root 167: continue;
! 168: }
1.1 root 169: j=atoi(str);
170: if(j && j>lastuser(&cfg))
171: j=0;
172: if(!j)
1.1.1.2 ! root 173: j=matchuser(&cfg,str,TRUE /* sysop_alias */);
1.1 root 174: if(!j) {
175: bputs(text[UnknownUser]);
1.1.1.2 ! root 176: continue;
! 177: }
1.1 root 178: if(j==1 && useron.rest&FLAG('S')) {
179: bprintf(text[R_Feedback],cfg.sys_op);
1.1.1.2 ! root 180: continue;
! 181: }
1.1 root 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);
1.1.1.2 ! root 188: continue;
! 189: }
1.1 root 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);
1.1.1.2 ! root 196: lastsub=INVALID_SUB;
! 197: }
1.1 root 198:
1.1.1.2 ! root 199: smb.subnum=INVALID_SUB;
1.1 root 200: if((k=smb_open(&smb))!=0) {
201: errormsg(WHERE,ERR_OPEN,smb.file,k,smb.last_error);
1.1.1.2 ! root 202: continue;
! 203: }
1.1 root 204:
205: if(!filelength(fileno(smb.shd_fp))) {
206: smb.status.max_crcs=cfg.mail_maxcrcs;
1.1.1.2 ! root 207: smb.status.max_msgs=0;
1.1 root 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);
1.1.1.2 ! root 213: continue;
! 214: }
! 215: }
1.1 root 216:
217: if((k=smb_locksmbhdr(&smb))!=0) {
218: smb_close(&smb);
219: errormsg(WHERE,ERR_LOCK,smb.file,k);
1.1.1.2 ! root 220: continue;
! 221: }
1.1 root 222:
223: if((k=smb_getstatus(&smb))!=0) {
224: smb_close(&smb);
225: errormsg(WHERE,ERR_READ,smb.file,k);
1.1.1.2 ! root 226: continue;
! 227: }
1.1 root 228:
229: smb_unlocksmbhdr(&smb);
230:
231: if(!qwktomsg(rep,block,0,INVALID_SUB,j)) {
232: smb_close(&smb);
1.1.1.2 ! root 233: continue;
! 234: }
1.1 root 235: smb_close(&smb);
236:
237: if(j==1) {
238: useron.fbacks++;
239: logon_fbacks++;
240: putuserrec(&cfg,useron.number,U_FBACKS,5
1.1.1.2 ! root 241: ,ultoa(useron.fbacks,tmp,10));
! 242: }
1.1 root 243: else {
244: useron.emails++;
245: logon_emails++;
246: putuserrec(&cfg,useron.number,U_EMAILS,5
1.1.1.2 ! root 247: ,ultoa(useron.emails,tmp,10));
! 248: }
1.1 root 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);
1.1.1.2 ! root 253: sprintf(str,"%s sent e-mail to %s #%d"
! 254: ,useron.alias,username(&cfg,j,tmp),j);
1.1 root 255: logline("E+",str);
256: if(useron.rest&FLAG('Q')) {
257: sprintf(tmp,"%-25.25s",block+46);
1.1.1.2 ! root 258: truncsp(tmp);
! 259: }
1.1 root 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);
1.1.1.2 ! root 269: putnmsg(&cfg,k,str);
! 270: break;
! 271: }
! 272: }
1.1 root 273: if(k>cfg.sys_nodes) {
274: sprintf(str,text[UserSentYouMail],tmp);
1.1.1.2 ! root 275: putsmsg(&cfg,j,str);
! 276: }
! 277: } /* end of email */
1.1 root 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])
1.1.1.2 ! root 288: break;
! 289: }
1.1 root 290:
291: if(j>=usrgrps) {
292: if(n<1000) { /* version 1 method, start at 101 */
293: j=n/100;
1.1.1.2 ! root 294: k=n-(j*100);
! 295: }
1.1 root 296: else { /* version 2 method, start at 1001 */
297: j=n/1000;
1.1.1.2 ! root 298: k=n-(j*1000);
! 299: }
1.1 root 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);
1.1.1.2 ! root 304: sprintf(str,"%s: Invalid conference number %lu",useron.alias,n);
1.1 root 305: logline("P!",str);
1.1.1.2 ! root 306: continue;
! 307: }
! 308: }
1.1 root 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'))
1.1.1.2 ! root 314: subscan[n].cfg|=SUB_CFG_NSCAN;
1.1 root 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);
1.1.1.2 ! root 319: continue;
! 320: }
1.1 root 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 */
1.1.1.2 ! root 328: continue;
! 329: }
1.1 root 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");
1.1.1.2 ! root 334: continue;
! 335: }
1.1 root 336:
337: if(useron.rest&FLAG('P')) {
338: bputs(text[R_Post]);
339: logline("P!","Post attempted");
1.1.1.2 ! root 340: continue;
! 341: }
1.1 root 342:
343: if(useron.ptoday>=cfg.level_postsperday[useron.level]
344: && !(useron.rest&FLAG('Q'))) {
345: bputs(text[TooManyPostsToday]);
1.1.1.2 ! root 346: continue;
! 347: }
1.1 root 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");
1.1.1.2 ! root 353: continue;
! 354: }
1.1 root 355:
356: if(!chk_ar(cfg.sub[n]->post_ar,&useron)) {
357: bputs(text[CantPostOnSub]);
358: logline("P!","Post attempted");
1.1.1.2 ! root 359: continue;
! 360: }
1.1 root 361:
362: if((block[0]=='*' || block[0]=='+')
363: && !(cfg.sub[n]->misc&SUB_PRIV)) {
364: bputs(text[PrivatePostsNotAllowed]);
365: logline("P!","Private post attempt");
1.1.1.2 ! root 366: continue;
! 367: }
1.1 root 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 */
1.1.1.2 ! root 376: continue;
! 377: }
! 378: }
1.1 root 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));
1.1.1.2 ! root 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: }
1.1 root 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;
1.1.1.2 ! root 412: smb.subnum=n;
1.1 root 413: if((j=smb_open(&smb))!=0) {
414: errormsg(WHERE,ERR_OPEN,smb.file,j,smb.last_error);
1.1.1.2 ! root 415: continue;
! 416: }
1.1 root 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);
1.1.1.2 ! root 427: continue;
! 428: }
! 429: }
1.1 root 430:
431: if((j=smb_locksmbhdr(&smb))!=0) {
432: smb_close(&smb);
433: lastsub=INVALID_SUB;
434: errormsg(WHERE,ERR_LOCK,smb.file,j);
1.1.1.2 ! root 435: continue;
! 436: }
1.1 root 437: if((j=smb_getstatus(&smb))!=0) {
438: smb_close(&smb);
439: lastsub=INVALID_SUB;
440: errormsg(WHERE,ERR_READ,smb.file,j);
1.1.1.2 ! root 441: continue;
! 442: }
1.1 root 443: smb_unlocksmbhdr(&smb);
1.1.1.2 ! root 444: lastsub=n;
! 445: }
1.1 root 446:
447: if(!qwktomsg(rep,block,0,n,0))
448: continue;
449:
450: useron.ptoday++;
451: useron.posts++;
452: logon_posts++;
453: putuserrec(&cfg,useron.number,U_POSTS,5,ultoa(useron.posts,str,10));
454: putuserrec(&cfg,useron.number,U_PTODAY,5,ultoa(useron.ptoday,str,10));
455: bprintf(text[Posted],cfg.grp[cfg.sub[n]->grp]->sname
456: ,cfg.sub[n]->lname);
1.1.1.2 ! root 457: sprintf(str,"%s posted on %s %s"
! 458: ,useron.alias,cfg.grp[cfg.sub[n]->grp]->sname,cfg.sub[n]->lname);
! 459: signal_sub_sem(&cfg,n);
! 460: logline("P+",str);
! 461: if(!(useron.rest&FLAG('Q')))
! 462: user_event(EVENT_POST);
! 463: } /* end of public message */
! 464: }
1.1 root 465:
466: update_qwkroute(NULL); /* Write ROUTE.DAT */
467:
468: if(lastsub!=INVALID_SUB)
469: smb_close(&smb);
470: fclose(rep);
471:
472: if(useron.rest&FLAG('Q')) { /* QWK Net Node */
473: sprintf(str,"%s%s.msg",cfg.temp_dir,cfg.sys_id);
1.1.1.2 ! root 474: if(fexistcase(str))
! 475: remove(str);
1.1 root 476: sprintf(str,"%s%s.rep",cfg.temp_dir,cfg.sys_id);
1.1.1.2 ! root 477: if(fexistcase(str))
! 478: remove(str);
1.1 root 479:
480: dir=opendir(cfg.temp_dir);
1.1.1.2 ! root 481: while(dir!=NULL && (dirent=readdir(dir))!=NULL) { /* Extra files */
1.1 root 482: // Move files
483: sprintf(str,"%s%s",cfg.temp_dir,dirent->d_name);
484: if(isdir(str))
485: continue;
1.1.1.2 ! root 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);
1.1 root 492: mv(str,fname,1);
493: sprintf(str,text[ReceivedFileViaQWK],dirent->d_name,useron.alias);
494: putsmsg(&cfg,1,str);
495: }
1.1.1.2 ! root 496: if(dir!=NULL)
! 497: closedir(dir);
1.1 root 498: sprintf(str,"%sqnet-rep.now",cfg.data_dir);
1.1.1.2 ! root 499: ftouch(str);
1.1 root 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.