home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / UTIL / WWIVE / MYWIVE.ZIP / MSGBASE1.C < prev    next >
Text File  |  1993-05-19  |  40KB  |  1,607 lines

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