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

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
1.1.1.2 ! root      109:        ,attr&MSG_REPLIED       ? "Replied  "   :nulstr
        !           110:        ,nulstr
        !           111:        ,nulstr
        !           112:        ,nulstr
        !           113:        ,nulstr
        !           114:        ,nulstr
        !           115:        ,nulstr
1.1       root      116:        );
                    117: }
                    118: 
                    119: /****************************************************************************/
                    120: /* Displays a message header to the screen                                  */
                    121: /****************************************************************************/
                    122: void show_msghdr(smbmsg_t msg)
                    123: {
                    124:        char    *sender=NULL;
                    125:        int     i;
                    126: 
                    127: attr(LIGHTGRAY);
                    128: if(useron.misc&CLRSCRN)
                    129:     outchar(FF);
                    130: else
                    131:     CRLF;
                    132: bprintf(text[MsgSubj],msg.subj);
                    133: if(msg.hdr.attr)
                    134:        show_msgattr(msg.hdr.attr);
                    135: 
                    136: bprintf(text[MsgTo],msg.to);
                    137: if(msg.to_ext)
                    138:        bprintf(text[MsgToExt],msg.to_ext);
                    139: if(msg.to_net.addr)
                    140:        bprintf(text[MsgToNet],msg.to_net.type==NET_FIDO
                    141:         ? faddrtoa(*(faddr_t *)msg.to_net.addr) : msg.to_net.addr);
                    142: if(!(msg.hdr.attr&MSG_ANONYMOUS) || SYSOP) {
                    143:        bprintf(text[MsgFrom],msg.from);
                    144:        if(msg.from_ext)
                    145:                bprintf(text[MsgFromExt],msg.from_ext);
                    146:        if(msg.from_net.addr)
                    147:                bprintf(text[MsgFromNet],msg.from_net.type==NET_FIDO
                    148:                        ? faddrtoa(*(faddr_t *)msg.from_net.addr)
                    149:                                : msg.from_net.addr); }
                    150: bprintf(text[MsgDate]
                    151:        ,timestr((time_t *)&msg.hdr.when_written.time)
                    152:     ,zonestr(msg.hdr.when_written.zone));
                    153: 
                    154: CRLF;
                    155: 
                    156: for(i=0;i<msg.total_hfields;i++) {
                    157:        if(msg.hfield[i].type==SENDER)
                    158:                sender=msg.hfield_dat[i];
                    159:        if(msg.hfield[i].type==FORWARDED && sender)
                    160:                bprintf(text[ForwardedFrom],sender
                    161:                        ,timestr((time_t *)msg.hfield_dat[i])); }
                    162: 
                    163: /* Debug stuff
                    164: if(SYSOP) {
                    165:        bprintf("\1n\1c\r\nAux  : \1h%08lX",msg.hdr.auxattr);
                    166:        bprintf("\1n\1c\r\nNum  : \1h%lu",msg.hdr.number); }
                    167: */
                    168: 
                    169: CRLF;
                    170: }
                    171: 
                    172: #if !LZH
                    173: 
                    174: /****************************************************************************/
                    175: /* Displays message header and text (if not deleted)                        */
                    176: /****************************************************************************/
                    177: void show_msg(smbmsg_t msg, int mode)
                    178: {
                    179:        ushort xlat;
                    180:     int i;
                    181: 
                    182: show_msghdr(msg);
                    183: for(i=0;i<msg.hdr.total_dfields;i++)
                    184:        switch(msg.dfield[i].type) {
                    185:         case TEXT_BODY:
                    186:         case TEXT_TAIL:
                    187:                        fseek(smb.sdt_fp,msg.hdr.offset+msg.dfield[i].offset
                    188:                 ,SEEK_SET);
                    189:                        fread(&xlat,2,1,smb.sdt_fp);
                    190:                        if(xlat!=XLAT_NONE)             /* no translations supported */
                    191:                                continue;
                    192:                        putmsg_fp(smb.sdt_fp,msg.dfield[i].length-2,mode);
                    193:             CRLF;
                    194:             break; }
                    195: }
                    196: 
                    197: #else
                    198: 
                    199: /****************************************************************************/
                    200: /* Displays message header and text (if not deleted)                        */
                    201: /****************************************************************************/
                    202: void show_msg(smbmsg_t msg, int mode)
                    203: {
                    204:        char *inbuf,*lzhbuf;
                    205:        ushort xlat;
                    206:        int i,lzh;
                    207:        long lzhlen,length;
                    208: 
                    209: show_msghdr(msg);
                    210: for(i=0;i<msg.hdr.total_dfields;i++)
                    211:        switch(msg.dfield[i].type) {
                    212:         case TEXT_BODY:
                    213:         case TEXT_TAIL:
                    214:                        fseek(smb.sdt_fp,msg.hdr.offset+msg.dfield[i].offset
                    215:                 ,SEEK_SET);
                    216:                        fread(&xlat,2,1,smb.sdt_fp);
                    217:                        lzh=0;
                    218:                        if(xlat==XLAT_LZH) {
                    219:                                lzh=1;
                    220:                                fread(&xlat,2,1,smb.sdt_fp); }
                    221:                        if(xlat!=XLAT_NONE)             /* no translations supported */
                    222:                                continue;
                    223:                        if(lzh) {
                    224:                                length=msg.dfield[i].length-4;
                    225:                                if((inbuf=MALLOC(length))==NULL) {
                    226:                                        errormsg(WHERE,ERR_ALLOC,nulstr,length);
                    227:                                        continue; }
                    228:                                fread(inbuf,length,1,smb.sdt_fp);
                    229:                                lzhlen=*(long *)inbuf;
                    230: /**
                    231:                                if(SYSOP)
                    232:                                bprintf("Decoding %lu bytes of LZH into %lu bytes of text "
                    233:                                        "(%d%% compression)"
                    234:                                        ,length,lzhlen
                    235:                                        ,(int)(((float)(lzhlen-length)/lzhlen)*100.0));
                    236: **/
                    237:                                if((lzhbuf=MALLOC(lzhlen+2L))==NULL) {
                    238:                                        FREE(inbuf);
                    239:                                        errormsg(WHERE,ERR_ALLOC,nulstr,lzhlen+2L);
                    240:                                        continue; }
                    241:                                lzh_decode(inbuf,length,lzhbuf);
                    242:                                lzhbuf[lzhlen]=0;
                    243: //                               CRLF;
                    244:                                putmsg(lzhbuf,P_NOATCODES);
                    245:                                FREE(lzhbuf);
                    246:                                FREE(inbuf); }
                    247:                        else
                    248:                                putmsg_fp(smb.sdt_fp,msg.dfield[i].length-2,mode);
                    249:             CRLF;
                    250:             break; }
                    251: }
                    252: 
                    253: #endif
                    254: 
                    255: void quotemsg(smbmsg_t msg, int tails)
                    256: {
                    257:        char    str[256];
                    258: 
                    259: sprintf(str,"%sQUOTES.TXT",node_dir);
                    260: remove(str);
                    261: msgtotxt(msg,str,0,tails);
                    262: }
                    263: 
                    264: 
                    265: /****************************************************************************/
                    266: /* Writes message header and text data to a text file                                          */
                    267: /****************************************************************************/
                    268: void msgtotxt(smbmsg_t msg, char *str, int header, int tails)
                    269: {
                    270:        uchar   HUGE16 *buf;
                    271:        ushort  xlat;
                    272:        int     i,j,x;
                    273:        ulong   l;
                    274:        FILE    *out;
                    275: 
                    276: if((out=fnopen(&i,str,O_WRONLY|O_CREAT|O_APPEND))==NULL) {
                    277:        errormsg(WHERE,ERR_OPEN,str,0);
                    278:        return; }
                    279: if(header) {
                    280:        fprintf(out,"\r\n");
                    281:        fprintf(out,"Subj : %s\r\n",msg.subj);
                    282:        fprintf(out,"To   : %s",msg.to);
                    283:        if(msg.to_ext)
                    284:                fprintf(out," #%s",msg.to_ext);
                    285:        if(msg.to_net.addr)
                    286:                fprintf(out," (%s)",msg.to_net.type==NET_FIDO
                    287:                        ? faddrtoa(*(faddr_t *)msg.to_net.addr) : msg.to_net.addr);
                    288:        fprintf(out,"\r\nFrom : %s",msg.from);
                    289:        if(msg.from_ext && !(msg.hdr.attr&MSG_ANONYMOUS))
                    290:                fprintf(out," #%s",msg.from_ext);
                    291:        if(msg.from_net.addr)
                    292:                fprintf(out," (%s)",msg.from_net.type==NET_FIDO
                    293:                        ? faddrtoa(*(faddr_t *)msg.from_net.addr)
                    294:                                : msg.from_net.addr);
                    295:        fprintf(out,"\r\nDate : %.24s %s"
                    296:                ,timestr((time_t *)&msg.hdr.when_written.time)
                    297:                ,zonestr(msg.hdr.when_written.zone));
                    298:        fprintf(out,"\r\n\r\n"); }
                    299: 
                    300: buf=smb_getmsgtxt(&smb,&msg,tails);
                    301: if(buf) {
                    302:        lfputs(buf,out);
                    303:        LFREE(buf); }
                    304: else if(smb_getmsgdatlen(&msg)>2)
                    305:        errormsg(WHERE,ERR_ALLOC,smb.file,smb_getmsgdatlen(&msg));
                    306: fclose(out);
                    307: }
                    308: 
                    309: 
                    310: /****************************************************************************/
                    311: /* Returns total number of posts in a sub-board                                                        */
                    312: /****************************************************************************/
                    313: ulong getposts(uint subnum)
                    314: {
                    315:        char str[128];
                    316:        ulong l;
                    317: 
                    318: sprintf(str,"%s%s.SID",sub[subnum]->data_dir,sub[subnum]->code);
                    319: l=flength(str);
                    320: if((long)l==-1)
                    321:        return(0);
                    322: return(l/sizeof(idxrec_t));
                    323: }
                    324: 
                    325: /****************************************************************************/
                    326: /* Returns message number posted at or after time                                                      */
                    327: /****************************************************************************/
                    328: ulong getmsgnum(uint subnum, time_t t)
                    329: {
                    330:     int     i;
                    331:        ulong   l,total,bot,top;
                    332:        smbmsg_t msg;
                    333: 
                    334: if(!t)
                    335:        return(0);
                    336: 
                    337: sprintf(smb.file,"%s%s",sub[subnum]->data_dir,sub[subnum]->code);
                    338: smb.retry_time=smb_retry_time;
                    339: if((i=smb_open(&smb))!=0) {
                    340:        errormsg(WHERE,ERR_OPEN,smb.file,i);
                    341:        return(0); }
                    342: 
                    343: total=filelength(fileno(smb.sid_fp))/sizeof(idxrec_t);
                    344: 
                    345: if(!total) {              /* Empty base */
                    346:        smb_close(&smb);
                    347:        return(0); }
                    348: 
                    349: if((i=smb_locksmbhdr(&smb))!=0) {
                    350:        smb_close(&smb);
                    351:        errormsg(WHERE,ERR_LOCK,smb.file,i);
                    352:     return(0); }
                    353: 
                    354: if((i=smb_getlastidx(&smb,&msg.idx))!=0) {
                    355:        smb_close(&smb);
                    356:        errormsg(WHERE,ERR_READ,smb.file,i);
                    357:     return(0); }
                    358: 
                    359: if(msg.idx.time<=t) {
                    360:        smb_close(&smb);
                    361:        return(msg.idx.number); }
                    362: 
                    363: bot=0;
                    364: top=total;
                    365: l=total/2; /* Start at middle index */
                    366: clearerr(smb.sid_fp);
                    367: while(1) {
                    368:        fseek(smb.sid_fp,l*sizeof(idxrec_t),SEEK_SET);
                    369:        if(!fread(&msg.idx,sizeof(idxrec_t),1,smb.sid_fp))
                    370:                break;
                    371:        if(bot==top-1)
                    372:                break;
                    373:        if(msg.idx.time>t) {
                    374:                top=l;
                    375:                l=bot+((top-bot)/2);
                    376:                continue; }
                    377:        if(msg.idx.time<t) {
                    378:                bot=l;
                    379:                l=top-((top-bot)/2);
                    380:                continue; }
                    381:        break; }
                    382: smb_close(&smb);
                    383: return(msg.idx.number);
                    384: }
                    385: 
                    386: /****************************************************************************/
                    387: /* Returns the time of the message number pointed to by 'ptr'               */
                    388: /****************************************************************************/
                    389: time_t getmsgtime(uint subnum, ulong ptr)
                    390: {
                    391:        char    str[128];
                    392:        int     i;
                    393:        long    l;
                    394:        smbmsg_t msg;
                    395:        idxrec_t lastidx;
                    396: 
                    397: sprintf(smb.file,"%s%s",sub[subnum]->data_dir,sub[subnum]->code);
                    398: smb.retry_time=smb_retry_time;
                    399: if((i=smb_open(&smb))!=0) {
                    400:        errormsg(WHERE,ERR_OPEN,smb.file,i);
                    401:        return(0); }
                    402: if(!filelength(fileno(smb.sid_fp))) {                  /* Empty base */
                    403:        smb_close(&smb);
                    404:        return(0); }
                    405: msg.offset=0;
                    406: msg.hdr.number=0;
                    407: if(smb_getmsgidx(&smb,&msg)) {                         /* Get first message index */
                    408:        smb_close(&smb);
                    409:        return(0); }
                    410: if(!ptr || msg.idx.number>=ptr) {                      /* ptr is before first message */
                    411:        smb_close(&smb);
                    412:        return(msg.idx.time); }                                 /* so return time of first msg */
                    413: 
                    414: if(smb_getlastidx(&smb,&lastidx)) {                     /* Get last message index */
                    415:        smb_close(&smb);
                    416:        return(0); }
                    417: if(lastidx.number<ptr) {                                       /* ptr is after last message */
                    418:        smb_close(&smb);
                    419:        return(lastidx.time); }                                 /* so return time of last msg */
                    420: 
                    421: msg.idx.time=0;
                    422: msg.hdr.number=ptr;
                    423: if(!smb_getmsgidx(&smb,&msg)) {
                    424:        smb_close(&smb);
                    425:        return(msg.idx.time); }
                    426: 
                    427: if(ptr-msg.idx.number < lastidx.number-ptr) {
                    428:        msg.offset=0;
                    429:        msg.idx.number=0;
                    430:        while(msg.idx.number<ptr) {
                    431:                msg.hdr.number=0;
                    432:                if(smb_getmsgidx(&smb,&msg) || msg.idx.number>=ptr)
                    433:                        break;
                    434:                msg.offset++; }
                    435:        smb_close(&smb);
                    436:        return(msg.idx.time); }
                    437: 
                    438: ptr--;
                    439: while(ptr) {
                    440:        msg.hdr.number=ptr;
                    441:        if(!smb_getmsgidx(&smb,&msg))
                    442:                break;
                    443:        ptr--; }
                    444: smb_close(&smb);
                    445: return(msg.idx.time);
                    446: }
                    447: 
                    448: 
                    449: /****************************************************************************/
                    450: /* Returns the total number of msgs in the sub-board and sets 'ptr' to the  */
                    451: /* number of the last message in the sub (0) if no messages.                           */
                    452: /****************************************************************************/
                    453: ulong getlastmsg(uint subnum, ulong *ptr, time_t *t)
                    454: {
                    455:        char            str[256];
                    456:        int             i;
                    457:        ulong           total;
                    458:        idxrec_t        idx;
                    459: 
                    460: if(ptr)
                    461:        (*ptr)=0;
                    462: if(t)
                    463:        (*t)=0;
                    464: if(subnum>=total_subs)
                    465:        return(0);
                    466: 
                    467: sprintf(smb.file,"%s%s",sub[subnum]->data_dir,sub[subnum]->code);
                    468: smb.retry_time=smb_retry_time;
                    469: if((i=smb_open(&smb))!=0) {
                    470:        errormsg(WHERE,ERR_OPEN,smb.file,i);
                    471:        return(0); }
                    472: 
                    473: if(!filelength(fileno(smb.sid_fp))) {                  /* Empty base */
                    474:        smb_close(&smb);
                    475:        return(0); }
                    476: if((i=smb_locksmbhdr(&smb))!=0) {
                    477:        smb_close(&smb);
                    478:        errormsg(WHERE,ERR_LOCK,smb.file,i);
                    479:        return(0); }
                    480: if((i=smb_getlastidx(&smb,&idx))!=0) {
                    481:        smb_close(&smb);
                    482:        errormsg(WHERE,ERR_READ,smb.file,i);
                    483:        return(0); }
                    484: total=filelength(fileno(smb.sid_fp))/sizeof(idxrec_t);
                    485: smb_unlocksmbhdr(&smb);
                    486: smb_close(&smb);
                    487: if(ptr)
                    488:        (*ptr)=idx.number;
                    489: if(t)
                    490:        (*t)=idx.time;
                    491: return(total);
                    492: }
                    493: 

unix.superglobalmegacorp.com

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