|
|
1.1 root 1: /* readmsgs.cpp */
2:
3: /* Synchronet public message reading function */
4:
1.1.1.2 ! root 5: /* $Id: readmsgs.cpp,v 1.56 2011/07/21 11:19:22 rswindell Exp $ */
1.1 root 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: * *
1.1.1.2 ! root 11: * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html *
1.1 root 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:
40: int sbbs_t::sub_op(uint subnum)
41: {
1.1.1.2 ! root 42: return(is_user_subop(&cfg, subnum, &useron, &client));
1.1 root 43: }
44:
45:
46: long sbbs_t::listmsgs(uint subnum, long mode, post_t *post, long i, long posts)
47: {
48: char ch;
49: smbmsg_t msg;
50: long listed=0;
51:
52: bputs(text[MailOnSystemLstHdr]);
53: msg.total_hfields=0;
54: for(;i<posts && !msgabort();i++) {
55: if(msg.total_hfields)
56: smb_freemsgmem(&msg);
57: msg.total_hfields=0;
58: msg.idx.offset=post[i].offset;
59: if(!loadmsg(&msg,post[i].number))
60: break;
61: smb_unlockmsghdr(&smb,&msg);
62: if(mode&SCAN_NEW && msg.hdr.number<=subscan[subnum].ptr)
63: continue;
64: if(msg.hdr.attr&MSG_DELETE)
65: ch='-';
66: else if((!stricmp(msg.to,useron.alias) || !stricmp(msg.to,useron.name))
67: && !(msg.hdr.attr&MSG_READ))
68: ch='!';
69: else if(msg.hdr.number>subscan[subnum].ptr)
70: ch='*';
71: else
72: ch=' ';
73: bprintf(text[SubMsgLstFmt],(long)i+1
74: ,msg.hdr.attr&MSG_ANONYMOUS && !sub_op(subnum)
75: ? text[Anonymous] : msg.from
76: ,msg.to
77: ,ch
78: ,msg.subj);
79: smb_freemsgmem(&msg);
80: msg.total_hfields=0;
81: listed++;
82: }
83:
84: return(listed);
85: }
86:
1.1.1.2 ! root 87: char *binstr(uchar *buf, ushort length, char* str)
1.1 root 88: {
89: char tmp[128];
90: int i;
91:
92: str[0]=0;
93: for(i=0;i<length;i++)
94: if(buf[i] && (buf[i]<' ' || buf[i]>=0x7f)
95: && buf[i]!='\r' && buf[i]!='\n' && buf[i]!='\t')
96: break;
97: if(i==length) /* not binary */
98: return((char*)buf);
99: for(i=0;i<length;i++) {
100: sprintf(tmp,"%02X ",buf[i]);
101: strcat(str,tmp);
1.1.1.2 ! root 102: if(i >= 100) {
! 103: strcat(str,"...");
! 104: break;
! 105: }
1.1 root 106: }
107: return(str);
108: }
109:
110:
111: void sbbs_t::msghdr(smbmsg_t* msg)
112: {
113: int i;
1.1.1.2 ! root 114: char str[512];
1.1 root 115:
116: CRLF;
117:
118: /* variable fields */
119: for(i=0;i<msg->total_hfields;i++)
120: bprintf("%-16.16s %s\r\n"
121: ,smb_hfieldtype(msg->hfield[i].type)
1.1.1.2 ! root 122: ,binstr((uchar *)msg->hfield_dat[i],msg->hfield[i].length,str));
1.1 root 123:
124: /* fixed fields */
1.1.1.2 ! root 125: bprintf("%-16.16s %08lX %04hX %.24s %s\r\n","when_written"
! 126: ,msg->hdr.when_written.time, msg->hdr.when_written.zone
! 127: ,timestr(msg->hdr.when_written.time)
! 128: ,smb_zonestr(msg->hdr.when_written.zone,NULL));
! 129: bprintf("%-16.16s %08lX %04hX %.24s %s\r\n","when_imported"
! 130: ,msg->hdr.when_imported.time, msg->hdr.when_imported.zone
! 131: ,timestr(msg->hdr.when_imported.time)
! 132: ,smb_zonestr(msg->hdr.when_imported.zone,NULL));
1.1 root 133: bprintf("%-16.16s %04Xh\r\n","type" ,msg->hdr.type);
134: bprintf("%-16.16s %04Xh\r\n","version" ,msg->hdr.version);
135: bprintf("%-16.16s %04Xh\r\n","attr" ,msg->hdr.attr);
136: bprintf("%-16.16s %08lXh\r\n","auxattr" ,msg->hdr.auxattr);
137: bprintf("%-16.16s %08lXh\r\n","netattr" ,msg->hdr.netattr);
138: bprintf("%-16.16s %ld\r\n" ,"number" ,msg->hdr.number);
139: bprintf("%-16.16s %06lXh\r\n","header offset" ,msg->idx.offset);
140: bprintf("%-16.16s %u\r\n" ,"header length" ,msg->hdr.length);
141:
142: /* optional fixed fields */
143: if(msg->hdr.thread_back)
144: bprintf("%-16.16s %ld\r\n" ,"thread_back" ,msg->hdr.thread_back);
145: if(msg->hdr.thread_next)
146: bprintf("%-16.16s %ld\r\n" ,"thread_next" ,msg->hdr.thread_next);
147: if(msg->hdr.thread_first)
148: bprintf("%-16.16s %ld\r\n" ,"thread_first" ,msg->hdr.thread_first);
149: if(msg->hdr.delivery_attempts)
150: bprintf("%-16.16s %hu\r\n" ,"delivery_attempts",msg->hdr.delivery_attempts);
151: if(msg->hdr.times_downloaded)
152: bprintf("%-16.16s %lu\r\n" ,"times_downloaded" ,msg->hdr.times_downloaded);
153: if(msg->hdr.last_downloaded)
1.1.1.2 ! root 154: bprintf("%-16.16s %s\r\n" ,"last_downloaded" ,timestr(msg->hdr.last_downloaded));
1.1 root 155:
156: /* convenience integers */
157: if(msg->expiration)
158: bprintf("%-16.16s %s\r\n" ,"expiration"
1.1.1.2 ! root 159: ,timestr(msg->expiration));
1.1 root 160: if(msg->priority)
161: bprintf("%-16.16s %lu\r\n" ,"priority" ,msg->priority);
162: if(msg->cost)
163: bprintf("%-16.16s %lu\r\n" ,"cost" ,msg->cost);
164:
165: bprintf("%-16.16s %06lXh\r\n" ,"data offset" ,msg->hdr.offset);
166: for(i=0;i<msg->hdr.total_dfields;i++)
167: bprintf("data field[%u] %s, offset %lu, length %lu\r\n"
168: ,i
169: ,smb_dfieldtype(msg->dfield[i].type)
170: ,msg->dfield[i].offset
171: ,msg->dfield[i].length);
172: }
173:
174: /****************************************************************************/
175: /****************************************************************************/
1.1.1.2 ! root 176: post_t * sbbs_t::loadposts(int32_t *posts, uint subnum, ulong ptr, long mode)
1.1 root 177: {
178: char name[128];
179: ushort aliascrc,namecrc,sysop;
180: int i,skip;
181: ulong l=0,total,alloc_len;
182: smbmsg_t msg;
183: idxrec_t idx;
184: post_t *post;
185:
186: if(posts==NULL)
187: return(NULL);
188:
189: (*posts)=0;
190:
191: if((i=smb_locksmbhdr(&smb))!=0) { /* Be sure noone deletes or */
1.1.1.2 ! root 192: errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); /* adds while we're reading */
1.1 root 193: return(NULL);
194: }
195:
1.1.1.2 ! root 196: total=(long)filelength(fileno(smb.sid_fp))/sizeof(idxrec_t); /* total msgs in sub */
1.1 root 197:
198: if(!total) { /* empty */
199: smb_unlocksmbhdr(&smb);
200: return(NULL);
201: }
202:
203: strcpy(name,useron.name);
204: strlwr(name);
205: namecrc=crc16(name,0);
206: strcpy(name,useron.alias);
207: strlwr(name);
208: aliascrc=crc16(name,0);
209: sysop=crc16("sysop",0);
210:
211: rewind(smb.sid_fp);
212:
213: alloc_len=sizeof(post_t)*total;
214: #ifdef __OS2__
215: while(alloc_len%4096)
216: alloc_len++;
217: #endif
218: if((post=(post_t *)malloc(alloc_len))==NULL) { /* alloc for max */
219: smb_unlocksmbhdr(&smb);
220: errormsg(WHERE,ERR_ALLOC,smb.file,sizeof(post_t *)*cfg.sub[subnum]->maxmsgs);
221: return(NULL);
222: }
223: while(!feof(smb.sid_fp)) {
224: skip=0;
225: if(smb_fread(&smb, &idx,sizeof(idx),smb.sid_fp) != sizeof(idx))
226: break;
227:
228: if(idx.number==0) /* invalid message number, ignore */
229: continue;
230:
231: if(idx.number<=ptr)
232: continue;
233:
234: if(idx.attr&MSG_READ && mode&LP_UNREAD) /* Skip read messages */
235: continue;
236:
237: if(idx.attr&MSG_DELETE) { /* Pre-flagged */
238: if(mode&LP_REP) /* Don't include deleted msgs in REP pkt */
239: continue;
240: if(!(cfg.sys_misc&SM_SYSVDELM)) /* Noone can view deleted msgs */
241: continue;
242: if(!(cfg.sys_misc&SM_USRVDELM) /* Users can't view deleted msgs */
243: && !sub_op(subnum)) /* not sub-op */
244: continue;
245: if(!sub_op(subnum) /* not sub-op */
246: && idx.from!=namecrc && idx.from!=aliascrc) /* not for you */
247: continue;
248: }
249:
250: if(idx.attr&MSG_MODERATED && !(idx.attr&MSG_VALIDATED)
251: && (mode&LP_REP || !sub_op(subnum)))
252: break;
253:
254: if(idx.attr&MSG_PRIVATE && !(mode&LP_PRIVATE)
255: && !sub_op(subnum) && !(useron.rest&FLAG('Q'))) {
256: if(idx.to!=namecrc && idx.from!=namecrc
257: && idx.to!=aliascrc && idx.from!=aliascrc
258: && (useron.number!=1 || idx.to!=sysop))
259: continue;
260: if(!smb_lockmsghdr(&smb,&msg)) {
261: if(!smb_getmsghdr(&smb,&msg)) {
262: if(stricmp(msg.to,useron.alias)
263: && stricmp(msg.from,useron.alias)
264: && stricmp(msg.to,useron.name)
265: && stricmp(msg.from,useron.name)
266: && (useron.number!=1 || stricmp(msg.to,"sysop")
267: || msg.from_net.type))
268: skip=1;
269: smb_freemsgmem(&msg);
270: }
271: smb_unlockmsghdr(&smb,&msg);
272: }
273: if(skip)
274: continue;
275: }
276:
277:
278: if(!(mode&LP_BYSELF) && (idx.from==namecrc || idx.from==aliascrc)) {
279: msg.idx=idx;
280: if(!smb_lockmsghdr(&smb,&msg)) {
281: if(!smb_getmsghdr(&smb,&msg)) {
282: if(!stricmp(msg.from,useron.alias)
283: || !stricmp(msg.from,useron.name))
284: skip=1;
285: smb_freemsgmem(&msg);
286: }
287: smb_unlockmsghdr(&smb,&msg);
288: }
289: if(skip)
290: continue;
291: }
292:
293: if(!(mode&LP_OTHERS)) {
294: if(idx.to!=namecrc && idx.to!=aliascrc
295: && (useron.number!=1 || idx.to!=sysop))
296: continue;
297: msg.idx=idx;
298: if(!smb_lockmsghdr(&smb,&msg)) {
299: if(!smb_getmsghdr(&smb,&msg)) {
300: if(stricmp(msg.to,useron.alias) && stricmp(msg.to,useron.name)
301: && (useron.number!=1 || stricmp(msg.to,"sysop")
302: || msg.from_net.type))
303: skip=1;
304: smb_freemsgmem(&msg);
305: }
306: smb_unlockmsghdr(&smb,&msg);
307: }
308: if(skip)
309: continue;
310: }
311:
312: memcpy(&post[l],&idx,sizeof(idx));
313: l++;
314: }
315: smb_unlocksmbhdr(&smb);
316: if(!l)
317: FREE_AND_NULL(post);
318:
319: (*posts)=l;
320: return(post);
321: }
322:
323: static int get_start_msg(sbbs_t* sbbs, smb_t* smb)
324: {
325: int i,j=smb->curmsg+1;
326:
327: if(j<smb->msgs)
328: j++;
329: else
330: j=1;
331: sbbs->bprintf(sbbs->text[StartWithN],j);
332: if((i=sbbs->getnum(smb->msgs))<0)
333: return(i);
334: if(i==0)
335: return(j-1);
336: return(i-1);
337: }
338:
339: /****************************************************************************/
340: /* Reads posts on subboard sub. 'mode' determines new-posts only, browse, */
341: /* or continuous read. */
342: /* Returns 0 if normal completion, 1 if aborted. */
343: /* Called from function main_sec */
344: /****************************************************************************/
1.1.1.2 ! root 345: int sbbs_t::scanposts(uint subnum, long mode, const char *find)
1.1 root 346: {
347: char str[256],str2[256],do_find=true,mismatches=0
348: ,done=0,domsg=1,*buf,*p;
1.1.1.2 ! root 349: char subj[128];
1.1 root 350: char find_buf[128];
351: char tmp[128];
352: int i;
1.1.1.2 ! root 353: int quit=0;
1.1 root 354: uint usub,ugrp,reads=0;
355: uint lp=0;
356: long org_mode=mode;
1.1.1.2 ! root 357: ulong msgs,l;
! 358: uint32_t last;
1.1 root 359: post_t *post;
360: smbmsg_t msg;
361:
1.1.1.2 ! root 362: find_buf[0]=0;
1.1 root 363: cursubnum=subnum; /* for ARS */
1.1.1.2 ! root 364: if(!chk_ar(cfg.sub[subnum]->read_ar,&useron,&client)) {
! 365: bprintf(text[CantReadSub]
1.1 root 366: ,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->sname);
367: return(0);
368: }
369: msg.total_hfields=0; /* init to NULL, specify not-allocated */
370: if(!(mode&SCAN_CONST))
371: lncntr=0;
372: if((msgs=getlastmsg(subnum,&last,0))==0) {
373: if(mode&(SCAN_NEW|SCAN_TOYOU))
374: bprintf(text[NScanStatusFmt]
375: ,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname,0L,0L);
376: else
377: bprintf(text[NoMsgsOnSub]
378: ,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->sname);
379: return(0);
380: }
381: if(mode&SCAN_NEW && subscan[subnum].ptr>=last && !(mode&SCAN_BACK)) {
382: if(subscan[subnum].ptr>last)
383: subscan[subnum].ptr=subscan[subnum].last=last;
384: bprintf(text[NScanStatusFmt]
385: ,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname,0L,msgs);
386: return(0);
387: }
388:
389: if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) {
390: errormsg(WHERE,ERR_OPEN,cfg.sub[subnum]->code,i);
391: return(0);
392: }
393: sprintf(smb.file,"%s%s",cfg.sub[subnum]->data_dir,cfg.sub[subnum]->code);
394: smb.retry_time=cfg.smb_retry_time;
395: smb.subnum=subnum;
396: if((i=smb_open(&smb))!=0) {
397: errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
398: smb_stack(&smb,SMB_STACK_POP);
399: return(0);
400: }
401:
402: if(!(mode&SCAN_TOYOU)
403: && (!mode || mode&SCAN_FIND || !(subscan[subnum].cfg&SUB_CFG_YSCAN)))
404: lp=LP_BYSELF|LP_OTHERS;
405: if(mode&SCAN_TOYOU)
406: lp|=LP_UNREAD;
407: post=loadposts(&smb.msgs,subnum,0,lp);
408: if(mode&SCAN_NEW) { /* Scanning for new messages */
409: for(smb.curmsg=0;smb.curmsg<smb.msgs;smb.curmsg++)
410: if(subscan[subnum].ptr<post[smb.curmsg].number)
411: break;
412: bprintf(text[NScanStatusFmt]
413: ,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname,smb.msgs-smb.curmsg,msgs);
414: if(!smb.msgs) { /* no messages at all */
415: smb_close(&smb);
416: smb_stack(&smb,SMB_STACK_POP);
417: return(0);
418: }
419: if(smb.curmsg==smb.msgs) { /* no new messages */
420: if(!(mode&SCAN_BACK)) {
421: if(post)
422: free(post);
423: smb_close(&smb);
424: smb_stack(&smb,SMB_STACK_POP);
425: return(0);
426: }
427: smb.curmsg=smb.msgs-1;
428: }
429: }
430: else {
431: if(mode&SCAN_TOYOU)
432: bprintf(text[NScanStatusFmt]
433: ,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname,smb.msgs,msgs);
434: if(!smb.msgs) {
435: if(!(mode&SCAN_TOYOU))
436: bprintf(text[NoMsgsOnSub]
437: ,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->sname);
438: smb_close(&smb);
439: smb_stack(&smb,SMB_STACK_POP);
440: return(0);
441: }
442: if(mode&SCAN_FIND) {
443: bprintf(text[SearchSubFmt]
444: ,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname,smb.msgs);
445: domsg=1;
446: smb.curmsg=0;
447: }
448: else if(mode&SCAN_TOYOU)
449: smb.curmsg=0;
450: else {
451: for(smb.curmsg=0;smb.curmsg<smb.msgs;smb.curmsg++)
452: if(post[smb.curmsg].number>=subscan[subnum].last)
453: break;
454: if(smb.curmsg==smb.msgs)
455: smb.curmsg=smb.msgs-1;
456:
457: domsg=1;
458: }
459: }
460:
461: if(useron.misc&RIP)
462: menu("msgscan");
463:
464: if((i=smb_locksmbhdr(&smb))!=0) {
465: smb_close(&smb);
1.1.1.2 ! root 466: errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);
1.1 root 467: smb_stack(&smb,SMB_STACK_POP);
468: return(0);
469: }
470: if((i=smb_getstatus(&smb))!=0) {
471: smb_close(&smb);
1.1.1.2 ! root 472: errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error);
1.1 root 473: smb_stack(&smb,SMB_STACK_POP);
474: return(0);
475: }
476: smb_unlocksmbhdr(&smb);
477: last=smb.status.last_msg;
478:
479: action=NODE_RMSG;
480: if(mode&SCAN_CONST) { /* update action */
481: getnodedat(cfg.node_num,&thisnode,1);
482: thisnode.action=NODE_RMSG;
483: putnodedat(cfg.node_num,&thisnode);
484: }
485: while(online && !done) {
486:
487: action=NODE_RMSG;
488:
489: if(mode&(SCAN_CONST|SCAN_FIND) && sys_status&SS_ABORT)
490: break;
491:
492: if(post==NULL) /* Been unloaded */
493: post=loadposts(&smb.msgs,subnum,0,lp); /* So re-load */
494:
495: if(!smb.msgs) {
496: done=1;
497: continue;
498: }
499:
500: while(smb.curmsg>=smb.msgs) smb.curmsg--;
501:
502: for(ugrp=0;ugrp<usrgrps;ugrp++)
503: if(usrgrp[ugrp]==cfg.sub[subnum]->grp)
504: break;
505: for(usub=0;usub<usrsubs[ugrp];usub++)
506: if(usrsub[ugrp][usub]==subnum)
507: break;
508: usub++;
509: ugrp++;
510:
511: msg.idx.offset=post[smb.curmsg].offset;
512: msg.idx.number=post[smb.curmsg].number;
513: msg.idx.to=post[smb.curmsg].to;
514: msg.idx.from=post[smb.curmsg].from;
515: msg.idx.subj=post[smb.curmsg].subj;
516:
517: if((i=smb_locksmbhdr(&smb))!=0) {
1.1.1.2 ! root 518: errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);
1.1 root 519: break;
520: }
521: if((i=smb_getstatus(&smb))!=0) {
522: smb_unlocksmbhdr(&smb);
1.1.1.2 ! root 523: errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error);
1.1 root 524: break;
525: }
526: smb_unlocksmbhdr(&smb);
527:
528: if(smb.status.last_msg!=last) { /* New messages */
529: last=smb.status.last_msg;
530: if(post) {
531: free((void *)post);
532: }
533: post=loadposts(&smb.msgs,subnum,0,lp); /* So re-load */
534: if(!smb.msgs)
535: break;
536: for(smb.curmsg=0;smb.curmsg<smb.msgs;smb.curmsg++)
537: if(post[smb.curmsg].number==msg.idx.number)
538: break;
539: if(smb.curmsg>(smb.msgs-1))
540: smb.curmsg=(smb.msgs-1);
541: continue;
542: }
543:
544: if(msg.total_hfields)
545: smb_freemsgmem(&msg);
546: msg.total_hfields=0;
547:
548: if(!loadmsg(&msg,post[smb.curmsg].number)) {
549: if(mismatches>5) { /* We can't do this too many times in a row */
550: errormsg(WHERE,ERR_CHK,smb.file,post[smb.curmsg].number);
551: break;
552: }
553: if(post)
554: free(post);
555: post=loadposts(&smb.msgs,subnum,0,lp);
556: if(!smb.msgs)
557: break;
558: if(smb.curmsg>(smb.msgs-1))
559: smb.curmsg=(smb.msgs-1);
560: mismatches++;
561: continue;
562: }
563: smb_unlockmsghdr(&smb,&msg);
564:
565: mismatches=0;
566:
567: if(domsg && !(sys_status&SS_ABORT)) {
568:
569: if(do_find && mode&SCAN_FIND) { /* Find text in messages */
570: buf=smb_getmsgtxt(&smb,&msg,GETMSGTXT_ALL);
571: if(!buf) {
572: if(smb.curmsg<smb.msgs-1)
573: smb.curmsg++;
574: else if(org_mode&SCAN_FIND)
575: done=1;
576: else if(smb.curmsg>=smb.msgs-1)
577: domsg=0;
578: continue;
579: }
1.1.1.2 ! root 580: strupr(buf);
! 581: strip_ctrl(buf, buf);
! 582: SAFECOPY(subj,msg.subj);
! 583: strupr(subj);
! 584: if(!strstr(buf,find) && !strstr(subj,find)) {
1.1 root 585: free(buf);
586: if(smb.curmsg<smb.msgs-1)
587: smb.curmsg++;
588: else if(org_mode&SCAN_FIND)
589: done=1;
590: else if(smb.curmsg>=smb.msgs-1)
591: domsg=0;
592: continue;
593: }
594: free(buf);
595: }
596:
597: if(mode&SCAN_CONST)
598: bprintf(text[ZScanPostHdr],ugrp,usub,smb.curmsg+1,smb.msgs);
599:
600: if(!reads && mode)
601: CRLF;
602:
603: show_msg(&msg
604: ,msg.from_ext && !strcmp(msg.from_ext,"1") && !msg.from_net.type
605: ? 0:P_NOATCODES);
606:
607: reads++; /* number of messages actually read during this sub-scan */
608:
609: /* Message is to this user and hasn't been read, so flag as read */
610: if((!stricmp(msg.to,useron.name) || !stricmp(msg.to,useron.alias)
611: || (useron.number==1 && !stricmp(msg.to,"sysop")
612: && !msg.from_net.type))
613: && !(msg.hdr.attr&MSG_READ)) {
614: if(msg.total_hfields)
615: smb_freemsgmem(&msg);
616: msg.total_hfields=0;
617: msg.idx.offset=0;
618: if(!smb_locksmbhdr(&smb)) { /* Lock the entire base */
619: if(loadmsg(&msg,msg.idx.number)) {
620: msg.hdr.attr|=MSG_READ;
621: msg.idx.attr=msg.hdr.attr;
622: if((i=smb_putmsg(&smb,&msg))!=0)
1.1.1.2 ! root 623: errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);
1.1 root 624: smb_unlockmsghdr(&smb,&msg);
625: }
626: smb_unlocksmbhdr(&smb);
627: }
628: if(!msg.total_hfields) { /* unsuccessful reload */
629: domsg=0;
630: continue;
631: }
632: }
633:
634: subscan[subnum].last=post[smb.curmsg].number;
635:
636: if(subscan[subnum].ptr<post[smb.curmsg].number && !(mode&SCAN_TOYOU)) {
637: posts_read++;
638: subscan[subnum].ptr=post[smb.curmsg].number;
639: }
1.1.1.2 ! root 640:
! 641: if(sub_op(subnum) && (msg.hdr.attr&(MSG_MODERATED|MSG_VALIDATED)) == MSG_MODERATED) {
! 642: uint16_t msg_attr = msg.hdr.attr;
! 643: SAFEPRINTF2(str,text[ValidatePostQ],msg.hdr.number,msg.subj);
! 644: if(!noyes(str))
! 645: msg.hdr.attr|=MSG_VALIDATED;
! 646: else {
! 647: SAFEPRINTF2(str,text[DeletePostQ],msg.hdr.number,msg.subj);
! 648: if(yesno(str))
! 649: msg.hdr.attr|=MSG_DELETE;
! 650: }
! 651: if(msg_attr!=msg.hdr.attr) {
! 652: if(msg.total_hfields)
! 653: smb_freemsgmem(&msg);
! 654: msg.total_hfields=0;
! 655: msg.idx.offset=0;
! 656: if(!smb_locksmbhdr(&smb)) { /* Lock the entire base */
! 657: if(loadmsg(&msg,msg.idx.number)) {
! 658: msg.hdr.attr=msg.idx.attr=msg_attr;
! 659: if((i=smb_putmsg(&smb,&msg))!=0)
! 660: errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);
! 661: smb_unlockmsghdr(&smb,&msg);
! 662: }
! 663: smb_unlocksmbhdr(&smb);
! 664: }
! 665: if(!msg.total_hfields) { /* unsuccessful reload */
! 666: domsg=0;
! 667: continue;
! 668: }
! 669: }
! 670:
! 671: }
1.1 root 672: }
673: else domsg=1;
674: if(mode&SCAN_CONST) {
675: if(smb.curmsg<smb.msgs-1) smb.curmsg++;
676: else done=1;
677: continue;
678: }
679: if(useron.misc&WIP)
680: menu("msgscan");
681: ASYNC;
682: bprintf(text[ReadingSub],ugrp,cfg.grp[cfg.sub[subnum]->grp]->sname
683: ,usub,cfg.sub[subnum]->sname,smb.curmsg+1,smb.msgs);
684: sprintf(str,"ABCDEFILMPQRTY?<>[]{}-+.,");
685: if(sub_op(subnum))
686: strcat(str,"O");
687: do_find=true;
688: l=getkeys(str,smb.msgs);
689: if(l&0x80000000L) {
690: if((long)l==-1) { /* ctrl-c */
1.1.1.2 ! root 691: quit=1;
! 692: break;
1.1 root 693: }
694: smb.curmsg=(l&~0x80000000L)-1;
695: do_find=false;
696: continue;
697: }
698: switch(l) {
699: case 'A':
700: case 'R':
701: if((char)l==(cfg.sys_misc&SM_RA_EMU ? 'A' : 'R')) {
702: do_find=false; /* re-read last message */
703: break;
704: }
705: /* Reply to last message */
706: domsg=0;
1.1.1.2 ! root 707: if(!chk_ar(cfg.sub[subnum]->post_ar,&useron,&client)) {
1.1 root 708: bputs(text[CantPostOnSub]);
709: break;
710: }
1.1.1.2 ! root 711: if(msg.hdr.attr&MSG_NOREPLY && !sub_op(subnum)) {
! 712: bputs(text[CantReplyToMsg]);
! 713: break;
! 714: }
! 715: quotemsg(&msg,/* include tails: */FALSE);
1.1 root 716: FREE_AND_NULL(post);
717: postmsg(subnum,&msg,WM_QUOTE);
718: if(mode&SCAN_TOYOU)
719: domsg=1;
720: break;
721: case 'B': /* Skip sub-board */
1.1.1.2 ! root 722: if(mode&SCAN_NEW && text[RemoveFromNewScanQ][0] && !noyes(text[RemoveFromNewScanQ]))
1.1 root 723: subscan[subnum].cfg&=~SUB_CFG_NSCAN;
724: if(msg.total_hfields)
725: smb_freemsgmem(&msg);
726: if(post)
727: free(post);
728: smb_close(&smb);
729: smb_stack(&smb,SMB_STACK_POP);
730: return(0);
731: case 'C': /* Continuous */
732: mode|=SCAN_CONST;
733: if(smb.curmsg<smb.msgs-1) smb.curmsg++;
734: else done=1;
735: break;
736: case 'D': /* Delete message on sub-board */
737: domsg=0;
738: if(!sub_op(subnum)) {
739: if(!(cfg.sub[subnum]->misc&SUB_DEL)) {
740: bputs(text[CantDeletePosts]);
741: domsg=0;
742: break;
743: }
744: if(cfg.sub[subnum]->misc&SUB_DELLAST && smb.curmsg!=(smb.msgs-1)) {
1.1.1.2 ! root 745: bputs(text[CantDeleteMsg]);
1.1 root 746: domsg=0;
747: break;
748: }
749: if(stricmp(cfg.sub[subnum]->misc&SUB_NAME
750: ? useron.name : useron.alias, msg.from)
751: && stricmp(cfg.sub[subnum]->misc&SUB_NAME
752: ? useron.name : useron.alias, msg.to)) {
753: bprintf(text[YouDidntPostMsgN],smb.curmsg+1);
754: break;
755: }
756: }
757: if(msg.hdr.attr&MSG_PERMANENT) {
1.1.1.2 ! root 758: bputs(text[CantDeleteMsg]);
1.1 root 759: domsg=0;
760: break;
761: }
762:
763: FREE_AND_NULL(post);
764:
765: if(msg.total_hfields)
766: smb_freemsgmem(&msg);
767: msg.total_hfields=0;
768: msg.idx.offset=0;
769: if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */
770: if(loadmsg(&msg,msg.idx.number)) {
771: msg.idx.attr^=MSG_DELETE;
772: msg.hdr.attr=msg.idx.attr;
773: if((i=smb_putmsg(&smb,&msg))!=0)
1.1.1.2 ! root 774: errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);
1.1 root 775: smb_unlockmsghdr(&smb,&msg);
776: if(i==0 && msg.idx.attr&MSG_DELETE) {
777: sprintf(str,"%s removed post from %s %s"
778: ,useron.alias
779: ,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname);
780: logline("P-",str);
781: if(!stricmp(cfg.sub[subnum]->misc&SUB_NAME
782: ? useron.name : useron.alias, msg.from))
783: useron.posts=(ushort)adjustuserrec(&cfg,useron.number
784: ,U_POSTS,5,-1);
785: }
786: }
787: smb_unlocksmbhdr(&smb);
788: }
789: domsg=1;
790: if((cfg.sys_misc&SM_SYSVDELM // anyone can view delete msgs
791: || (cfg.sys_misc&SM_USRVDELM // sys/subops can view deleted msgs
792: && sub_op(subnum)))
793: && smb.curmsg<smb.msgs-1)
794: smb.curmsg++;
795: if(smb.curmsg>=smb.msgs)
796: done=1;
797: break;
798: case 'E': /* edit last post */
799: if(!sub_op(subnum)) {
800: if(!(cfg.sub[subnum]->misc&SUB_EDIT)) {
1.1.1.2 ! root 801: bputs(text[CantEditMsg]);
1.1 root 802: domsg=0;
803: break;
804: }
805: if(cfg.sub[subnum]->misc&SUB_EDITLAST && smb.curmsg!=(smb.msgs-1)) {
1.1.1.2 ! root 806: bputs(text[CantEditMsg]);
1.1 root 807: domsg=0;
808: break;
809: }
810: if(stricmp(cfg.sub[subnum]->misc&SUB_NAME
811: ? useron.name : useron.alias, msg.from)) {
812: bprintf(text[YouDidntPostMsgN],smb.curmsg+1);
813: domsg=0;
814: break;
815: }
816: }
817: FREE_AND_NULL(post);
818: editmsg(&msg,subnum);
819: break;
820: case 'F': /* find text in messages */
821: domsg=0;
822: mode&=~SCAN_FIND; /* turn off find mode */
823: if((i=get_start_msg(this,&smb))<0)
824: break;
825: bputs(text[SearchStringPrompt]);
1.1.1.2 ! root 826: if(!getstr(find_buf,40,K_LINE|K_UPPER|K_EDIT|K_AUTODEL))
1.1 root 827: break;
1.1.1.2 ! root 828: if(text[DisplaySubjectsOnlyQ][0] && yesno(text[DisplaySubjectsOnlyQ]))
1.1 root 829: searchposts(subnum,post,(long)i,smb.msgs,find_buf);
830: else {
831: smb.curmsg=i;
832: find=find_buf;
833: mode|=SCAN_FIND;
834: domsg=1;
835: }
836: break;
837: case 'I': /* Sub-board information */
838: domsg=0;
839: subinfo(subnum);
840: break;
841: case 'L': /* List messages */
842: domsg=0;
843: if((i=get_start_msg(this,&smb))<0)
844: break;
845: listmsgs(subnum,0,post,i,smb.msgs);
846: sys_status&=~SS_ABORT;
847: break;
848: case 'M': /* Reply to last post in mail */
849: domsg=0;
1.1.1.2 ! root 850: if(msg.hdr.attr&(MSG_NOREPLY|MSG_ANONYMOUS) && !sub_op(subnum)) {
! 851: bputs(text[CantReplyToMsg]);
1.1 root 852: break;
853: }
854: if(!sub_op(subnum) && msg.hdr.attr&MSG_PRIVATE
855: && stricmp(msg.to,useron.name)
856: && stricmp(msg.to,useron.alias))
857: break;
858: sprintf(str2,text[Regarding]
859: ,msg.subj
1.1.1.2 ! root 860: ,timestr(msg.hdr.when_written.time));
1.1 root 861: if(msg.from_net.addr==NULL)
1.1.1.2 ! root 862: SAFECOPY(str,msg.from);
1.1 root 863: else if(msg.from_net.type==NET_FIDO)
1.1.1.2 ! root 864: SAFEPRINTF2(str,"%s@%s",msg.from
1.1 root 865: ,smb_faddrtoa((faddr_t *)msg.from_net.addr,tmp));
1.1.1.2 ! root 866: else if(msg.from_net.type==NET_INTERNET || strchr((char*)msg.from_net.addr,'@')!=NULL) {
! 867: if(msg.replyto_net.type==NET_INTERNET)
! 868: SAFECOPY(str,(char *)msg.replyto_net.addr);
! 869: else
! 870: SAFECOPY(str,(char *)msg.from_net.addr);
! 871: }
1.1 root 872: else
1.1.1.2 ! root 873: SAFEPRINTF2(str,"%s@%s",msg.from,(char *)msg.from_net.addr);
1.1 root 874: bputs(text[Email]);
875: if(!getstr(str,60,K_EDIT|K_AUTODEL))
876: break;
877:
878: FREE_AND_NULL(post);
1.1.1.2 ! root 879: quotemsg(&msg,/* include tails: */TRUE);
! 880: if(smb_netaddr_type(str)==NET_INTERNET)
1.1 root 881: inetmail(str,msg.subj,WM_QUOTE|WM_NETMAIL);
882: else {
883: p=strrchr(str,'@');
884: if(p) /* FidoNet or QWKnet */
885: netmail(str,msg.subj,WM_QUOTE);
886: else {
887: i=atoi(str);
888: if(!i) {
889: if(cfg.sub[subnum]->misc&SUB_NAME)
1.1.1.2 ! root 890: i=userdatdupe(0,U_NAME,LEN_NAME,str);
1.1 root 891: else
892: i=matchuser(&cfg,str,TRUE /* sysop_alias */);
893: }
894: email(i,str2,msg.subj,WM_EMAIL|WM_QUOTE);
895: }
896: }
897: break;
898: case 'P': /* Post message on sub-board */
899: domsg=0;
1.1.1.2 ! root 900: if(!chk_ar(cfg.sub[subnum]->post_ar,&useron,&client))
1.1 root 901: bputs(text[CantPostOnSub]);
902: else {
903: FREE_AND_NULL(post);
904: postmsg(subnum,0,0);
905: }
906: break;
907: case 'Q': /* Quit */
1.1.1.2 ! root 908: quit=1;
! 909: done=1;
! 910: break;
1.1 root 911: case 'T': /* List titles of next ten messages */
912: domsg=0;
913: if(!smb.msgs)
914: break;
915: if(smb.curmsg>=smb.msgs-1) {
916: done=1;
917: break;
918: }
919: i=smb.curmsg+11;
920: if(i>smb.msgs)
921: i=smb.msgs;
922: listmsgs(subnum,0,post,smb.curmsg+1,i);
923: smb.curmsg=i-1;
924: if(subscan[subnum].ptr<post[smb.curmsg].number)
925: subscan[subnum].ptr=post[smb.curmsg].number;
926: break;
927: case 'Y': /* Your messages */
928: domsg=0;
929: showposts_toyou(post,0,smb.msgs);
930: break;
931: case '-':
932: if(smb.curmsg>0) smb.curmsg--;
933: do_find=false;
934: break;
935: case 'O': /* Operator commands */
936: while(online) {
937: if(!(useron.misc&EXPERT))
938: menu("sysmscan");
1.1.1.2 ! root 939: bputs(text[OperatorPrompt]);
1.1 root 940: strcpy(str,"?CEHMPQUV");
941: if(SYSOP)
942: strcat(str,"S");
943: switch(getkeys(str,0)) {
944: case '?':
945: if(useron.misc&EXPERT)
946: menu("sysmscan");
947: continue;
948: case 'P': /* Purge user */
1.1.1.2 ! root 949: if(noyes(text[AreYouSureQ]))
! 950: break;
1.1 root 951: purgeuser(cfg.sub[subnum]->misc&SUB_NAME
1.1.1.2 ! root 952: ? userdatdupe(0,U_NAME,LEN_NAME,msg.from)
1.1 root 953: : matchuser(&cfg,msg.from,FALSE));
954: break;
955: case 'C': /* Change message attributes */
956: i=chmsgattr(msg.hdr.attr);
957: if(msg.hdr.attr==i)
958: break;
959: if(msg.total_hfields)
960: smb_freemsgmem(&msg);
961: msg.total_hfields=0;
962: msg.idx.offset=0;
963: if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */
964: if(loadmsg(&msg,msg.idx.number)) {
965: msg.hdr.attr=msg.idx.attr=i;
966: if((i=smb_putmsg(&smb,&msg))!=0)
1.1.1.2 ! root 967: errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);
1.1 root 968: smb_unlockmsghdr(&smb,&msg);
969: }
970: smb_unlocksmbhdr(&smb);
971: }
972: break;
973: case 'E': /* edit last post */
974: FREE_AND_NULL(post);
975: editmsg(&msg,subnum);
976: break;
977: case 'H': /* View message header */
978: msghdr(&msg);
979: domsg=0;
980: break;
981: case 'M': /* Move message */
982: domsg=0;
983: FREE_AND_NULL(post);
984: if(msg.total_hfields)
985: smb_freemsgmem(&msg);
986: msg.total_hfields=0;
987: msg.idx.offset=0;
988: if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */
989: if(!loadmsg(&msg,msg.idx.number)) {
990: errormsg(WHERE,ERR_READ,smb.file,msg.idx.number);
991: break;
992: }
993: sprintf(str,text[DeletePostQ],msg.hdr.number,msg.subj);
994: if(movemsg(&msg,subnum) && yesno(str)) {
995: msg.idx.attr|=MSG_DELETE;
996: msg.hdr.attr=msg.idx.attr;
997: if((i=smb_putmsg(&smb,&msg))!=0)
1.1.1.2 ! root 998: errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);
1.1 root 999: }
1000: smb_unlockmsghdr(&smb,&msg);
1001: }
1002: smb_unlocksmbhdr(&smb);
1003: break;
1004:
1005: case 'Q':
1006: break;
1007: case 'S': /* Save/Append message to another file */
1008: /* 05/26/95
1009: if(!yesno(text[SaveMsgToFile]))
1010: break;
1011: */
1012: bputs(text[FileToWriteTo]);
1013: if(getstr(str,40,K_LINE))
1014: msgtotxt(&msg,str,1,1);
1015: break;
1016: case 'U': /* User edit */
1017: useredit(cfg.sub[subnum]->misc&SUB_NAME
1.1.1.2 ! root 1018: ? userdatdupe(0,U_NAME,LEN_NAME,msg.from)
1.1 root 1019: : matchuser(&cfg,msg.from,TRUE /* sysop_alias */));
1020: break;
1021: case 'V': /* Validate message */
1022: if(msg.total_hfields)
1023: smb_freemsgmem(&msg);
1024: msg.total_hfields=0;
1025: msg.idx.offset=0;
1026: if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */
1027: if(loadmsg(&msg,msg.idx.number)) {
1028: msg.idx.attr|=MSG_VALIDATED;
1029: msg.hdr.attr=msg.idx.attr;
1030: if((i=smb_putmsg(&smb,&msg))!=0)
1.1.1.2 ! root 1031: errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);
1.1 root 1032: smb_unlockmsghdr(&smb,&msg);
1033: }
1034: smb_unlocksmbhdr(&smb);
1035: }
1036: break;
1037: default:
1038: continue;
1039: }
1040: break;
1041: }
1042: break;
1043: case '.': /* Thread forward */
1044: l=msg.hdr.thread_first;
1045: if(!l) l=msg.hdr.thread_next;
1046: if(!l) {
1047: domsg=0;
1048: break;
1049: }
1050: for(i=0;i<smb.msgs;i++)
1051: if(l==post[i].number)
1052: break;
1053: if(i<smb.msgs)
1054: smb.curmsg=i;
1055: do_find=false;
1056: break;
1057: case ',': /* Thread backwards */
1058: if(!msg.hdr.thread_back) {
1059: domsg=0;
1060: break;
1061: }
1062: for(i=0;i<smb.msgs;i++)
1063: if(msg.hdr.thread_back==post[i].number)
1064: break;
1065: if(i<smb.msgs)
1066: smb.curmsg=i;
1067: do_find=false;
1068: break;
1069: case '>': /* Search Title forward */
1070: for(i=smb.curmsg+1;i<smb.msgs;i++)
1071: if(post[i].subj==msg.idx.subj)
1072: break;
1073: if(i<smb.msgs)
1074: smb.curmsg=i;
1075: else
1076: domsg=0;
1077: do_find=false;
1078: break;
1079: case '<': /* Search Title backward */
1080: for(i=smb.curmsg-1;i>-1;i--)
1081: if(post[i].subj==msg.idx.subj)
1082: break;
1083: if(i>-1)
1084: smb.curmsg=i;
1085: else
1086: domsg=0;
1087: do_find=false;
1088: break;
1089: case '}': /* Search Author forward */
1090: strcpy(str,msg.from);
1091: for(i=smb.curmsg+1;i<smb.msgs;i++)
1092: if(post[i].from==msg.idx.from)
1093: break;
1094: if(i<smb.msgs)
1095: smb.curmsg=i;
1096: else
1097: domsg=0;
1098: do_find=false;
1099: break;
1100: case '{': /* Search Author backward */
1101: strcpy(str,msg.from);
1102: for(i=smb.curmsg-1;i>-1;i--)
1103: if(post[i].from==msg.idx.from)
1104: break;
1105: if(i>-1)
1106: smb.curmsg=i;
1107: else
1108: domsg=0;
1109: do_find=false;
1110: break;
1111: case ']': /* Search To User forward */
1112: strcpy(str,msg.to);
1113: for(i=smb.curmsg+1;i<smb.msgs;i++)
1114: if(post[i].to==msg.idx.to)
1115: break;
1116: if(i<smb.msgs)
1117: smb.curmsg=i;
1118: else
1119: domsg=0;
1120: do_find=false;
1121: break;
1122: case '[': /* Search To User backward */
1123: strcpy(str,msg.to);
1124: for(i=smb.curmsg-1;i>-1;i--)
1125: if(post[i].to==msg.idx.to)
1126: break;
1127: if(i>-1)
1128: smb.curmsg=i;
1129: else
1130: domsg=0;
1131: do_find=false;
1132: break;
1133: case 0: /* Carriage return - Next Message */
1134: case '+':
1135: if(smb.curmsg<smb.msgs-1) smb.curmsg++;
1136: else done=1;
1137: break;
1138: case '?':
1139: menu("msgscan");
1140: domsg=0;
1.1.1.2 ! root 1141: break;
! 1142: }
! 1143: }
1.1 root 1144: if(msg.total_hfields)
1145: smb_freemsgmem(&msg);
1146: if(post)
1147: free(post);
1.1.1.2 ! root 1148: if(!quit
! 1149: && !(org_mode&(SCAN_CONST|SCAN_TOYOU|SCAN_FIND)) && !(cfg.sub[subnum]->misc&SUB_PONLY)
! 1150: && reads && chk_ar(cfg.sub[subnum]->post_ar,&useron,&client) && text[Post][0]
1.1 root 1151: && !(useron.rest&FLAG('P'))) {
1152: sprintf(str,text[Post],cfg.grp[cfg.sub[subnum]->grp]->sname
1153: ,cfg.sub[subnum]->lname);
1154: if(!noyes(str))
1155: postmsg(subnum,0,0);
1156: }
1.1.1.2 ! root 1157: if(!(org_mode&(SCAN_CONST|SCAN_TOYOU|SCAN_FIND))
! 1158: && !(subscan[subnum].cfg&SUB_CFG_NSCAN) && text[AddSubToNewScanQ][0] && yesno(text[AddSubToNewScanQ]))
! 1159: subscan[subnum].cfg|=SUB_CFG_NSCAN;
1.1 root 1160: smb_close(&smb);
1161: smb_stack(&smb,SMB_STACK_POP);
1.1.1.2 ! root 1162: return(quit);
1.1 root 1163: }
1164:
1165: /****************************************************************************/
1166: /* This function lists all messages in sub-board */
1167: /* Returns number of messages found/displayed. */
1168: /****************************************************************************/
1.1.1.2 ! root 1169: long sbbs_t::listsub(uint subnum, long mode, long start, const char* search)
1.1 root 1170: {
1171: int i;
1.1.1.2 ! root 1172: int32_t posts;
1.1 root 1173: long displayed;
1174: post_t *post;
1175:
1176: if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) {
1177: errormsg(WHERE,ERR_OPEN,cfg.sub[subnum]->code,i);
1178: return(0);
1179: }
1180: SAFEPRINTF2(smb.file,"%s%s",cfg.sub[subnum]->data_dir,cfg.sub[subnum]->code);
1181: smb.retry_time=cfg.smb_retry_time;
1182: smb.subnum=subnum;
1183: if((i=smb_open(&smb))!=0) {
1184: errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
1185: smb_stack(&smb,SMB_STACK_POP);
1186: return(0);
1187: }
1188: post=loadposts(&posts,subnum,0,LP_BYSELF|LP_OTHERS);
1189: bprintf(text[SearchSubFmt]
1190: ,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname,posts /* total? */);
1191: if(mode&SCAN_FIND)
1192: displayed=searchposts(subnum, post, start, posts, search);
1193: else if(mode&SCAN_TOYOU)
1194: displayed=showposts_toyou(post, start, posts);
1195: else
1196: displayed=listmsgs(subnum, mode, post, start, posts);
1197: if(posts)
1198: free(post);
1199: smb_close(&smb);
1200: smb_stack(&smb,SMB_STACK_POP);
1201:
1202: return(displayed);
1203: }
1204:
1205: /****************************************************************************/
1206: /* Will search the messages pointed to by 'msg' for the occurance of the */
1207: /* string 'search' and display any messages (number of message, author and */
1208: /* title). 'msgs' is the total number of valid messages. */
1209: /* Returns number of messages found. */
1210: /****************************************************************************/
1211: long sbbs_t::searchposts(uint subnum, post_t *post, long start, long posts
1.1.1.2 ! root 1212: , const char *search)
1.1 root 1213: {
1.1.1.2 ! root 1214: char* buf,ch;
! 1215: char subj[128];
1.1 root 1216: long l,found=0;
1217: smbmsg_t msg;
1218:
1219: msg.total_hfields=0;
1220: for(l=start;l<posts && !msgabort();l++) {
1221: msg.idx.offset=post[l].offset;
1222: if(!loadmsg(&msg,post[l].number))
1223: continue;
1224: smb_unlockmsghdr(&smb,&msg);
1225: buf=smb_getmsgtxt(&smb,&msg,GETMSGTXT_ALL);
1226: if(!buf) {
1227: smb_freemsgmem(&msg);
1228: continue;
1229: }
1.1.1.2 ! root 1230: strupr(buf);
! 1231: strip_ctrl(buf, buf);
! 1232: SAFECOPY(subj,msg.subj);
! 1233: strupr(subj);
! 1234: if(strstr(buf,search) || strstr(subj,search)) {
1.1 root 1235: if(!found)
1236: CRLF;
1237: if(msg.hdr.attr&MSG_DELETE)
1238: ch='-';
1239: else if((!stricmp(msg.to,useron.alias) || !stricmp(msg.to,useron.name))
1240: && !(msg.hdr.attr&MSG_READ))
1241: ch='!';
1242: else if(msg.hdr.number>subscan[subnum].ptr)
1243: ch='*';
1244: else
1245: ch=' ';
1246: bprintf(text[SubMsgLstFmt],l+1
1247: ,(msg.hdr.attr&MSG_ANONYMOUS) && !sub_op(subnum) ? text[Anonymous]
1248: : msg.from
1249: ,msg.to
1250: ,ch
1251: ,msg.subj);
1252: found++;
1253: }
1254: free(buf);
1255: smb_freemsgmem(&msg);
1256: }
1257:
1258: return(found);
1259: }
1260:
1261: /****************************************************************************/
1262: /* Will search the messages pointed to by 'msg' for message to the user on */
1263: /* Returns number of messages found. */
1264: /****************************************************************************/
1265: long sbbs_t::showposts_toyou(post_t *post, ulong start, long posts)
1266: {
1267: char str[128];
1268: ushort namecrc,aliascrc,sysop;
1269: long l,found;
1270: smbmsg_t msg;
1271:
1272: strcpy(str,useron.alias);
1273: strlwr(str);
1274: aliascrc=crc16(str,0);
1275: strcpy(str,useron.name);
1276: strlwr(str);
1277: namecrc=crc16(str,0);
1278: sysop=crc16("sysop",0);
1279: msg.total_hfields=0;
1280: for(l=start,found=0;l<posts && !msgabort();l++) {
1281:
1282: if((useron.number!=1 || post[l].to!=sysop)
1283: && post[l].to!=aliascrc && post[l].to!=namecrc)
1284: continue;
1285:
1286: if(msg.total_hfields)
1287: smb_freemsgmem(&msg);
1288: msg.total_hfields=0;
1289: msg.idx.offset=post[l].offset;
1290: if(!loadmsg(&msg,post[l].number))
1291: continue;
1292: smb_unlockmsghdr(&smb,&msg);
1293: if((useron.number==1 && !stricmp(msg.to,"sysop") && !msg.from_net.type)
1294: || !stricmp(msg.to,useron.alias) || !stricmp(msg.to,useron.name)) {
1295: if(!found)
1296: CRLF;
1297: found++;
1298: bprintf(text[SubMsgLstFmt],l+1
1299: ,(msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP
1300: ? text[Anonymous] : msg.from
1301: ,msg.to
1302: ,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_READ ? ' ' : '*'
1303: ,msg.subj);
1304: }
1305: }
1306:
1307: if(msg.total_hfields)
1308: smb_freemsgmem(&msg);
1309:
1310: return(found);
1311: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.