Annotation of sbbs/sbbs3/getmsg.cpp, revision 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.