|
|
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.