Annotation of sbbs/sbbs2/msg1.c, revision 1.1.1.1

1.1       root        1: #line 1 "MSG1.C"
                      2: 
                      3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
                      4: 
                      5: /***********************************************************************/
                      6: /* Functions that do i/o with messages (posts/mail/auto) or their data */
                      7: /***********************************************************************/
                      8: 
                      9: #include "sbbs.h"
                     10: 
                     11: #define LZH 1
                     12: 
                     13: void lfputs(char HUGE16 *buf, FILE *fp)
                     14: {
                     15: while(*buf) {
                     16:     fputc(*buf,fp);
                     17:     buf++; }
                     18: }
                     19: 
                     20: /****************************************************************************/
                     21: /* Loads an SMB message from the open msg base the fastest way possible        */
                     22: /* first by offset, and if that's the wrong message, then by number.        */
                     23: /* Returns 1 if the message was loaded and left locked, otherwise                      */
                     24: /****************************************************************************/
                     25: int loadmsg(smbmsg_t *msg, ulong number)
                     26: {
                     27:        char str[128];
                     28:        int i;
                     29: 
                     30: if(msg->idx.offset) {                          /* Load by offset if specified */
                     31: 
                     32:        if((i=smb_lockmsghdr(&smb,msg))!=0) {
                     33:                errormsg(WHERE,ERR_LOCK,smb.file,i);
                     34:                return(0); }
                     35: 
                     36:        i=smb_getmsghdr(&smb,msg);
                     37:        if(!i && msg->hdr.number==number)
                     38:                return(1);
                     39: 
                     40:        /* Wrong offset  */
                     41: 
                     42:        if(!i) {
                     43:                smb_freemsgmem(msg);
                     44:                msg->total_hfields=0; }
                     45: 
                     46:        smb_unlockmsghdr(&smb,msg); }
                     47: 
                     48: msg->hdr.number=number;
                     49: if((i=smb_getmsgidx(&smb,msg))!=0)                              /* Message is deleted */
                     50:        return(0);
                     51: if((i=smb_lockmsghdr(&smb,msg))!=0) {
                     52:        errormsg(WHERE,ERR_LOCK,smb.file,i);
                     53:        return(0); }
                     54: if((i=smb_getmsghdr(&smb,msg))!=0) {
                     55:        sprintf(str,"(%06lX) #%lu/%lu %s",msg->idx.offset,msg->idx.number
                     56:                ,number,smb.file);
                     57:        smb_unlockmsghdr(&smb,msg);
                     58:        errormsg(WHERE,ERR_READ,str,i);
                     59:        return(0); }
                     60: return(msg->total_hfields);
                     61: }
                     62: 
                     63: /****************************************************************************/
                     64: /* Displays a text file to the screen, reading/display a block at time         */
                     65: /****************************************************************************/
                     66: void putmsg_fp(FILE *fp, long length, int mode)
                     67: {
                     68:        uchar *buf,tmpatr;
                     69:        int i,j,b=8192,orgcon=console;
                     70:        long l;
                     71: 
                     72: tmpatr=curatr; /* was lclatr(-1) */
                     73: if((buf=MALLOC(b+1))==NULL) {
                     74:        errormsg(WHERE,ERR_ALLOC,nulstr,b+1L);
                     75:     return; }
                     76: for(l=0;l<length;l+=b) {
                     77:        if(l+b>length)
                     78:                b=length-l;
                     79:        i=j=fread(buf,1,b,fp);
                     80:        if(!j) break;                                           /* No bytes read */
                     81:        if(l+i<length)                                          /* Not last block */
                     82:                while(i && buf[i-1]!=LF) i--;   /* Search for last LF */
                     83:        if(!i) i=j;                                             /* None found */
                     84:        buf[i]=0;
                     85:        if(i<j)
                     86:                fseek(fp,(long)-(j-i),SEEK_CUR);
                     87:        b=i;
                     88:        if(putmsg(buf,mode|P_SAVEATR))
                     89:                break; }
                     90: if(!(mode&P_SAVEATR)) {
                     91:        console=orgcon;
                     92:        attr(tmpatr); }
                     93: FREE(buf);
                     94: }
                     95: 
                     96: void 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:        );
                    110: }
                    111: 
                    112: /****************************************************************************/
                    113: /* Displays a message header to the screen                                  */
                    114: /****************************************************************************/
                    115: void show_msghdr(smbmsg_t msg)
                    116: {
                    117:        char    *sender=NULL;
                    118:        int     i;
                    119: 
                    120: attr(LIGHTGRAY);
                    121: if(useron.misc&CLRSCRN)
                    122:     outchar(FF);
                    123: else
                    124:     CRLF;
                    125: bprintf(text[MsgSubj],msg.subj);
                    126: if(msg.hdr.attr)
                    127:        show_msgattr(msg.hdr.attr);
                    128: 
                    129: bprintf(text[MsgTo],msg.to);
                    130: if(msg.to_ext)
                    131:        bprintf(text[MsgToExt],msg.to_ext);
                    132: if(msg.to_net.addr)
                    133:        bprintf(text[MsgToNet],msg.to_net.type==NET_FIDO
                    134:         ? faddrtoa(*(faddr_t *)msg.to_net.addr) : msg.to_net.addr);
                    135: if(!(msg.hdr.attr&MSG_ANONYMOUS) || SYSOP) {
                    136:        bprintf(text[MsgFrom],msg.from);
                    137:        if(msg.from_ext)
                    138:                bprintf(text[MsgFromExt],msg.from_ext);
                    139:        if(msg.from_net.addr)
                    140:                bprintf(text[MsgFromNet],msg.from_net.type==NET_FIDO
                    141:                        ? faddrtoa(*(faddr_t *)msg.from_net.addr)
                    142:                                : msg.from_net.addr); }
                    143: bprintf(text[MsgDate]
                    144:        ,timestr((time_t *)&msg.hdr.when_written.time)
                    145:     ,zonestr(msg.hdr.when_written.zone));
                    146: 
                    147: CRLF;
                    148: 
                    149: for(i=0;i<msg.total_hfields;i++) {
                    150:        if(msg.hfield[i].type==SENDER)
                    151:                sender=msg.hfield_dat[i];
                    152:        if(msg.hfield[i].type==FORWARDED && sender)
                    153:                bprintf(text[ForwardedFrom],sender
                    154:                        ,timestr((time_t *)msg.hfield_dat[i])); }
                    155: 
                    156: /* Debug stuff
                    157: if(SYSOP) {
                    158:        bprintf("\1n\1c\r\nAux  : \1h%08lX",msg.hdr.auxattr);
                    159:        bprintf("\1n\1c\r\nNum  : \1h%lu",msg.hdr.number); }
                    160: */
                    161: 
                    162: CRLF;
                    163: }
                    164: 
                    165: #if !LZH
                    166: 
                    167: /****************************************************************************/
                    168: /* Displays message header and text (if not deleted)                        */
                    169: /****************************************************************************/
                    170: void show_msg(smbmsg_t msg, int mode)
                    171: {
                    172:        ushort xlat;
                    173:     int i;
                    174: 
                    175: show_msghdr(msg);
                    176: for(i=0;i<msg.hdr.total_dfields;i++)
                    177:        switch(msg.dfield[i].type) {
                    178:         case TEXT_BODY:
                    179:         case TEXT_TAIL:
                    180:                        fseek(smb.sdt_fp,msg.hdr.offset+msg.dfield[i].offset
                    181:                 ,SEEK_SET);
                    182:                        fread(&xlat,2,1,smb.sdt_fp);
                    183:                        if(xlat!=XLAT_NONE)             /* no translations supported */
                    184:                                continue;
                    185:                        putmsg_fp(smb.sdt_fp,msg.dfield[i].length-2,mode);
                    186:             CRLF;
                    187:             break; }
                    188: }
                    189: 
                    190: #else
                    191: 
                    192: /****************************************************************************/
                    193: /* Displays message header and text (if not deleted)                        */
                    194: /****************************************************************************/
                    195: void show_msg(smbmsg_t msg, int mode)
                    196: {
                    197:        char *inbuf,*lzhbuf;
                    198:        ushort xlat;
                    199:        int i,lzh;
                    200:        long lzhlen,length;
                    201: 
                    202: show_msghdr(msg);
                    203: for(i=0;i<msg.hdr.total_dfields;i++)
                    204:        switch(msg.dfield[i].type) {
                    205:         case TEXT_BODY:
                    206:         case TEXT_TAIL:
                    207:                        fseek(smb.sdt_fp,msg.hdr.offset+msg.dfield[i].offset
                    208:                 ,SEEK_SET);
                    209:                        fread(&xlat,2,1,smb.sdt_fp);
                    210:                        lzh=0;
                    211:                        if(xlat==XLAT_LZH) {
                    212:                                lzh=1;
                    213:                                fread(&xlat,2,1,smb.sdt_fp); }
                    214:                        if(xlat!=XLAT_NONE)             /* no translations supported */
                    215:                                continue;
                    216:                        if(lzh) {
                    217:                                length=msg.dfield[i].length-4;
                    218:                                if((inbuf=MALLOC(length))==NULL) {
                    219:                                        errormsg(WHERE,ERR_ALLOC,nulstr,length);
                    220:                                        continue; }
                    221:                                fread(inbuf,length,1,smb.sdt_fp);
                    222:                                lzhlen=*(long *)inbuf;
                    223: /**
                    224:                                if(SYSOP)
                    225:                                bprintf("Decoding %lu bytes of LZH into %lu bytes of text "
                    226:                                        "(%d%% compression)"
                    227:                                        ,length,lzhlen
                    228:                                        ,(int)(((float)(lzhlen-length)/lzhlen)*100.0));
                    229: **/
                    230:                                if((lzhbuf=MALLOC(lzhlen+2L))==NULL) {
                    231:                                        FREE(inbuf);
                    232:                                        errormsg(WHERE,ERR_ALLOC,nulstr,lzhlen+2L);
                    233:                                        continue; }
                    234:                                lzh_decode(inbuf,length,lzhbuf);
                    235:                                lzhbuf[lzhlen]=0;
                    236: //                               CRLF;
                    237:                                putmsg(lzhbuf,P_NOATCODES);
                    238:                                FREE(lzhbuf);
                    239:                                FREE(inbuf); }
                    240:                        else
                    241:                                putmsg_fp(smb.sdt_fp,msg.dfield[i].length-2,mode);
                    242:             CRLF;
                    243:             break; }
                    244: }
                    245: 
                    246: #endif
                    247: 
                    248: void quotemsg(smbmsg_t msg, int tails)
                    249: {
                    250:        char    str[256];
                    251: 
                    252: sprintf(str,"%sQUOTES.TXT",node_dir);
                    253: remove(str);
                    254: msgtotxt(msg,str,0,tails);
                    255: }
                    256: 
                    257: 
                    258: /****************************************************************************/
                    259: /* Writes message header and text data to a text file                                          */
                    260: /****************************************************************************/
                    261: void msgtotxt(smbmsg_t msg, char *str, int header, int tails)
                    262: {
                    263:        uchar   HUGE16 *buf;
                    264:        ushort  xlat;
                    265:        int     i,j,x;
                    266:        ulong   l;
                    267:        FILE    *out;
                    268: 
                    269: if((out=fnopen(&i,str,O_WRONLY|O_CREAT|O_APPEND))==NULL) {
                    270:        errormsg(WHERE,ERR_OPEN,str,0);
                    271:        return; }
                    272: if(header) {
                    273:        fprintf(out,"\r\n");
                    274:        fprintf(out,"Subj : %s\r\n",msg.subj);
                    275:        fprintf(out,"To   : %s",msg.to);
                    276:        if(msg.to_ext)
                    277:                fprintf(out," #%s",msg.to_ext);
                    278:        if(msg.to_net.addr)
                    279:                fprintf(out," (%s)",msg.to_net.type==NET_FIDO
                    280:                        ? faddrtoa(*(faddr_t *)msg.to_net.addr) : msg.to_net.addr);
                    281:        fprintf(out,"\r\nFrom : %s",msg.from);
                    282:        if(msg.from_ext && !(msg.hdr.attr&MSG_ANONYMOUS))
                    283:                fprintf(out," #%s",msg.from_ext);
                    284:        if(msg.from_net.addr)
                    285:                fprintf(out," (%s)",msg.from_net.type==NET_FIDO
                    286:                        ? faddrtoa(*(faddr_t *)msg.from_net.addr)
                    287:                                : msg.from_net.addr);
                    288:        fprintf(out,"\r\nDate : %.24s %s"
                    289:                ,timestr((time_t *)&msg.hdr.when_written.time)
                    290:                ,zonestr(msg.hdr.when_written.zone));
                    291:        fprintf(out,"\r\n\r\n"); }
                    292: 
                    293: buf=smb_getmsgtxt(&smb,&msg,tails);
                    294: if(buf) {
                    295:        lfputs(buf,out);
                    296:        LFREE(buf); }
                    297: else if(smb_getmsgdatlen(&msg)>2)
                    298:        errormsg(WHERE,ERR_ALLOC,smb.file,smb_getmsgdatlen(&msg));
                    299: fclose(out);
                    300: }
                    301: 
                    302: 
                    303: /****************************************************************************/
                    304: /* Returns total number of posts in a sub-board                                                        */
                    305: /****************************************************************************/
                    306: ulong getposts(uint subnum)
                    307: {
                    308:        char str[128];
                    309:        ulong l;
                    310: 
                    311: sprintf(str,"%s%s.SID",sub[subnum]->data_dir,sub[subnum]->code);
                    312: l=flength(str);
                    313: if((long)l==-1)
                    314:        return(0);
                    315: return(l/sizeof(idxrec_t));
                    316: }
                    317: 
                    318: /****************************************************************************/
                    319: /* Returns message number posted at or after time                                                      */
                    320: /****************************************************************************/
                    321: ulong getmsgnum(uint subnum, time_t t)
                    322: {
                    323:     int     i;
                    324:        ulong   l,total,bot,top;
                    325:        smbmsg_t msg;
                    326: 
                    327: if(!t)
                    328:        return(0);
                    329: 
                    330: sprintf(smb.file,"%s%s",sub[subnum]->data_dir,sub[subnum]->code);
                    331: smb.retry_time=smb_retry_time;
                    332: if((i=smb_open(&smb))!=0) {
                    333:        errormsg(WHERE,ERR_OPEN,smb.file,i);
                    334:        return(0); }
                    335: 
                    336: total=filelength(fileno(smb.sid_fp))/sizeof(idxrec_t);
                    337: 
                    338: if(!total) {              /* Empty base */
                    339:        smb_close(&smb);
                    340:        return(0); }
                    341: 
                    342: if((i=smb_locksmbhdr(&smb))!=0) {
                    343:        smb_close(&smb);
                    344:        errormsg(WHERE,ERR_LOCK,smb.file,i);
                    345:     return(0); }
                    346: 
                    347: if((i=smb_getlastidx(&smb,&msg.idx))!=0) {
                    348:        smb_close(&smb);
                    349:        errormsg(WHERE,ERR_READ,smb.file,i);
                    350:     return(0); }
                    351: 
                    352: if(msg.idx.time<=t) {
                    353:        smb_close(&smb);
                    354:        return(msg.idx.number); }
                    355: 
                    356: bot=0;
                    357: top=total;
                    358: l=total/2; /* Start at middle index */
                    359: clearerr(smb.sid_fp);
                    360: while(1) {
                    361:        fseek(smb.sid_fp,l*sizeof(idxrec_t),SEEK_SET);
                    362:        if(!fread(&msg.idx,sizeof(idxrec_t),1,smb.sid_fp))
                    363:                break;
                    364:        if(bot==top-1)
                    365:                break;
                    366:        if(msg.idx.time>t) {
                    367:                top=l;
                    368:                l=bot+((top-bot)/2);
                    369:                continue; }
                    370:        if(msg.idx.time<t) {
                    371:                bot=l;
                    372:                l=top-((top-bot)/2);
                    373:                continue; }
                    374:        break; }
                    375: smb_close(&smb);
                    376: return(msg.idx.number);
                    377: }
                    378: 
                    379: /****************************************************************************/
                    380: /* Returns the time of the message number pointed to by 'ptr'               */
                    381: /****************************************************************************/
                    382: time_t getmsgtime(uint subnum, ulong ptr)
                    383: {
                    384:        char    str[128];
                    385:        int     i;
                    386:        long    l;
                    387:        smbmsg_t msg;
                    388:        idxrec_t lastidx;
                    389: 
                    390: sprintf(smb.file,"%s%s",sub[subnum]->data_dir,sub[subnum]->code);
                    391: smb.retry_time=smb_retry_time;
                    392: if((i=smb_open(&smb))!=0) {
                    393:        errormsg(WHERE,ERR_OPEN,smb.file,i);
                    394:        return(0); }
                    395: if(!filelength(fileno(smb.sid_fp))) {                  /* Empty base */
                    396:        smb_close(&smb);
                    397:        return(0); }
                    398: msg.offset=0;
                    399: msg.hdr.number=0;
                    400: if(smb_getmsgidx(&smb,&msg)) {                         /* Get first message index */
                    401:        smb_close(&smb);
                    402:        return(0); }
                    403: if(!ptr || msg.idx.number>=ptr) {                      /* ptr is before first message */
                    404:        smb_close(&smb);
                    405:        return(msg.idx.time); }                                 /* so return time of first msg */
                    406: 
                    407: if(smb_getlastidx(&smb,&lastidx)) {                     /* Get last message index */
                    408:        smb_close(&smb);
                    409:        return(0); }
                    410: if(lastidx.number<ptr) {                                       /* ptr is after last message */
                    411:        smb_close(&smb);
                    412:        return(lastidx.time); }                                 /* so return time of last msg */
                    413: 
                    414: msg.idx.time=0;
                    415: msg.hdr.number=ptr;
                    416: if(!smb_getmsgidx(&smb,&msg)) {
                    417:        smb_close(&smb);
                    418:        return(msg.idx.time); }
                    419: 
                    420: if(ptr-msg.idx.number < lastidx.number-ptr) {
                    421:        msg.offset=0;
                    422:        msg.idx.number=0;
                    423:        while(msg.idx.number<ptr) {
                    424:                msg.hdr.number=0;
                    425:                if(smb_getmsgidx(&smb,&msg) || msg.idx.number>=ptr)
                    426:                        break;
                    427:                msg.offset++; }
                    428:        smb_close(&smb);
                    429:        return(msg.idx.time); }
                    430: 
                    431: ptr--;
                    432: while(ptr) {
                    433:        msg.hdr.number=ptr;
                    434:        if(!smb_getmsgidx(&smb,&msg))
                    435:                break;
                    436:        ptr--; }
                    437: smb_close(&smb);
                    438: return(msg.idx.time);
                    439: }
                    440: 
                    441: 
                    442: /****************************************************************************/
                    443: /* Returns the total number of msgs in the sub-board and sets 'ptr' to the  */
                    444: /* number of the last message in the sub (0) if no messages.                           */
                    445: /****************************************************************************/
                    446: ulong getlastmsg(uint subnum, ulong *ptr, time_t *t)
                    447: {
                    448:        char            str[256];
                    449:        int             i;
                    450:        ulong           total;
                    451:        idxrec_t        idx;
                    452: 
                    453: if(ptr)
                    454:        (*ptr)=0;
                    455: if(t)
                    456:        (*t)=0;
                    457: if(subnum>=total_subs)
                    458:        return(0);
                    459: 
                    460: sprintf(smb.file,"%s%s",sub[subnum]->data_dir,sub[subnum]->code);
                    461: smb.retry_time=smb_retry_time;
                    462: if((i=smb_open(&smb))!=0) {
                    463:        errormsg(WHERE,ERR_OPEN,smb.file,i);
                    464:        return(0); }
                    465: 
                    466: if(!filelength(fileno(smb.sid_fp))) {                  /* Empty base */
                    467:        smb_close(&smb);
                    468:        return(0); }
                    469: if((i=smb_locksmbhdr(&smb))!=0) {
                    470:        smb_close(&smb);
                    471:        errormsg(WHERE,ERR_LOCK,smb.file,i);
                    472:        return(0); }
                    473: if((i=smb_getlastidx(&smb,&idx))!=0) {
                    474:        smb_close(&smb);
                    475:        errormsg(WHERE,ERR_READ,smb.file,i);
                    476:        return(0); }
                    477: total=filelength(fileno(smb.sid_fp))/sizeof(idxrec_t);
                    478: smb_unlocksmbhdr(&smb);
                    479: smb_close(&smb);
                    480: if(ptr)
                    481:        (*ptr)=idx.number;
                    482: if(t)
                    483:        (*t)=idx.time;
                    484: return(total);
                    485: }
                    486: 

unix.superglobalmegacorp.com

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