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