|
|
1.1 ! root 1: #line 1 "READMSGS.C" ! 2: ! 3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */ ! 4: ! 5: #include "sbbs.h" ! 6: #include "post.h" ! 7: ! 8: char movemsg(smbmsg_t msg, uint subnum); ! 9: void editmsg(smbmsg_t *msg, uint subnum); ! 10: ! 11: int sub_op(uint subnum) ! 12: { ! 13: return(SYSOP || (sub[subnum]->op_ar[0] && chk_ar(sub[subnum]->op_ar,useron))); ! 14: } ! 15: ! 16: ! 17: void listmsgs(int subnum, post_t HUGE16 *post, long i, long posts) ! 18: { ! 19: char ch; ! 20: int j; ! 21: smbmsg_t msg; ! 22: ! 23: ! 24: bputs(text[MailOnSystemLstHdr]); ! 25: msg.total_hfields=0; ! 26: while(i<posts && !msgabort()) { ! 27: if(msg.total_hfields) ! 28: smb_freemsgmem(&msg); ! 29: msg.total_hfields=0; ! 30: msg.idx.offset=post[i].offset; ! 31: if(!loadmsg(&msg,post[i].number)) ! 32: break; ! 33: smb_unlockmsghdr(&smb,&msg); ! 34: if(msg.hdr.attr&MSG_DELETE) ! 35: ch='-'; ! 36: else if((!stricmp(msg.to,useron.alias) || !stricmp(msg.to,useron.name)) ! 37: && !(msg.hdr.attr&MSG_READ)) ! 38: ch='!'; ! 39: else if(msg.hdr.number>sub[subnum]->ptr) ! 40: ch='*'; ! 41: else ! 42: ch=' '; ! 43: bprintf(text[SubMsgLstFmt],(long)i+1 ! 44: ,msg.hdr.attr&MSG_ANONYMOUS && !sub_op(subnum) ! 45: ? text[Anonymous] : msg.from ! 46: ,msg.to ! 47: ,ch ! 48: ,msg.subj); ! 49: smb_freemsgmem(&msg); ! 50: msg.total_hfields=0; ! 51: i++; } ! 52: } ! 53: ! 54: char *binstr(uchar *buf, ushort length) ! 55: { ! 56: static char str[128]; ! 57: char tmp[128]; ! 58: int i; ! 59: ! 60: str[0]=0; ! 61: for(i=0;i<length;i++) ! 62: if(buf[i] && (buf[i]<SP || buf[i]>=0x7f)) ! 63: break; ! 64: if(i==length) /* not binary */ ! 65: return(buf); ! 66: for(i=0;i<length;i++) { ! 67: sprintf(tmp,"%02X ",buf[i]); ! 68: strcat(str,tmp); } ! 69: return(str); ! 70: } ! 71: ! 72: ! 73: void msghdr(smbmsg_t msg) ! 74: { ! 75: int i; ! 76: ! 77: for(i=0;i<msg.total_hfields;i++) ! 78: bprintf("hfield[%u].type %02Xh\r\n" ! 79: "hfield[%u].length %d\r\n" ! 80: "hfield[%u]_dat %s\r\n" ! 81: ,i,msg.hfield[i].type ! 82: ,i,msg.hfield[i].length ! 83: ,i,binstr(msg.hfield_dat[i],msg.hfield[i].length)); ! 84: } ! 85: ! 86: /****************************************************************************/ ! 87: /****************************************************************************/ ! 88: post_t HUGE16 *loadposts(ulong *posts, uint subnum, ulong ptr, uint mode) ! 89: { ! 90: char name[128]; ! 91: ushort aliascrc,namecrc,sysop; ! 92: int i,file,skip; ! 93: ulong l=0,total,alloc_len; ! 94: smbmsg_t msg; ! 95: idxrec_t idx; ! 96: post_t HUGE16 *post; ! 97: ! 98: if(posts==NULL) ! 99: return(NULL); ! 100: ! 101: (*posts)=0; ! 102: ! 103: if((i=smb_locksmbhdr(&smb))!=0) { /* Be sure noone deletes or */ ! 104: errormsg(WHERE,ERR_LOCK,smb.file,i); /* adds while we're reading */ ! 105: return(NULL); } ! 106: ! 107: total=filelength(fileno(smb.sid_fp))/sizeof(idxrec_t); /* total msgs in sub */ ! 108: ! 109: if(!total) { /* empty */ ! 110: smb_unlocksmbhdr(&smb); ! 111: return(NULL); } ! 112: ! 113: strcpy(name,useron.name); ! 114: strlwr(name); ! 115: namecrc=crc16(name); ! 116: strcpy(name,useron.alias); ! 117: strlwr(name); ! 118: aliascrc=crc16(name); ! 119: sysop=crc16("sysop"); ! 120: ! 121: rewind(smb.sid_fp); ! 122: ! 123: alloc_len=sizeof(post_t)*total; ! 124: #ifdef __OS2__ ! 125: while(alloc_len%4096) ! 126: alloc_len++; ! 127: #endif ! 128: if((post=(post_t HUGE16 *)LMALLOC(alloc_len))==NULL) { /* alloc for max */ ! 129: smb_unlocksmbhdr(&smb); ! 130: errormsg(WHERE,ERR_ALLOC,smb.file,sizeof(post_t *)*sub[subnum]->maxmsgs); ! 131: return(NULL); } ! 132: while(!feof(smb.sid_fp)) { ! 133: skip=0; ! 134: if(!fread(&idx,sizeof(idxrec_t),1,smb.sid_fp)) ! 135: break; ! 136: ! 137: if(idx.number<=ptr) ! 138: continue; ! 139: ! 140: if(idx.attr&MSG_READ && mode&LP_UNREAD) /* Skip read messages */ ! 141: continue; ! 142: ! 143: if(idx.attr&MSG_DELETE) { /* Pre-flagged */ ! 144: if(mode&LP_REP) /* Don't include deleted msgs in REP pkt */ ! 145: continue; ! 146: if(!(sys_misc&SM_SYSVDELM)) /* Noone can view deleted msgs */ ! 147: continue; ! 148: if(!(sys_misc&SM_USRVDELM) /* Users can't view deleted msgs */ ! 149: && !sub_op(subnum)) /* not sub-op */ ! 150: continue; ! 151: if(!sub_op(subnum) /* not sub-op */ ! 152: && idx.from!=namecrc && idx.from!=aliascrc) /* not for you */ ! 153: continue; } ! 154: ! 155: if(idx.attr&MSG_MODERATED && !(idx.attr&MSG_VALIDATED) ! 156: && (mode&LP_REP || !sub_op(subnum))) ! 157: break; ! 158: ! 159: if(idx.attr&MSG_PRIVATE && !(mode&LP_PRIVATE) ! 160: && !sub_op(subnum) && !(useron.rest&FLAG('Q'))) { ! 161: if(idx.to!=namecrc && idx.from!=namecrc ! 162: && idx.to!=aliascrc && idx.from!=aliascrc ! 163: && (useron.number!=1 || idx.to!=sysop)) ! 164: continue; ! 165: if(!smb_lockmsghdr(&smb,&msg)) { ! 166: if(!smb_getmsghdr(&smb,&msg)) { ! 167: if(stricmp(msg.to,useron.alias) ! 168: && stricmp(msg.from,useron.alias) ! 169: && stricmp(msg.to,useron.name) ! 170: && stricmp(msg.from,useron.name) ! 171: && (useron.number!=1 || stricmp(msg.to,"sysop") ! 172: || msg.from_net.type)) ! 173: skip=1; ! 174: smb_freemsgmem(&msg); } ! 175: smb_unlockmsghdr(&smb,&msg); } ! 176: if(skip) ! 177: continue; } ! 178: ! 179: ! 180: if(!(mode&LP_BYSELF) && (idx.from==namecrc || idx.from==aliascrc)) { ! 181: msg.idx=idx; ! 182: if(!smb_lockmsghdr(&smb,&msg)) { ! 183: if(!smb_getmsghdr(&smb,&msg)) { ! 184: if(!stricmp(msg.from,useron.alias) ! 185: || !stricmp(msg.from,useron.name)) ! 186: skip=1; ! 187: smb_freemsgmem(&msg); } ! 188: smb_unlockmsghdr(&smb,&msg); } ! 189: if(skip) ! 190: continue; } ! 191: ! 192: if(!(mode&LP_OTHERS)) { ! 193: if(idx.to!=namecrc && idx.to!=aliascrc ! 194: && (useron.number!=1 || idx.to!=sysop)) ! 195: continue; ! 196: msg.idx=idx; ! 197: if(!smb_lockmsghdr(&smb,&msg)) { ! 198: if(!smb_getmsghdr(&smb,&msg)) { ! 199: if(stricmp(msg.to,useron.alias) && stricmp(msg.to,useron.name) ! 200: && (useron.number!=1 || stricmp(msg.to,"sysop") ! 201: || msg.from_net.type)) ! 202: skip=1; ! 203: smb_freemsgmem(&msg); } ! 204: smb_unlockmsghdr(&smb,&msg); } ! 205: if(skip) ! 206: continue; } ! 207: ! 208: post[l].offset=idx.offset; ! 209: post[l].number=idx.number; ! 210: post[l].to=idx.to; ! 211: post[l].from=idx.from; ! 212: post[l].subj=idx.subj; ! 213: l++; } ! 214: smb_unlocksmbhdr(&smb); ! 215: if(!l) { ! 216: LFREE(post); ! 217: post=NULL; } ! 218: (*posts)=l; ! 219: return(post); ! 220: } ! 221: ! 222: ! 223: /****************************************************************************/ ! 224: /* Reads posts on subboard sub. 'mode' determines new-posts only, browse, */ ! 225: /* or continuous read. */ ! 226: /* Returns 0 if normal completion, 1 if aborted. */ ! 227: /* Called from function main_sec */ ! 228: /****************************************************************************/ ! 229: char scanposts(uint subnum, char mode, char *find) ! 230: { ! 231: char str[256],str2[256],str3[256],reread=0,mismatches=0 ! 232: ,done=0,domsg=1,HUGE16 *buf,*p; ! 233: int file,i,j,usub,ugrp,reads=0; ! 234: uint lp=0; ! 235: long curpost; ! 236: ulong msgs,last,posts,l; ! 237: post_t HUGE16 *post; ! 238: smbmsg_t msg; ! 239: ! 240: cursubnum=subnum; /* for ARS */ ! 241: if(!chk_ar(sub[subnum]->read_ar,useron)) { ! 242: bprintf("\1n\r\nYou can't read messages on %s %s\r\n" ! 243: ,grp[sub[subnum]->grp]->sname,sub[subnum]->sname); ! 244: return(0); } ! 245: msg.total_hfields=0; /* init to NULL, specify not-allocated */ ! 246: if(!(mode&SCAN_CONST)) ! 247: lncntr=0; ! 248: if((msgs=getlastmsg(subnum,&last,0))==0) { ! 249: if(mode&(SCAN_NEW|SCAN_TOYOU)) ! 250: bprintf(text[NScanStatusFmt] ! 251: ,grp[sub[subnum]->grp]->sname,sub[subnum]->lname,0L,0L); ! 252: else ! 253: bprintf(text[NoMsgsOnSub] ! 254: ,grp[sub[subnum]->grp]->sname,sub[subnum]->sname); ! 255: return(0); } ! 256: if(mode&SCAN_NEW && sub[subnum]->ptr>=last && !(mode&SCAN_BACK)) { ! 257: if(sub[subnum]->ptr>last) ! 258: sub[subnum]->ptr=sub[subnum]->last=last; ! 259: bprintf(text[NScanStatusFmt] ! 260: ,grp[sub[subnum]->grp]->sname,sub[subnum]->lname,0L,msgs); ! 261: return(0); } ! 262: ! 263: if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) { ! 264: errormsg(WHERE,ERR_OPEN,sub[subnum]->code,i); ! 265: return(0); } ! 266: sprintf(smb.file,"%s%s",sub[subnum]->data_dir,sub[subnum]->code); ! 267: smb.retry_time=smb_retry_time; ! 268: if((i=smb_open(&smb))!=0) { ! 269: smb_stack(&smb,SMB_STACK_POP); ! 270: errormsg(WHERE,ERR_OPEN,smb.file,i); ! 271: return(0); } ! 272: ! 273: if(!(mode&SCAN_TOYOU) ! 274: && (!mode || mode&SCAN_FIND || !(sub[subnum]->misc&SUB_YSCAN))) ! 275: lp=LP_BYSELF|LP_OTHERS; ! 276: if(mode&SCAN_TOYOU) ! 277: lp|=LP_UNREAD; ! 278: post=loadposts(&posts,subnum,0,lp); ! 279: if(mode&SCAN_NEW) { /* Scanning for new messages */ ! 280: for(curpost=0;curpost<posts;curpost++) ! 281: if(sub[subnum]->ptr<post[curpost].number) ! 282: break; ! 283: bprintf(text[NScanStatusFmt] ! 284: ,grp[sub[subnum]->grp]->sname,sub[subnum]->lname,posts-curpost,msgs); ! 285: if(!posts) { /* no messages at all */ ! 286: smb_close(&smb); ! 287: smb_stack(&smb,SMB_STACK_POP); ! 288: return(0); } ! 289: if(curpost==posts) { /* no new messages */ ! 290: if(!(mode&SCAN_BACK)) { ! 291: if(post) ! 292: LFREE(post); ! 293: smb_close(&smb); ! 294: smb_stack(&smb,SMB_STACK_POP); ! 295: return(0); } ! 296: curpost=posts-1; } } ! 297: else { ! 298: if(mode&SCAN_TOYOU) ! 299: bprintf(text[NScanStatusFmt] ! 300: ,grp[sub[subnum]->grp]->sname,sub[subnum]->lname,posts,msgs); ! 301: if(!posts) { ! 302: if(!(mode&SCAN_TOYOU)) ! 303: bprintf(text[NoMsgsOnSub] ! 304: ,grp[sub[subnum]->grp]->sname,sub[subnum]->sname); ! 305: smb_close(&smb); ! 306: smb_stack(&smb,SMB_STACK_POP); ! 307: return(0); } ! 308: if(mode&SCAN_FIND) { ! 309: bprintf(text[SearchSubFmt] ! 310: ,grp[sub[subnum]->grp]->sname,sub[subnum]->lname,posts); ! 311: domsg=1; ! 312: curpost=0; } ! 313: else if(mode&SCAN_TOYOU) ! 314: curpost=0; ! 315: else { ! 316: for(curpost=0;curpost<posts;curpost++) ! 317: if(post[curpost].number>=sub[subnum]->last) ! 318: break; ! 319: if(curpost==posts) ! 320: curpost=posts-1; ! 321: ! 322: domsg=1; } } ! 323: ! 324: if(useron.misc&RIP) ! 325: menu("MSGSCAN"); ! 326: ! 327: if((i=smb_locksmbhdr(&smb))!=0) { ! 328: smb_close(&smb); ! 329: smb_stack(&smb,SMB_STACK_POP); ! 330: errormsg(WHERE,ERR_LOCK,smb.file,i); ! 331: return(0); } ! 332: if((i=smb_getstatus(&smb))!=0) { ! 333: smb_close(&smb); ! 334: smb_stack(&smb,SMB_STACK_POP); ! 335: errormsg(WHERE,ERR_READ,smb.file,i); ! 336: return(0); } ! 337: smb_unlocksmbhdr(&smb); ! 338: last=smb.status.last_msg; ! 339: ! 340: action=NODE_RMSG; ! 341: if(mode&SCAN_CONST) { /* update action */ ! 342: getnodedat(node_num,&thisnode,1); ! 343: thisnode.action=NODE_RMSG; ! 344: putnodedat(node_num,thisnode); } ! 345: while(online && !done) { ! 346: ! 347: action=NODE_RMSG; ! 348: if((i=heapcheck())!=_HEAPOK) { ! 349: errormsg(WHERE,ERR_CHK,"heap",i); ! 350: break; } ! 351: ! 352: if(mode&(SCAN_CONST|SCAN_FIND) && sys_status&SS_ABORT) ! 353: break; ! 354: ! 355: if(post==NULL) /* Been unloaded */ ! 356: post=loadposts(&posts,subnum,0,lp); /* So re-load */ ! 357: ! 358: if(!posts) { ! 359: done=1; ! 360: continue; } ! 361: ! 362: while(curpost>=posts) curpost--; ! 363: ! 364: for(ugrp=0;ugrp<usrgrps;ugrp++) ! 365: if(usrgrp[ugrp]==sub[subnum]->grp) ! 366: break; ! 367: for(usub=0;usub<usrsubs[ugrp];usub++) ! 368: if(usrsub[ugrp][usub]==subnum) ! 369: break; ! 370: usub++; ! 371: ugrp++; ! 372: ! 373: msg.idx.offset=post[curpost].offset; ! 374: msg.idx.number=post[curpost].number; ! 375: msg.idx.to=post[curpost].to; ! 376: msg.idx.from=post[curpost].from; ! 377: msg.idx.subj=post[curpost].subj; ! 378: ! 379: if((i=smb_locksmbhdr(&smb))!=0) { ! 380: errormsg(WHERE,ERR_LOCK,smb.file,i); ! 381: break; } ! 382: if((i=smb_getstatus(&smb))!=0) { ! 383: smb_unlocksmbhdr(&smb); ! 384: errormsg(WHERE,ERR_READ,smb.file,i); ! 385: break; } ! 386: smb_unlocksmbhdr(&smb); ! 387: ! 388: if(smb.status.last_msg!=last) { /* New messages */ ! 389: last=smb.status.last_msg; ! 390: if(post) { ! 391: LFREE((void *)post); } ! 392: post=loadposts(&posts,subnum,0,lp); /* So re-load */ ! 393: if(!posts) ! 394: break; ! 395: for(curpost=0;curpost<posts;curpost++) ! 396: if(post[curpost].number==msg.idx.number) ! 397: break; ! 398: if(curpost>(posts-1)) ! 399: curpost=(posts-1); ! 400: continue; } ! 401: ! 402: if(msg.total_hfields) ! 403: smb_freemsgmem(&msg); ! 404: msg.total_hfields=0; ! 405: ! 406: if(!loadmsg(&msg,post[curpost].number)) { ! 407: if(mismatches>5) { /* We can't do this too many times in a row */ ! 408: errormsg(WHERE,ERR_CHK,smb.file,post[curpost].number); ! 409: break; } ! 410: if(post) ! 411: LFREE(post); ! 412: post=loadposts(&posts,subnum,0,lp); ! 413: if(!posts) ! 414: break; ! 415: if(curpost>(posts-1)) ! 416: curpost=(posts-1); ! 417: mismatches++; ! 418: continue; } ! 419: smb_unlockmsghdr(&smb,&msg); ! 420: ! 421: mismatches=0; ! 422: ! 423: if(domsg) { ! 424: ! 425: if(!reread && mode&SCAN_FIND) { /* Find text in messages */ ! 426: buf=smb_getmsgtxt(&smb,&msg,GETMSGTXT_TAILS); ! 427: if(!buf) { ! 428: if(curpost<posts-1) curpost++; ! 429: else done=1; ! 430: continue; } ! 431: strupr((char *)buf); ! 432: if(!strstr((char *)buf,find) && !strstr(msg.subj,find)) { ! 433: FREE(buf); ! 434: if(curpost<posts-1) curpost++; ! 435: else done=1; ! 436: continue; } ! 437: FREE(buf); } ! 438: ! 439: if(mode&SCAN_CONST) ! 440: bprintf(text[ZScanPostHdr],ugrp,usub,curpost+1,posts); ! 441: ! 442: if(!reads && mode) ! 443: CRLF; ! 444: ! 445: show_msg(msg ! 446: ,msg.from_ext && !strcmp(msg.from_ext,"1") && !msg.from_net.type ! 447: ? 0:P_NOATCODES); ! 448: ! 449: reads++; /* number of messages actually read during this sub-scan */ ! 450: ! 451: /* Message is to this user and hasn't been read, so flag as read */ ! 452: if((!stricmp(msg.to,useron.name) || !stricmp(msg.to,useron.alias) ! 453: || (useron.number==1 && !stricmp(msg.to,"sysop") ! 454: && !msg.from_net.type)) ! 455: && !(msg.hdr.attr&MSG_READ)) { ! 456: if(msg.total_hfields) ! 457: smb_freemsgmem(&msg); ! 458: msg.total_hfields=0; ! 459: msg.idx.offset=0; ! 460: if(!smb_locksmbhdr(&smb)) { /* Lock the entire base */ ! 461: if(loadmsg(&msg,msg.idx.number)) { ! 462: msg.hdr.attr|=MSG_READ; ! 463: msg.idx.attr=msg.hdr.attr; ! 464: if((i=smb_putmsg(&smb,&msg))!=0) ! 465: errormsg(WHERE,ERR_WRITE,smb.file,i); ! 466: smb_unlockmsghdr(&smb,&msg); } ! 467: smb_unlocksmbhdr(&smb); } ! 468: if(!msg.total_hfields) { /* unsuccessful reload */ ! 469: domsg=0; ! 470: continue; } } ! 471: ! 472: sub[subnum]->last=post[curpost].number; ! 473: ! 474: if(sub[subnum]->ptr<post[curpost].number && !(mode&SCAN_TOYOU)) { ! 475: posts_read++; ! 476: sub[subnum]->ptr=post[curpost].number; } } ! 477: else domsg=1; ! 478: if(mode&SCAN_CONST) { ! 479: if(curpost<posts-1) curpost++; ! 480: else done=1; ! 481: continue; } ! 482: if(useron.misc&WIP) ! 483: menu("MSGSCAN"); ! 484: ASYNC; ! 485: bprintf(text[ReadingSub],ugrp,grp[sub[subnum]->grp]->sname ! 486: ,usub,sub[subnum]->sname,curpost+1,posts); ! 487: sprintf(str,"ABCDFILMPQRTY?<>[]{}-+.,"); ! 488: if(sub_op(subnum)) ! 489: strcat(str,"O"); ! 490: reread=0; ! 491: l=getkeys(str,posts); ! 492: if(l&0x80000000L) { ! 493: if((long)l==-1) { /* ctrl-c */ ! 494: if(msg.total_hfields) ! 495: smb_freemsgmem(&msg); ! 496: if(post) ! 497: LFREE(post); ! 498: smb_close(&smb); ! 499: smb_stack(&smb,SMB_STACK_POP); ! 500: return(1); } ! 501: curpost=(l&~0x80000000L)-1; ! 502: reread=1; ! 503: continue; } ! 504: switch(l) { ! 505: case 'A': /* Reply to last message */ ! 506: domsg=0; ! 507: if(!chk_ar(sub[subnum]->post_ar,useron)) { ! 508: bputs(text[CantPostOnSub]); ! 509: break; } ! 510: quotemsg(msg,0); ! 511: if(post) ! 512: LFREE(post); ! 513: post=NULL; ! 514: postmsg(subnum,&msg,WM_QUOTE); ! 515: // post=loadposts(&posts,subnum,0,lp); ! 516: if(mode&SCAN_TOYOU) ! 517: domsg=1; ! 518: break; ! 519: case 'B': /* Skip sub-board */ ! 520: if(mode&SCAN_NEW && !noyes(text[RemoveFromNewScanQ])) ! 521: sub[subnum]->misc&=~SUB_NSCAN; ! 522: if(msg.total_hfields) ! 523: smb_freemsgmem(&msg); ! 524: if(post) ! 525: LFREE(post); ! 526: smb_close(&smb); ! 527: smb_stack(&smb,SMB_STACK_POP); ! 528: return(0); ! 529: case 'C': /* Continuous */ ! 530: mode|=SCAN_CONST; ! 531: if(curpost<posts-1) curpost++; ! 532: else done=1; ! 533: break; ! 534: case 'D': /* Delete message on sub-board */ ! 535: domsg=0; ! 536: if(!sub_op(subnum) && !(sub[subnum]->misc&SUB_DEL)) { ! 537: bputs(text[CantDeletePosts]); ! 538: break; } ! 539: if(!sub_op(subnum)) { ! 540: if(stricmp(sub[subnum]->misc&SUB_NAME ! 541: ? useron.name : useron.alias, msg.from) ! 542: && stricmp(sub[subnum]->misc&SUB_NAME ! 543: ? useron.name : useron.alias, msg.to)) { ! 544: bprintf(text[YouDidntPostMsgN],curpost+1); ! 545: break; } } ! 546: if(msg.hdr.attr&MSG_PERMANENT) { ! 547: bputs("\1n\r\nMessage is marked permanent.\r\n"); ! 548: domsg=0; ! 549: break; } ! 550: if(post) ! 551: LFREE(post); ! 552: post=NULL; ! 553: ! 554: if(msg.total_hfields) ! 555: smb_freemsgmem(&msg); ! 556: msg.total_hfields=0; ! 557: msg.idx.offset=0; ! 558: if(loadmsg(&msg,msg.idx.number)) { ! 559: msg.idx.attr^=MSG_DELETE; ! 560: msg.hdr.attr=msg.idx.attr; ! 561: if((i=smb_putmsg(&smb,&msg))!=0) ! 562: errormsg(WHERE,ERR_WRITE,smb.file,i); ! 563: smb_unlockmsghdr(&smb,&msg); ! 564: if(i==0 && msg.idx.attr&MSG_DELETE) { ! 565: sprintf(str,"Removed post from %s %s" ! 566: ,grp[sub[subnum]->grp]->sname,sub[subnum]->lname); ! 567: logline("P-",str); ! 568: if(!stricmp(sub[subnum]->misc&SUB_NAME ! 569: ? useron.name : useron.alias, msg.from)) ! 570: useron.posts=adjustuserrec(useron.number ! 571: ,U_POSTS,5,-1); } } ! 572: domsg=1; ! 573: if((sys_misc&SM_SYSVDELM // anyone can view delete msgs ! 574: || (sys_misc&SM_USRVDELM // sys/subops can view deleted msgs ! 575: && sub_op(subnum))) ! 576: && curpost<posts-1) ! 577: curpost++; ! 578: if(curpost>=posts-1) ! 579: done=1; ! 580: break; ! 581: ! 582: case 'F': /* find text in messages */ ! 583: domsg=0; ! 584: bprintf(text[StartWithN],curpost+2); ! 585: if((i=getnum(posts))<0) ! 586: break; ! 587: if(i) ! 588: i--; ! 589: else ! 590: i=curpost+1; ! 591: bputs(text[SearchStringPrompt]); ! 592: if(!getstr(str,40,K_LINE|K_UPPER)) ! 593: break; ! 594: searchposts(subnum,post,(long)i,posts,str); ! 595: break; ! 596: case 'I': /* Sub-board information */ ! 597: domsg=0; ! 598: subinfo(subnum); ! 599: break; ! 600: case 'L': /* List messages */ ! 601: domsg=0; ! 602: bprintf(text[StartWithN],curpost+1); ! 603: if((i=getnum(posts))<0) ! 604: break; ! 605: if(i) i--; ! 606: else i=curpost; ! 607: listmsgs(subnum,post,i,posts); ! 608: break; ! 609: case 'M': /* Reply to last post in mail */ ! 610: domsg=0; ! 611: if(msg.hdr.attr&MSG_ANONYMOUS && !sub_op(subnum)) { ! 612: bputs(text[CantReplyToAnonMsg]); ! 613: break; } ! 614: if(!sub_op(subnum) && msg.hdr.attr&MSG_PRIVATE ! 615: && stricmp(msg.to,useron.name) ! 616: && stricmp(msg.to,useron.alias)) ! 617: break; ! 618: sprintf(str2,text[Regarding] ! 619: ,msg.subj ! 620: ,timestr((time_t *)&msg.hdr.when_written.time)); ! 621: if(msg.from_net.type==NET_FIDO) ! 622: sprintf(str,"%s @%s",msg.from ! 623: ,faddrtoa(*(faddr_t *)msg.from_net.addr)); ! 624: else if(msg.from_net.type==NET_INTERNET) ! 625: strcpy(str,msg.from_net.addr); ! 626: else if(msg.from_net.type) ! 627: sprintf(str,"%s@%s",msg.from,msg.from_net.addr); ! 628: else ! 629: strcpy(str,msg.from); ! 630: bputs(text[Email]); ! 631: if(!getstr(str,60,K_EDIT|K_AUTODEL)) ! 632: break; ! 633: if(post) ! 634: LFREE(post); ! 635: post=NULL; ! 636: quotemsg(msg,1); ! 637: if(msg.from_net.type==NET_INTERNET ! 638: && (!strcmp(str,msg.from_net.addr) || strchr(str,'@'))) ! 639: inetmail(str,msg.subj,WM_QUOTE|WM_NETMAIL); ! 640: else { ! 641: p=strrchr(str,'@'); ! 642: if(p) /* FidoNet or QWKnet */ ! 643: netmail(str,msg.subj,WM_QUOTE); ! 644: else { ! 645: i=atoi(str); ! 646: if(!i) { ! 647: if(sub[subnum]->misc&SUB_NAME) ! 648: i=userdatdupe(0,U_NAME,LEN_NAME,str,0); ! 649: else ! 650: i=matchuser(str); } ! 651: email(i,str2,msg.subj,WM_EMAIL|WM_QUOTE); } } ! 652: // post=loadposts(&posts,subnum,0,lp); ! 653: break; ! 654: case 'P': /* Post message on sub-board */ ! 655: domsg=0; ! 656: if(!chk_ar(sub[subnum]->post_ar,useron)) ! 657: bputs(text[CantPostOnSub]); ! 658: else { ! 659: if(post) ! 660: LFREE(post); ! 661: post=NULL; ! 662: postmsg(subnum,0,0); ! 663: // post=loadposts(&posts,subnum,0,lp); ! 664: } ! 665: break; ! 666: case 'Q': /* Quit */ ! 667: if(msg.total_hfields) ! 668: smb_freemsgmem(&msg); ! 669: if(post) ! 670: LFREE(post); ! 671: smb_close(&smb); ! 672: smb_stack(&smb,SMB_STACK_POP); ! 673: return(1); ! 674: case 'R': /* re-read last message */ ! 675: reread=1; ! 676: break; ! 677: case 'T': /* List titles of next ten messages */ ! 678: domsg=0; ! 679: if(!posts) ! 680: break; ! 681: if(curpost>=posts-1) { ! 682: done=1; ! 683: break; } ! 684: i=curpost+11; ! 685: if(i>posts) ! 686: i=posts; ! 687: listmsgs(subnum,post,curpost+1,i); ! 688: curpost=i-1; ! 689: if(sub[subnum]->ptr<post[curpost].number) ! 690: sub[subnum]->ptr=post[curpost].number; ! 691: break; ! 692: case 'Y': /* Your messages */ ! 693: domsg=0; ! 694: showposts_toyou(post,0,posts); ! 695: break; ! 696: case '-': ! 697: if(curpost>0) curpost--; ! 698: reread=1; ! 699: break; ! 700: case 'O': /* Operator commands */ ! 701: while(online) { ! 702: if(!(useron.misc&EXPERT)) ! 703: menu("SYSMSCAN"); ! 704: bprintf("\r\n\1y\1hOperator: \1w"); ! 705: strcpy(str,"?CEHMPQUV"); ! 706: if(SYSOP) ! 707: strcat(str,"S"); ! 708: switch(getkeys(str,0)) { ! 709: case '?': ! 710: if(useron.misc&EXPERT) ! 711: menu("SYSMSCAN"); ! 712: continue; ! 713: case 'P': /* Purge user */ ! 714: purgeuser(sub[subnum]->misc&SUB_NAME ! 715: ? userdatdupe(0,U_NAME,LEN_NAME,msg.from,0) ! 716: : matchuser(msg.from)); ! 717: break; ! 718: case 'C': /* Change message attributes */ ! 719: i=chmsgattr(msg.hdr.attr); ! 720: if(msg.hdr.attr==i) ! 721: break; ! 722: if(msg.total_hfields) ! 723: smb_freemsgmem(&msg); ! 724: msg.total_hfields=0; ! 725: msg.idx.offset=0; ! 726: if(loadmsg(&msg,msg.idx.number)) { ! 727: msg.hdr.attr=msg.idx.attr=i; ! 728: if((i=smb_putmsg(&smb,&msg))!=0) ! 729: errormsg(WHERE,ERR_WRITE,smb.file,i); ! 730: smb_unlockmsghdr(&smb,&msg); } ! 731: break; ! 732: case 'E': /* edit last post */ ! 733: if(post) ! 734: LFREE(post); ! 735: post=NULL; ! 736: editmsg(&msg,subnum); ! 737: // post=loadposts(&posts,subnum,0,lp); ! 738: break; ! 739: case 'H': /* View message header */ ! 740: msghdr(msg); ! 741: domsg=0; ! 742: break; ! 743: case 'M': /* Move message */ ! 744: domsg=0; ! 745: if(post) ! 746: LFREE(post); ! 747: post=NULL; ! 748: if(msg.total_hfields) ! 749: smb_freemsgmem(&msg); ! 750: msg.total_hfields=0; ! 751: msg.idx.offset=0; ! 752: if(!loadmsg(&msg,msg.idx.number)) { ! 753: errormsg(WHERE,ERR_READ,smb.file,msg.idx.number); ! 754: break; } ! 755: sprintf(str,text[DeletePostQ],msg.hdr.number,msg.subj); ! 756: if(movemsg(msg,subnum) && yesno(str)) { ! 757: msg.idx.attr|=MSG_DELETE; ! 758: msg.hdr.attr=msg.idx.attr; ! 759: if((i=smb_putmsg(&smb,&msg))!=0) ! 760: errormsg(WHERE,ERR_WRITE,smb.file,i); } ! 761: smb_unlockmsghdr(&smb,&msg); ! 762: // post=loadposts(&posts,subnum,0,lp); ! 763: break; ! 764: ! 765: case 'Q': ! 766: break; ! 767: case 'S': /* Save/Append message to another file */ ! 768: /* 05/26/95 ! 769: if(!yesno(text[SaveMsgToFile])) ! 770: break; ! 771: */ ! 772: bputs(text[FileToWriteTo]); ! 773: if(getstr(str,40,K_LINE|K_UPPER)) ! 774: msgtotxt(msg,str,1,1); ! 775: break; ! 776: case 'U': /* User edit */ ! 777: useredit(sub[subnum]->misc&SUB_NAME ! 778: ? userdatdupe(0,U_NAME,LEN_NAME,msg.from,0) ! 779: : matchuser(msg.from),0); ! 780: break; ! 781: case 'V': /* Validate message */ ! 782: if(msg.total_hfields) ! 783: smb_freemsgmem(&msg); ! 784: msg.total_hfields=0; ! 785: msg.idx.offset=0; ! 786: if(loadmsg(&msg,msg.idx.number)) { ! 787: msg.idx.attr|=MSG_VALIDATED; ! 788: msg.hdr.attr=msg.idx.attr; ! 789: if((i=smb_putmsg(&smb,&msg))!=0) ! 790: errormsg(WHERE,ERR_WRITE,smb.file,i); ! 791: smb_unlockmsghdr(&smb,&msg); } ! 792: break; ! 793: default: ! 794: continue; } ! 795: break; } ! 796: break; ! 797: case '.': /* Thread forward */ ! 798: l=msg.hdr.thread_first; ! 799: if(!l) l=msg.hdr.thread_next; ! 800: if(!l) { ! 801: domsg=0; ! 802: break; } ! 803: for(i=0;i<posts;i++) ! 804: if(l==post[i].number) ! 805: break; ! 806: if(i<posts) ! 807: curpost=i; ! 808: break; ! 809: case ',': /* Thread backwards */ ! 810: if(!msg.hdr.thread_orig) { ! 811: domsg=0; ! 812: break; } ! 813: for(i=0;i<posts;i++) ! 814: if(msg.hdr.thread_orig==post[i].number) ! 815: break; ! 816: if(i<posts) ! 817: curpost=i; ! 818: break; ! 819: case '>': /* Search Title forward */ ! 820: for(i=curpost+1;i<posts;i++) ! 821: if(post[i].subj==msg.idx.subj) ! 822: break; ! 823: if(i<posts) ! 824: curpost=i; ! 825: else ! 826: domsg=0; ! 827: break; ! 828: case '<': /* Search Title backward */ ! 829: for(i=curpost-1;i>-1;i--) ! 830: if(post[i].subj==msg.idx.subj) ! 831: break; ! 832: if(i>-1) ! 833: curpost=i; ! 834: else ! 835: domsg=0; ! 836: break; ! 837: case '}': /* Search Author forward */ ! 838: strcpy(str,msg.from); ! 839: for(i=curpost+1;i<posts;i++) ! 840: if(post[i].from==msg.idx.from) ! 841: break; ! 842: if(i<posts) ! 843: curpost=i; ! 844: else ! 845: domsg=0; ! 846: break; ! 847: case '{': /* Search Author backward */ ! 848: strcpy(str,msg.from); ! 849: for(i=curpost-1;i>-1;i--) ! 850: if(post[i].from==msg.idx.from) ! 851: break; ! 852: if(i>-1) ! 853: curpost=i; ! 854: else ! 855: domsg=0; ! 856: break; ! 857: case ']': /* Search To User forward */ ! 858: strcpy(str,msg.to); ! 859: for(i=curpost+1;i<posts;i++) ! 860: if(post[i].to==msg.idx.to) ! 861: break; ! 862: if(i<posts) ! 863: curpost=i; ! 864: else ! 865: domsg=0; ! 866: break; ! 867: case '[': /* Search To User backward */ ! 868: strcpy(str,msg.to); ! 869: for(i=curpost-1;i>-1;i--) ! 870: if(post[i].to==msg.idx.to) ! 871: break; ! 872: if(i>-1) ! 873: curpost=i; ! 874: else ! 875: domsg=0; ! 876: break; ! 877: case 0: /* Carriage return - Next Message */ ! 878: case '+': ! 879: if(curpost<posts-1) curpost++; ! 880: else done=1; ! 881: break; ! 882: case '?': ! 883: menu("MSGSCAN"); ! 884: domsg=0; ! 885: break; } } ! 886: if(msg.total_hfields) ! 887: smb_freemsgmem(&msg); ! 888: if(post) ! 889: LFREE(post); ! 890: if(!(mode&(SCAN_CONST|SCAN_TOYOU|SCAN_FIND)) && !(sub[subnum]->misc&SUB_PONLY) ! 891: && reads && chk_ar(sub[subnum]->post_ar,useron) ! 892: && !(useron.rest&FLAG('P'))) { ! 893: sprintf(str,text[Post],grp[sub[subnum]->grp]->sname ! 894: ,sub[subnum]->lname); ! 895: if(!noyes(str)) ! 896: postmsg(subnum,0,0); } ! 897: smb_close(&smb); ! 898: smb_stack(&smb,SMB_STACK_POP); ! 899: return(0); ! 900: } ! 901: ! 902: /****************************************************************************/ ! 903: /* This function will search the specified sub-board for messages that */ ! 904: /* contain the string 'search'. */ ! 905: /* Returns number of messages found. */ ! 906: /****************************************************************************/ ! 907: int searchsub(uint subnum,char *search) ! 908: { ! 909: int i,found; ! 910: ulong l,posts,total; ! 911: post_t HUGE16 *post; ! 912: ! 913: if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) { ! 914: errormsg(WHERE,ERR_OPEN,sub[subnum]->code,i); ! 915: return(0); } ! 916: total=getposts(subnum); ! 917: sprintf(smb.file,"%s%s",sub[subnum]->data_dir,sub[subnum]->code); ! 918: smb.retry_time=smb_retry_time; ! 919: if((i=smb_open(&smb))!=0) { ! 920: smb_stack(&smb,SMB_STACK_POP); ! 921: errormsg(WHERE,ERR_OPEN,smb.file,i); ! 922: return(0); } ! 923: post=loadposts(&posts,subnum,0,LP_BYSELF|LP_OTHERS); ! 924: bprintf(text[SearchSubFmt] ! 925: ,grp[sub[subnum]->grp]->sname,sub[subnum]->lname,posts,total); ! 926: found=searchposts(subnum,post,0,posts,search); ! 927: if(posts) ! 928: LFREE(post); ! 929: smb_close(&smb); ! 930: smb_stack(&smb,SMB_STACK_POP); ! 931: return(found); ! 932: } ! 933: ! 934: /****************************************************************************/ ! 935: /* Will search the messages pointed to by 'msg' for the occurance of the */ ! 936: /* string 'search' and display any messages (number of message, author and */ ! 937: /* title). 'msgs' is the total number of valid messages. */ ! 938: /* Returns number of messages found. */ ! 939: /****************************************************************************/ ! 940: int searchposts(uint subnum, post_t HUGE16 *post, long start, long posts ! 941: , char *search) ! 942: { ! 943: char HUGE16 *buf,ch; ! 944: ushort xlat; ! 945: int i,j; ! 946: long l,length,found=0; ! 947: smbmsg_t msg; ! 948: ! 949: msg.total_hfields=0; ! 950: for(l=start;l<posts && !msgabort();l++) { ! 951: msg.idx.offset=post[l].offset; ! 952: if(!loadmsg(&msg,post[l].number)) ! 953: continue; ! 954: smb_unlockmsghdr(&smb,&msg); ! 955: buf=smb_getmsgtxt(&smb,&msg,1); ! 956: if(!buf) { ! 957: smb_freemsgmem(&msg); ! 958: continue; } ! 959: strupr((char *)buf); ! 960: if(strstr((char *)buf,search) || strstr(msg.subj,search)) { ! 961: if(!found) ! 962: CRLF; ! 963: if(msg.hdr.attr&MSG_DELETE) ! 964: ch='-'; ! 965: else if((!stricmp(msg.to,useron.alias) || !stricmp(msg.to,useron.name)) ! 966: && !(msg.hdr.attr&MSG_READ)) ! 967: ch='!'; ! 968: else if(msg.hdr.number>sub[subnum]->ptr) ! 969: ch='*'; ! 970: else ! 971: ch=' '; ! 972: bprintf(text[SubMsgLstFmt],l+1 ! 973: ,(msg.hdr.attr&MSG_ANONYMOUS) && !sub_op(subnum) ? text[Anonymous] ! 974: : msg.from ! 975: ,msg.to ! 976: ,ch ! 977: ,msg.subj); ! 978: found++; } ! 979: FREE(buf); ! 980: smb_freemsgmem(&msg); } ! 981: ! 982: return(found); ! 983: } ! 984: ! 985: /****************************************************************************/ ! 986: /* Will search the messages pointed to by 'msg' for message to the user on */ ! 987: /* Returns number of messages found. */ ! 988: /****************************************************************************/ ! 989: void showposts_toyou(post_t HUGE16 *post, ulong start, ulong posts) ! 990: { ! 991: char str[128]; ! 992: ushort namecrc,aliascrc,sysop; ! 993: int i; ! 994: ulong l,found; ! 995: smbmsg_t msg; ! 996: ! 997: strcpy(str,useron.alias); ! 998: strlwr(str); ! 999: aliascrc=crc16(str); ! 1000: strcpy(str,useron.name); ! 1001: strlwr(str); ! 1002: namecrc=crc16(str); ! 1003: sysop=crc16("sysop"); ! 1004: msg.total_hfields=0; ! 1005: for(l=start,found=0;l<posts && !msgabort();l++) { ! 1006: ! 1007: if((useron.number!=1 || post[l].to!=sysop) ! 1008: && post[l].to!=aliascrc && post[l].to!=namecrc) ! 1009: continue; ! 1010: ! 1011: if(msg.total_hfields) ! 1012: smb_freemsgmem(&msg); ! 1013: msg.total_hfields=0; ! 1014: msg.idx.offset=post[l].offset; ! 1015: if(!loadmsg(&msg,post[l].number)) ! 1016: continue; ! 1017: smb_unlockmsghdr(&smb,&msg); ! 1018: if((useron.number==1 && !stricmp(msg.to,"sysop") && !msg.from_net.type) ! 1019: || !stricmp(msg.to,useron.alias) || !stricmp(msg.to,useron.name)) { ! 1020: if(!found) ! 1021: CRLF; ! 1022: found++; ! 1023: bprintf(text[SubMsgLstFmt],l+1 ! 1024: ,(msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP ! 1025: ? text[Anonymous] : msg.from ! 1026: ,msg.to ! 1027: ,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_READ ? ' ' : '*' ! 1028: ,msg.subj); } } ! 1029: ! 1030: if(msg.total_hfields) ! 1031: smb_freemsgmem(&msg); ! 1032: } ! 1033: ! 1034: /****************************************************************************/ ! 1035: /* This function will search the specified sub-board for messages that */ ! 1036: /* are sent to the currrent user. */ ! 1037: /* returns number of messages found */ ! 1038: /****************************************************************************/ ! 1039: int searchsub_toyou(uint subnum) ! 1040: { ! 1041: int i; ! 1042: ulong l,posts,total; ! 1043: post_t HUGE16 *post; ! 1044: ! 1045: if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) { ! 1046: errormsg(WHERE,ERR_OPEN,sub[subnum]->code,i); ! 1047: return(0); } ! 1048: total=getposts(subnum); ! 1049: sprintf(smb.file,"%s%s",sub[subnum]->data_dir,sub[subnum]->code); ! 1050: smb.retry_time=smb_retry_time; ! 1051: if((i=smb_open(&smb))!=0) { ! 1052: smb_stack(&smb,SMB_STACK_POP); ! 1053: errormsg(WHERE,ERR_OPEN,smb.file,i); ! 1054: return(0); } ! 1055: post=loadposts(&posts,subnum,0,0); ! 1056: bprintf(text[SearchSubFmt] ! 1057: ,grp[sub[subnum]->grp]->sname,sub[subnum]->lname,total); ! 1058: if(posts) { ! 1059: if(post) ! 1060: LFREE(post); ! 1061: post=loadposts(&posts,subnum,0,LP_BYSELF|LP_OTHERS); ! 1062: showposts_toyou(post,0,posts); } ! 1063: if(post) ! 1064: LFREE(post); ! 1065: smb_close(&smb); ! 1066: smb_stack(&smb,SMB_STACK_POP); ! 1067: return(posts); ! 1068: } ! 1069: ! 1070:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.