|
|
1.1 root 1: /* un_rep.cpp */
2:
3: /* Synchronet QWK replay (REP) packet unpacking routine */
4:
5: /* $Id: un_rep.cpp,v 1.9 2000/12/31 03:41:55 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 2000 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[256],fname[128]
47: ,*AttemptedToUploadREPpacket="Attempted to upload REP packet";
48: char tmp[512];
49: char block[128];
50: int file;
51: uint i,j,k,lastsub=INVALID_SUB;
52: long l,size,misc;
53: ulong n;
54: ulong ex;
55: node_t node;
56: FILE* rep;
57: DIR* dir;
58: DIRENT* dirent;
59:
60: if(repfile!=NULL)
61: strcpy(str,repfile);
62: else
63: sprintf(str,"%s%s.rep",cfg.temp_dir,cfg.sys_id);
64: if(!fexist(str)) {
65: bputs(text[QWKReplyNotReceived]);
66: logline("U!",AttemptedToUploadREPpacket);
67: logline(nulstr,"REP file not received");
68: return(false);
69: }
70: for(k=0;k<cfg.total_fextrs;k++)
71: if(!stricmp(cfg.fextr[k]->ext,useron.tmpext) && chk_ar(cfg.fextr[k]->ar,&useron))
72: break;
73: if(k>=cfg.total_fextrs)
74: k=0;
75: ex=EX_OUTL|EX_OUTR;
76: if(!online)
77: ex|=EX_OFFLINE;
78: i=external(cmdstr(cfg.fextr[k]->cmd,str,ALLFILES,NULL),ex);
79: if(i) {
80: bputs(text[QWKExtractionFailed]);
81: logline("U!",AttemptedToUploadREPpacket);
82: logline(nulstr,"Extraction failed");
83: return(false);
84: }
85: sprintf(str,"%s%s.msg",cfg.temp_dir,cfg.sys_id);
86: if(!fexist(str)) {
87: bputs(text[QWKReplyNotReceived]);
88: logline("U!",AttemptedToUploadREPpacket);
89: logline(nulstr,"MSG file not received");
90: return(false);
91: }
92: if((rep=fnopen(&file,str,O_RDONLY))==NULL) {
93: errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
94: return(false);
95: }
96: size=filelength(file);
97: fread(block,128,1,rep);
98: if(strnicmp((char *)block,cfg.sys_id,strlen(cfg.sys_id))) {
99: fclose(rep);
100: bputs(text[QWKReplyNotReceived]);
101: logline("U!",AttemptedToUploadREPpacket);
102: logline(nulstr,"Incorrect BBSID");
103: return(false);
104: }
105: logline("U+","Uploaded REP packet");
106: /********************/
107: /* Process messages */
108: /********************/
109: bputs(text[QWKUnpacking]);
110:
111: for(l=128;l<size;l+=i*128) {
112: lncntr=0; /* defeat pause */
113: if(fseek(rep,l,SEEK_SET)!=0) {
114: sprintf(str,"%s.msg", cfg.sys_id);
115: errormsg(WHERE,ERR_SEEK,str,l);
116: break;
117: }
118: if(fread(block,1,128,rep)!=128) {
119: sprintf(str,"%s.msg", cfg.sys_id);
120: errormsg(WHERE,ERR_READ,str,ftell(rep));
121: break;
122: }
123: sprintf(tmp,"%.6s",block+116);
124: i=atoi(tmp); /* i = number of 128 byte records */
125: if(i<2) {
126: sprintf(str,"%s.msg blocks (read '%s' at offset %ld)", cfg.sys_id, tmp, l);
127: errormsg(WHERE,ERR_CHK,str,i);
128: i=1;
129: continue; }
130: if(atoi(block+1)==0) { /**********/
131: if(useron.rest&FLAG('E')) { /* E-mail */
132: bputs(text[R_Email]); /**********/
133: continue; }
134:
135: sprintf(str,"%25.25s",block+21);
136: truncsp(str);
137: if(!stricmp(str,"NETMAIL")) { /* QWK to FidoNet NetMail */
138: qwktonetmail(rep,block,NULL,0);
139: continue; }
140: if(strchr(str,'@')) {
141: qwktonetmail(rep,block,str,0);
142: continue; }
143: if(!stricmp(str,"SBBS")) { /* to SBBS, config stuff */
144: qwkcfgline(block+71,INVALID_SUB);
145: continue; }
146:
147: if(useron.etoday>=cfg.level_emailperday[useron.level]
148: && !(useron.rest&FLAG('Q'))) {
149: bputs(text[TooManyEmailsToday]);
150: continue; }
151: j=atoi(str);
152: if(j && j>lastuser(&cfg))
153: j=0;
154: if(!j &&
155: (!stricmp(str,"SYSOP")
156: || !stricmp(str,cfg.sys_id)
157: || !stricmp(str,cfg.sys_op)))
158: j=1;
159: if(!j)
160: j=matchuser(&cfg,str);
161: if(!j) {
162: bputs(text[UnknownUser]);
163: continue; }
164: if(j==1 && useron.rest&FLAG('S')) {
165: bprintf(text[R_Feedback],cfg.sys_op);
166: continue; }
167:
168: getuserrec(&cfg,j,U_MISC,8,str);
169: misc=ahtoul(str);
170: if(misc&NETMAIL && cfg.sys_misc&SM_FWDTONET) {
171: getuserrec(&cfg,j,U_NETMAIL,LEN_NETMAIL,str);
172: qwktonetmail(rep,block,str,0);
173: continue; }
174:
175: sprintf(smb.file,"%smail",cfg.data_dir);
176: smb.retry_time=cfg.smb_retry_time;
177:
178: if(lastsub!=INVALID_SUB) {
179: smb_close(&smb);
180: lastsub=INVALID_SUB; }
181:
182: if((k=smb_open(&smb))!=0) {
183: errormsg(WHERE,ERR_OPEN,smb.file,k,smb.last_error);
184: continue; }
185:
186: if(!filelength(fileno(smb.shd_fp))) {
187: smb.status.max_crcs=cfg.mail_maxcrcs;
188: smb.status.max_msgs=MAX_SYSMAIL;
189: smb.status.max_age=cfg.mail_maxage;
190: smb.status.attr=SMB_EMAIL;
191: if((k=smb_create(&smb))!=0) {
192: smb_close(&smb);
193: errormsg(WHERE,ERR_CREATE,smb.file,k);
194: continue; } }
195:
196: if((k=smb_locksmbhdr(&smb))!=0) {
197: smb_close(&smb);
198: errormsg(WHERE,ERR_LOCK,smb.file,k);
199: continue; }
200:
201: if((k=smb_getstatus(&smb))!=0) {
202: smb_close(&smb);
203: errormsg(WHERE,ERR_READ,smb.file,k);
204: continue; }
205:
206: smb_unlocksmbhdr(&smb);
207:
208: if(!qwktomsg(rep,block,0,INVALID_SUB,j)) {
209: smb_close(&smb);
210: continue; }
211: smb_close(&smb);
212:
213: if(j==1) {
214: useron.fbacks++;
215: logon_fbacks++;
216: putuserrec(&cfg,useron.number,U_FBACKS,5
217: ,ultoa(useron.fbacks,tmp,10)); }
218: else {
219: useron.emails++;
220: logon_emails++;
221: putuserrec(&cfg,useron.number,U_EMAILS,5
222: ,ultoa(useron.emails,tmp,10)); }
223: useron.etoday++;
224: putuserrec(&cfg,useron.number,U_ETODAY,5
225: ,ultoa(useron.etoday,tmp,10));
226: bprintf(text[Emailed],username(&cfg,j,tmp),j);
227: sprintf(str,"E-mailed %s #%d",username(&cfg,j,tmp),j);
228: logline("E+",str);
229: if(useron.rest&FLAG('Q')) {
230: sprintf(tmp,"%-25.25s",block+46);
231: truncsp(tmp); }
232: else
233: strcpy(tmp,useron.alias);
234: for(k=1;k<=cfg.sys_nodes;k++) { /* Tell user, if online */
235: getnodedat(k,&node,0);
236: if(node.useron==j && !(node.misc&NODE_POFF)
237: && (node.status==NODE_INUSE
238: || node.status==NODE_QUIET)) {
239: sprintf(str,text[EmailNodeMsg]
240: ,cfg.node_num,tmp);
241: putnmsg(k,str);
242: break; } }
243: if(k>cfg.sys_nodes) {
244: sprintf(str,text[UserSentYouMail],tmp);
245: putsmsg(&cfg,j,str); } } /* end of email */
246:
247: /**************************/
248: else { /* message on a sub-board */
249: /**************************/
250: n=atol((char *)block+1); /* conference number */
251: for(j=0;j<usrgrps;j++) {
252: for(k=0;k<usrsubs[j];k++)
253: if(cfg.sub[usrsub[j][k]]->qwkconf==n)
254: break;
255: if(k<usrsubs[j])
256: break; }
257:
258: if(j>=usrgrps) {
259: if(n<1000) { /* version 1 method, start at 101 */
260: j=n/100;
261: k=n-(j*100); }
262: else { /* version 2 method, start at 1001 */
263: j=n/1000;
264: k=n-(j*1000); }
265: j--; /* j is group */
266: k--; /* k is sub */
267: if(j>=usrgrps || k>=usrsubs[j] || cfg.sub[usrsub[j][k]]->qwkconf) {
268: bprintf(text[QWKInvalidConferenceN],n);
269: sprintf(str,"Invalid conference number %d",n);
270: logline("P!",str);
271: continue; } }
272:
273: n=usrsub[j][k];
274:
275: /* if posting, add to new-scan config for QWKnet nodes automatically */
276: if(useron.rest&FLAG('Q'))
277: sub_cfg[n]|=SUB_CFG_NSCAN;
278:
279: sprintf(str,"%-25.25s","SBBS");
280: if(!strnicmp((char *)block+21,str,25)) { /* to SBBS, config stuff */
281: qwkcfgline((char *)block+71,n);
282: continue; }
283:
284: if(!SYSOP && cfg.sub[n]->misc&SUB_QNET) { /* QWK Netted */
285: sprintf(str,"%-25.25s","DROP"); /* Drop from new-scan? */
286: if(!strnicmp((char *)block+71,str,25)) /* don't allow post */
287: continue;
288: sprintf(str,"%-25.25s","ADD"); /* Add to new-scan? */
289: if(!strnicmp((char *)block+71,str,25)) /* don't allow post */
290: continue; }
291:
292: if(useron.rest&FLAG('Q') && !(cfg.sub[n]->misc&SUB_QNET)) {
293: bputs(text[CantPostOnSub]);
294: logline("P!","Attempted to post on non-QWKnet sub");
295: continue; }
296:
297: if(useron.rest&FLAG('P')) {
298: bputs(text[R_Post]);
299: logline("P!","Post attempted");
300: continue; }
301:
302: if(useron.ptoday>=cfg.level_postsperday[useron.level]
303: && !(useron.rest&FLAG('Q'))) {
304: bputs(text[TooManyPostsToday]);
305: continue; }
306:
307: if(useron.rest&FLAG('N')
308: && cfg.sub[n]->misc&(SUB_FIDO|SUB_PNET|SUB_QNET|SUB_INET)) {
309: bputs(text[CantPostOnSub]);
310: logline("P!","Networked post attempted");
311: continue; }
312:
313: if(!chk_ar(cfg.sub[n]->post_ar,&useron)) {
314: bputs(text[CantPostOnSub]);
315: logline("P!","Post attempted");
316: continue; }
317:
318: if((block[0]=='*' || block[0]=='+')
319: && !(cfg.sub[n]->misc&SUB_PRIV)) {
320: bputs(text[PrivatePostsNotAllowed]);
321: logline("P!","Private post attempt");
322: continue; }
323:
324: if(block[0]=='*' || block[0]=='+' /* Private post */
325: || cfg.sub[n]->misc&SUB_PONLY) {
326: sprintf(str,"%-25.25s",nulstr);
327: sprintf(tmp,"%-25.25s","ALL");
328: if(!strnicmp((char *)block+21,str,25)
329: || !strnicmp((char *)block+21,tmp,25)) { /* to blank */
330: bputs(text[NoToUser]); /* or all */
331: continue; } }
332:
333: if(!SYSOP && !(useron.rest&FLAG('Q'))) {
334: sprintf(str,"%-25.25s","SYSOP");
335: if(!strnicmp((char *)block+21,str,25)) {
336: sprintf(str,"%-25.25s",username(&cfg,1,tmp));
337: memcpy((char *)block+21,str,25); } } /* change from sysop */
338: /* to user name */
339:
340: #if 0 /* TWIT FILTER */
341: sprintf(str,"%25.25s",block+46); /* From user */
342: truncsp(str);
343:
344: if(!stricmp(str,"Lee Matherne")
345: || !stricmp(str,"Big Joe")
346: ) {
347: bprintf(text[Posted],cfg.grp[cfg.sub[n]->grp]->sname
348: ,cfg.sub[n]->lname);
349: continue; }
350: #endif
351:
352: if(n!=lastsub) {
353: if(lastsub!=INVALID_SUB)
354: smb_close(&smb);
355: lastsub=INVALID_SUB;
356: sprintf(smb.file,"%s%s",cfg.sub[n]->data_dir,cfg.sub[n]->code);
357: smb.retry_time=cfg.smb_retry_time;
358: if((j=smb_open(&smb))!=0) {
359: errormsg(WHERE,ERR_OPEN,smb.file,j,smb.last_error);
360: continue; }
361:
362: if(!filelength(fileno(smb.shd_fp))) {
363: smb.status.max_crcs=cfg.sub[n]->maxcrcs;
364: smb.status.max_msgs=cfg.sub[n]->maxmsgs;
365: smb.status.max_age=cfg.sub[n]->maxage;
366: smb.status.attr=cfg.sub[n]->misc&SUB_HYPER ? SMB_HYPERALLOC:0;
367: if((j=smb_create(&smb))!=0) {
368: smb_close(&smb);
369: lastsub=INVALID_SUB;
370: errormsg(WHERE,ERR_CREATE,smb.file,j);
371: continue; } }
372:
373: if((j=smb_locksmbhdr(&smb))!=0) {
374: smb_close(&smb);
375: lastsub=INVALID_SUB;
376: errormsg(WHERE,ERR_LOCK,smb.file,j);
377: continue; }
378: if((j=smb_getstatus(&smb))!=0) {
379: smb_close(&smb);
380: lastsub=INVALID_SUB;
381: errormsg(WHERE,ERR_READ,smb.file,j);
382: continue; }
383: smb_unlocksmbhdr(&smb);
384: lastsub=n; }
385:
386: if(!qwktomsg(rep,block,0,n,0))
387: continue;
388:
389: useron.ptoday++;
390: useron.posts++;
391: logon_posts++;
392: putuserrec(&cfg,useron.number,U_POSTS,5,ultoa(useron.posts,str,10));
393: putuserrec(&cfg,useron.number,U_PTODAY,5,ultoa(useron.ptoday,str,10));
394: bprintf(text[Posted],cfg.grp[cfg.sub[n]->grp]->sname
395: ,cfg.sub[n]->lname);
396: sprintf(str,"Posted on %s/%s",cfg.grp[cfg.sub[n]->grp]->sname
397: ,cfg.sub[n]->lname);
398: if(cfg.sub[n]->misc&SUB_FIDO && cfg.sub[n]->echomail_sem[0]) /* semaphore */
399: if((file=nopen(cmdstr(cfg.sub[n]->echomail_sem,nulstr,nulstr,NULL)
400: ,O_WRONLY|O_CREAT|O_TRUNC))!=-1)
401: close(file);
402: logline("P+",str); } } /* end of public message */
403:
404: update_qwkroute(NULL); /* Write ROUTE.DAT */
405:
406: if(lastsub!=INVALID_SUB)
407: smb_close(&smb);
408: fclose(rep);
409:
410: if(useron.rest&FLAG('Q')) { /* QWK Net Node */
411: sprintf(str,"%s%s.msg",cfg.temp_dir,cfg.sys_id);
412: remove(str);
413: sprintf(str,"%s%s.rep",cfg.temp_dir,cfg.sys_id);
414: remove(str);
415:
416: dir=opendir(cfg.temp_dir);
417: while((dirent=readdir(dir))!=NULL) { /* Extra files */
418: // Create directory if necessary
419: sprintf(str,"%sqnet/%s.in",cfg.data_dir,useron.alias);
420: _mkdir(str);
421: // Move files
422: sprintf(str,"%s%s",cfg.temp_dir,dirent->d_name);
423: if(isdir(str))
424: continue;
425: sprintf(fname,"%sqnet/%s.in/%s",cfg.data_dir,useron.alias,dirent->d_name);
426: mv(str,fname,1);
427: sprintf(str,text[ReceivedFileViaQWK],dirent->d_name,useron.alias);
428: putsmsg(&cfg,1,str);
429: }
430: closedir(dir);
431: sprintf(str,"%sqnet-rep.now",cfg.data_dir);
432: if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))!=-1)
433: close(file);
434: }
435:
436: bputs(text[QWKUnpacked]);
437: CRLF;
438: /**********************************************/
439: /* Hang-up now if that's what the user wanted */
440: /**********************************************/
441: autohangup();
442:
443: return(true);
444: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.