Annotation of sbbs/src/sbbs3/getmsg.cpp, revision 1.1.1.2

1.1       root        1: /* getmsg.cpp */
                      2: 
                      3: /* Synchronet message retrieval functions */
                      4: 
1.1.1.2 ! root        5: /* $Id: getmsg.cpp,v 1.39 2011/08/25 19:22:44 rswindell Exp $ */
1.1       root        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:  *                                                                                                                                                     *
1.1.1.2 ! root       11:  * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html         *
1.1       root       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
1.1.1.2 ! root      107:                ,attr&MSG_NOREPLY       ? "NoReply  "   :nulstr
1.1       root      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)
1.1.1.2 ! root      147:                bprintf(text[MsgToNet],smb_netaddrstr(&msg->to_net,str));
1.1       root      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,'@'))
1.1.1.2 ! root      153:                        bprintf(text[MsgFromNet],smb_netaddrstr(&msg->from_net,str)); 
1.1       root      154:        }
                    155:        bprintf(text[MsgDate]
1.1.1.2 ! root      156:                ,timestr(msg->hdr.when_written.time)
1.1       root      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
1.1.1.2 ! root      166:                                ,timestr(*(time32_t *)msg->hfield_dat[i])); 
        !           167:        }
1.1       root      168: 
                    169:        /* Debug stuff
                    170:        if(SYSOP) {
                    171:                bprintf("\1n\1c\r\nAux  : \1h%08lX",msg->hdr.auxattr);
1.1.1.2 ! root      172:                bprintf("\1n\1c\r\nNum  : \1h%lu",msg->hdr.number); 
        !           173:                }
1.1       root      174:        */
                    175: 
                    176:        CRLF;
                    177:        current_msg=NULL;
                    178: }
                    179: 
                    180: /****************************************************************************/
                    181: /* Displays message header and text (if not deleted)                        */
                    182: /****************************************************************************/
                    183: void sbbs_t::show_msg(smbmsg_t* msg, long mode)
                    184: {
                    185:        char*   text;
                    186: 
                    187:        show_msghdr(msg);
                    188: 
                    189:        if((text=smb_getmsgtxt(&smb,msg,GETMSGTXT_ALL))!=NULL) {
                    190:                truncsp_lines(text);
                    191:                putmsg(text, mode);
                    192:                smb_freemsgtxt(text);
                    193:        }
                    194: }
                    195: 
                    196: /****************************************************************************/
                    197: /* Writes message header and text data to a text file                                          */
                    198: /****************************************************************************/
                    199: void sbbs_t::msgtotxt(smbmsg_t* msg, char *str, int header, int tails)
                    200: {
                    201:        char    *buf;
1.1.1.2 ! root      202:        char    tmp[128];
1.1       root      203:        int     i;
                    204:        FILE    *out;
                    205: 
                    206:        if((out=fnopen(&i,str,O_WRONLY|O_CREAT|O_APPEND))==NULL) {
                    207:                errormsg(WHERE,ERR_OPEN,str,0);
1.1.1.2 ! root      208:                return; 
        !           209:        }
1.1       root      210:        if(header) {
                    211:                fprintf(out,"\r\n");
                    212:                fprintf(out,"Subj : %s\r\n",msg->subj);
                    213:                fprintf(out,"To   : %s",msg->to);
                    214:                if(msg->to_ext)
                    215:                        fprintf(out," #%s",msg->to_ext);
                    216:                if(msg->to_net.addr)
1.1.1.2 ! root      217:                        fprintf(out," (%s)",smb_netaddrstr(&msg->to_net,tmp));
1.1       root      218:                fprintf(out,"\r\nFrom : %s",msg->from);
                    219:                if(msg->from_ext && !(msg->hdr.attr&MSG_ANONYMOUS))
                    220:                        fprintf(out," #%s",msg->from_ext);
                    221:                if(msg->from_net.addr)
1.1.1.2 ! root      222:                        fprintf(out," (%s)",smb_netaddrstr(&msg->from_net,tmp));
1.1       root      223:                fprintf(out,"\r\nDate : %.24s %s"
1.1.1.2 ! root      224:                        ,timestr(msg->hdr.when_written.time)
1.1       root      225:                        ,smb_zonestr(msg->hdr.when_written.zone,NULL));
1.1.1.2 ! root      226:                fprintf(out,"\r\n\r\n"); 
        !           227:        }
1.1       root      228: 
                    229:        buf=smb_getmsgtxt(&smb,msg,tails);
                    230:        if(buf!=NULL) {
1.1.1.2 ! root      231:                strip_invalid_attr(buf);
1.1       root      232:                fputs(buf,out);
                    233:                smb_freemsgtxt(buf); 
                    234:        } else if(smb_getmsgdatlen(msg)>2)
                    235:                errormsg(WHERE,ERR_READ,smb.file,smb_getmsgdatlen(msg));
                    236:        fclose(out);
                    237: }
                    238: 
                    239: /****************************************************************************/
                    240: /* Returns message number posted at or after time                                                      */
                    241: /****************************************************************************/
                    242: ulong sbbs_t::getmsgnum(uint subnum, time_t t)
                    243: {
                    244:     int     i;
                    245:        ulong   l,total,bot,top;
                    246:        smbmsg_t msg;
                    247: 
                    248:        if(!t)
                    249:                return(0);
                    250: 
                    251:        sprintf(smb.file,"%s%s",cfg.sub[subnum]->data_dir,cfg.sub[subnum]->code);
                    252:        smb.retry_time=cfg.smb_retry_time;
                    253:        smb.subnum=subnum;
                    254:        if((i=smb_open(&smb))!=0) {
                    255:                errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
1.1.1.2 ! root      256:                return(0)        !           257:        }
1.1       root      258: 
1.1.1.2 ! root      259:        total=(long)filelength(fileno(smb.sid_fp))/sizeof(idxrec_t);
1.1       root      260: 
                    261:        if(!total) {               /* Empty base */
                    262:                smb_close(&smb);
1.1.1.2 ! root      263:                return(0)        !           264:        }
1.1       root      265: 
                    266:        if((i=smb_locksmbhdr(&smb))!=0) {
                    267:                smb_close(&smb);
                    268:                errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);
1.1.1.2 ! root      269:                return(0)        !           270:        }
1.1       root      271: 
                    272:        if((i=smb_getlastidx(&smb,&msg.idx))!=0) {
                    273:                smb_close(&smb);
                    274:                errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error);
1.1.1.2 ! root      275:                return(0)        !           276:        }
1.1       root      277: 
                    278:        if((time_t)msg.idx.time<=t) {
                    279:                smb_close(&smb);
1.1.1.2 ! root      280:                return(msg.idx.number); 
        !           281:        }
1.1       root      282: 
                    283:        bot=0;
                    284:        top=total;
                    285:        l=total/2; /* Start at middle index */
                    286:        clearerr(smb.sid_fp);
                    287:        while(1) {
                    288:                fseek(smb.sid_fp,l*sizeof(idxrec_t),SEEK_SET);
                    289:                if(!fread(&msg.idx,sizeof(idxrec_t),1,smb.sid_fp))
                    290:                        break;
                    291:                if(bot==top-1)
                    292:                        break;
                    293:                if((time_t)msg.idx.time>t) {
                    294:                        top=l;
                    295:                        l=bot+((top-bot)/2);
1.1.1.2 ! root      296:                        continue; 
        !           297:                }
1.1       root      298:                if((time_t)msg.idx.time<t) {
                    299:                        bot=l;
                    300:                        l=top-((top-bot)/2);
1.1.1.2 ! root      301:                        continue; 
        !           302:                }
        !           303:                break; 
        !           304:        }
1.1       root      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);
1.1.1.2 ! root      323:                return(0)        !           324:        }
1.1       root      325:        if(!filelength(fileno(smb.sid_fp))) {                   /* Empty base */
                    326:                smb_close(&smb);
1.1.1.2 ! root      327:                return(0)        !           328:        }
1.1       root      329:        msg.offset=0;
                    330:        msg.hdr.number=0;
                    331:        if(smb_getmsgidx(&smb,&msg)) {                          /* Get first message index */
                    332:                smb_close(&smb);
1.1.1.2 ! root      333:                return(0)        !           334:        }
1.1       root      335:        if(!ptr || msg.idx.number>=ptr) {                       /* ptr is before first message */
                    336:                smb_close(&smb);
1.1.1.2 ! root      337:                return(msg.idx.time);                                   /* so return time of first msg */
        !           338:        }
1.1       root      339: 
                    340:        if(smb_getlastidx(&smb,&lastidx)) {                      /* Get last message index */
                    341:                smb_close(&smb);
1.1.1.2 ! root      342:                return(0)        !           343:        }
1.1       root      344:        if(lastidx.number<ptr) {                                        /* ptr is after last message */
                    345:                smb_close(&smb);
1.1.1.2 ! root      346:                return(lastidx.time);                                   /* so return time of last msg */
        !           347:        }
1.1       root      348: 
                    349:        msg.idx.time=0;
                    350:        msg.hdr.number=ptr;
                    351:        if(!smb_getmsgidx(&smb,&msg)) {
                    352:                smb_close(&smb);
1.1.1.2 ! root      353:                return(msg.idx.time); 
        !           354:        }
1.1       root      355: 
                    356:        if(ptr-msg.idx.number < lastidx.number-ptr) {
                    357:                msg.offset=0;
                    358:                msg.idx.number=0;
                    359:                while(msg.idx.number<ptr) {
                    360:                        msg.hdr.number=0;
                    361:                        if(smb_getmsgidx(&smb,&msg) || msg.idx.number>=ptr)
                    362:                                break;
1.1.1.2 ! root      363:                        msg.offset++; 
        !           364:                }
1.1       root      365:                smb_close(&smb);
1.1.1.2 ! root      366:                return(msg.idx.time); 
        !           367:        }
1.1       root      368: 
                    369:        ptr--;
                    370:        while(ptr) {
                    371:                msg.hdr.number=ptr;
                    372:                if(!smb_getmsgidx(&smb,&msg))
                    373:                        break;
1.1.1.2 ! root      374:                ptr--; 
        !           375:        }
1.1       root      376:        smb_close(&smb);
                    377:        return(msg.idx.time);
                    378: }
                    379: 
                    380: 
                    381: /****************************************************************************/
                    382: /* Returns the total number of msgs in the sub-board and sets 'ptr' to the  */
                    383: /* number of the last message in the sub (0) if no messages.                           */
                    384: /****************************************************************************/
1.1.1.2 ! root      385: ulong sbbs_t::getlastmsg(uint subnum, uint32_t *ptr, time_t *t)
1.1       root      386: {
                    387:        int             i;
                    388:        ulong           total;
                    389:        idxrec_t        idx;
                    390: 
                    391:        if(ptr)
                    392:                (*ptr)=0;
                    393:        if(t)
                    394:                (*t)=0;
                    395:        if(subnum>=cfg.total_subs)
                    396:                return(0);
                    397: 
                    398:        sprintf(smb.file,"%s%s",cfg.sub[subnum]->data_dir,cfg.sub[subnum]->code);
                    399:        smb.retry_time=cfg.smb_retry_time;
                    400:        smb.subnum=subnum;
                    401:        if((i=smb_open(&smb))!=0) {
                    402:                errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
1.1.1.2 ! root      403:                return(0)        !           404:        }
1.1       root      405: 
                    406:        if(!filelength(fileno(smb.sid_fp))) {                   /* Empty base */
                    407:                smb_close(&smb);
1.1.1.2 ! root      408:                return(0)        !           409:        }
1.1       root      410:        if((i=smb_locksmbhdr(&smb))!=0) {
                    411:                smb_close(&smb);
                    412:                errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);
1.1.1.2 ! root      413:                return(0)        !           414:        }
1.1       root      415:        if((i=smb_getlastidx(&smb,&idx))!=0) {
                    416:                smb_close(&smb);
                    417:                errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error);
1.1.1.2 ! root      418:                return(0)        !           419:        }
        !           420:        total=(long)filelength(fileno(smb.sid_fp))/sizeof(idxrec_t);
1.1       root      421:        smb_unlocksmbhdr(&smb);
                    422:        smb_close(&smb);
                    423:        if(ptr)
                    424:                (*ptr)=idx.number;
                    425:        if(t)
                    426:                (*t)=idx.time;
                    427:        return(total);
                    428: }
                    429: 

unix.superglobalmegacorp.com

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