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