Annotation of sbbs/src/sbbs3/qwktomsg.cpp, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.