home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 September / PCO_0998.ISO / filesbbs / dos / sbbs_src.exe / SBBS / READMSGS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-25  |  28.9 KB  |  1,071 lines

  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.  
  1071.