home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / W / DEVBBS.ZIP / MSGBASE1.C < prev    next >
Text File  |  1992-07-20  |  40KB  |  1,604 lines

  1. /*****************************************************************************
  2.  
  3.                 WWIV Version 4
  4.                     Copyright (C) 1988-1991 by Wayne Bell
  5.  
  6. *****************************************************************************/
  7.  
  8. #include "vars.h"
  9. #pragma hdrstop
  10. #include <dir.h>
  11. #define ALLOW_FULLSCREEN 1
  12. #define EMAIL_STORAGE 2
  13.  
  14. int deleted_flag;
  15.  
  16. void send_net_post(postrec *p, unsigned int type, char *extra)
  17. {
  18.   net_header_rec nh;
  19.   char *b, *b1,*ss;
  20.   long len1, len2;
  21.   char s[81];
  22.   int f,i;
  23.   unsigned int ui;
  24.   unsigned int *list;
  25.   FILE *fi;
  26.  
  27.   b=readfile(&(p -> msg),extra,&len1);
  28.   if (b==NULL)
  29.     return;
  30.   nh.tosys=0;
  31.   nh.touser=0;
  32.   if (p -> ownersys)
  33.     nh.fromsys=p -> ownersys;
  34.   else
  35.     nh.fromsys =syscfg.systemnumber;
  36.   nh.fromuser=p -> owneruser;
  37.   nh.main_type=main_type_post;
  38.   nh.minor_type=type;
  39.   nh.list_len=0;
  40.   nh.daten=p -> daten;
  41.   nh.length=len1+1+strlen(p -> title);
  42.   if (nh.length > 32760) {
  43.     npr("Message truncated by %lu bytes for the network.\r\n",nh.length-32760L);
  44.     nh.length = 32760;
  45.   }
  46.   nh.method=0;
  47.   if ((b1=malloca(nh.length+100))==NULL) {
  48.     farfree(b);
  49.     return;
  50.   }
  51.   strcpy(b1,p -> title);
  52.   memmove(&(b1[strlen(p -> title)+1]),b,(unsigned int) len1);
  53.   farfree(b);
  54.   if ((list=malloca(2*(num_sys_list+2)))==NULL) {
  55.     farfree(b1);
  56.     return;
  57.   }
  58.   sprintf(s,"%sN%u.NET",syscfg.datadir,type);
  59.   f=open(s,O_RDONLY | O_BINARY);
  60.   if (f>0) {
  61.     len1=filelength(f);
  62.     if ((b=malloca(len1+100L))==NULL) {
  63.       farfree(list);
  64.       farfree(b1);
  65.       return;
  66.     }
  67.     lseek(f,0L,SEEK_SET);
  68.     read(f,(void *)b,len1);
  69.     b[len1]=0;
  70.     close(f);
  71.     len2=0;
  72.     while (len2<len1) {
  73.       while ((len2<len1) && ((b[len2]<'0') || (b[len2]>'9')))
  74.         ++len2;
  75.       if ((b[len2]>='0') && (b[len2]<='9') && (len2<len1)) {
  76.         i=atoi(&(b[len2]));
  77.         if ((i!=syscfg.systemnumber) && (i != p -> ownersys))
  78.           list[nh.list_len++]=i;
  79.         while ((len2<len1) && (b[len2]>='0') && (b[len2]<='9'))
  80.           ++len2;
  81.       }
  82.     }
  83.     farfree(b);
  84.   }
  85.   if (nh.list_len) {
  86.     strcpy(s,syscfg.datadir);
  87.     strcat(s,"P1.NET");
  88.     f=open(s,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  89.     lseek(f,0L,SEEK_END);
  90.     write(f,(void *)&nh,sizeof(net_header_rec));
  91.     write(f,(void *)list,2*nh.list_len);
  92.     write(f,(void *)b1,nh.length);
  93.     close(f);
  94.   }
  95.   sprintf(s,"%sNNALL.NET", syscfg.datadir);
  96.   fi=fopen(s,"r");
  97.   if (fi) {
  98.     while (fgets(s,80,fi)) {
  99.       ss=strtok(s," \r\n\t");
  100.       if (ss) {
  101.         ui=(unsigned long) atol(ss);
  102.         if (ui==type) {
  103.           ss=strtok(NULL," \r\n\t");
  104.           if (ss) {
  105.             ui=(unsigned long) atol(ss);
  106.             nh.list_len=0L;
  107.             nh.main_type = main_type_pre_post;
  108.             nh.tosys=ui;
  109.             nh.touser=0;
  110.             strcpy(s,syscfg.datadir);
  111.             strcat(s,"P1.NET");
  112.             f=open(s,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  113.             lseek(f,0L,SEEK_END);
  114.             write(f,(void *)&nh,sizeof(net_header_rec));
  115.             write(f,(void *)b1,nh.length);
  116.             close(f);
  117.             fclose(fi);
  118.             farfree(list);
  119.             farfree(b1);
  120.             return;
  121.           }
  122.         }
  123.       }
  124.     }
  125.     fclose(fi);
  126.   }
  127.   sprintf(s,"%sNN%u.NET",syscfg.datadir,subboards[curlsub].type);
  128.   f=open(s,O_RDONLY | O_BINARY);
  129.   nh.list_len=0;
  130.   nh.main_type=main_type_pre_post;
  131.   if (f>0) {
  132.     len1=filelength(f);
  133.     if ((b=malloca(len1+100L))==NULL) {
  134.       farfree(b1);
  135.       farfree(list);
  136.       return;
  137.     }
  138.     lseek(f,0L,SEEK_SET);
  139.     read(f,(void *)b,len1);
  140.     b[len1]=0;
  141.     close(f);
  142.     len2=0;
  143.     while (len2<len1) {
  144.       while ((len2<len1) && ((b[len2]<'0') || (b[len2]>'9')))
  145.         ++len2;
  146.       if ((b[len2]>='0') && (b[len2]<='9') && (len2<len1)) {
  147.         i=atoi(&(b[len2]));
  148.         if ((i!=syscfg.systemnumber) && (i != p -> ownersys))
  149.           list[nh.list_len++]=i;
  150.         while ((len2<len1) && (b[len2]>='0') && (b[len2]<='9'))
  151.           ++len2;
  152.       }
  153.     }
  154.     farfree(b);
  155.   }
  156.   if (nh.list_len) {
  157.     strcpy(s,syscfg.datadir);
  158.     strcat(s,"P1.NET");
  159.     f=open(s,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  160.     lseek(f,0L,SEEK_END);
  161.     write(f,(void *)&nh,sizeof(net_header_rec));
  162.     write(f,(void *)list,2*nh.list_len);
  163.     write(f,(void *)b1,nh.length);
  164.     close(f);
  165.   }
  166.   farfree(list);
  167.   farfree(b1);
  168. }
  169.  
  170. void post()
  171. {
  172.   messagerec m;
  173.   postrec p;
  174.   char s[121],*b,*b1;
  175.   int i,dm,a,f;
  176.   slrec ss;
  177.   long len1,len2;
  178.   unsigned int *list;
  179.  
  180.   iscan(cursub);
  181.   if (curlsub<0) {
  182.     nl();
  183.     pl("No subs available.");
  184.     nl();
  185.     return;
  186.   }
  187.   ss=syscfg.sl[actsl];
  188.   if (freek1(syscfg.msgsdir)<10.0) {
  189.     nl();
  190.     pl("Sorry, not enough disk space left.");
  191.     nl();
  192.     return;
  193.   }
  194.   if ((restrict_post & thisuser.restrict) || (thisuser.posttoday>=ss.posts)) {
  195.     nl();
  196.     pl("6Too many messages posted today.");
  197.     nl();
  198.     return;
  199.   }
  200.   if (actsl<subboards[curlsub].postsl) {
  201.     nl();
  202.     pl("6You can't post here.");
  203.     nl();
  204.     return;
  205.   }
  206.   m.storage_type=subboards[curlsub].storage_type;
  207.   a=subboards[curlsub].anony & 0x0f;
  208.   if ((a==0) && (ss.ability & ability_post_anony))
  209.     a=anony_enable_anony;
  210.   if ((a==anony_enable_anony) && (thisuser.restrict & restrict_anony))
  211.     a=0;
  212.   if (subboards[curlsub].type) {
  213.     a &= (anony_real_name);
  214.     if (thisuser.restrict & restrict_net) {
  215.       nl();
  216.       pl("6You can't post on networked sub-boards.");
  217.       nl();
  218.       return;
  219.     }
  220.     if (thisuser.restrict & (restrict_validate | restrict_auto_msg_delete)) {
  221.       nl();
  222.       pl("6You can't post on networked sub-boards.");
  223.       nl();
  224.       return;
  225.     }
  226.     if (syscfg.systemnumber) {
  227.       nl();
  228.       pl("1Careful! This message base is networked!");
  229.       nl();
  230.     }
  231.   }
  232.   inmsg(&m,p.title,&a,1,(subboards[curlsub].filename),ALLOW_FULLSCREEN);
  233.   if (m.stored_as!=0xffffffff) {
  234.     p.anony=a;
  235.     p.msg=m;
  236.     p.ownersys=0;
  237.     p.owneruser=usernum;
  238.     p.qscan=status.qscanptr++;
  239.     time((long *)(&p.daten));
  240.     if (thisuser.restrict & restrict_auto_msg_delete)
  241.       p.status=status_delete;
  242.     else
  243.       if (thisuser.restrict & restrict_validate)
  244.         p.status=status_unvalidated;
  245.       else
  246.         p.status=0;
  247.     if ((subboards[curlsub].type) && (syscfg.systemnumber) &&
  248.       (subboards[curlsub].anony & anony_val_net) && (!lcs())) {
  249.       p.status |= status_pending_net;
  250.       dm=1;
  251.       for (i=1; i<=nummsgs; i++)
  252.         if (msgs[i].status & status_pending_net)
  253.           dm=0;
  254.       if (dm) {
  255.         sprintf(s,"Unvalidated net posts on %s.",subboards[curlsub].name);
  256.         ssm(1,0,s);
  257.       }
  258.     }
  259.     if (nummsgs>=subboards[curlsub].maxmsgs) {
  260.       i=1;
  261.       dm=0;
  262.       while ((dm==0) && (i<=nummsgs)) {
  263.         if ((msgs[i].status & status_no_delete)==0)
  264.           dm=i;
  265.         ++i;
  266.       }
  267.       if (dm==0)
  268.         dm=1;
  269.       delete(dm);
  270.       deleted_flag=dm;
  271.     }
  272.     msgs[++nummsgs]=p;
  273.     sub_dates[curlsub]=p.qscan;
  274.     bchanged=1;
  275.     savebase();
  276.     ++thisuser.msgpost;
  277.     ++thisuser.posttoday;
  278.     ++status.msgposttoday;
  279.     save_status();
  280.     topscreen();
  281.     sprintf(s,"+%s posted on %s",p.title,subboards[curlsub].name);
  282.     sysoplog(s);
  283.     sprintf(s,"fPosted on 1%s",subboards[curlsub].name);
  284.     save_status();
  285.     pl(s);
  286.     npr("3Post5/3Call Ratio is now 5: 1%-5.3f\r\n",post_ratio(),syscfg.post_call_ratio);
  287.     thisuser.gold=thisuser.gold+1;
  288.     npr("fYou recieved one gold for this post, you now have 1%d fgold",(int) thisuser.gold);
  289.     nl();
  290.     if ((subboards[curlsub].type) && (syscfg.systemnumber)) {
  291.       ++thisuser.postnet;
  292.       if (((subboards[curlsub].anony & anony_val_net)==0) || (lcs()))
  293.         send_net_post(&p, subboards[curlsub].type, subboards[curlsub].filename);
  294.     }
  295.   }
  296. }
  297.  
  298. void extract_out(char *b, long len, char *title)
  299. {
  300.   char s1[81],s2[81],ch=26,ch1;
  301.   int i;
  302.  
  303.   do {
  304.     prt(2,"Save under what filename? ");
  305.     input(s1,12);
  306.     if (s1[0]) {
  307.       sprintf(s2,"%s%s",syscfg.gfilesdir,s1);
  308.       if (exist(s2)) {
  309.         nl();
  310.         pl("Filename already in use.");
  311.         nl();
  312.         prt(2,"O)verwrite, A)ppend, N)ew name, Q)uit? ");
  313.         ch1=onek("QOAN");
  314.         switch(ch1) {
  315.           case 'Q':
  316.             s2[0]=0;
  317.             s1[0]=0;
  318.             break;
  319.           case 'N':
  320.             s1[0]=0;
  321.             break;
  322.           case 'A':
  323.             break;
  324.           case 'O':
  325.             unlink(s2);
  326.             break;
  327.         }
  328.         nl();
  329.       }
  330.     } else
  331.       s2[0]=0;
  332.   } while ((!hangup) && (s2[0]!=0) && (s1[0]==0));
  333.   if ((s1[0]) && (!hangup)) {
  334.     i=open(s2,O_RDWR | O_BINARY | O_CREAT , S_IREAD | S_IWRITE);
  335.     if (filelength(i)) {
  336.       lseek(i, -1L, SEEK_END);
  337.       read(i, ((void *)&ch1), 1);
  338.       if (ch1 == 26)
  339.         lseek(i, -1L, SEEK_END);
  340.     }
  341.     write(i,title,strlen(title));
  342.     write(i,"\r\n",2);
  343.     write(i,(void *)b,len);
  344.     write(i,&ch,1);
  345.     close(i);
  346.     npr("Message written to: %s.\r\n",s2);
  347.   }
  348.   farfree(b);
  349. }
  350.  
  351. void grab_user_name(messagerec *m, char *fn)
  352. {
  353.   char *ss,*ss1;
  354.   long len;
  355.  
  356.   ss=readfile(m,fn,&len);
  357.   if (ss) {
  358.     ss1=strchr(ss,'\r');
  359.     if (ss1) {
  360.       *ss1=0;
  361.       strcpy(net_email_name,ss);
  362.     } else
  363.       net_email_name[0]=0;
  364.     farfree(ss);
  365.   } else
  366.     net_email_name[0]=0;
  367. }
  368.  
  369. void quote_message(messagerec *m1, char *aux)     /* mod - add entire void */
  370.  {
  371.    char *b,*c,s1[81];
  372.    int cc,dq,lc,f,ok,mc;
  373.    long l,l1,l2;
  374.    messagerec m;
  375.  
  376.    sprintf(s1,"%sINPUT.MSG",syscfg.tempdir);
  377.    if (exist(s1))
  378.      return;
  379.    nl();
  380.    prt(2,"Quote from message? ");
  381.    if (!yn())
  382.      return;
  383.    m=*m1;
  384.    b=readfile(&m,aux,&l);
  385.    if ((c=malloca(l+1000))==NULL) {
  386.      farfree(b);
  387.      return;
  388.    }
  389.    lc=0; l1=0; l2=0; ok=1;
  390.    do {
  391.      if (b[l1]==10)
  392.        lc++;
  393.      l1++;
  394.    } while (lc<2);
  395.    lc=0; dq=1; cc=48;
  396.    do {
  397.      if (lc==0) {
  398.        for (f=0; f<dq; f++) {
  399.      c[l2++]='>'; lc++;
  400.        }
  401.        if (dq==1) {
  402.      c[l2++]=' '; lc++;
  403.        }
  404.        if (cc!=48) {
  405.      c[l2++]=3;
  406.      c[l2++]=cc;
  407.        }
  408.      }
  409.      switch(b[l1]) {
  410.        case 3:
  411.      l1++;
  412.      cc=b[l1++];
  413.      c[l2++]=3;
  414.      c[l2++]=cc;
  415.      break;
  416.        case 1:
  417.      if (b[l1-1]!=64)/* changed 32 to 64 */
  418.        c[l2++]=' ';
  419.      l1+=3;
  420.      dq=1;
  421.      break;
  422.        case 13:
  423.      lc=0;
  424.      l1+=2;
  425.      dq=1;
  426.      while (b[l1]=='>') {
  427.        dq++; l1++;
  428.      }
  429.      if (dq>=6)
  430.        ok=0;
  431.      if (dq==1) {
  432.        cc=48;
  433.        c[l2++]=3;
  434.        c[l2++]=48;
  435.      }
  436.      c[l2++]=13;
  437.      c[l2++]=10;
  438.      break;
  439.        default:
  440.      c[l2++]=b[l1++];
  441.      lc++;
  442.      break;
  443.      }
  444.      if (dq==1)
  445.        mc=72;
  446.      else
  447.        mc=78;
  448.      if (lc>=mc) {
  449.        while ((b[l1]!=64) && (lc>0)) {  /* changed 32 to 64 */
  450.      --l1; --l2; --lc;
  451.      if (b[l1]==3) {
  452.        lc+=2;
  453.        l2++;
  454.      }
  455.      if (b[l1]==1) {
  456.        l2+=3;
  457.        lc+=3;
  458.      }
  459.        }
  460.        if (lc==0) {
  461.      l1+=mc;
  462.      l2+=mc;
  463.        } else {
  464.      lc=0;
  465.      l1++;
  466.        }
  467.        c[l2++]=13;
  468.        c[l2++]=10;
  469.      }
  470.    } while (l1<l);
  471.    c[l2++]=13;
  472.    c[l2++]=10;
  473.    if (ok) {
  474.      sprintf(s1,"%sQUOTE.MSG",syscfg.tempdir);
  475.      f=open(s1,O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
  476.      write(f,(void *)c,l2);
  477.      close(f);
  478.      farfree(b);
  479.      farfree(c);
  480.      load_workspace(s1,0);
  481.      unlink(s1);
  482.    }
  483.  }
  484.  
  485. void scan(int msgnum, int optype, int *nextsub)
  486. {
  487.   char s[81],s1[81],s2[81],*b,*ss1,*f;
  488.   int i,i1,i2,done,quit,abort,next,val,realexpress;
  489.   slrec ss;
  490.   long l,len;
  491.   postrec p,p1;
  492.  
  493.   irt[0]=0;
  494.   irt_name[0]=0;
  495.   done=0;
  496.   quit=0;
  497.   val=0;
  498.   realexpress=express;
  499.   iscan(cursub);
  500.   if (curlsub<0) {
  501.     nl();
  502.     pl("No subs available.");
  503.     nl();
  504.     return;
  505.   }
  506.   do {
  507.     tleft(1);
  508.     switch(optype) {
  509.       case 0: /* Read Prompt */
  510.     npr("7[1Sub7]3:5 %s",subboards[curlsub].name);
  511.     sprintf(s,"7[1Read7]f:7(11-%u,^%u7)f,1? f:",nummsgs,msgnum);
  512.     nl();
  513.     if (express) {
  514.           s[0]=0;
  515.           nl();
  516.           nl();
  517.         } else {
  518.           prt(2,s);
  519.           helpl=16;
  520.           input(s,3);
  521.       while (s[0]==32) {
  522.         strcpy(s1,&(s[1]));
  523.         strcpy(s,s1);
  524.       }
  525.         }
  526.         optype=0;
  527.         i=atoi(s);
  528.         if (s[0]==0) {
  529.           i=msgnum+1;
  530.           if (i>=nummsgs+1)
  531.             done=1;
  532.         }
  533.         if ((i!=0) && (i<=nummsgs) && (i>=1)) {
  534.           optype=2;
  535.           msgnum=i;
  536.         } else
  537.           if (s[1]==0) {
  538.             switch(s[0]) {
  539.               case 'Q':
  540.                 quit=1;
  541.                 done=1;
  542.                 *nextsub=0;
  543.         break;
  544.           case 'Z':
  545.            if (incom)
  546.          upload_post();
  547.          else {
  548.           nl();
  549.           prt(2,"Filename? ");
  550.           input(s1,50);
  551.           if (s1[0]) {
  552.             nl();
  553.             prt(5,"Allow editing? ");
  554.             if (yn()) {
  555.               nl();
  556.               load_workspace(s1,0);
  557.           } else {
  558.               nl();
  559.               load_workspace(s1,1);
  560.             }
  561.          }
  562.         }
  563.         break;
  564.           case 'B':
  565.         npr("3Would you like to take this sub out of your Q-scan? ");
  566.         if (yn()) {
  567.           f=usub[cursub].keys;
  568.           for (i=0; i<64; i++)
  569.           {
  570.             if (strcmp(usub[i].keys,f)==0)
  571.               if (usub[i].subnum<32)
  572.             thisuser.qscn ^=((1L) << (usub[i].subnum));
  573.               else
  574.             thisuser.qscn2 ^=((1L) << (usub[i].subnum-32));
  575.           }
  576.           pl("5Sub has been removed.");
  577.           pausescr();
  578.         }
  579.         if (*nextsub!=0)
  580.           {
  581.           *nextsub=1;
  582.           done=1;
  583.           quit=1;
  584.           }
  585.         break;
  586.           case 'T':
  587.         optype=1;
  588.                 break;
  589.               case 'R':
  590.                 optype=2;
  591.                 break;
  592.           case 'A':
  593.         quote_message(&(msgs[msgnum].msg),
  594.           (subboards[curlsub].filename));
  595.         if ((msgs[msgnum].ownersys) && (!msgs[msgnum].owneruser))
  596.           grab_user_name(&(msgs[msgnum].msg),subboards[curlsub].filename);
  597.         ss=syscfg.sl[actsl];
  598.         if ((lcs()) || (ss.ability & ability_read_post_anony) || (msgs[msgnum].anony==0))
  599.           email(msgs[msgnum].owneruser,msgs[msgnum].ownersys,0,0);
  600.         else
  601.           email(msgs[msgnum].owneruser,msgs[msgnum].ownersys,0,msgs[msgnum].anony);
  602.         break;
  603.           case 'P':
  604.         irt[0]=0;
  605.         irt_name[0]=0;
  606.           case 'W':
  607.         if (s[0]!='P')
  608.           quote_message(&(msgs[msgnum].msg),
  609.             (subboards[curlsub].filename));
  610.         deleted_flag=0;
  611.         post();
  612.         if (deleted_flag && (deleted_flag<=msgnum))
  613.           --msgnum;
  614.         break;
  615.           case '?':
  616.         if (lcs())
  617.           printmenu(13);
  618.         else
  619.                   printmenu(1);
  620.         break;
  621.           case '-':
  622.         if ((msgnum>1) && (msgnum-1<nummsgs)) {
  623.           --msgnum;
  624.           optype=2;
  625.         }
  626.         break;
  627.           case 'C':
  628.         express=1;
  629.         break;
  630.           case 'V':
  631.                 if ((cs()) && (msgs[msgnum].ownersys==0) && (msgnum>0) && (msgnum<=nummsgs))
  632.                   valuser(msgs[msgnum].owneruser);
  633.         else
  634.                   if ((cs()) && (msgnum>0) && (msgnum<=nummsgs)) {
  635.             nl();
  636.             pl("Post from another system.");
  637.             nl();
  638.           }
  639.                 break;
  640.           case 'N':
  641.         if ((lcs()) && (msgnum>0) && (msgnum<=nummsgs)) {
  642.           msgs[msgnum].status ^= status_no_delete;
  643.                   bchanged=1;
  644.           nl();
  645.           if (msgs[msgnum].status & status_no_delete)
  646.                     pl("Message will NOT be auto-purged.");
  647.           else
  648.             pl("Message CAN now be auto-purged.");
  649.           nl();
  650.         }
  651.         break;
  652.               case 'X':
  653.         if ((lcs()) && (msgnum>0) && (msgnum<=nummsgs)) {
  654.                   msgs[msgnum].status ^= status_pending_net;
  655.                   bchanged=1;
  656.           nl();
  657.                   if (msgs[msgnum].status & status_pending_net) {
  658.                     val |= 2;
  659.                     pl("Will be sent out on net now.");
  660.                   } else
  661.                     pl("Not set for net pending now.");
  662.           nl();
  663.         }
  664.         break;
  665.           case 'U':
  666.         if ((lcs()) && (msgnum>0) && (msgnum<=nummsgs)) {
  667.           msgs[msgnum].anony=0;
  668.                   bchanged=1;
  669.           nl();
  670.                   pl("Message is not anonymous now.");
  671.         }
  672.         break;
  673.               case 'D':
  674.                 if (lcs()) {
  675.                   if (msgnum) {
  676.                     delete(msgnum);
  677.                     if (msgnum>1)
  678.                       msgnum--;
  679.                     savebase();
  680.                   }
  681.                 }
  682.                 break;
  683.           case 'E':
  684.         if (so()) {
  685.                   if ((msgnum>0) && (msgnum<=nummsgs)) {
  686.                     b=readfile(&(msgs[msgnum].msg),(subboards[curlsub].filename),&len);
  687.                     extract_out(b,len, msgs[msgnum].title);
  688.                   }
  689.         }
  690.         break;
  691.           case 'M':
  692.         if ((cs()) && (msgnum>0) && (msgnum<=nummsgs)) {
  693.                   nl();
  694.           do {
  695.                     prt(2,"Move to which sub? ");
  696.                     ss1=mmkey(0);
  697.             if (ss1[0]=='?')
  698.               sublist();
  699.           } while ((!hangup) && (ss1[0]=='?'));
  700.           i=-1;
  701.           if (ss1[0]==0)
  702.             break;
  703.                   for (i1=0; i1<MAX_SUBS; i1++)
  704.                     if (strcmp(usub[i1].keys,ss1)==0)
  705.                       i=i1;
  706.                   if (i!=-1) {
  707.             p=msgs[msgnum];
  708.                     b=readfile(&(p.msg),(subboards[curlsub].filename),&len);
  709.                     delete(msgnum);
  710.             savebase();
  711.                     iscan(i);
  712.             p.msg.storage_type=subboards[curlsub].storage_type;
  713.             savefile(b,len,&(p.msg),(subboards[curlsub].filename));
  714.                     p.qscan=status.qscanptr++;
  715.             if (nummsgs>=subboards[curlsub].maxmsgs) {
  716.                       i1=1;
  717.                       i2=0;
  718.                       while ((i2==0) && (i1<=nummsgs)) {
  719.                         if ((msgs[i1].status & status_no_delete)==0)
  720.                           i2=i1;
  721.                         ++i1;
  722.                        }
  723.                        if (i2==0)
  724.                          i2=1;
  725.                        p1=msgs[i2];
  726.                        remove_link(&p1.msg,(subboards[curlsub].filename));
  727.                        for (i1=i2; i1<nummsgs; i1++)
  728.                          msgs[i1]=msgs[i1+1];
  729.                --nummsgs;
  730.                      }
  731.                      msgs[++nummsgs]=p;
  732.                      bchanged=1;
  733.                      savebase();
  734.                      save_status();
  735.                      iscan(cursub);
  736.              nl();
  737.              pl("Message moved.");
  738.              nl();
  739.           }
  740.         }
  741.         break;
  742.         }
  743.       } else {
  744.         if (strcmp(s,"CLS")==0)
  745.           outchr('\x0c');
  746.       }
  747.         break;
  748.       case 1: /* List Titles */
  749.         i=0;
  750.         abort=0;
  751.         if (msgnum>=nummsgs)
  752.           abort=1;
  753.         while ((!abort) && (!hangup) && (++i<=10)) {
  754.           ++msgnum;
  755.           if ((msgs[msgnum].ownersys==0) && (msgs[msgnum].owneruser==usernum))
  756.             sprintf(s1,"[%d]",msgnum);
  757.           else
  758.             sprintf(s1,"(%d)",msgnum);
  759.           for (i1=0; i1<5; i1++)
  760.             s[i1]=32;
  761.           if (msgs[msgnum].qscan>QSCN(curlsub))
  762.             s[0]='*';
  763.           strcpy(&s[7-strlen(s1)],s1);
  764.           strcat(s," ");
  765.           if ((msgs[msgnum].status&(status_unvalidated|status_delete))&&(!lcs()))
  766.         strcat(s,"7<<< 1NOT VALIDATED YET 7>>>");
  767.           else
  768.             strcat(s,msgs[msgnum].title);
  769.           pla(s,&abort);
  770.           if (msgnum>=nummsgs)
  771.             abort=1;
  772.         }
  773.         optype=0;
  774.         break;
  775.       case 2: /* Read Message */
  776.     if ((msgnum>0) && (msgnum<=nummsgs))
  777.           read_message(msgnum,&next,&val);
  778.     ansic(0);
  779.         nl();
  780.         if (next) {
  781.           ++msgnum;
  782.           if (msgnum>nummsgs)
  783.             done=1;
  784.           optype=2;
  785.         } else
  786.           optype=0;
  787.         if (expressabort)
  788.       if (realexpress) {
  789.             done=1;
  790.             quit=1;
  791.             *nextsub=0;
  792.           } else {
  793.         expressabort=0;
  794.         express=0;
  795.         optype=0;
  796.       }
  797.         break;
  798.     }
  799.   } while ((!done) && (!hangup));
  800.   if (!realexpress) {
  801.     express=0;
  802.     expressabort=0;
  803.   }
  804.   if ((val & 1) && (lcs()) && (!express)) {
  805.     nl();
  806.     prt(5,"Validate messages here? ");
  807.     if (yn()) {
  808.       for (i=1; i<=nummsgs; i++)
  809.         if (msgs[i].status & (status_unvalidated | status_delete))
  810.           msgs[i].status &= (~(status_unvalidated | status_delete));
  811.       bchanged=1;
  812.     }
  813.   }
  814.   if ((val & 2) && (lcs()) && (!express)) {
  815.     nl();
  816.     prt(5,"Network validate here? ");
  817.     if (yn()) {
  818.       i1=0;
  819.       for (i=1; i<=nummsgs; i++)
  820.         if (msgs[i].status & status_pending_net) {
  821.           send_net_post(msgs+i, subboards[curlsub].type,
  822.             subboards[curlsub].filename);
  823.           ++i1;
  824.           msgs[i].status &= (~status_pending_net);
  825.         }
  826.       sprintf(s,"%d messages sent.",i1);
  827.       nl();
  828.       pl(s);
  829.       nl();
  830.       bchanged=1;
  831.     }
  832.   }
  833.   if ((!quit) && (!express)) {
  834.     nl();
  835.     ss=syscfg.sl[actsl];
  836.     if (
  837.         ((restrict_post & thisuser.restrict)==0) &&
  838.         (thisuser.posttoday<ss.posts) &&
  839.         (actsl>=subboards[curlsub].postsl)) {
  840.       sprintf(s,"fPost on e%s? ",subboards[curlsub].name);
  841.       prt(5,s);
  842.       irt[0]=0;
  843.       irt_name[0]=0;
  844.       if (yn())
  845.         post();
  846.     }
  847.   }
  848.   savebase();
  849.   nl();
  850. }
  851.  
  852. void qscan(int bn, int *ns)
  853. {
  854.   int i,nextsub,os,sn;
  855.   char s[81],s1[81];
  856.   unsigned long qscnptrx,sd;
  857.  
  858.   sn=usub[bn].subnum;
  859.   if ((hangup) || (sn<0))
  860.     return;
  861.   nl();
  862.   qscnptrx=QSCN(sn);
  863.   sd=sub_dates[sn];
  864.   if ((!sd) || (sd>qscnptrx)) {
  865.     nextsub=*ns;
  866.     os=cursub;
  867.     cursub=bn;
  868.     i=1;
  869.     iscan(cursub);
  870.     pl("f┌────────────────────────────────────────────────────────────────┐");
  871.     sprintf(s,"f│7 Q-scan 2%-41s 1%-2s - %-3u 7msgs f│\r\n",subboards[curlsub].name,
  872.           usub[cursub].keys,nummsgs);
  873.     prt(1,s);
  874.     pl("f└────────────────────────────────────────────────────────────────┘");
  875.     nl();
  876.     while ((i<=nummsgs) && (msgs[i].qscan<=qscnptrx))
  877.     ++i;
  878.     if ((nummsgs>0) && (msgs[nummsgs].qscan<=qscnptrx)) {
  879.       QSCN(curlsub)=status.qscanptr-1;
  880.     }
  881.     if ((nummsgs>0) && (i<=nummsgs))
  882.       if (msgs[i].qscan>QSCN(curlsub))
  883.         scan(i,2,&nextsub);
  884.     cursub=os;
  885.     *ns=nextsub;
  886.     pl("f┌───────────────────────────────────────────────────────┐");
  887.     sprintf(s,"f│7 Q-Scan Done 2%-41s f│\r\n",subboards[curlsub].name);
  888.     prt(1,s);
  889.     pl("f└───────────────────────────────────────────────────────┘");
  890.   } else {
  891.     sprintf(s,"7───1 Nothing new on 3%s1 %s7 ───",subboards[sn].name, usub[bn].keys);
  892.     prt(1,s);
  893.   }
  894.   nl();
  895. }
  896.  
  897. void nscan(int ss)
  898. {
  899.   int i,nextsub,abort,next;
  900.  
  901.   nl();
  902.   nextsub=1;
  903.   prt(7,"─── 1Q-Scan All7 ─── ");
  904.   nl();
  905.   for (i=ss; (usub[i].subnum!=-1) && (i<MAX_SUBS) && (nextsub) && (!hangup); i++) {
  906. #if MAX_SUBS>32
  907.     if (((usub[i].subnum<32) && (thisuser.qscn & (1L<<(usub[i].subnum)))) ||
  908.         ((usub[i].subnum>=32) && (thisuser.qscn2 & (1L<<(usub[i].subnum-32)))))
  909. #else
  910.     if (thisuser.qscn & (1L<<(usub[i].subnum)))
  911. #endif
  912.       qscan(i,&nextsub);
  913.     abort=next=0;
  914.     checka(&abort,&next);
  915.     if (abort)
  916.       nextsub=0;
  917.   }
  918.   nl();
  919.   prt(7,"─── 1Global Q-Scan Done7 ───");
  920.   nl();
  921.   nl();
  922.   if ((nextsub) && (thisuser.sysstatus & sysstatus_nscan_file_system) &&
  923.     ((syscfg.sysconfig & sysconfig_no_xfer)==0))
  924.     {
  925.     prt(7,"Now scanning Tranfers for new files...");
  926.     nscanall();
  927.     }
  928. }
  929.  
  930. void scan2()
  931. {
  932.   char s[81];
  933.   int i,i1;
  934.  
  935.   iscan(cursub);
  936.   nl();
  937.   if (curlsub<0) {
  938.     pl("No subs available.");
  939.     nl();
  940.     return;
  941.   }
  942.   npr("1%d fmsgs on 1%s\r\n",nummsgs, subboards[curlsub].name);
  943.   if (nummsgs==0)
  944.     return;
  945.   helpl=11;
  946.   prt(2,"Start listing at? ");
  947.   input(s,4);
  948.   i=atoi(s);
  949.   if (i<1)
  950.     i=0;
  951.   else
  952.     if (i>nummsgs)
  953.       i=nummsgs;
  954.     else
  955.       i--;
  956.   i1=0;
  957.   if (strcmp(s,"S")==0)
  958.     scan(0,0,&i1);
  959.   else
  960.     if (strcmp(s,"Q")) {
  961.       if (strcmp(s,"N")==0) {
  962.       } else
  963.         scan(i,1,&i1);
  964.     }
  965. }
  966.  
  967. void printmenu(int i)
  968. {
  969.   char s[81],s1[81];
  970.   int next;
  971.  
  972.   next=0;
  973.   if ((thisuser.sysstatus & (sysstatus_color | sysstatus_ansi))
  974.       == (sysstatus_color | sysstatus_ansi)) {
  975.     sprintf(s1,"MENU%u.ANS", i);
  976.     sprintf(s,"%s%s",syscfg.gfilesdir,s1);
  977.     if (exist(s)) {
  978.       printfile(s1);
  979.       return;
  980.     }
  981.   }
  982.   sprintf(s1,"MENU%u.MSG", i);
  983.   sprintf(s,"%s%s",syscfg.gfilesdir,s1);
  984.   if (exist(s)) {
  985.     printfile(s1);
  986.     return;
  987.   }
  988.   if ((thisuser.screenchars==40) && (menus2[i].stored_as)) {
  989.     sprintf(s,"%sMENUS40.MSG",syscfg.gfilesdir);
  990.     read_message1(&menus2[i],0,0,&next,s);
  991.   } else
  992.     if ((okansi()) && (menus1[i].stored_as)) {
  993.       sprintf(s,"%sMENUSANS.MSG",syscfg.gfilesdir);
  994.       read_message1(&menus1[i],0,0,&next,s);
  995.     } else {
  996.       sprintf(s,"%sMENUS.MSG",syscfg.gfilesdir);
  997.       if (menus[i].stored_as)
  998.         read_message1(&menus[i],0,0,&next,s);
  999.     }
  1000. }
  1001.  
  1002. void delmail(int f, int loc)
  1003. {
  1004.   mailrec m,m1;
  1005.   userrec u;
  1006.   int rm,i,t,otf;
  1007.  
  1008.   lseek(f,((long) loc) * ((long) sizeof(mailrec)), SEEK_SET);
  1009.   read(f,(void *)&m,sizeof(mailrec));
  1010.   rm=1;
  1011.   if (m.status & status_multimail) {
  1012.     t=filelength(f)/sizeof(mailrec);
  1013.     otf=0;
  1014.     for (i=0; i<t; i++)
  1015.       if (i!=loc) {
  1016.         lseek(f,((long)i)*((long)sizeof(mailrec)),SEEK_SET);
  1017.         read(f,(void *)&m1,sizeof(mailrec));
  1018.         if ((m.msg.stored_as==m1.msg.stored_as) && (m.msg.storage_type==m1.msg.storage_type) && (m1.daten!=0xffffffff))
  1019.           otf=1;
  1020.       }
  1021.     if (otf)
  1022.       rm=0;
  1023.   }
  1024.   if (rm)
  1025.     remove_link(&m.msg,"EMAIL");
  1026.   if (m.tosys==0) {
  1027.     read_user(m.touser,&u);
  1028.     if (u.waiting) {
  1029.       --u.waiting;
  1030.       write_user(m.touser,&u);
  1031.       close_user();
  1032.     }
  1033.     if (m.touser==1)
  1034.       --fwaiting;
  1035.   }
  1036.   lseek(f,((long) loc) * ((long) sizeof(mailrec)), SEEK_SET);
  1037.   m.touser=0;
  1038.   m.tosys=0;
  1039.   m.daten=0xffffffff;
  1040.   m.msg.storage_type=0;
  1041.   m.msg.stored_as=0xffffffff;
  1042.   write(f,(void *)&m,sizeof(mailrec));
  1043.   mailcheck=1;
  1044. }
  1045.  
  1046. void readmail()
  1047. {
  1048.   int i,i1,i2,i3,f,mw,mloc[256],mfl,curmail,done,abort,next,okmail;
  1049.   unsigned short x,xx;
  1050.   char s[81],s1[81],s2[81],fn[81],*b;
  1051.   mailrec m;
  1052.   slrec ss;
  1053.   userrec u;
  1054.   char ch;
  1055.   long len,num_mail,num_mail1;
  1056.   char work[81];
  1057.   size_t namelen;
  1058.   int counter;
  1059.  
  1060.   ss=syscfg.sl[actsl];
  1061.   sprintf(fn,"%sEMAIL.DAT",syscfg.datadir);
  1062.   f=open(fn,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  1063.   if (f<0) {
  1064.     nl();
  1065.     nl();
  1066.     pl("No mail file exists!");
  1067.     nl();
  1068.     return;
  1069.   }
  1070.   mfl=filelength(f)/sizeof(mailrec);
  1071.   mw=0;
  1072.   for (i=0; (i<mfl) && (mw<255); i++) {
  1073.     lseek(f,((long) (i)) * (sizeof(mailrec)), SEEK_SET);
  1074.     read(f,(void *)(&m),sizeof(mailrec));
  1075.     if ((m.tosys==0) && (m.touser==usernum))
  1076.       mloc[mw++]=i;
  1077.   }
  1078.   thisuser.waiting=mw;
  1079.   if (usernum==1)
  1080.     fwaiting=mw;
  1081.   if (mw==0) {
  1082.     nl();
  1083.     nl();
  1084.     pl("7Ha ha! You have no mail!");
  1085.     nl();
  1086.     return;
  1087.   }
  1088.   if (mw==1)
  1089.     curmail=0;
  1090.   else {
  1091.     nl();
  1092.     nl();
  1093.     pl("fYou have mail from:");
  1094.     nl();
  1095.     for (i=0; i<mw; i++) {
  1096.       lseek(f,((long) mloc[i]) * sizeof(mailrec),SEEK_SET);
  1097.       read(f,(void *) (&m),sizeof(mailrec));
  1098.       sprintf(s,"%d. ",i+1);
  1099.       if ((m.anony & anony_sender) && ((ss.ability & ability_read_email_anony)==0)) {
  1100.     strcat(s,"7>1UNKNOWN7<");
  1101.       } else {
  1102.         if (m.fromsys==0) {
  1103.       if (m.fromuser==65535)
  1104.         strcat(s,"WWIVnet");
  1105.       else {
  1106.             read_user(m.fromuser,&u);
  1107.             strcat(s,nam(&u,m.fromuser));
  1108.       }
  1109.         } else {
  1110.           sprintf(s1,"User %u @%u",m.fromuser,m.fromsys);
  1111.           strcat(s,s1);
  1112.         }
  1113.       }
  1114.       prt(0, s);
  1115.       work[0]=0;
  1116.       namelen=strlen(s);
  1117.       s[0]=0;
  1118.       for (counter=namelen; counter<42; counter++)
  1119.     strcat(work, " ");
  1120.       prt(0, work);
  1121.       strcpy(work, m.title);
  1122.       work[36]=0;
  1123.       if (work[35]==3) {
  1124.     work[36]=48;
  1125.     work[37]=0;
  1126.       }
  1127.       s[0]=34;
  1128.       s[1]=0;
  1129.       strcat(s, work);
  1130.       namelen=strlen(s);
  1131.       s[namelen]=34;
  1132.       s[namelen+1]=0;
  1133.       pl(s);
  1134.     }
  1135.     nl();
  1136.     helpl=10;
  1137.     pl("7Hit return, or enter number");
  1138.     outstr(":");
  1139.     input(s,3);
  1140.     if (strcmp(s,"Q")==0) {
  1141.       close(f);
  1142.       return;
  1143.     }
  1144.     i=atoi(s);
  1145.     if (i)
  1146.       if (i<=mw)
  1147.         curmail=i-1;
  1148.       else
  1149.         curmail=0;
  1150.     else
  1151.       curmail=0;
  1152.   }
  1153.   done=0;
  1154.   do {
  1155.     sprintf(s,"(%u/%u): ",curmail+1,mw);
  1156.     abort=0;
  1157.     nl();
  1158.     nl();
  1159.     osan(s,&abort,&next);
  1160.     next=0;
  1161.     ansic(MSG_COLOR);
  1162.     s[0]=0;
  1163.     if (mloc[curmail]<0) {
  1164.       strcat(s,">>> MAIL DELETED <<<");
  1165.       okmail=0;
  1166.       pl(s);
  1167.       nl();
  1168.       nl();
  1169.     } else {
  1170.       lseek(f,((long) (mloc[curmail])) * (sizeof(mailrec)), SEEK_SET);
  1171.       read(f,(void *)&m,sizeof(mailrec));
  1172.       if ((m.tosys!=0) || (m.touser!=usernum)) {
  1173.     mloc[curmail]=-1;
  1174.         strcat(s,">>> MAIL DELETED <<<");
  1175.         okmail=0;
  1176.         pl(s);
  1177.         nl();
  1178.         nl();
  1179.       } else {
  1180.         strcat(s,m.title);
  1181.         strcpy(irt,m.title);
  1182.         irt_name[0]=0;
  1183.         abort=0;
  1184.         i=((ability_read_email_anony & ss.ability)!=0);
  1185.         okmail=1;
  1186.         pla(s,&abort);
  1187.         if ((m.fromsys) && (!m.fromuser))
  1188.           grab_user_name(&(m.msg),"EMAIL");
  1189.         else
  1190.           net_email_name[0]=0;
  1191.         setorigin(m.fromsys, m.fromuser);
  1192.         if (m.status & status_source_verified) {
  1193.           if (strlen(m.title)<=78) {
  1194.             xx=*(short *) (m.title+79);
  1195.             sprintf(s,"-=-=: Type %u Source Verified",xx);
  1196.             if (xx==1) {
  1197.               strcat(s," (From NC)");
  1198.             } else if ((xx>256) && (xx<512)) {
  1199.               sprintf(s2," (From group %u GC)",xx-256);
  1200.               strcat(s,s2);
  1201.             }
  1202.           } else {
  1203.             strcpy(s,"-=-=: Source Verified (unknown type)");
  1204.           }
  1205.           if (!abort) {
  1206.             ansic(4);
  1207.             pla(s,&abort);
  1208.           }
  1209.         }
  1210.         if (!abort)
  1211.           read_message1(&m.msg, (m.anony & 0x0f), i, &next, "EMAIL");
  1212.       }
  1213.     }
  1214.     do {
  1215.       i2=1;
  1216.       irt_name[0]=0;
  1217.       prt(2,"1Mail 7{1?7} f: ");
  1218.       helpl=34;
  1219.       if (!okmail)
  1220.     ch=onek("QI?-+G");
  1221.       else
  1222.         if (so())
  1223.             ch=onek("QSRIDAF?-+GEZVUOL");
  1224.         else
  1225.           if (cs())
  1226.             ch=onek("QSRIDAF?-+GZVUO");
  1227.           else
  1228.             ch=onek("QSRIDAF?+-G");
  1229.       switch (ch) {
  1230.     case 'E':
  1231.           if ((so()) && (okmail)) {
  1232.             b=readfile(&(m.msg),"EMAIL",&len);
  1233.             extract_out(b,len,m.title);
  1234.           }
  1235.           i2=0;
  1236.       break;
  1237.         case 'Q':
  1238.           done=1;
  1239.       break;
  1240.     case 'O':
  1241.       if ((cs()) && (okmail) && (m.fromuser!=65535)) {
  1242.         nl();
  1243.         prt(2,"Which form letter? ");
  1244.             input(s,4);
  1245.             sprintf(s1,"%sFORM%s.MSG",syscfg.gfilesdir,s);
  1246.         if (exist(s1)) {
  1247.               strcpy(s,nam(&thisuser,usernum));
  1248.           if (m.anony & anony_receiver)
  1249.             strcpy(s,">UNKNOWN<");
  1250.               strcat(s," read your mail on ");
  1251.               strcat(s,date());
  1252.           if (m.fromsys==0)
  1253.         ssm(m.fromuser,m.fromsys,s);
  1254.           nl();                                     /** add **/
  1255.           prt(1,"Delete this piece of mail?");      /** add **/
  1256.           if (yn()){                                 /** add **/
  1257.         delmail(f,mloc[curmail]);
  1258.           mloc[curmail]=-1;}
  1259.           nl(); nl();                               /** add **/
  1260.               ++curmail;
  1261.               if (curmail>=mw)
  1262.                 done=1;
  1263.               if (!wfc)
  1264.         topscreen();
  1265.               close(f);
  1266.               load_workspace(s1,1);
  1267.               email(m.fromuser,m.fromsys,0,m.anony);
  1268.               f=open(fn,O_RDWR | O_BINARY);
  1269.         } else {
  1270.           nl();
  1271.           pl("File not found.");
  1272.           nl();
  1273.               i2=0;
  1274.         }
  1275.       }
  1276.       break;
  1277.     case 'G':
  1278.       sprintf(s,"eGo to which (1-%u) ? ",mw);
  1279.       prt(2,s);
  1280.       input(s,3);
  1281.       i2=atoi(s);
  1282.       if ((i2>0) && (i2<=mw)) {
  1283.         curmail=i2-1;
  1284.         i2=1;
  1285.       } else
  1286.         i2=0;
  1287.       break;
  1288.         case 'I':
  1289.     case '+':
  1290.           ++curmail;
  1291.           if (curmail>=mw)
  1292.             done=1;
  1293.           break;
  1294.     case '-':
  1295.       if (curmail)
  1296.             --curmail;
  1297.       break;
  1298.         case 'R':
  1299.           break;
  1300.         case '?':
  1301.           printmenu(4);
  1302.           i2=0;
  1303.           break;
  1304.         case 'D':
  1305.       if (!okmail)
  1306.         break;
  1307.           strcpy(s,nam(&thisuser,usernum));
  1308.       if (m.anony & anony_receiver)
  1309.         strcpy(s,"7>1UNKNOWN7<");
  1310.       strcat(s," 1read your mail on ");
  1311.       strcat(s,date());
  1312.       if ((m.fromsys==0) && (m.fromuser!=65535))
  1313.             ssm(m.fromuser,m.fromsys,s);
  1314.         case 'Z':
  1315.       if (!okmail)
  1316.         break;
  1317.           delmail(f,mloc[curmail]);
  1318.           mloc[curmail]=-1;
  1319.           ++curmail;
  1320.           if (curmail>=mw)
  1321.             done=1;
  1322.           if (!wfc)
  1323.             topscreen();
  1324.           break;
  1325.         case 'F':
  1326.       if (!okmail)
  1327.         break;
  1328.       if (m.status & status_multimail) {
  1329.         nl();
  1330.         pl("Can't forward multimail.");
  1331.         nl();
  1332.         break;
  1333.       }
  1334.           nl();
  1335.           nl();
  1336.           prt(2,"Forward to: ");
  1337.           input(s,30);
  1338.           x=finduser(s);
  1339.           if ((x==usernum) && (!cs())) {
  1340.             x=0;
  1341.             nl();
  1342.             pl("Can't forward to yourself.");
  1343.             nl();
  1344.           }
  1345.           xx=0;
  1346.           if ((x) && (forwardm(&x,&xx))) {
  1347.             nl();
  1348.             if (x)
  1349.               pl("Forwarded from there.");
  1350.             else
  1351.               pl("Can't forward to him.");
  1352.           }
  1353.       if (x>0) {
  1354.         read_user(x,&u);
  1355.             sprintf(s,"Forward to %s? ",nam(&u,x));
  1356.         prt(5,s);
  1357.         if (!yn())
  1358.           x=0;
  1359.       }
  1360.           if (x>0) {
  1361.             --thisuser.waiting;
  1362.             if (usernum==1)
  1363.               --fwaiting;
  1364.             m.touser=x;
  1365.             lseek(f,((long) (mloc[curmail])) * (sizeof(mailrec)), SEEK_SET);
  1366.             write(f,(void *)&m,sizeof(mailrec));
  1367.             read_user(x,&u);
  1368.             ++u.waiting;
  1369.             write_user(x,&u);
  1370.             if (x==1)
  1371.               ++fwaiting;
  1372.             sprintf(s,"\r\nForwarded from: %s",nam(&thisuser,usernum));
  1373.             lineadd(&m.msg,s,"EMAIL");
  1374.             sprintf(s,"%s forwarded your mail to %s",
  1375.               nam(&thisuser,usernum), nam(&u,x));
  1376.         if (m.fromsys==0)
  1377.               ssm(m.fromuser,m.fromsys,s);
  1378.             mloc[curmail]=-1;
  1379.             ++curmail;
  1380.             if (curmail>=mw)
  1381.               done=1;
  1382.             if (!wfc)
  1383.               topscreen();
  1384.             npr("Forwarded to %s\r\n",nam(&u,x));
  1385.           } else {
  1386.             nl();
  1387.             pl("Unknown user.");
  1388.             nl();
  1389.           }
  1390.           break;
  1391.         case 'A':
  1392.         case 'S':
  1393.       if (!okmail)
  1394.         break;
  1395.       close(f);
  1396.       quote_message(&(m.msg),"EMAIL");
  1397.           num_mail=((long) thisuser.feedbacksent) +
  1398.                    ((long) thisuser.emailsent) +
  1399.                    ((long) thisuser.emailnet);
  1400.       if (m.fromuser!=65535)
  1401.             email(m.fromuser,m.fromsys,0,m.anony);
  1402.           f=open(fn,O_RDWR | O_BINARY);
  1403.           num_mail1=((long) thisuser.feedbacksent) +
  1404.                     ((long) thisuser.emailsent) +
  1405.                     ((long) thisuser.emailnet);
  1406.           if (ch=='A') {
  1407.             if (num_mail!=num_mail1) {
  1408.               strcpy(s,nam(&thisuser,usernum));
  1409.               if (m.anony & anony_receiver)
  1410.                 strcpy(s,">UNKNOWN<");
  1411.               strcat(s," read your mail on ");
  1412.               strcat(s,date());
  1413.               if ((m.fromsys==0) && (m.fromuser!=65535))
  1414.         ssm(m.fromuser,m.fromsys,s);
  1415.           nl();
  1416.           prt(1,"Delete original mail now?");
  1417.           if (yn()){
  1418.         delmail(f,mloc[curmail]);
  1419.         mloc[curmail]=-1;}
  1420.           nl(); nl();
  1421.           ++curmail;
  1422.               if (curmail>=mw)
  1423.                 done=1;
  1424.               if (!wfc)
  1425.                 topscreen();
  1426.             } else {
  1427.               nl();
  1428.               pl("No mail sent.");
  1429.               nl();
  1430.               i2=0;
  1431.             }
  1432.           } else {
  1433.             if (num_mail != num_mail1) {
  1434.               ++curmail;
  1435.               if (curmail>=mw)
  1436.                 done=1;
  1437.               if (!wfc)
  1438.                 topscreen();
  1439.             }
  1440.           }
  1441.           break;
  1442.         case 'U':
  1443.         case 'V':
  1444.       if (!okmail)
  1445.         break;
  1446.           if ((m.fromsys==0) && (cs()) && (m.fromuser!=65535))
  1447.             if (ch=='V')
  1448.               valuser(m.fromuser);
  1449.             else
  1450.               uedit(m.fromuser,0);
  1451.       else
  1452.         if (cs()) {
  1453.           nl();
  1454.           pl("Mail from another system.");
  1455.           nl();
  1456.         }
  1457.           i2=0;
  1458.           break;
  1459.         case 'L':
  1460.           if (!so())
  1461.             break;
  1462.           nl();
  1463.           prt(2,"Filename? ");
  1464.           input(s,50);
  1465.           if (s[0]) {
  1466.             nl();
  1467.             prt(5,"Allow editing? ");
  1468.             if (yn()) {
  1469.               nl();
  1470.               load_workspace(s,0);
  1471.             } else {
  1472.               nl();
  1473.               load_workspace(s,1);
  1474.             }
  1475.           }
  1476.       }
  1477.     } while ((!i2) && (!hangup));
  1478.   } while ((!hangup) && (!done));
  1479.   close(f);
  1480. }
  1481.  
  1482. void remove_post()
  1483. {
  1484.   int i,i1,any,abort;
  1485.   char s[161];
  1486.  
  1487.   iscan(cursub);
  1488.   if (curlsub<0) {
  1489.     nl();
  1490.     pl("No subs available.");
  1491.     nl();
  1492.     return;
  1493.   }
  1494.   any=0;
  1495.   abort=0;
  1496.   nl();
  1497.   nl();
  1498.   npr("Posts by you on %s\r\n", subboards[curlsub].name);
  1499.   nl();
  1500.   for (i=1; (i<=nummsgs) && (!abort); i++) {
  1501.     if ((msgs[i].ownersys==0) && (msgs[i].owneruser==usernum)) {
  1502.       any=1;
  1503.       sprintf(s,"%u: %s",i,msgs[i].title);
  1504.       pla(s,&abort);
  1505.     }
  1506.   }
  1507.   if (!any) {
  1508.     pl("None.");
  1509.     if (!cs())
  1510.       return;
  1511.   }
  1512.   nl();
  1513.   prt(2,"Remove which? ");
  1514.   input(s,3);
  1515.   i=atoi(s);
  1516.   if ((i>0) && (i<=nummsgs)) {
  1517.     if (((msgs[i].ownersys==0) && (msgs[i].owneruser==usernum)) || (lcs())) {
  1518.       sprintf(s,"-%s removed from %s",msgs[i].title,subboards[curlsub].name);
  1519.       sysoplog(s);
  1520.       delete(i);
  1521.       savebase();
  1522.       nl();
  1523.       pl("Message removed.");
  1524.       thisuser.gold=thisuser.gold-1;
  1525.       npr("fRemoving your message cost you 1 gold, you now have 1%d fgold",(int) thisuser.gold);
  1526.       nl();
  1527.     }
  1528.   }
  1529. }
  1530.  
  1531. int external_edit(char *fn1, char *direc, int ednum, int numlines)
  1532. {
  1533.   char s[255],s1[128],fn[128],s2[128],s3[81],sx1[21],sx2[21],sx3[21],ch;
  1534.   int i,i1,i2,r,w,filethere,mod,newtl;
  1535.   struct ftime ftimep,ftimep1;
  1536.  
  1537.   if ((ednum>=numed) || (!okansi())) {
  1538.     nl();
  1539.     pl("You can't use that full screen editor.");
  1540.     nl();
  1541.     return(0);
  1542.   }
  1543.   i1=0;
  1544.   for (i2=0; i2<81; i2++) {
  1545.     i1+=editors[ednum].filename[i2];
  1546.     i1+=editors[ednum].filenamecon[i2];
  1547.   }
  1548.   if (incom)
  1549.     strcpy(s1,(editors[ednum].filename));
  1550.   else
  1551.     strcpy(s1,(editors[ednum].filenamecon));
  1552.   if (s1[0]==0) {
  1553.     nl();
  1554.     pl("You can't use that full screen editor.");
  1555.     nl();
  1556.     return(0);
  1557.   }
  1558.   strcpy(s3,fn1);
  1559.   stripfn1(s3);
  1560.   if (direc[0]) {
  1561.     cd_to(direc);
  1562.     get_dir(fn,1);
  1563.     cd_to(cdir);
  1564.   } else
  1565.     fn[0]=0;
  1566.   strcat(fn,s3);
  1567.   filethere=exist(fn);
  1568.   if (filethere) {
  1569.     i=open(fn,O_RDONLY | O_BINARY);
  1570.     getftime(i,&ftimep);
  1571.     close(i);
  1572.   }
  1573.   itoa(thisuser.screenchars,sx1,10);
  1574.   if (screenlinest>defscreenbottom-topline)
  1575.     newtl=0;
  1576.   else
  1577.     newtl=topline;
  1578.   if (using_modem)
  1579.     itoa(thisuser.screenlines,sx2,10);
  1580.   else
  1581.     itoa(defscreenbottom+1-newtl,sx2,10);
  1582.   itoa(numlines,sx3,10);
  1583.   stuff_in(s,s1,fn,sx1,sx2,sx3,"");
  1584.   full_external(s,0,1);
  1585.   if (!wfc)
  1586.     topscreen();
  1587.   mod=0;
  1588.   if (!filethere) {
  1589.     mod=exist(fn);
  1590.   } else {
  1591.     i=open(fn,O_RDONLY | O_BINARY);
  1592.     getftime(i,&ftimep1);
  1593.     close(i);
  1594.     if ((ftimep.ft_year!=ftimep1.ft_year) ||
  1595.         (ftimep.ft_month!=ftimep1.ft_month) ||
  1596.         (ftimep.ft_day!=ftimep1.ft_day) ||
  1597.         (ftimep.ft_hour!=ftimep1.ft_hour) ||
  1598.         (ftimep.ft_min!=ftimep1.ft_min) ||
  1599.         (ftimep.ft_tsec!=ftimep1.ft_tsec))
  1600.       mod=1;
  1601.   }
  1602.   return(mod);
  1603. }
  1604.