|
|
1.1 root 1: /* un_qwk.cpp */
2:
3: /* Synchronet QWK unpacking routine */
4:
1.1.1.2 ! root 5: /* $Id: un_qwk.cpp,v 1.29 2004/12/29 04:40:14 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 .QWK packet, hubnum is the number of the QWK net hub */
43: /****************************************************************************/
44: bool sbbs_t::unpack_qwk(char *packet,uint hubnum)
45: {
1.1.1.2 ! root 46: char str[MAX_PATH+1],fname[MAX_PATH+1];
1.1 root 47: char tmp[512];
1.1.1.2 ! root 48: char from[26];
! 49: char to[26];
! 50: char inbox[MAX_PATH+1];
! 51: uchar block[QWK_BLOCK_LEN];
1.1 root 52: int k,file;
53: uint i,j,n,lastsub=INVALID_SUB;
54: uint blocks;
55: long l,size,misc;
1.1.1.2 ! root 56: ulong t;
! 57: ulong msgs=0;
! 58: ulong tmsgs=0;
! 59: time_t start;
! 60: time_t startsub;
1.1 root 61: DIR* dir;
62: DIRENT* dirent;
63: FILE* qwk;
1.1.1.2 ! root 64: BOOL twit_list;
1.1 root 65:
1.1.1.2 ! root 66: sprintf(fname,"%stwitlist.cfg",cfg.ctrl_dir);
! 67: twit_list=fexist(fname);
! 68:
! 69: start=time(NULL);
1.1 root 70: if((l=flength(packet))<1) {
71: errormsg(WHERE,ERR_LEN,packet,l);
72: return(false);
73: }
74: i=external(cmdstr(cfg.qhub[hubnum]->unpack,packet,ALLFILES,NULL),EX_OFFLINE);
75: if(i) {
76: errormsg(WHERE,ERR_EXEC,cmdstr(cfg.qhub[hubnum]->unpack,packet,ALLFILES,NULL),i);
77: return(false);
78: }
79: sprintf(str,"%sMESSAGES.DAT",cfg.temp_dir);
1.1.1.2 ! root 80: if(!fexistcase(str)) {
1.1 root 81: sprintf(str,"%s doesn't contain MESSAGES.DAT",packet);
82: errorlog(str);
83: return(false);
84: }
85: if((qwk=fnopen(&file,str,O_RDONLY))==NULL) {
86: errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
87: return(false);
88: }
89: size=filelength(file);
90: /********************/
91: /* Process messages */
92: /********************/
1.1.1.2 ! root 93: eprintf(LOG_INFO,"Importing QWK Network Packet: %s",packet);
1.1 root 94:
1.1.1.2 ! root 95: for(l=QWK_BLOCK_LEN;l<size;l+=blocks*QWK_BLOCK_LEN) {
! 96: if(terminated) {
! 97: eprintf(LOG_NOTICE,"!Terminated");
! 98: break;
! 99: }
1.1 root 100: fseek(qwk,l,SEEK_SET);
1.1.1.2 ! root 101: fread(block,QWK_BLOCK_LEN,1,qwk);
1.1 root 102: if(block[0]<' ' || block[0]&0x80) {
1.1.1.2 ! root 103: eprintf(LOG_NOTICE,"!Invalid message status (%02X) at offset %lu in %s"
1.1 root 104: ,block[0], l, packet);
105: blocks=1;
106: continue;
107: }
108: sprintf(tmp,"%.6s",block+116);
1.1.1.2 ! root 109: blocks=atoi(tmp); /* i = number of blocks */
1.1 root 110: if(blocks<2) {
1.1.1.2 ! root 111: eprintf(LOG_NOTICE,"!Invalid number of blocks (%d) at offset %lu in %s"
1.1 root 112: ,blocks, l+116, packet);
113: blocks=1;
114: continue;
115: }
116: /*********************************/
117: /* public message on a sub-board */
118: /*********************************/
119: n=(uint)block[123]|(((uint)block[124])<<8); /* conference number */
120:
121: if(!n) { /* NETMAIL */
122: sprintf(str,"%25.25s",block+21);
123: truncsp(str);
1.1.1.2 ! root 124: eprintf(LOG_INFO,"NetMail from %s to %s", cfg.qhub[hubnum]->id, str);
1.1 root 125: if(!stricmp(str,"NETMAIL")) { /* QWK to FidoNet NetMail */
126: qwktonetmail(qwk,(char *)block,NULL,hubnum+1);
127: continue;
128: }
129: if(strchr(str,'@')) {
130: qwktonetmail(qwk,(char *)block,str,hubnum+1);
131: continue;
132: }
133: j=atoi(str);
134: if(j && j>lastuser(&cfg))
135: j=0;
136: if(!j)
1.1.1.2 ! root 137: j=matchuser(&cfg,str,TRUE /* sysop_alias */);
1.1 root 138: if(!j) {
1.1.1.2 ! root 139: eprintf(LOG_NOTICE,"!NetMail from %s to UNKNOWN USER: %s", cfg.qhub[hubnum]->id, str);
1.1 root 140: continue;
141: }
142:
143: getuserrec(&cfg,j,U_MISC,8,str);
144: misc=ahtoul(str);
145: if(misc&NETMAIL && cfg.sys_misc&SM_FWDTONET) {
146: getuserrec(&cfg,j,U_NETMAIL,LEN_NETMAIL,str);
147: qwktonetmail(qwk,(char*)block,str,hubnum+1);
148: continue;
149: }
150:
151: smb_stack(&smb,SMB_STACK_PUSH);
152: sprintf(smb.file,"%smail",cfg.data_dir);
153: smb.retry_time=cfg.smb_retry_time;
1.1.1.2 ! root 154: smb.subnum=INVALID_SUB;
1.1 root 155: if((k=smb_open(&smb))!=0) {
156: errormsg(WHERE,ERR_OPEN,smb.file,k,smb.last_error);
157: smb_stack(&smb,SMB_STACK_POP);
158: continue;
159: }
160: if(!filelength(fileno(smb.shd_fp))) {
161: smb.status.max_crcs=cfg.mail_maxcrcs;
1.1.1.2 ! root 162: smb.status.max_msgs=0;
1.1 root 163: smb.status.max_age=cfg.mail_maxage;
164: smb.status.attr=SMB_EMAIL;
165: if((k=smb_create(&smb))!=0) {
166: smb_close(&smb);
167: errormsg(WHERE,ERR_CREATE,smb.file,k);
168: smb_stack(&smb,SMB_STACK_POP);
169: continue;
170: }
171: }
172: if((k=smb_locksmbhdr(&smb))!=0) {
173: smb_close(&smb);
174: errormsg(WHERE,ERR_LOCK,smb.file,k);
175: smb_stack(&smb,SMB_STACK_POP);
176: continue;
177: }
178: if((k=smb_getstatus(&smb))!=0) {
179: smb_close(&smb);
180: errormsg(WHERE,ERR_READ,smb.file,k);
181: smb_stack(&smb,SMB_STACK_POP);
182: continue;
183: }
184: smb_unlocksmbhdr(&smb);
1.1.1.2 ! root 185: if(qwktomsg(qwk,(char *)block,hubnum+1,INVALID_SUB,j)) {
! 186: sprintf(tmp,"%-25.25s",block+46);
! 187: truncsp(tmp);
! 188: sprintf(str,text[UserSentYouMail],tmp);
! 189: putsmsg(&cfg,j,str);
! 190: tmsgs++;
! 191: }
1.1 root 192: smb_close(&smb);
193: smb_stack(&smb,SMB_STACK_POP);
194: continue;
1.1.1.2 ! root 195: }
1.1 root 196:
197: for(j=0;j<cfg.qhub[hubnum]->subs;j++)
198: if(cfg.qhub[hubnum]->conf[j]==n)
199: break;
200: if(j>=cfg.qhub[hubnum]->subs) { /* ignore messages for subs not in config */
1.1.1.2 ! root 201: eprintf(LOG_NOTICE,"!Message from %s on UNKNOWN CONFERENCE NUMBER: %u"
1.1 root 202: ,cfg.qhub[hubnum]->id, n);
203: continue;
204: }
205:
206: j=cfg.qhub[hubnum]->sub[j];
207:
1.1.1.2 ! root 208: /* TWIT FILTER */
! 209: if(twit_list) {
! 210: sprintf(fname,"%stwitlist.cfg",cfg.ctrl_dir);
! 211:
! 212: sprintf(from,"%25.25s",block+46); /* From user */
! 213: truncsp(from);
! 214: sprintf(to,"%25.25s",block+21); /* To user */
! 215: truncsp(to);
! 216:
! 217: if(findstr(from,fname) || findstr(to,fname)) {
! 218: eprintf(LOG_NOTICE,"!Filtering post from %s to %s on %s %s"
! 219: ,from
! 220: ,to
! 221: ,cfg.grp[cfg.sub[j]->grp]->sname,cfg.sub[j]->lname);
! 222: continue;
! 223: }
! 224: }
! 225:
1.1 root 226: if(j!=lastsub) {
1.1.1.2 ! root 227:
! 228: if(msgs) {
! 229: t=time(NULL)-startsub;
! 230: if(t<1)
! 231: t=1;
! 232: eprintf(LOG_INFO,"Imported %lu msgs in %lu seconds (%lu msgs/sec)", msgs,t,msgs/t);
! 233: }
! 234: msgs=0;
! 235: startsub=time(NULL);
! 236:
! 237: eprintf(LOG_INFO,"Importing messages from %s into %s %s"
! 238: ,cfg.qhub[hubnum]->id, cfg.grp[cfg.sub[j]->grp]->sname,cfg.sub[j]->lname);
! 239:
1.1 root 240: if(lastsub!=INVALID_SUB)
241: smb_close(&smb);
242: lastsub=INVALID_SUB;
243: sprintf(smb.file,"%s%s",cfg.sub[j]->data_dir,cfg.sub[j]->code);
244: smb.retry_time=cfg.smb_retry_time;
1.1.1.2 ! root 245: smb.subnum=j;
1.1 root 246: if((k=smb_open(&smb))!=0) {
247: errormsg(WHERE,ERR_OPEN,smb.file,k,smb.last_error);
248: continue;
249: }
250: if(!filelength(fileno(smb.shd_fp))) {
251: smb.status.max_crcs=cfg.sub[j]->maxcrcs;
252: smb.status.max_msgs=cfg.sub[j]->maxmsgs;
253: smb.status.max_age=cfg.sub[j]->maxage;
254: smb.status.attr=cfg.sub[j]->misc&SUB_HYPER ? SMB_HYPERALLOC :0;
255: if((k=smb_create(&smb))!=0) {
256: smb_close(&smb);
257: errormsg(WHERE,ERR_CREATE,smb.file,k);
258: continue;
259: }
260: }
261: if((k=smb_locksmbhdr(&smb))!=0) {
262: smb_close(&smb);
263: errormsg(WHERE,ERR_LOCK,smb.file,k);
264: continue;
265: }
266: if((k=smb_getstatus(&smb))!=0) {
267: smb_close(&smb);
268: errormsg(WHERE,ERR_READ,smb.file,k);
269: continue;
270: }
271: smb_unlocksmbhdr(&smb);
272: lastsub=j;
273: }
274:
275: if(!qwktomsg(qwk,(char *)block,hubnum+1,j,0)) {
1.1.1.2 ! root 276: // eprintf("!QWKTOMSG failed");
1.1 root 277: continue;
278: }
279:
1.1.1.2 ! root 280: signal_sub_sem(&cfg,j);
! 281: /*
! 282: eprintf("Message from %s Posted on %s %s"
1.1 root 283: ,cfg.qhub[hubnum]->id,cfg.grp[cfg.sub[j]->grp]->sname,cfg.sub[j]->lname);
1.1.1.2 ! root 284: */
! 285: msgs++;
! 286: tmsgs++;
1.1 root 287: }
288:
289: update_qwkroute(NULL); /* Write ROUTE.DAT */
290:
291: fclose(qwk);
292: if(lastsub!=INVALID_SUB)
293: smb_close(&smb);
294:
295: delfiles(cfg.temp_dir,"*.NDX");
296: sprintf(str,"%sMESSAGES.DAT",cfg.temp_dir);
297: remove(str);
298: sprintf(str,"%sDOOR.ID",cfg.temp_dir);
299: remove(str);
300: sprintf(str,"%sCONTROL.DAT",cfg.temp_dir);
301: remove(str);
302: sprintf(str,"%sNETFLAGS.DAT",cfg.temp_dir);
303: remove(str);
304:
305: dir=opendir(cfg.temp_dir);
1.1.1.2 ! root 306: while(dir!=NULL && (dirent=readdir(dir))!=NULL) {
1.1 root 307: sprintf(str,"%s%s",cfg.temp_dir,dirent->d_name);
308: if(isdir(str)) /* sub-dir */
309: continue;
1.1.1.2 ! root 310:
! 311: // Create directory if necessary
! 312: sprintf(inbox,"%sqnet/%s.in",cfg.data_dir,cfg.qhub[hubnum]->id);
! 313: MKDIR(inbox);
! 314:
1.1 root 315: // Copy files
1.1.1.2 ! root 316: sprintf(fname,"%s/%s",inbox,dirent->d_name);
1.1 root 317: mv(str,fname,1 /* overwrite */);
318: sprintf(str,text[ReceivedFileViaQWK],dirent->d_name,cfg.qhub[hubnum]->id);
319: putsmsg(&cfg,1,str);
1.1.1.2 ! root 320: eprintf(LOG_INFO,"Received %s from %s", dirent->d_name, cfg.qhub[hubnum]->id);
1.1 root 321: }
1.1.1.2 ! root 322: if(dir!=NULL)
! 323: closedir(dir);
1.1 root 324:
1.1.1.2 ! root 325: t=time(NULL)-start;
! 326: if(tmsgs) {
! 327: if(t<1)
! 328: t=1;
! 329: eprintf(LOG_INFO,"Finished Importing QWK Network Packet from %s: "
! 330: "(%lu msgs) in %lu seconds (%lu msgs/sec)"
! 331: ,cfg.qhub[hubnum]->id, tmsgs, t, tmsgs/t);
! 332: }
1.1 root 333: delfiles(cfg.temp_dir,ALLFILES);
334: return(true);
335: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.