|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.