Annotation of sbbs/src/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.30 2005/09/30 09:12:37 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 2005 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: /****************************************************************************/
        !            45: /* Loads an SMB message from the open msg base the fastest way possible        */
        !            46: /* first by offset, and if that's the wrong message, then by number.        */
        !            47: /* Returns 1 if the message was loaded and left locked, otherwise                      */
        !            48: /* !WARNING!: If you're going to write the msg index back to disk, you must */
        !            49: /* Call this function with a msg->idx.offset of 0 (so msg->offset will be      */
        !            50: /* initialized correctly)                                                                                                      */
        !            51: /****************************************************************************/
        !            52: int sbbs_t::loadmsg(smbmsg_t *msg, ulong number)
        !            53: {
        !            54:        char str[128];
        !            55:        int i;
        !            56: 
        !            57:        if(msg->idx.offset) {                           /* Load by offset if specified */
        !            58: 
        !            59:                if((i=smb_lockmsghdr(&smb,msg))!=0) {
        !            60:                        errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);
        !            61:                        return(0)        !            62:                }
        !            63: 
        !            64:                i=smb_getmsghdr(&smb,msg);
        !            65:                if(i==SMB_SUCCESS) {
        !            66:                        if(msg->hdr.number==number)
        !            67:                                return(1);
        !            68:                        /* Wrong offset  */
        !            69:                        smb_freemsgmem(msg);
        !            70:                }
        !            71: 
        !            72:                smb_unlockmsghdr(&smb,msg); 
        !            73:        }
        !            74: 
        !            75:        msg->hdr.number=number;
        !            76:        if((i=smb_getmsgidx(&smb,msg))!=SMB_SUCCESS)                             /* Message is deleted */
        !            77:                return(0);
        !            78:        if((i=smb_lockmsghdr(&smb,msg))!=SMB_SUCCESS) {
        !            79:                errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);
        !            80:                return(0)        !            81:        }
        !            82:        if((i=smb_getmsghdr(&smb,msg))!=SMB_SUCCESS) {
        !            83:                sprintf(str,"(%06lX) #%lu/%lu %s",msg->idx.offset,msg->idx.number
        !            84:                        ,number,smb.file);
        !            85:                smb_unlockmsghdr(&smb,msg);
        !            86:                errormsg(WHERE,ERR_READ,str,i,smb.last_error);
        !            87:                return(0)        !            88:        }
        !            89:        return(msg->total_hfields);
        !            90: }
        !            91: 
        !            92: 
        !            93: void sbbs_t::show_msgattr(ushort attr)
        !            94: {
        !            95: 
        !            96:        bprintf(text[MsgAttr]
        !            97:                ,attr&MSG_PRIVATE       ? "Private  "   :nulstr
        !            98:                ,attr&MSG_READ          ? "Read  "      :nulstr
        !            99:                ,attr&MSG_DELETE        ? "Deleted  "   :nulstr
        !           100:                ,attr&MSG_KILLREAD      ? "Kill  "      :nulstr
        !           101:                ,attr&MSG_ANONYMOUS ? "Anonymous  " :nulstr
        !           102:                ,attr&MSG_LOCKED        ? "Locked  "    :nulstr
        !           103:                ,attr&MSG_PERMANENT ? "Permanent  " :nulstr
        !           104:                ,attr&MSG_MODERATED ? "Moderated  " :nulstr
        !           105:                ,attr&MSG_VALIDATED ? "Validated  " :nulstr
        !           106:                ,attr&MSG_REPLIED       ? "Replied  "   :nulstr
        !           107:                ,nulstr
        !           108:                ,nulstr
        !           109:                ,nulstr
        !           110:                ,nulstr
        !           111:                ,nulstr
        !           112:                ,nulstr
        !           113:                );
        !           114: }
        !           115: 
        !           116: /****************************************************************************/
        !           117: /* Displays a message header to the screen                                  */
        !           118: /****************************************************************************/
        !           119: void sbbs_t::show_msghdr(smbmsg_t* msg)
        !           120: {
        !           121:        char    str[MAX_PATH+1];
        !           122:        char    *sender=NULL;
        !           123:        int     i;
        !           124: 
        !           125:        current_msg=msg;
        !           126:        attr(LIGHTGRAY);
        !           127:        if(useron.misc&CLRSCRN)
        !           128:                outchar(FF);
        !           129:        else
        !           130:                CRLF;
        !           131: 
        !           132:        sprintf(str,"%smenu/msghdr.*", cfg.text_dir);
        !           133:        if(fexist(str)) {
        !           134:                menu("msghdr");
        !           135:                current_msg=NULL;
        !           136:                return; 
        !           137:        }
        !           138: 
        !           139:        bprintf(text[MsgSubj],msg->subj);
        !           140:        if(msg->hdr.attr)
        !           141:                show_msgattr(msg->hdr.attr);
        !           142: 
        !           143:        bprintf(text[MsgTo],msg->to);
        !           144:        if(msg->to_ext)
        !           145:                bprintf(text[MsgToExt],msg->to_ext);
        !           146:        if(msg->to_net.addr)
        !           147:                bprintf(text[MsgToNet],smb_netaddr(&msg->to_net));
        !           148:        if(!(msg->hdr.attr&MSG_ANONYMOUS) || SYSOP) {
        !           149:                bprintf(text[MsgFrom],msg->from);
        !           150:                if(msg->from_ext)
        !           151:                        bprintf(text[MsgFromExt],msg->from_ext);
        !           152:                if(msg->from_net.addr && !strchr(msg->from,'@'))
        !           153:                        bprintf(text[MsgFromNet],smb_netaddr(&msg->from_net)); 
        !           154:        }
        !           155:        bprintf(text[MsgDate]
        !           156:                ,timestr((time_t *)&msg->hdr.when_written.time)
        !           157:                ,smb_zonestr(msg->hdr.when_written.zone,NULL));
        !           158: 
        !           159:        CRLF;
        !           160: 
        !           161:        for(i=0;i<msg->total_hfields;i++) {
        !           162:                if(msg->hfield[i].type==SENDER)
        !           163:                        sender=(char *)msg->hfield_dat[i];
        !           164:                if(msg->hfield[i].type==FORWARDED && sender)
        !           165:                        bprintf(text[ForwardedFrom],sender
        !           166:                                ,timestr((time_t *)msg->hfield_dat[i])); }
        !           167: 
        !           168:        /* Debug stuff
        !           169:        if(SYSOP) {
        !           170:                bprintf("\1n\1c\r\nAux  : \1h%08lX",msg->hdr.auxattr);
        !           171:                bprintf("\1n\1c\r\nNum  : \1h%lu",msg->hdr.number); }
        !           172:        */
        !           173: 
        !           174:        CRLF;
        !           175:        current_msg=NULL;
        !           176: }
        !           177: 
        !           178: /****************************************************************************/
        !           179: /* Displays message header and text (if not deleted)                        */
        !           180: /****************************************************************************/
        !           181: void sbbs_t::show_msg(smbmsg_t* msg, long mode)
        !           182: {
        !           183:        char*   text;
        !           184: 
        !           185:        show_msghdr(msg);
        !           186: 
        !           187:        if((text=smb_getmsgtxt(&smb,msg,GETMSGTXT_ALL))!=NULL) {
        !           188:                truncsp_lines(text);
        !           189:                putmsg(text, mode);
        !           190:                smb_freemsgtxt(text);
        !           191:        }
        !           192: }
        !           193: 
        !           194: void sbbs_t::quotemsg(smbmsg_t* msg, int tails)
        !           195: {
        !           196:        char    str[256];
        !           197:        char    tmp[13];
        !           198: 
        !           199:        strcpy(tmp,"QUOTES.TXT");
        !           200:        if(useron.xedit && cfg.xedit[useron.xedit-1]->misc&XTRN_LWRCASE)
        !           201:                strlwr(tmp);
        !           202:        sprintf(str,"%s%s",cfg.node_dir,tmp);
        !           203:        remove(str);
        !           204:        msgtotxt(msg,str,0,tails);
        !           205: }
        !           206: 
        !           207: 
        !           208: /****************************************************************************/
        !           209: /* Writes message header and text data to a text file                                          */
        !           210: /****************************************************************************/
        !           211: void sbbs_t::msgtotxt(smbmsg_t* msg, char *str, int header, int tails)
        !           212: {
        !           213:        char    *buf;
        !           214:        int     i;
        !           215:        FILE    *out;
        !           216: 
        !           217:        if((out=fnopen(&i,str,O_WRONLY|O_CREAT|O_APPEND))==NULL) {
        !           218:                errormsg(WHERE,ERR_OPEN,str,0);
        !           219:                return; }
        !           220:        if(header) {
        !           221:                fprintf(out,"\r\n");
        !           222:                fprintf(out,"Subj : %s\r\n",msg->subj);
        !           223:                fprintf(out,"To   : %s",msg->to);
        !           224:                if(msg->to_ext)
        !           225:                        fprintf(out," #%s",msg->to_ext);
        !           226:                if(msg->to_net.addr)
        !           227:                        fprintf(out," (%s)",smb_netaddr(&msg->to_net));
        !           228:                fprintf(out,"\r\nFrom : %s",msg->from);
        !           229:                if(msg->from_ext && !(msg->hdr.attr&MSG_ANONYMOUS))
        !           230:                        fprintf(out," #%s",msg->from_ext);
        !           231:                if(msg->from_net.addr)
        !           232:                        fprintf(out," (%s)",smb_netaddr(&msg->from_net));
        !           233:                fprintf(out,"\r\nDate : %.24s %s"
        !           234:                        ,timestr((time_t *)&msg->hdr.when_written.time)
        !           235:                        ,smb_zonestr(msg->hdr.when_written.zone,NULL));
        !           236:                fprintf(out,"\r\n\r\n"); }
        !           237: 
        !           238:        buf=smb_getmsgtxt(&smb,msg,tails);
        !           239:        if(buf!=NULL) {
        !           240:                fputs(buf,out);
        !           241:                smb_freemsgtxt(buf); 
        !           242:        } else if(smb_getmsgdatlen(msg)>2)
        !           243:                errormsg(WHERE,ERR_READ,smb.file,smb_getmsgdatlen(msg));
        !           244:        fclose(out);
        !           245: }
        !           246: 
        !           247: /****************************************************************************/
        !           248: /* Returns message number posted at or after time                                                      */
        !           249: /****************************************************************************/
        !           250: ulong sbbs_t::getmsgnum(uint subnum, time_t t)
        !           251: {
        !           252:     int     i;
        !           253:        ulong   l,total,bot,top;
        !           254:        smbmsg_t msg;
        !           255: 
        !           256:        if(!t)
        !           257:                return(0);
        !           258: 
        !           259:        sprintf(smb.file,"%s%s",cfg.sub[subnum]->data_dir,cfg.sub[subnum]->code);
        !           260:        smb.retry_time=cfg.smb_retry_time;
        !           261:        smb.subnum=subnum;
        !           262:        if((i=smb_open(&smb))!=0) {
        !           263:                errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
        !           264:                return(0); }
        !           265: 
        !           266:        total=filelength(fileno(smb.sid_fp))/sizeof(idxrec_t);
        !           267: 
        !           268:        if(!total) {               /* Empty base */
        !           269:                smb_close(&smb);
        !           270:                return(0); }
        !           271: 
        !           272:        if((i=smb_locksmbhdr(&smb))!=0) {
        !           273:                smb_close(&smb);
        !           274:                errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);
        !           275:                return(0); }
        !           276: 
        !           277:        if((i=smb_getlastidx(&smb,&msg.idx))!=0) {
        !           278:                smb_close(&smb);
        !           279:                errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error);
        !           280:                return(0); }
        !           281: 
        !           282:        if((time_t)msg.idx.time<=t) {
        !           283:                smb_close(&smb);
        !           284:                return(msg.idx.number); }
        !           285: 
        !           286:        bot=0;
        !           287:        top=total;
        !           288:        l=total/2; /* Start at middle index */
        !           289:        clearerr(smb.sid_fp);
        !           290:        while(1) {
        !           291:                fseek(smb.sid_fp,l*sizeof(idxrec_t),SEEK_SET);
        !           292:                if(!fread(&msg.idx,sizeof(idxrec_t),1,smb.sid_fp))
        !           293:                        break;
        !           294:                if(bot==top-1)
        !           295:                        break;
        !           296:                if((time_t)msg.idx.time>t) {
        !           297:                        top=l;
        !           298:                        l=bot+((top-bot)/2);
        !           299:                        continue; }
        !           300:                if((time_t)msg.idx.time<t) {
        !           301:                        bot=l;
        !           302:                        l=top-((top-bot)/2);
        !           303:                        continue; }
        !           304:                break; }
        !           305:        smb_close(&smb);
        !           306:        return(msg.idx.number);
        !           307: }
        !           308: 
        !           309: /****************************************************************************/
        !           310: /* Returns the time of the message number pointed to by 'ptr'               */
        !           311: /****************************************************************************/
        !           312: time_t sbbs_t::getmsgtime(uint subnum, ulong ptr)
        !           313: {
        !           314:        int     i;
        !           315:        smbmsg_t msg;
        !           316:        idxrec_t lastidx;
        !           317: 
        !           318:        sprintf(smb.file,"%s%s",cfg.sub[subnum]->data_dir,cfg.sub[subnum]->code);
        !           319:        smb.retry_time=cfg.smb_retry_time;
        !           320:        smb.subnum=subnum;
        !           321:        if((i=smb_open(&smb))!=0) {
        !           322:                errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
        !           323:                return(0); }
        !           324:        if(!filelength(fileno(smb.sid_fp))) {                   /* Empty base */
        !           325:                smb_close(&smb);
        !           326:                return(0); }
        !           327:        msg.offset=0;
        !           328:        msg.hdr.number=0;
        !           329:        if(smb_getmsgidx(&smb,&msg)) {                          /* Get first message index */
        !           330:                smb_close(&smb);
        !           331:                return(0); }
        !           332:        if(!ptr || msg.idx.number>=ptr) {                       /* ptr is before first message */
        !           333:                smb_close(&smb);
        !           334:                return(msg.idx.time); }                                 /* so return time of first msg */
        !           335: 
        !           336:        if(smb_getlastidx(&smb,&lastidx)) {                      /* Get last message index */
        !           337:                smb_close(&smb);
        !           338:                return(0); }
        !           339:        if(lastidx.number<ptr) {                                        /* ptr is after last message */
        !           340:                smb_close(&smb);
        !           341:                return(lastidx.time); }                                 /* so return time of last msg */
        !           342: 
        !           343:        msg.idx.time=0;
        !           344:        msg.hdr.number=ptr;
        !           345:        if(!smb_getmsgidx(&smb,&msg)) {
        !           346:                smb_close(&smb);
        !           347:                return(msg.idx.time); }
        !           348: 
        !           349:        if(ptr-msg.idx.number < lastidx.number-ptr) {
        !           350:                msg.offset=0;
        !           351:                msg.idx.number=0;
        !           352:                while(msg.idx.number<ptr) {
        !           353:                        msg.hdr.number=0;
        !           354:                        if(smb_getmsgidx(&smb,&msg) || msg.idx.number>=ptr)
        !           355:                                break;
        !           356:                        msg.offset++; }
        !           357:                smb_close(&smb);
        !           358:                return(msg.idx.time); }
        !           359: 
        !           360:        ptr--;
        !           361:        while(ptr) {
        !           362:                msg.hdr.number=ptr;
        !           363:                if(!smb_getmsgidx(&smb,&msg))
        !           364:                        break;
        !           365:                ptr--; }
        !           366:        smb_close(&smb);
        !           367:        return(msg.idx.time);
        !           368: }
        !           369: 
        !           370: 
        !           371: /****************************************************************************/
        !           372: /* Returns the total number of msgs in the sub-board and sets 'ptr' to the  */
        !           373: /* number of the last message in the sub (0) if no messages.                           */
        !           374: /****************************************************************************/
        !           375: ulong sbbs_t::getlastmsg(uint subnum, ulong *ptr, time_t *t)
        !           376: {
        !           377:        int             i;
        !           378:        ulong           total;
        !           379:        idxrec_t        idx;
        !           380: 
        !           381:        if(ptr)
        !           382:                (*ptr)=0;
        !           383:        if(t)
        !           384:                (*t)=0;
        !           385:        if(subnum>=cfg.total_subs)
        !           386:                return(0);
        !           387: 
        !           388:        sprintf(smb.file,"%s%s",cfg.sub[subnum]->data_dir,cfg.sub[subnum]->code);
        !           389:        smb.retry_time=cfg.smb_retry_time;
        !           390:        smb.subnum=subnum;
        !           391:        if((i=smb_open(&smb))!=0) {
        !           392:                errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
        !           393:                return(0); }
        !           394: 
        !           395:        if(!filelength(fileno(smb.sid_fp))) {                   /* Empty base */
        !           396:                smb_close(&smb);
        !           397:                return(0); }
        !           398:        if((i=smb_locksmbhdr(&smb))!=0) {
        !           399:                smb_close(&smb);
        !           400:                errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);
        !           401:                return(0); }
        !           402:        if((i=smb_getlastidx(&smb,&idx))!=0) {
        !           403:                smb_close(&smb);
        !           404:                errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error);
        !           405:                return(0); }
        !           406:        total=filelength(fileno(smb.sid_fp))/sizeof(idxrec_t);
        !           407:        smb_unlocksmbhdr(&smb);
        !           408:        smb_close(&smb);
        !           409:        if(ptr)
        !           410:                (*ptr)=idx.number;
        !           411:        if(t)
        !           412:                (*t)=idx.time;
        !           413:        return(total);
        !           414: }
        !           415: 

unix.superglobalmegacorp.com

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