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