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

unix.superglobalmegacorp.com

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