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

1.1       root        1: /* getmsg.cpp */
                      2: 
                      3: /* Synchronet message retrieval functions */
                      4: 
                      5: /* $Id: getmsg.cpp,v 1.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.