|
|
1.1 root 1: /* qwktomsg.cpp */
2:
3: /* Synchronet QWK to SMB message conversion routine */
4:
5: /* $Id: qwktomsg.cpp,v 1.4 2000/11/14 02:16:57 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: /* Converts a QWK message packet into a message. */
43: /****************************************************************************/
44: bool sbbs_t::qwktomsg(FILE *qwk_fp, char *hdrblk, char fromhub, uint subnum
45: , uint touser)
46: {
47: char str[256],*body,*tail,col=0,lastch=0,*p,*lzhbuf,qwkbuf[128];
48: uint i,j,k,lzh=0,storage,skip=0;
49: ushort xlat;
50: long l,bodylen,taillen,length;
51: ulong crc,block,blocks;
52: smbmsg_t msg;
53: struct tm tm;
54:
55: memset(&msg,0,sizeof(smbmsg_t)); /* Initialize message header */
56: memcpy(msg.hdr.id,"SHD\x1a",4);
57: msg.hdr.version=smb_ver();
58:
59: blocks=atol(hdrblk+116);
60: if(blocks<2) {
61: errormsg(WHERE,ERR_CHK,"QWK packet header blocks",blocks);
62: return(false);
63: }
64:
65: if(subnum!=INVALID_SUB
66: && (hdrblk[0]=='*' || hdrblk[0]=='+' || cfg.sub[subnum]->misc&SUB_PONLY))
67: msg.idx.attr|=MSG_PRIVATE;
68: if(subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_AONLY)
69: msg.idx.attr|=MSG_ANONYMOUS;
70: if(subnum==INVALID_SUB && cfg.sys_misc&SM_DELREADM)
71: msg.idx.attr|=MSG_KILLREAD;
72: if((fromhub || useron.rest&FLAG('Q')) &&
73: (hdrblk[0]=='*' || hdrblk[0]=='-' || hdrblk[0]=='`'))
74: msg.idx.attr|=MSG_READ;
75:
76: if(subnum!=INVALID_SUB && !fromhub && cfg.sub[subnum]->mod_ar[0]
77: && chk_ar(cfg.sub[subnum]->mod_ar,&useron))
78: msg.idx.attr|=MSG_MODERATED;
79: if(subnum!=INVALID_SUB && !fromhub && cfg.sub[subnum]->misc&SUB_SYSPERM
80: && sub_op(subnum))
81: msg.idx.attr|=MSG_PERMANENT;
82:
83: msg.hdr.attr=msg.idx.attr;
84:
85: memset(&tm,0,sizeof(tm));
86: tm.tm_mon = ((hdrblk[8]&0xf)*10)+(hdrblk[9]&0xf);
87: if(tm.tm_mon>0) tm.tm_mon--; /* zero based */
88: tm.tm_mday=((hdrblk[11]&0xf)*10)+(hdrblk[12]&0xf);
89: tm.tm_year=((hdrblk[14]&0xf)*10)+(hdrblk[15]&0xf);
90: if(tm.tm_year<Y2K_2DIGIT_WINDOW)
91: tm.tm_year+=100;
92: tm.tm_hour=((hdrblk[16]&0xf)*10)+(hdrblk[17]&0xf);
93: tm.tm_min=((hdrblk[19]&0xf)*10)+(hdrblk[20]&0xf);
94: tm.tm_sec=0;
95:
96: msg.hdr.when_written.time=mktime(&tm);
97: if(!(useron.rest&FLAG('Q')) && !fromhub)
98: msg.hdr.when_written.zone=cfg.sys_timezone;
99: msg.hdr.when_imported.time=time(NULL);
100: msg.hdr.when_imported.zone=cfg.sys_timezone;
101:
102: hdrblk[116]=0; // don't include number of blocks in "re: msg number"
103: msg.hdr.thread_orig=atol((char *)hdrblk+108);
104:
105: if((uint)subnum==INVALID_SUB) { /* E-mail */
106: msg.idx.to=touser;
107:
108: username(&cfg,touser,str);
109: smb_hfield(&msg,RECIPIENT,strlen(str),str);
110: sprintf(str,"%u",touser);
111: smb_hfield(&msg,RECIPIENTEXT,strlen(str),str); }
112:
113: else {
114: sprintf(str,"%25.25s",(char *)hdrblk+21); /* To user */
115: truncsp(str);
116: smb_hfield(&msg,RECIPIENT,strlen(str),str);
117: strlwr(str);
118: msg.idx.to=crc16(str); }
119:
120: fread(qwkbuf,1,128,qwk_fp);
121:
122: if(useron.rest&FLAG('Q') || fromhub) { /* QWK Net */
123: if(!strnicmp(qwkbuf,"@VIA:",5)) {
124: p=strchr(qwkbuf,'\xe3');
125: if(p) {
126: *p=0;
127: skip=strlen(qwkbuf)+1; }
128: truncsp(qwkbuf);
129: p=qwkbuf+5; /* Skip "@VIA:" */
130: while(*p && *p<=SP) p++; /* Skip any spaces */
131: if(route_circ(p,cfg.sys_id)) {
132: smb_freemsgmem(&msg);
133: bprintf("\r\nCircular message path: %s\r\n",p);
134: sprintf(str,"Circular message path: %s from %s"
135: ,p,fromhub ? cfg.qhub[fromhub-1]->id:useron.alias);
136: errorlog(str);
137: return(false); }
138: sprintf(str,"%s/%s"
139: ,fromhub ? cfg.qhub[fromhub-1]->id : useron.alias,p);
140: strupr(str);
141: update_qwkroute(str); }
142: else {
143: if(fromhub)
144: strcpy(str,cfg.qhub[fromhub-1]->id);
145: else
146: strcpy(str,useron.alias); }
147: strupr(str);
148: j=NET_QWK;
149: smb_hfield(&msg,SENDERNETTYPE,2,&j);
150: smb_hfield(&msg,SENDERNETADDR,strlen(str),str);
151: sprintf(str,"%25.25s",hdrblk+46); /* From user */
152: truncsp(str);
153: if(!strnicmp(qwkbuf+skip,"@TZ:",4)) {
154: p=strchr(qwkbuf+skip,'\xe3');
155: i=skip;
156: if(p) {
157: *p=0;
158: skip+=strlen(qwkbuf+i)+1; }
159: p=qwkbuf+i+4; /* Skip "@TZ:" */
160: while(*p && *p<=SP) p++; /* Skip any spaces */
161: msg.hdr.when_written.zone=(short)ahtoul(p); }
162: }
163: else {
164: sprintf(str,"%u",useron.number);
165: smb_hfield(&msg,SENDEREXT,strlen(str),str);
166: if((uint)subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_NAME)
167: strcpy(str,useron.name);
168: else
169: strcpy(str,useron.alias); }
170:
171: smb_hfield(&msg,SENDER,strlen(str),str);
172: if((uint)subnum==INVALID_SUB) {
173: if(useron.rest&FLAG('Q') || fromhub)
174: msg.idx.from=0;
175: else
176: msg.idx.from=useron.number; }
177: else {
178: strlwr(str);
179: msg.idx.from=crc16(str); }
180:
181: sprintf(str,"%25.25s",hdrblk+71); /* Subject */
182: truncsp(str);
183: remove_re(str);
184: smb_hfield(&msg,SUBJECT,strlen(str),str);
185: strlwr(str);
186: msg.idx.subj=crc16(str);
187:
188: /********************************/
189: /* Convert the QWK message text */
190: /********************************/
191:
192: bodylen=0;
193: if((body=(char *)LMALLOC((blocks-1L)*128L*2L))==NULL) {
194: smb_freemsgmem(&msg);
195: errormsg(WHERE,ERR_ALLOC,"QWK msg body",(blocks-1L)*128L*2L);
196: return(false); }
197:
198: taillen=0;
199: if((tail=(char *)LMALLOC((blocks-1L)*128L*2L))==NULL) {
200: LFREE(body);
201: smb_freemsgmem(&msg);
202: errormsg(WHERE,ERR_ALLOC,"QWK msg tail",(blocks-1L)*128L*2L);
203: return(false); }
204:
205: for(block=1;block<blocks;block++) {
206: if(block>1)
207: if(!fread(qwkbuf,1,128,qwk_fp))
208: break;
209: for(k=skip;k<128;k++,skip=0) {
210: if(qwkbuf[k]==0)
211: continue;
212: if(!taillen && qwkbuf[k]==SP && col==3 && bodylen>=3
213: && body[bodylen-3]=='-' && body[bodylen-2]=='-'
214: && body[bodylen-1]=='-') {
215: bodylen-=3;
216: strcpy(tail,"--- ");
217: taillen=4;
218: col++;
219: continue; }
220: if((uchar)qwkbuf[k]==0xE3) { /* expand 0xe3 to crlf */
221: if(!taillen && col==3 && bodylen>=3 && body[bodylen-3]=='-'
222: && body[bodylen-2]=='-' && body[bodylen-1]=='-') {
223: bodylen-=3;
224: strcpy(tail,"---");
225: taillen=3; }
226: col=0;
227: if(taillen) {
228: tail[taillen++]=CR;
229: tail[taillen++]=LF; }
230: else {
231: body[bodylen++]=CR;
232: body[bodylen++]=LF; }
233: continue; }
234: /* beep restrict */
235: if(!fromhub && qwkbuf[k]==BEL && useron.rest&FLAG('B'))
236: continue;
237: /* ANSI restriction */
238: if(!fromhub && (qwkbuf[k]==1 || qwkbuf[k]==ESC)
239: && useron.rest&FLAG('A'))
240: continue;
241: if(qwkbuf[k]!=1 && lastch!=1)
242: col++;
243: if(lastch==1 && !validattr(qwkbuf[k])) {
244: if(taillen) taillen--;
245: else bodylen--;
246: lastch=0;
247: continue; }
248: lastch=qwkbuf[k];
249: if(taillen)
250: tail[taillen++]=qwkbuf[k];
251: else
252: body[bodylen++]=qwkbuf[k]; } }
253:
254: while(bodylen && body[bodylen-1]==SP) bodylen--; /* remove trailing spaces */
255: if(bodylen>=2 && body[bodylen-2]==CR && body[bodylen-1]==LF)
256: bodylen-=2;
257:
258: while(taillen && tail[taillen-1]<=SP) taillen--; /* remove trailing garbage */
259:
260: /*****************/
261: /* Calculate CRC */
262: /*****************/
263:
264: if(smb.status.max_crcs) {
265: crc=0xffffffffUL;
266: for(l=0;l<bodylen;l++)
267: crc=ucrc32(body[l],crc);
268: crc=~crc;
269:
270: /*******************/
271: /* Check for dupes */
272: /*******************/
273:
274: j=smb_addcrc(&smb,crc);
275: if(j) {
276: if(j==1) {
277: bprintf("\r\nDuplicate message\r\n");
278: if(subnum==INVALID_SUB)
279: logline("E!","Duplicate e-mail attempt");
280: else {
281: sprintf(str,"Duplicate message attempt in %s/%s"
282: ,cfg.grp[cfg.sub[subnum]->grp]->sname
283: ,cfg.sub[subnum]->lname);
284: logline("P!",str);
285: }
286: } else
287: errormsg(WHERE,ERR_CHK,smb.file,j);
288:
289: smb_freemsgmem(&msg);
290: LFREE(body);
291: LFREE(tail);
292: return(false); } }
293:
294: bputs(text[WritingIndx]);
295:
296: /*************************************/
297: /* Write SMB message header and text */
298: /*************************************/
299:
300: if(subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_LZH && bodylen
301: && bodylen+2+taillen+2>=SDT_BLOCK_LEN
302: && (lzhbuf=(char *)LMALLOC(bodylen*2))!=NULL) {
303: length=lzh_encode((uchar *)body,bodylen,(uchar *)lzhbuf);
304: if(length>1L
305: && smb_datblocks(length+4L+taillen+2L)
306: <smb_datblocks(bodylen+2L+taillen+2L)) {
307: bodylen=length; /* Compressable */
308: length+=4L;
309: lzh=1;
310: LFREE(body);
311: body=lzhbuf; }
312: else { /* Non-compressable */
313: length=bodylen+2L;
314: LFREE(lzhbuf); } }
315: else
316: length=bodylen+2L; /* +2 for translation string */
317:
318: if(taillen)
319: length+=taillen+2L;
320:
321: if(length&0xfff00000UL) {
322: errormsg(WHERE,ERR_LEN,"REP msg",length);
323: smb_freemsgmem(&msg);
324: LFREE(body);
325: LFREE(tail);
326: return(false); }
327:
328: if((i=smb_locksmbhdr(&smb))!=0) {
329: errormsg(WHERE,ERR_LOCK,smb.file,i);
330: FREE(body);
331: FREE(tail);
332: return(false); }
333:
334: if(smb.status.attr&SMB_HYPERALLOC) {
335: msg.hdr.offset=smb_hallocdat(&smb);
336: storage=SMB_HYPERALLOC; }
337: else {
338: if((i=smb_open_da(&smb))!=0) {
339: errormsg(WHERE,ERR_OPEN,smb.file,i);
340: FREE(body);
341: FREE(tail);
342: return(false); }
343: if((subnum==INVALID_SUB && cfg.sys_misc&SM_FASTMAIL)
344: || (subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_FAST)) {
345: msg.hdr.offset=smb_fallocdat(&smb,length,1);
346: storage=SMB_FASTALLOC; }
347: else {
348: msg.hdr.offset=smb_allocdat(&smb,length,1);
349: storage=SMB_SELFPACK; }
350: smb_close_da(&smb); }
351:
352: if(msg.hdr.offset && msg.hdr.offset<1L) {
353: smb_unlocksmbhdr(&smb);
354: errormsg(WHERE,ERR_READ,smb.file,msg.hdr.offset);
355: smb_freemsgmem(&msg);
356: FREE(body);
357: FREE(tail); }
358: fseek(smb.sdt_fp,msg.hdr.offset,SEEK_SET);
359: if(lzh) {
360: xlat=XLAT_LZH;
361: fwrite(&xlat,2,1,smb.sdt_fp); }
362: xlat=XLAT_NONE;
363: fwrite(&xlat,2,1,smb.sdt_fp);
364: fwrite(body,bodylen,1,smb.sdt_fp);
365: smb_dfield(&msg,TEXT_BODY,bodylen+2+(lzh ? 2:0));
366: if(taillen) {
367: fwrite(&xlat,2,1,smb.sdt_fp);
368: fwrite(tail,taillen,1,smb.sdt_fp);
369: smb_dfield(&msg,TEXT_TAIL,taillen+2); }
370: fflush(smb.sdt_fp);
371: smb_unlocksmbhdr(&smb);
372:
373: if((i=smb_addmsghdr(&smb,&msg,storage))!=0)
374: errormsg(WHERE,ERR_WRITE,smb.file,i);
375:
376: smb_freemsgmem(&msg);
377:
378: LFREE(body);
379: LFREE(tail);
380:
381: return(true);
382: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.