Annotation of sbbs/sbbs3/getmsg.cpp, revision 1.1.1.1

1.1       root        1: /* getmsg.cpp */
                      2: 
                      3: /* Synchronet message retrieval functions */
                      4: 
                      5: /* $Id: getmsg.cpp,v 1.3 2000/12/11 23:03:16 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: /***********************************************************************/
                     39: /* Functions that do i/o with messages (posts/mail/auto) or their data */
                     40: /***********************************************************************/
                     41: 
                     42: #include "sbbs.h"
                     43: 
                     44: #define LZH TRUE
                     45: 
                     46: void lfputs(char HUGE16 *buf, FILE *fp)
                     47: {
                     48:        while(*buf) {
                     49:                fputc(*buf,fp);
                     50:                buf++; }
                     51: }
                     52: 
                     53: /****************************************************************************/
                     54: /* Loads an SMB message from the open msg base the fastest way possible        */
                     55: /* first by offset, and if that's the wrong message, then by number.        */
                     56: /* Returns 1 if the message was loaded and left locked, otherwise                      */
                     57: /****************************************************************************/
                     58: int sbbs_t::loadmsg(smbmsg_t *msg, ulong number)
                     59: {
                     60:        char str[128];
                     61:        int i;
                     62: 
                     63:        if(msg->idx.offset) {                           /* Load by offset if specified */
                     64: 
                     65:                if((i=smb_lockmsghdr(&smb,msg))!=0) {
                     66:                        errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);
                     67:                        return(0); }
                     68: 
                     69:                i=smb_getmsghdr(&smb,msg);
                     70:                if(!i && msg->hdr.number==number)
                     71:                        return(1);
                     72: 
                     73:                /* Wrong offset  */
                     74: 
                     75:                if(!i) {
                     76:                        smb_freemsgmem(msg);
                     77:                        msg->total_hfields=0; }
                     78: 
                     79:                smb_unlockmsghdr(&smb,msg); }
                     80: 
                     81:        msg->hdr.number=number;
                     82:        if((i=smb_getmsgidx(&smb,msg))!=0)                               /* Message is deleted */
                     83:                return(0);
                     84:        if((i=smb_lockmsghdr(&smb,msg))!=0) {
                     85:                errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);
                     86:                return(0); }
                     87:        if((i=smb_getmsghdr(&smb,msg))!=0) {
                     88:                sprintf(str,"(%06lX) #%lu/%lu %s",msg->idx.offset,msg->idx.number
                     89:                        ,number,smb.file);
                     90:                smb_unlockmsghdr(&smb,msg);
                     91:                errormsg(WHERE,ERR_READ,str,i,smb.last_error);
                     92:                return(0); }
                     93:        return(msg->total_hfields);
                     94: }
                     95: 
                     96: 
                     97: void sbbs_t::show_msgattr(ushort attr)
                     98: {
                     99: 
                    100:        bprintf(text[MsgAttr]
                    101:                ,attr&MSG_PRIVATE       ? "Private  "   :nulstr
                    102:                ,attr&MSG_READ          ? "Read  "      :nulstr
                    103:                ,attr&MSG_DELETE        ? "Deleted  "   :nulstr
                    104:                ,attr&MSG_KILLREAD      ? "Kill  "      :nulstr
                    105:                ,attr&MSG_ANONYMOUS ? "Anonymous  " :nulstr
                    106:                ,attr&MSG_LOCKED        ? "Locked  "    :nulstr
                    107:                ,attr&MSG_PERMANENT ? "Permanent  " :nulstr
                    108:                ,attr&MSG_MODERATED ? "Moderated  " :nulstr
                    109:                ,attr&MSG_VALIDATED ? "Validated  " :nulstr
                    110:                ,attr&MSG_REPLIED       ? "Replied  "   :nulstr
                    111:                ,nulstr
                    112:                ,nulstr
                    113:                ,nulstr
                    114:                ,nulstr
                    115:                ,nulstr
                    116:                ,nulstr
                    117:                );
                    118: }
                    119: 
                    120: /****************************************************************************/
                    121: /* Displays a message header to the screen                                  */
                    122: /****************************************************************************/
                    123: void sbbs_t::show_msghdr(smbmsg_t* msg)
                    124: {
                    125:        char    *sender=NULL;
                    126:        int     i;
                    127: 
                    128:        attr(LIGHTGRAY);
                    129:        if(useron.misc&CLRSCRN)
                    130:                outchar(FF);
                    131:        else
                    132:                CRLF;
                    133:        bprintf(text[MsgSubj],msg->subj);
                    134:        if(msg->hdr.attr)
                    135:                show_msgattr(msg->hdr.attr);
                    136: 
                    137:        bprintf(text[MsgTo],msg->to);
                    138:        if(msg->to_ext)
                    139:                bprintf(text[MsgToExt],msg->to_ext);
                    140:        if(msg->to_net.addr)
                    141:                bprintf(text[MsgToNet],msg->to_net.type==NET_FIDO
                    142:                        ? faddrtoa(*(faddr_t *)msg->to_net.addr) : msg->to_net.addr);
                    143:        if(!(msg->hdr.attr&MSG_ANONYMOUS) || SYSOP) {
                    144:                bprintf(text[MsgFrom],msg->from);
                    145:                if(msg->from_ext)
                    146:                        bprintf(text[MsgFromExt],msg->from_ext);
                    147:                if(msg->from_net.addr && !strchr(msg->from,'@'))
                    148:                        bprintf(text[MsgFromNet],msg->from_net.type==NET_FIDO
                    149:                                ? faddrtoa(*(faddr_t *)msg->from_net.addr)
                    150:                                        : msg->from_net.addr); }
                    151:        bprintf(text[MsgDate]
                    152:                ,timestr((time_t *)&msg->hdr.when_written.time)
                    153:                ,zonestr(msg->hdr.when_written.zone));
                    154: 
                    155:        CRLF;
                    156: 
                    157:        for(i=0;i<msg->total_hfields;i++) {
                    158:                if(msg->hfield[i].type==SENDER)
                    159:                        sender=(char *)msg->hfield_dat[i];
                    160:                if(msg->hfield[i].type==FORWARDED && sender)
                    161:                        bprintf(text[ForwardedFrom],sender
                    162:                                ,timestr((time_t *)msg->hfield_dat[i])); }
                    163: 
                    164:        /* Debug stuff
                    165:        if(SYSOP) {
                    166:                bprintf("\1n\1c\r\nAux  : \1h%08lX",msg->hdr.auxattr);
                    167:                bprintf("\1n\1c\r\nNum  : \1h%lu",msg->hdr.number); }
                    168:        */
                    169: 
                    170:        CRLF;
                    171: }
                    172: 
                    173: #if !LZH
                    174: 
                    175: /****************************************************************************/
                    176: /* Displays message header and text (if not deleted)                        */
                    177: /****************************************************************************/
                    178: void sbbs_t::show_msg(smbmsg_t msg, long mode)
                    179: {
                    180:        ushort xlat;
                    181:     int i;
                    182: 
                    183:        show_msghdr(msg);
                    184:        for(i=0;i<msg.hdr.total_dfields;i++)
                    185:                switch(msg.dfield[i].type) {
                    186:                        case TEXT_BODY:
                    187:                        case TEXT_TAIL:
                    188:                                smb_fseek(smb.sdt_fp,msg.hdr.offset+msg.dfield[i].offset
                    189:                                        ,SEEK_SET);
                    190:                                smb_fread(&xlat,2,1,smb.sdt_fp);
                    191:                                if(xlat!=XLAT_NONE)             /* no translations supported */
                    192:                                        continue;
                    193:                                putmsg_fp(smb.sdt_fp,msg.dfield[i].length-2,mode);
                    194:                                CRLF;
                    195:                                break; }
                    196: }
                    197: 
                    198: #else
                    199: 
                    200: /****************************************************************************/
                    201: /* Displays message header and text (if not deleted)                        */
                    202: /****************************************************************************/
                    203: void sbbs_t::show_msg(smbmsg_t* msg, long mode)
                    204: {
                    205:        uchar *inbuf,*lzhbuf;
                    206:        ushort xlat;
                    207:        int i,lzh;
                    208:        long lzhlen,length;
                    209: 
                    210:        show_msghdr(msg);
                    211:        for(i=0;i<msg->hdr.total_dfields;i++)
                    212:                switch(msg->dfield[i].type) {
                    213:                        case TEXT_BODY:
                    214:                        case TEXT_TAIL:
                    215:                                fseek(smb.sdt_fp,msg->hdr.offset+msg->dfield[i].offset
                    216:                                        ,SEEK_SET);
                    217:                                fread(&xlat,2,1,smb.sdt_fp);
                    218:                                lzh=0;
                    219:                                if(xlat==XLAT_LZH) {
                    220:                                        lzh=1;
                    221:                                        fread(&xlat,2,1,smb.sdt_fp); }
                    222:                                if(xlat!=XLAT_NONE)             /* no translations supported */
                    223:                                        continue;
                    224:                                if(lzh) {
                    225:                                        length=msg->dfield[i].length-4;
                    226:                                        if((inbuf=(uchar *)MALLOC(length))==NULL) {
                    227:                                                errormsg(WHERE,ERR_ALLOC,nulstr,length);
                    228:                                                continue; }
                    229:                                        fread(inbuf,length,1,smb.sdt_fp);
                    230:                                        lzhlen=*(long *)inbuf;
                    231:        /**
                    232:                                        if(SYSOP)
                    233:                                        bprintf("Decoding %lu bytes of LZH into %lu bytes of text "
                    234:                                                "(%d%% compression)"
                    235:                                                ,length,lzhlen
                    236:                                                ,(int)(((float)(lzhlen-length)/lzhlen)*100.0));
                    237:        **/
                    238:                                        if((lzhbuf=(uchar *)MALLOC(lzhlen+2L))==NULL) {
                    239:                                                FREE(inbuf);
                    240:                                                errormsg(WHERE,ERR_ALLOC,nulstr,lzhlen+2L);
                    241:                                                continue; }
                    242:                                        lzh_decode(inbuf,length,lzhbuf);
                    243:                                        lzhbuf[lzhlen]=0;
                    244:        //                                CRLF;
                    245:                                        putmsg((char *)lzhbuf,P_NOATCODES);
                    246:                                        FREE(lzhbuf);
                    247:                                        FREE(inbuf); }
                    248:                                else
                    249:                                        putmsg_fp(smb.sdt_fp,msg->dfield[i].length-2,mode);
                    250:                                CRLF;
                    251:                                break; }
                    252: }
                    253: 
                    254: #endif
                    255: 
                    256: void sbbs_t::quotemsg(smbmsg_t* msg, int tails)
                    257: {
                    258:        char    str[256];
                    259: 
                    260:        sprintf(str,"%sQUOTES.TXT",cfg.node_dir);
                    261:        remove(str);
                    262:        msgtotxt(msg,str,0,tails);
                    263: }
                    264: 
                    265: 
                    266: /****************************************************************************/
                    267: /* Writes message header and text data to a text file                                          */
                    268: /****************************************************************************/
                    269: void sbbs_t::msgtotxt(smbmsg_t* msg, char *str, int header, int tails)
                    270: {
                    271:        char    HUGE16 *buf;
                    272:        int     i;
                    273:        FILE    *out;
                    274: 
                    275:        if((out=fnopen(&i,str,O_WRONLY|O_CREAT|O_APPEND))==NULL) {
                    276:                errormsg(WHERE,ERR_OPEN,str,0);
                    277:                return; }
                    278:        if(header) {
                    279:                fprintf(out,"\r\n");
                    280:                fprintf(out,"Subj : %s\r\n",msg->subj);
                    281:                fprintf(out,"To   : %s",msg->to);
                    282:                if(msg->to_ext)
                    283:                        fprintf(out," #%s",msg->to_ext);
                    284:                if(msg->to_net.addr)
                    285:                        fprintf(out," (%s)",msg->to_net.type==NET_FIDO
                    286:                                ? faddrtoa(*(faddr_t *)msg->to_net.addr) : msg->to_net.addr);
                    287:                fprintf(out,"\r\nFrom : %s",msg->from);
                    288:                if(msg->from_ext && !(msg->hdr.attr&MSG_ANONYMOUS))
                    289:                        fprintf(out," #%s",msg->from_ext);
                    290:                if(msg->from_net.addr)
                    291:                        fprintf(out," (%s)",msg->from_net.type==NET_FIDO
                    292:                                ? faddrtoa(*(faddr_t *)msg->from_net.addr)
                    293:                                        : msg->from_net.addr);
                    294:                fprintf(out,"\r\nDate : %.24s %s"
                    295:                        ,timestr((time_t *)&msg->hdr.when_written.time)
                    296:                        ,zonestr(msg->hdr.when_written.zone));
                    297:                fprintf(out,"\r\n\r\n"); }
                    298: 
                    299:        buf=smb_getmsgtxt(&smb,msg,tails);
                    300:        if(buf!=NULL) {
                    301:                lfputs(buf,out);
                    302:                LFREE(buf); 
                    303:        } else if(smb_getmsgdatlen(msg)>2)
                    304:                errormsg(WHERE,ERR_READ,smb.file,smb_getmsgdatlen(msg));
                    305:        fclose(out);
                    306: }
                    307: 
                    308: 
                    309: /****************************************************************************/
                    310: /* Returns total number of posts in a sub-board                                                        */
                    311: /****************************************************************************/
                    312: ulong sbbs_t::getposts(uint subnum)
                    313: {
                    314:        char str[128];
                    315:        ulong l;
                    316: 
                    317:        sprintf(str,"%s%s.sid",cfg.sub[subnum]->data_dir,cfg.sub[subnum]->code);
                    318:        l=flength(str);
                    319:        if((long)l==-1)
                    320:                return(0);
                    321:        return(l/sizeof(idxrec_t));
                    322: }
                    323: 
                    324: /****************************************************************************/
                    325: /* Returns message number posted at or after time                                                      */
                    326: /****************************************************************************/
                    327: ulong sbbs_t::getmsgnum(uint subnum, time_t t)
                    328: {
                    329:     int     i;
                    330:        ulong   l,total,bot,top;
                    331:        smbmsg_t msg;
                    332: 
                    333:        if(!t)
                    334:                return(0);
                    335: 
                    336:        sprintf(smb.file,"%s%s",cfg.sub[subnum]->data_dir,cfg.sub[subnum]->code);
                    337:        smb.retry_time=cfg.smb_retry_time;
                    338:        if((i=smb_open(&smb))!=0) {
                    339:                errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
                    340:                return(0); }
                    341: 
                    342:        total=filelength(fileno(smb.sid_fp))/sizeof(idxrec_t);
                    343: 
                    344:        if(!total) {               /* Empty base */
                    345:                smb_close(&smb);
                    346:                return(0); }
                    347: 
                    348:        if((i=smb_locksmbhdr(&smb))!=0) {
                    349:                smb_close(&smb);
                    350:                errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);
                    351:                return(0); }
                    352: 
                    353:        if((i=smb_getlastidx(&smb,&msg.idx))!=0) {
                    354:                smb_close(&smb);
                    355:                errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error);
                    356:                return(0); }
                    357: 
                    358:        if((time_t)msg.idx.time<=t) {
                    359:                smb_close(&smb);
                    360:                return(msg.idx.number); }
                    361: 
                    362:        bot=0;
                    363:        top=total;
                    364:        l=total/2; /* Start at middle index */
                    365:        clearerr(smb.sid_fp);
                    366:        while(1) {
                    367:                fseek(smb.sid_fp,l*sizeof(idxrec_t),SEEK_SET);
                    368:                if(!fread(&msg.idx,sizeof(idxrec_t),1,smb.sid_fp))
                    369:                        break;
                    370:                if(bot==top-1)
                    371:                        break;
                    372:                if((time_t)msg.idx.time>t) {
                    373:                        top=l;
                    374:                        l=bot+((top-bot)/2);
                    375:                        continue; }
                    376:                if((time_t)msg.idx.time<t) {
                    377:                        bot=l;
                    378:                        l=top-((top-bot)/2);
                    379:                        continue; }
                    380:                break; }
                    381:        smb_close(&smb);
                    382:        return(msg.idx.number);
                    383: }
                    384: 
                    385: /****************************************************************************/
                    386: /* Returns the time of the message number pointed to by 'ptr'               */
                    387: /****************************************************************************/
                    388: time_t sbbs_t::getmsgtime(uint subnum, ulong ptr)
                    389: {
                    390:        int     i;
                    391:        smbmsg_t msg;
                    392:        idxrec_t lastidx;
                    393: 
                    394:        sprintf(smb.file,"%s%s",cfg.sub[subnum]->data_dir,cfg.sub[subnum]->code);
                    395:        smb.retry_time=cfg.smb_retry_time;
                    396:        if((i=smb_open(&smb))!=0) {
                    397:                errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
                    398:                return(0); }
                    399:        if(!filelength(fileno(smb.sid_fp))) {                   /* Empty base */
                    400:                smb_close(&smb);
                    401:                return(0); }
                    402:        msg.offset=0;
                    403:        msg.hdr.number=0;
                    404:        if(smb_getmsgidx(&smb,&msg)) {                          /* Get first message index */
                    405:                smb_close(&smb);
                    406:                return(0); }
                    407:        if(!ptr || msg.idx.number>=ptr) {                       /* ptr is before first message */
                    408:                smb_close(&smb);
                    409:                return(msg.idx.time); }                                 /* so return time of first msg */
                    410: 
                    411:        if(smb_getlastidx(&smb,&lastidx)) {                      /* Get last message index */
                    412:                smb_close(&smb);
                    413:                return(0); }
                    414:        if(lastidx.number<ptr) {                                        /* ptr is after last message */
                    415:                smb_close(&smb);
                    416:                return(lastidx.time); }                                 /* so return time of last msg */
                    417: 
                    418:        msg.idx.time=0;
                    419:        msg.hdr.number=ptr;
                    420:        if(!smb_getmsgidx(&smb,&msg)) {
                    421:                smb_close(&smb);
                    422:                return(msg.idx.time); }
                    423: 
                    424:        if(ptr-msg.idx.number < lastidx.number-ptr) {
                    425:                msg.offset=0;
                    426:                msg.idx.number=0;
                    427:                while(msg.idx.number<ptr) {
                    428:                        msg.hdr.number=0;
                    429:                        if(smb_getmsgidx(&smb,&msg) || msg.idx.number>=ptr)
                    430:                                break;
                    431:                        msg.offset++; }
                    432:                smb_close(&smb);
                    433:                return(msg.idx.time); }
                    434: 
                    435:        ptr--;
                    436:        while(ptr) {
                    437:                msg.hdr.number=ptr;
                    438:                if(!smb_getmsgidx(&smb,&msg))
                    439:                        break;
                    440:                ptr--; }
                    441:        smb_close(&smb);
                    442:        return(msg.idx.time);
                    443: }
                    444: 
                    445: 
                    446: /****************************************************************************/
                    447: /* Returns the total number of msgs in the sub-board and sets 'ptr' to the  */
                    448: /* number of the last message in the sub (0) if no messages.                           */
                    449: /****************************************************************************/
                    450: ulong sbbs_t::getlastmsg(uint subnum, ulong *ptr, time_t *t)
                    451: {
                    452:        int             i;
                    453:        ulong           total;
                    454:        idxrec_t        idx;
                    455: 
                    456:        if(ptr)
                    457:                (*ptr)=0;
                    458:        if(t)
                    459:                (*t)=0;
                    460:        if(subnum>=cfg.total_subs)
                    461:                return(0);
                    462: 
                    463:        sprintf(smb.file,"%s%s",cfg.sub[subnum]->data_dir,cfg.sub[subnum]->code);
                    464:        smb.retry_time=cfg.smb_retry_time;
                    465:        if((i=smb_open(&smb))!=0) {
                    466:                errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
                    467:                return(0); }
                    468: 
                    469:        if(!filelength(fileno(smb.sid_fp))) {                   /* Empty base */
                    470:                smb_close(&smb);
                    471:                return(0); }
                    472:        if((i=smb_locksmbhdr(&smb))!=0) {
                    473:                smb_close(&smb);
                    474:                errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);
                    475:                return(0); }
                    476:        if((i=smb_getlastidx(&smb,&idx))!=0) {
                    477:                smb_close(&smb);
                    478:                errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error);
                    479:                return(0); }
                    480:        total=filelength(fileno(smb.sid_fp))/sizeof(idxrec_t);
                    481:        smb_unlocksmbhdr(&smb);
                    482:        smb_close(&smb);
                    483:        if(ptr)
                    484:                (*ptr)=idx.number;
                    485:        if(t)
                    486:                (*t)=idx.time;
                    487:        return(total);
                    488: }
                    489: 

unix.superglobalmegacorp.com

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