home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / W / WWIVSOR.ZIP / MSGBASE1.C < prev    next >
Text File  |  1995-05-17  |  44KB  |  1,669 lines

  1. /*****************************************************************************
  2.  
  3.                 WWIV Version 4
  4.                     Copyright (C) 1988-1995 by Wayne Bell
  5.  
  6. Distribution of the source code for WWIV, in any form, modified or unmodified,
  7. without PRIOR, WRITTEN APPROVAL by the author, is expressly prohibited.
  8. Distribution of compiled versions of WWIV is limited to copies compiled BY
  9. THE AUTHOR.  Distribution of any copies of WWIV not compiled by the author
  10. is expressly prohibited.
  11.  
  12.  
  13. *****************************************************************************/
  14.  
  15.  
  16.  
  17. #include "vars.h"
  18.  
  19. #pragma hdrstop
  20.  
  21. #include "subxtr.h"
  22. #include "ripint.h"
  23.  
  24. #include <dir.h>
  25.  
  26.  
  27.  
  28.  
  29. #define ALLOW_FULLSCREEN 1
  30. #define EMAIL_STORAGE 2
  31.  
  32. /****************************************************************************/
  33.  
  34. void send_net_post(postrec *p, char *extra, int subnum)
  35. {
  36.   net_header_rec nh, nh1;
  37.   char *b, *b1;
  38.   long len1, len2;
  39.   char s[81];
  40.   int f,i,onn,nn,n,nn1;
  41.   unsigned int *list;
  42.   xtrasubsnetrec *xnp;
  43.  
  44.   b=readfile(&(p -> msg),extra,&len1);
  45.   if (b==NULL)
  46.     return;
  47.  
  48.   onn=net_num;
  49.   if (p->status & status_post_new_net)
  50.     nn=p->title[80];
  51.   else if (xsubs[subnum].num_nets)
  52.     nn=xsubs[subnum].nets[0].net_num;
  53.   else
  54.     nn=net_num;
  55.  
  56.   nn1=nn;
  57.   if (p->ownersys==0)
  58.     nn=-1;
  59.  
  60.   nh1.tosys=0;
  61.   nh1.touser=0;
  62.   nh1.fromsys=p->ownersys;
  63.   nh1.fromuser=p->owneruser;
  64.   nh1.list_len=0;
  65.   nh1.daten=p->daten;
  66.   nh1.length=len1+1+strlen(p -> title);
  67.   nh1.method=0;
  68.  
  69.   if (nh1.length > 32755) {
  70.     outstr(get_string(645));
  71.     npr("%lu",nh1.length-32755L);
  72.     outstr(get_string(646));
  73.     nh1.length = 32755;
  74.     len1=nh1.length-strlen(p->title)-1;
  75.   }
  76.  
  77.   if ((b1=malloca(nh1.length+100))==NULL) {
  78.     bbsfree(b);
  79.     set_net_num(onn);
  80.     return;
  81.   }
  82.  
  83.   strcpy(b1,p -> title);
  84.   memmove(&(b1[strlen(p -> title)+1]),b,(unsigned int) len1);
  85.   bbsfree(b);
  86.  
  87.   for (n=0; n<xsubs[subnum].num_nets; n++) {
  88.     xnp=&(xsubs[subnum].nets[n]);
  89.  
  90.     if ((xnp->net_num==nn) && (xnp->host))
  91.       continue;
  92.  
  93.     set_net_num(xnp->net_num);
  94.  
  95.     nh=nh1;
  96.     list=NULL;
  97.     nh.minor_type=xnp->type;
  98.     if (!nh.fromsys)
  99.       nh.fromsys=net_sysnum;
  100.  
  101.     if (xnp->host) {
  102.       nh.main_type=main_type_pre_post;
  103.       nh.tosys=xnp->host;
  104.     } else {
  105.       nh.main_type=main_type_post;
  106.       sprintf(s,"%sN%s.NET",net_data, xnp->stype);
  107.       f=sh_open1(s,O_RDONLY|O_BINARY);
  108.       if (f>0) {
  109.         len1=filelength(f);
  110.         list=(unsigned int *)malloca(len1*2+1);
  111.         if (!list)
  112.           continue;
  113.         if ((b=malloca(len1+100L))==NULL) {
  114.           bbsfree(list);
  115.           continue;
  116.         }
  117.         sh_read(f,b,len1);
  118.         sh_close(f);
  119.         b[len1]=0;
  120.         len2=0;
  121.         while (len2<len1) {
  122.           while ((len2<len1) && ((b[len2]<'0') || (b[len2]>'9')))
  123.             ++len2;
  124.           if ((b[len2]>='0') && (b[len2]<='9') && (len2<len1)) {
  125.             i=atoi(&(b[len2]));
  126.             if (((net_num!=nn) || (nh.fromsys!=i)) && (i!=net_sysnum))
  127.               list[(nh.list_len)++]=i;
  128.             while ((len2<len1) && (b[len2]>='0') && (b[len2]<='9'))
  129.               ++len2;
  130.           }
  131.         }
  132.         bbsfree(b);
  133.       }
  134.       if (!nh.list_len) {
  135.         if (list)
  136.           bbsfree(list);
  137.         continue;
  138.       }
  139.     }
  140.     if (!xnp->type)
  141.       nh.main_type=main_type_new_post;
  142.     if (nn1==net_num)
  143.       send_net(&nh, list, b1, xnp->type?NULL:xnp->stype);
  144.     else
  145.       gate_msg(&nh, b1, xnp->net_num, xnp->stype, list, nn);
  146.     if (list)
  147.       bbsfree(list);
  148.   }
  149.  
  150.   bbsfree(b1);
  151.   set_net_num(onn);
  152. }
  153.  
  154. /****************************************************************************/
  155.  
  156.  
  157. void post(void)
  158. {
  159.   messagerec m;
  160.   postrec p;
  161.   char s[121];
  162.   int i,dm,a;
  163.   slrec ss;
  164.   time_t time1, time2;
  165.  
  166.   if (!iscan(cursub)) {
  167.     nl();
  168.     pl(get_string(1195));
  169.     return;
  170.   }
  171.   if (curlsub<0) {
  172.     nl();
  173.     pl(get_string(668));
  174.     nl();
  175.     return;
  176.   }
  177.  
  178.   ss=syscfg.sl[actsl];
  179.  
  180.   if (freek1(syscfg.msgsdir)<10.0) {
  181.     nl();
  182.     pl(get_string(332));
  183.     nl();
  184.     return;
  185.   }
  186.  
  187.   if ((restrict_post & thisuser.restrict) || (thisuser.posttoday>=ss.posts)) {
  188.     nl();
  189.     pl(get_string(669));
  190.     nl();
  191.     return;
  192.   }
  193.  
  194.   if (actsl<subboards[curlsub].postsl) {
  195.     nl();
  196.     pl(get_string(670));
  197.     nl();
  198.     return;
  199.   }
  200.  
  201.   m.storage_type=subboards[curlsub].storage_type;
  202.   a=subboards[curlsub].anony & 0x0f;
  203.   if ((a==0) && (ss.ability & ability_post_anony))
  204.     a=anony_enable_anony;
  205.   if ((a==anony_enable_anony) && (thisuser.restrict & restrict_anony))
  206.     a=0;
  207.   if (xsubs[curlsub].num_nets) {
  208.     a &= (anony_real_name);
  209.     if (thisuser.restrict & restrict_net) {
  210.       nl();
  211.       pl(get_string(671));
  212.       nl();
  213.       return;
  214.     }
  215.     if (net_sysnum) {
  216.       nl();
  217.       outstr(get_string(672));
  218.       for (i=0; i<xsubs[curlsub].num_nets; i++) {
  219.         if (i)
  220.           outstr(", ");
  221.         outstr(net_networks[xsubs[curlsub].nets[i].net_num].name);
  222.       }
  223.       outstr(".\r\n");
  224.       nl();
  225.     }
  226.   }
  227.  
  228.   time1=time(NULL);
  229.  
  230.   write_inst(INST_LOC_POST,curlsub,INST_FLAGS_NONE);
  231.  
  232.   inmsg(&m,p.title,&a,1,(subboards[curlsub].filename),ALLOW_FULLSCREEN,
  233.     subboards[curlsub].name, (subboards[curlsub].anony&anony_no_tag)?1:0);
  234.   if (m.stored_as!=0xffffffff) {
  235.  
  236.     p.anony=a;
  237.     p.msg=m;
  238.     p.ownersys=0;
  239.     p.owneruser=usernum;
  240.     lock_status();
  241.     p.qscan=status.qscanptr++;
  242.     save_status();
  243.     time((long *)(&p.daten));
  244.     if (thisuser.restrict & restrict_validate)
  245.       p.status=status_unvalidated;
  246.     else
  247.       p.status=0;
  248.  
  249.     open_sub(1);
  250.  
  251.     if ((xsubs[curlsub].num_nets) &&
  252.       (subboards[curlsub].anony & anony_val_net) && (!lcs() || irt[0])) {
  253.       p.status |= status_pending_net;
  254.       dm=1;
  255.       for (i=nummsgs; (i>=1) && (i>(nummsgs-28)); i--) {
  256.         if (get_post(i)->status & status_pending_net) {
  257.           dm=0;
  258.           break;
  259.         }
  260.       }
  261.       if (dm) {
  262.         sprintf(s,get_stringx(1,37),subboards[curlsub].name);
  263.         ssm(1,0,s);
  264.       }
  265.     }
  266.  
  267.  
  268.     if (nummsgs>=subboards[curlsub].maxmsgs) {
  269.       i=1;
  270.       dm=0;
  271.       while ((dm==0) && (i<=nummsgs)) {
  272.         if ((get_post(i)->status & status_no_delete)==0)
  273.           dm=i;
  274.         ++i;
  275.       }
  276.       if (dm==0)
  277.         dm=1;
  278.       delete(dm);
  279.     }
  280.  
  281.     add_post(&p);
  282.     ++thisuser.msgpost;
  283.     ++thisuser.posttoday;
  284.     lock_status();
  285.     ++status.msgposttoday;
  286.     ++status.localposts;
  287.  
  288.     if (sysinfo.flags & OP_FLAGS_POSTTIME_COMPENSATE) {
  289.       time2=time(NULL);
  290.       if (time1>time2)
  291.         time2+=24*3600;
  292.       time1=(float)(time2-time1);
  293.       if ((time1/60.0)>syscfg.sl[actsl].time_per_logon)
  294.         time1=(float)(syscfg.sl[actsl].time_per_logon*60.0);
  295.                   thisuser.extratime+=(float)(time1);
  296.     }
  297.  
  298.     save_status();
  299.     close_sub();
  300.  
  301.     topscreen();
  302.     sprintf(s,get_stringx(1,38),p.title,subboards[curlsub].name);
  303.     sysoplog(s);
  304.     outstr(get_string(673));
  305.     pl(subboards[curlsub].name);
  306.     if (xsubs[curlsub].num_nets) {
  307.       ++thisuser.postnet;
  308.       if (!(p.status & status_pending_net))
  309.         send_net_post(&p, subboards[curlsub].filename, curlsub);
  310.     }
  311.   }
  312. }
  313.  
  314.  
  315. void grab_user_name(messagerec *m, char *fn)
  316. {
  317.   char *ss,*ss1,*ss2;
  318.   long len;
  319.  
  320.   ss=readfile(m,fn,&len);
  321.   if (ss) {
  322.     ss1=strchr(ss,'\r');
  323.     if (ss1) {
  324.       *ss1=0;
  325.       ss2=ss;
  326.       if ((ss[0]=='`') && (ss[1]=='`')) {
  327.         for (ss1=ss+2; *ss1; ss1++) {
  328.           if ((ss1[0]=='`') && (ss1[1]=='`'))
  329.             ss2=ss1+2;
  330.         }
  331.         while (*ss2==' ')
  332.           ++ss2;
  333.       }
  334.       strcpy(net_email_name,ss2);
  335.     } else
  336.       net_email_name[0]=0;
  337.     bbsfree(ss);
  338.   } else
  339.     net_email_name[0]=0;
  340. }
  341.  
  342.  
  343. void scan(int msgnum, int optype, int *nextsub)
  344. {
  345.   char s[161],s1[81],*b,*ss1;
  346.  
  347.   char *fstr, ch, s2[81];
  348.   int fnd, sdir=1, lmt;
  349.   static char findstr[21];
  350.   int i,i1,i2,done,quit,abort,next,val,realexpress;
  351.   int title_lines;
  352.   slrec ss;
  353.   long len;
  354.   postrec p1, p2, *p3, *p4;
  355.   userrec tu;
  356.  
  357.   if (menu_on()) {
  358.     if (lcs())
  359.       printmenu(13);
  360.     else
  361.       printmenu(1);
  362.     cleared = NEEDCLEAR; //-1;
  363.   }
  364.   if (rip_on())
  365.     setmsgview(11);
  366.   irt[0]=0;
  367.   irt_name[0]=0;
  368.   done=0;
  369.   quit=0;
  370.   val=0;
  371.   realexpress=express;
  372.   iscan(cursub);
  373.   if (curlsub<0) {
  374.     nl();
  375.     pl(get_string(668));
  376.     nl();
  377.     return;
  378.   }
  379.   do {
  380.     tleft(1);
  381.     checkhangup();
  382.     if (xsubs[curlsub].num_nets)
  383.       set_net_num(xsubs[curlsub].nets[0].net_num);
  384.     else
  385.       set_net_num(0);
  386.     if (optype!=0)
  387.       resynch(cursub, &msgnum, NULL);
  388.     write_inst(INST_LOC_SUBS, usub[cursub].subnum, INST_FLAGS_NONE);
  389.     switch(optype) {
  390.       case 0: /* Read Prompt */
  391.         if (E_C) {
  392.           sprintf(s,"1%s0:7(11-%u,^%u7)1,? 0: 2",get_string(678),
  393.             nummsgs,msgnum);
  394.         } else {
  395.           sprintf(s,"%s:(1-%u,^%u),? :",get_string(678),
  396.             nummsgs,msgnum);
  397.         }
  398.         nl();
  399.         if (express) {
  400.           s[0]=0;
  401.           nln(2);
  402.         } else {
  403.           if (E_C) {
  404.             sprintf(s1,"7[1%s7] [1%s7]",usub[cursub].keys,
  405.               subboards[usub[cursub].subnum].name);
  406.           } else {
  407.             sprintf(s1,"[%s] [%s]",usub[cursub].keys,
  408.               subboards[usub[cursub].subnum].name);
  409.           }
  410.           ansic(2); pl(s1);
  411.           prt(2,s);
  412.           helpl=16;
  413.           input(s,5);
  414.           resynch(cursub, &msgnum, NULL);
  415.           while (s[0]==32) {
  416.             strcpy(s1,&(s[1]));
  417.             strcpy(s,s1);
  418.           }
  419.         }
  420.         optype=0;
  421.         i=atoi(s);
  422.         if (s[0]==0) {
  423.           i=msgnum+1;
  424.           if (i>=nummsgs+1)
  425.             done=1;
  426.         }
  427.         if ((i!=0) && (i<=nummsgs) && (i>=1)) {
  428.           optype=2;
  429.           msgnum=i;
  430.         } else
  431.           if (s[1]==0) {
  432.             switch(s[0]) {
  433.  
  434.               /* Find addition */
  435.               case 'F':
  436.                 abort=0;
  437.                 if (!(g_flags & g_flag_made_find_str)) {
  438.                   fstr=strupr(stripcolors(get_post(msgnum)->title));
  439.                   strncpy(findstr, fstr, sizeof(findstr)-1);
  440.                   g_flags |= g_flag_made_find_str;
  441.                 } else
  442.                   fstr=&findstr[0];
  443.                 while (strncmp(fstr,"RE:",3)==0 || *fstr==' ') {
  444.                   if (*fstr==' ')
  445.                     fstr++;
  446.                   else
  447.                     fstr+=3;
  448.                 }
  449.                 if (strlen(fstr)>=20)
  450.                   fstr[20]=0;
  451.                 strncpy(findstr, fstr, sizeof(findstr)-1);
  452.                 nl();
  453.                 outstr(get_string(1619));
  454.                 outstr(fstr);
  455.                 outstr(get_string(1620));
  456.                 input(s1,20);
  457.                 if (!*s1)
  458.                   strncpy(s1,fstr,sizeof(s1)-1);
  459.                 else
  460.                   strncpy(findstr,s1,sizeof(findstr)-1);
  461.                 nl();
  462.                 prt(1,get_string(1511));
  463.                 s2[0]='Q';
  464.                 s2[1]=upcase(*get_string(1512));
  465.                 s2[2]=upcase(*get_string(1513));
  466.                 strcpy(&s2[3],"+-");
  467.                 ch=onek(s2);
  468.                 if (ch=='Q')
  469.                   break;
  470.                 fnd=0;
  471.                 i=msgnum;
  472.                 nl();
  473.                 ansic(1);
  474.                 npr(get_string(1514));
  475.                 ansic(2);
  476.  
  477.                 /* Store search direction and limit */
  478.                 if (ch=='-' || ch==upcase(*get_string(1512))) {
  479.                   sdir=0;
  480.                   lmt=1;
  481.                 } else {
  482.                   sdir=1;
  483.                   lmt=nummsgs;
  484.                 }
  485.  
  486.                 while ((i!=lmt) && !abort && !hangup && !fnd) {
  487.                   if (!sdir)
  488.                     i--;
  489.                   else
  490.                     i++;
  491.                   checka(&abort,&next);
  492.                   if (!(i%5)) {
  493.                     npr("%5.5d",i);
  494.                     for (i1=0; i1<5; i1++)
  495.                       outstr("\b");
  496.                     if (!(i%100)) {
  497.                       tleft(1);
  498.                       checkhangup();
  499.                     }
  500.                   }
  501.                   b=strupr(readfile(&(get_post(i)->msg),subboards[curlsub].filename,&len));
  502.                   fnd=(strstr(strupr(stripcolors(get_post(i)->title)),s1) || strstr(b,s1));
  503.                   bbsfree(b);
  504.                 }
  505.                 if (fnd) {
  506.                   npr(get_string(1515));
  507.                   nl();
  508.                   msgnum=i;
  509.                   optype=2;
  510.                 } else {
  511.                   prt(6,get_string(1516));
  512.                   nl();
  513.                   optype=0;
  514.                 }
  515.                 break;
  516.               /* End of find addition */
  517.  
  518.               case 'Q':
  519.                 quit=1;
  520.                 done=1;
  521.                 *nextsub=0;
  522.                 break;
  523.               case 'B':
  524.                 if (*nextsub!=0) {
  525.                   *nextsub=1;
  526.                   done=1;
  527.                   quit=1;
  528.                 }
  529.                 break;
  530.               case 'T':
  531.                 optype=1;
  532.                 break;
  533.               case 'R':
  534.                 optype=2;
  535.                 break;
  536.               case 'A':
  537.                 if (rip_on()) {
  538.                   sprintf(s,"\n!|w000%c271610|e|#\r ", formery);
  539.                   comstr(s);
  540.                 }
  541.                 strcpy(irt_sub, subboards[usub[cursub].subnum].name);
  542.                 if ((get_post(msgnum)->ownersys) && (!get_post(msgnum)->owneruser))
  543.                   grab_user_name(&(get_post(msgnum)->msg),subboards[curlsub].filename);
  544.                 grab_quotes(&(get_post(msgnum)->msg),subboards[curlsub].filename);
  545.                 ss=syscfg.sl[actsl];
  546.                 if (get_post(msgnum)->status & status_post_new_net) {
  547.                   set_net_num(get_post(msgnum)->title[80]);
  548.                   if (get_post(msgnum)->title[80]==-1) {
  549.                     pl(get_string(679));
  550.                     break;
  551.                   }
  552.                 }
  553.                 if ((lcs()) || (ss.ability & ability_read_post_anony) || (get_post(msgnum)->anony==0))
  554.                   email(get_post(msgnum)->owneruser,get_post(msgnum)->ownersys,0,0);
  555.                 else
  556.                   email(get_post(msgnum)->owneruser,get_post(msgnum)->ownersys,0,get_post(msgnum)->anony);
  557.                 irt_sub[0]=0;
  558.                 grab_quotes(NULL, NULL);
  559.                 restore_msg_menu();
  560.                 break;
  561.               case 'P':
  562.                 irt[0]=0;
  563.                 irt_name[0]=0;
  564.               case 'W':
  565.                 if (rip_on()) {
  566.                   sprintf(s,"\n!|w000%c271610|e|#\r ", formery);
  567.                   comstr(s);
  568.                 }
  569.                 p2=*get_post(msgnum);
  570.                 grab_quotes(&(p2.msg),subboards[curlsub].filename);
  571.                 post();
  572.                 resynch(cursub, &msgnum, &p2);
  573.                 grab_quotes(NULL, NULL);
  574.                 restore_msg_menu();
  575.                 break;
  576.               case '?':
  577.                 if (lcs())
  578.                   printmenu(13);
  579.                 else
  580.                   printmenu(1);
  581.                 break;
  582.               case '-':
  583.                 if ((msgnum>1) && (msgnum-1<nummsgs)) {
  584.                   --msgnum;
  585.                   optype=2;
  586.                 }
  587.                 break;
  588.               case 'C':
  589.                 express=1;
  590.                 break;
  591. /*************/
  592.               case 'V':
  593.                 if ((cs()) && (get_post(msgnum)->ownersys==0) && (msgnum>0) && (msgnum<=nummsgs))
  594.                   valuser(get_post(msgnum)->owneruser);
  595.                 else
  596.                   if ((cs()) && (msgnum>0) && (msgnum<=nummsgs)) {
  597.                     nl();
  598.                     pl(get_string(680));
  599.                     nl();
  600.                   }
  601.                 break;
  602.               case 'N':
  603.                 if ((lcs()) && (msgnum>0) && (msgnum<=nummsgs)) {
  604.                   open_sub(1);
  605.                   resynch(cursub, &msgnum, NULL);
  606.                   p3=get_post(msgnum);
  607.                   p3->status ^= status_no_delete;
  608.                   write_post(msgnum, p3);
  609.                   close_sub();
  610.                   nl();
  611.                   if (p3->status & status_no_delete)
  612.                     pl(get_string(681));
  613.                   else
  614.                     pl(get_string(682));
  615.                   nl();
  616.                 }
  617.                 break;
  618.               case 'X':
  619.                 if ((lcs()) && (msgnum>0) && (msgnum<=nummsgs) &&
  620.                     (subboards[curlsub].anony & anony_val_net) &&
  621.                     (xsubs[curlsub].num_nets)) {
  622.                   open_sub(1);
  623.                   resynch(cursub, &msgnum, NULL);
  624.                   p3=get_post(msgnum);
  625.                   p3->status ^= status_pending_net;
  626.                   write_post(msgnum, p3);
  627.                   close_sub();
  628.                   nl();
  629.                   if (p3->status & status_pending_net) {
  630.                     val |= 2;
  631.                     pl(get_string(683));
  632.                   } else
  633.                     pl(get_string(684));
  634.                   nl();
  635.                 }
  636.                 break;
  637.               case 'U':
  638.                 if ((lcs()) && (msgnum>0) && (msgnum<=nummsgs)) {
  639.                   open_sub(1);
  640.                   resynch(cursub, &msgnum, NULL);
  641.                   p3=get_post(msgnum);
  642.                   p3->anony=0;
  643.                   write_post(msgnum, p3);
  644.                   close_sub();
  645.                   nl();
  646.                   pl(get_string(685));
  647.                 }
  648.                 break;
  649.               case 'D':
  650.                 if (lcs()) {
  651.                   if (msgnum) {
  652.                     open_sub(1);
  653.                     resynch(cursub, &msgnum, NULL);
  654.                     p2=*get_post(msgnum);
  655.                     delete(msgnum);
  656.                     close_sub();
  657.                     if (p2.ownersys==0) {
  658.                       read_user(p2.owneruser,&tu);
  659.                       if ((tu.inact & inact_deleted)==0) {
  660.                         if (date_to_daten(tu.firston) < p2.daten) {
  661.                           nl();
  662.                           prt(2,get_string(980));
  663.                           mpl(3);
  664.                           input(s1,3);
  665.                           if (s1[0])
  666.                             i1=(atoi(s1));
  667.                           else
  668.                             i1=1;
  669.                           if (i1>tu.msgpost)
  670.                             i1=tu.msgpost;
  671.                           if (i1)
  672.                             tu.msgpost-=i1;
  673.                           nl();
  674.                           ansic(3);
  675.                           outstr(get_string(993));
  676.                           pln(i1);
  677.                           tu.deletedposts++;
  678.                           write_user(p2.owneruser,&tu);
  679.                           topscreen();
  680.                         }
  681.                       }
  682.                     }
  683.                     resynch(cursub, &msgnum, &p2);
  684.                   }
  685.                 }
  686.                 break;
  687.               case 'E':
  688.                 if (so()) {
  689.                   if ((msgnum>0) && (msgnum<=nummsgs)) {
  690.                     b=readfile(&(get_post(msgnum)->msg),(subboards[curlsub].filename),&len);
  691.                     extract_out(b,len, get_post(msgnum)->title);
  692.                   }
  693.                 }
  694.                 break;
  695.               case 'M':
  696.                 if ((lcs()) && (msgnum>0) && (msgnum<=nummsgs)) {
  697.  
  698.                   tmp_disable_conf(1);
  699.                   nl();
  700.                   do {
  701.                     prt(2,get_string(686));
  702.                     ss1=mmkey(0);
  703.                     if (ss1[0]=='?') {
  704.                       sublist();
  705.                     }
  706.                   } while ((!hangup) && (ss1[0]=='?'));
  707.                   i=-1;
  708.                   if (ss1[0]==0) {
  709.                     tmp_disable_conf(0);
  710.                     break;
  711.                   }
  712.                   for (i1=0; (i1<num_subs) && (usub[i1].subnum!=-1); i1++)
  713.                     if (strcmp(usub[i1].keys,ss1)==0)
  714.                       i=i1;
  715.                   if (i!=-1) {
  716.                     if (actsl<subboards[usub[i].subnum].postsl) {
  717.                       nl();
  718.                       pl(get_string(1517));
  719.                       nl();
  720.                       i=-1;
  721.                     }
  722.                   }
  723.                   if (i!=-1) {
  724.  
  725.                     open_sub(1);
  726.                     resynch(cursub, &msgnum, NULL);
  727.                     p2=*get_post(msgnum);
  728.                     p1=p2;
  729.  
  730.                     b=readfile(&(p2.msg),(subboards[curlsub].filename),&len);
  731.                     delete(msgnum);
  732.                     if (msgnum>1)
  733.                       msgnum--;
  734.                     close_sub();
  735.  
  736.  
  737.                     iscan(i);
  738.                     open_sub(1);
  739.                     p2.msg.storage_type=subboards[curlsub].storage_type;
  740.                     savefile(b,len,&(p2.msg),(subboards[curlsub].filename));
  741.                     lock_status();
  742.                     p2.qscan=status.qscanptr++;
  743.                     save_status();
  744.                     if (nummsgs>=subboards[curlsub].maxmsgs) {
  745.                       i1=1;
  746.                       i2=0;
  747.                       while ((i2==0) && (i1<=nummsgs)) {
  748.                         if ((get_post(i1)->status & status_no_delete)==0)
  749.                           i2=i1;
  750.                         ++i1;
  751.                       }
  752.                       if (i2==0)
  753.                         i2=1;
  754.                       delete(i2);
  755.                     }
  756.                     if ((!(subboards[curlsub].anony & anony_val_net)) ||
  757.                         (!xsubs[curlsub].num_nets))
  758.                       p2.status &= ~status_pending_net;
  759.                     add_post(&p2);
  760.                     close_sub();
  761.                     tmp_disable_conf(0);
  762.                     iscan(cursub);
  763.                     nl();
  764.                     pl(get_string(687));
  765.                     nl();
  766.                     resynch(cursub, &msgnum, &p1);
  767.                   } else
  768.                     tmp_disable_conf(0);
  769.                 }
  770.                 break;
  771.               case 'L':
  772.                 if (!so())
  773.                   break;
  774.                 nl();
  775.                 prt(2,get_string(7));
  776.                 input(s,50);
  777.                 if (s[0]) {
  778.                   nl();
  779.                   prt(5,get_string(17));
  780.                   if (yn()) {
  781.                     nl();
  782.                     load_workspace(s,0);
  783.                   } else {
  784.                     nl();
  785.                     load_workspace(s,1);
  786.                   }
  787.                 }
  788.                 break;
  789. /*************/
  790.             }
  791.             restore_msg_menu();
  792.         } else {
  793.           if (strcmp(s,"CLS")==0)
  794.             outchr('\x0c');
  795.         }
  796.         break;
  797.       case 1: /* List Titles */
  798. #ifdef RIPDRIVE
  799.         rd_coff();
  800. #endif
  801.         i=0;
  802.         abort=0;
  803.         if (msgnum>=nummsgs)
  804.           abort=1;
  805.         else
  806.           nl();
  807.         title_lines=screenlinest-6;
  808.         if (title_lines<1)
  809.           title_lines=1;
  810.         while ((!abort) && (!hangup) && (++i<=title_lines)) {
  811.           ++msgnum;
  812.           p3=get_post(msgnum);
  813.           if ((p3->ownersys==0) && (p3->owneruser==usernum))
  814.             sprintf(s1,"7[1%d7]",msgnum);
  815.           else if (p3->ownersys!=0)
  816.             sprintf(s1,"7<1%d7>",msgnum);
  817.           else
  818.             sprintf(s1,"7(1%d7)",msgnum);
  819.           for (i1=0; i1<7; i1++)
  820.             s[i1]=32;
  821.           if (p3->qscan>qsc_p[curlsub])
  822.             s[0]='*';
  823.           if (p3->status & (status_pending_net | status_unvalidated))
  824.             s[0]='+';
  825.           strcpy(&s[9-strlen(stripcolors(s1))],s1);
  826.           strcat(s,"1 ");
  827.           if ((get_post(msgnum)->status&(status_unvalidated|status_delete))&&(!lcs()))
  828.             strcat(s,get_string(665));
  829.           else
  830.             strcat(s,stripcolors(get_post(msgnum)->title));
  831.  
  832.           if (thisuser.screenchars>=80) {
  833.             if (strlen(stripcolors(s))>50)
  834.               while (strlen(stripcolors(s))>50)
  835.                 s[strlen(s)-1]=0;
  836.             strcat(s,charstr(51-strlen(stripcolors(s)),' '));
  837.             if (okansi())
  838.               strcat(s,"7│1");
  839.             else
  840.               strcat(s,"|");
  841.             strcat(s," ");
  842.             if ((p3->anony & 0x0f) &&
  843.               ((syscfg.sl[actsl].ability & ability_read_post_anony)==0)) {
  844.                 strcat(s,get_string(482));
  845.             } else {
  846.               b=readfile(&(p3->msg),(subboards[curlsub].filename),
  847.                          &len);
  848.               if (b) {
  849.                 strncpy(s1,b,sizeof(s1)-1);
  850.                 s1[sizeof(s1)-1]=0;
  851.                 strcpy(b, stripcolors(s1));
  852.                 i1=0; strcpy(s1,"");
  853.                 while ((b[i1]!=13) && (b[i1]) && ((long)i1<len) &&
  854.                   (i1<(thisuser.screenchars-54)))
  855.                   s1[i1]=b[i1++];
  856.                 s1[i1]=0;
  857.                 strcat(s,s1);
  858.                 bbsfree(b);
  859.               }
  860.             }
  861.           }
  862.  
  863.           ansic(2);
  864.           pla(s,&abort);
  865.           if (msgnum>=nummsgs)
  866.             abort=1;
  867.         }
  868. #ifdef RIPDRIVE
  869.         rd_con();
  870. #endif
  871.         optype=0;
  872.         break;
  873.       case 2: /* Read Message */
  874. #ifdef RIPDRIVE
  875.         rd_coff();
  876. #endif
  877.         if ((msgnum>0) && (msgnum<=nummsgs))
  878.           read_message(msgnum,&next,&val);
  879.         ansic(0);
  880.         nl();
  881.         if (next) {
  882.           ++msgnum;
  883.           if (msgnum>nummsgs)
  884.             done=1;
  885.           optype=2;
  886.         } else
  887.           optype=0;
  888.         if (expressabort)
  889.           if (realexpress) {
  890.             done=1;
  891.             quit=1;
  892.             *nextsub=0;
  893.           } else {
  894.             expressabort=0;
  895.             express=0;
  896.             optype=0;
  897.           }
  898. #ifdef RIPDRIVE
  899.         rd_con();
  900. #endif
  901.         break;
  902.     }
  903.   } while ((!done) && (!hangup));
  904.   if (!realexpress) {
  905.     express=0;
  906.     expressabort=0;
  907.   }
  908.   if ((val & 1) && (lcs()) && (!express)) {
  909.     nl();
  910.     prt(5,get_string(688));
  911.     if (yn()) {
  912.       open_sub(1);
  913.       for (i=1; i<=nummsgs; i++) {
  914.         p3=get_post(i);
  915.         if (p3->status & (status_unvalidated | status_delete))
  916.           p3->status &= (~(status_unvalidated | status_delete));
  917.           write_post(i, p3);
  918.       }
  919.       close_sub();
  920.     }
  921.   }
  922.   if ((val & 2) && (lcs()) && (!express)) {
  923.     nl();
  924.     prt(5,get_string(689));
  925.     if (yn()) {
  926.       open_sub(1);
  927.       i2=0;
  928.       for (i=1; i<=nummsgs; i++) {
  929.         if (get_post(i)->status & status_pending_net) {
  930.           i2++;
  931.         }
  932.       }
  933.       p3=(postrec *)malloca(i2*sizeof(postrec));
  934.       if (p3) {
  935.         i2=0;
  936.         for (i=1; i<=nummsgs; i++) {
  937.           p4=get_post(i);
  938.           if (p4->status & status_pending_net) {
  939.             p3[i2++]=*p4;
  940.             p4->status &= ~status_pending_net;
  941.             write_post(i, p4);
  942.           }
  943.         }
  944.  
  945.         close_sub();
  946.  
  947.         i1=0;
  948.         for (i=0; i<i2; i++) {
  949.           send_net_post(p3+i, subboards[curlsub].filename, curlsub);
  950.           i1++;
  951.         }
  952.  
  953.         bbsfree(p3);
  954.       } else
  955.         close_sub();
  956.  
  957.       nl();
  958.       npr("%d",i1);
  959.       pl(get_string(690));
  960.       nl();
  961.     }
  962.   }
  963.   if ((!quit) && (!express)) {
  964.     nl();
  965.     ss=syscfg.sl[actsl];
  966.     if (
  967.         ((restrict_post & thisuser.restrict)==0) &&
  968.         (thisuser.posttoday<ss.posts) &&
  969.         (actsl>=subboards[curlsub].postsl)) {
  970.       sprintf(s,"%s %s? ",get_string(691), subboards[curlsub].name);
  971.       prt(5,s);
  972.       irt[0]=0;
  973.       irt_name[0]=0;
  974.       grab_quotes(NULL, NULL);
  975.       if (yn()) {
  976.         post();
  977.       }
  978.     }
  979.   }
  980.   nl();
  981. }
  982.  
  983.  
  984. void qscan(int bn, int *ns)
  985. {
  986.   int i,nextsub,os,sn;
  987.   char s[81];
  988.   unsigned long qscnptrx,sd;
  989.  
  990.   sn=usub[bn].subnum;
  991.   g_flags &= ~g_flag_made_find_str;
  992.  
  993.   if ((hangup) || (sn<0))
  994.     return;
  995.  
  996.   nl();
  997.  
  998.   qscnptrx=qsc_p[sn];
  999.  
  1000.   if (!sub_dates[sn])
  1001.     iscan1(sn, 1);
  1002.  
  1003.   sd=sub_dates[sn];
  1004.   if ((!sd) || (sd>qscnptrx)) {
  1005.     nextsub=*ns;
  1006.     os=cursub;
  1007.     cursub=bn;
  1008.  
  1009.     if (!iscan(cursub)) {
  1010.       nl();
  1011.       pl(get_string(1195));
  1012.       return;
  1013.     }
  1014.     qscnptrx=qsc_p[sn];
  1015.  
  1016.     sprintf(s,"< %s %s %s - %u %s >",get_string(692), subboards[curlsub].name,
  1017.               usub[cursub].keys,nummsgs, get_string(1518));
  1018.     prt(1,s);
  1019.     nl();
  1020.  
  1021.     for (i=nummsgs; (i>1) && (get_post(i-1)->qscan>qscnptrx); i--)
  1022.       ;
  1023.  
  1024.     if ((nummsgs>0) && (i<=nummsgs) && (get_post(i)->qscan>qsc_p[curlsub])) {
  1025.       scan(i,2,&nextsub);
  1026.     } else {
  1027.       read_status();
  1028.       qsc_p[curlsub]=status.qscanptr-1;
  1029.     }
  1030.  
  1031.     cursub=os;
  1032.     *ns=nextsub;
  1033.     sprintf(s,"< %s %s >",subboards[curlsub].name, get_string(693));
  1034.     prt(1,s);
  1035.   } else {
  1036.     sprintf(s,"< %s %s %s >",get_string(694), subboards[sn].name, usub[bn].keys);
  1037.     prt(1,s);
  1038.   }
  1039.   nl();
  1040. }
  1041.  
  1042.  
  1043. void nscan(int ss)
  1044. {
  1045.   int i,nextsub,abort,next;
  1046.  
  1047.   nl();
  1048.   nextsub=1;
  1049.  
  1050.   prt(3,get_string(695));
  1051.   nl();
  1052.   for (i=ss; (usub[i].subnum!=-1) && (i<num_subs) && (nextsub) && (!hangup); i++) {
  1053.     if (qsc_q[usub[i].subnum/32]&(1L<<(usub[i].subnum%32)))
  1054.       qscan(i,&nextsub);
  1055.     abort=next=0;
  1056.     checka(&abort,&next);
  1057.     if (abort)
  1058.       nextsub=0;
  1059.   }
  1060.   nl();
  1061.   prt(3,get_string(696));
  1062.   nln(2);
  1063.   if ((nextsub) && (thisuser.sysstatus & sysstatus_nscan_file_system) &&
  1064.     ((syscfg.sysconfig & sysconfig_no_xfer)==0) &&
  1065.     (!(g_flags & g_flag_scanned_files))) {
  1066.     g_flags |= g_flag_scanned_files;
  1067.     abort=0;
  1068.     lines_listed=0;
  1069.     tagging=1;
  1070.     tmp_disable_conf(1);
  1071.     nscanall();
  1072.     tmp_disable_conf(0);
  1073.     tagging=0;
  1074.   }
  1075. }
  1076.  
  1077.  
  1078.  
  1079. void scan2(void)
  1080. {
  1081.   char s[81];
  1082.   int i,i1;
  1083.  
  1084.   if (!iscan(cursub)) {
  1085.     nl();
  1086.     pl(get_string(1195));
  1087.     return;
  1088.   }
  1089.   nl();
  1090.   if (curlsub<0) {
  1091.     pl(get_string(668));
  1092.     nl();
  1093.     return;
  1094.   }
  1095.   npr("%d",nummsgs);
  1096.   outstr(get_string(697));
  1097.   pl(subboards[curlsub].name);
  1098.   if (nummsgs==0)
  1099.     return;
  1100.   helpl=11;
  1101.   prt(2,get_string(698));
  1102.   input(s,5);
  1103.   i=atoi(s);
  1104.   if (i<1)
  1105.     i=0;
  1106.   else
  1107.     if (i>nummsgs)
  1108.       i=nummsgs;
  1109.     else
  1110.       i--;
  1111.   i1=0;
  1112.   if (strcmp(s,"S")==0)
  1113.     scan(0,0,&i1);
  1114.   else
  1115.     if (strcmp(s,"Q")) {
  1116.       if (strcmp(s,"N")==0) {
  1117.       } else
  1118.         scan(i,1,&i1);
  1119.     }
  1120. }
  1121.  
  1122.  
  1123. void printmenu(int i)
  1124. {
  1125.   char s[81],s1[81],s2[81], ch;
  1126.   int next, cnt;
  1127.   messagerec m;
  1128.  
  1129.   next=0;
  1130.  
  1131.   ripcode = 0;
  1132.   tmp_disable_pause(1);
  1133.   if (rip_on() == 0 || ((sysstatus_expert & thisuser.sysstatus) && useron))
  1134.     goto normalmenu;
  1135.  
  1136.   if (rip_subset) {
  1137.     for (cnt = 0; cnt < sizeof(menus3)/sizeof(menus3[0]); cnt++)
  1138.       if (menus3[cnt].menu_num == i) {
  1139.         sprintf(s,"%sMENUSSOF.MSG",languagedir);
  1140.         if (!exist(s))
  1141.           sprintf(s,"%sMENUSSOF.MSG", syscfg.gfilesdir);
  1142.         m.stored_as = menus3[cnt].stored_as;
  1143.         m.storage_type = 255; //menus3[cnt].storage_type;
  1144.         ripcode = 1;
  1145.         if (m.stored_as)
  1146.           read_message1(&m,0,0,&next,s);
  1147.         break;
  1148.       }
  1149.     if (ripcode == 0)       //cnt >= sizeof(menus3)/sizeof(menus3[0]))
  1150.       goto normalmenu;
  1151.   } else {
  1152.     if (strcmp(ripext, "REM") == 0) {
  1153.       if (incom) {
  1154.         while (inkey());            /* Eat any extra junk */
  1155.         /* Check for file on user's machine */
  1156.         sprintf(s, "|1F000000MENU%u.MN%c|#\r ", i, user_menus);
  1157.         comstr(s);
  1158.         do {
  1159.           ch = delaykey(1);
  1160.         } while ((ch != '1') && (ch != '0') && (!hangup));
  1161.       } else {
  1162.         sprintf(s, "%smenu%d.mn%c", sysinfo.ripdir, i, user_menus);
  1163.         ch = (exist(s)) ? '1' : '0';
  1164.       }
  1165.     }
  1166.     if (hangup)
  1167.       return;
  1168.     if ((strcmp(ripext, "REM") == 0) && (ch == '1')) {
  1169.       sprintf(s, "|1R00000000MENU%d.MN%c\r ", i, user_menus);
  1170.       remstr(s);
  1171. #ifdef RIPDRIVE
  1172.       if (rd_on()) {
  1173.         sprintf(s, "%sMENU%d.MN%c", sysinfo.ripdir, i, user_menus);
  1174.         rd_print(s);
  1175.       }
  1176. #endif
  1177.     } else if (strcmp(ripext, "RIP") != 0) {
  1178.       //sprintf(s1,"MENU%u.", i);
  1179.       //if (strcmp(ripext,"REM") == 0)
  1180.       //  strcat (s1, ripext);
  1181.       //else
  1182.             sprintf(s1,"MENU%u.MN%c", i, user_menus);
  1183.       sprintf(s,"%s%s",sysinfo.ripdir,s1);
  1184.       if (exist(s) || i >= 300) {
  1185.         ripcode = 1;
  1186.         maybeprint(s, 2);
  1187.       } else
  1188.         goto normalmenu;
  1189.     } else {
  1190.       for (cnt = 0; cnt < sizeof(menusl)/sizeof(menusl[0]); cnt++)
  1191.         if (menusl[cnt].menu_num == i) {
  1192.           sprintf(s,"%sMENUSLCL.MSG",languagedir);
  1193.           if (!exist(s))
  1194.             sprintf(s,"%sMENUSLCL.MSG", syscfg.gfilesdir);
  1195.           m.stored_as = menusl[cnt].stored_as;
  1196.           m.storage_type = 255; //menusl[cnt].storage_type;
  1197.           ripcode = 1;
  1198.           if (m.stored_as)
  1199.             read_message1(&m,0,0,&next,s);
  1200.           break;
  1201.         }
  1202.       if (ripcode == 0)
  1203.         goto normalmenu;
  1204.     }
  1205.   }
  1206. #ifdef RIPDRIVE
  1207.   if (rd_on() == 0)
  1208. #endif
  1209.     printf("[Menu %d]\r", i);
  1210.   ripcode = 0;
  1211.   tmp_disable_pause(0);
  1212.   return;
  1213. normalmenu:
  1214.   tmp_disable_pause(0);
  1215. #ifdef RIPDRIVE
  1216.   rd_coff();
  1217. #endif
  1218.   if ((thisuser.sysstatus & (sysstatus_color | sysstatus_ansi))
  1219.       == (sysstatus_color | sysstatus_ansi)) {
  1220.     sprintf(s1,"MENU%u.ANS", i);
  1221.     sprintf(s,"%s%s",languagedir,s1);
  1222.     sprintf(s2,"%s%s",syscfg.gfilesdir, s1);
  1223.     if (exist(s) || exist(s2)) {
  1224.       printfile(s1);
  1225. #ifdef RIPDRIVE
  1226.       rd_con();
  1227. #endif
  1228.       return;
  1229.     }
  1230.   }
  1231.   sprintf(s1,"MENU%u.MSG", i);
  1232.   sprintf(s,"%s%s",languagedir,s1);
  1233.   sprintf(s2,"%s%s",syscfg.gfilesdir,s1);
  1234.   if (exist(s) || exist(s2)) {
  1235.     printfile(s1);
  1236. #ifdef RIPDRIVE
  1237.     rd_con();
  1238. #endif
  1239.     return;
  1240.   }
  1241.  
  1242. #define VALIDM(m,n) ((n>=0) && (n<(sizeof(m)/sizeof(m[0]))) && (m[n].stored_as))
  1243.  
  1244.   if ((thisuser.screenchars==40) && VALIDM(menus2,i)) {
  1245.     sprintf(s,"%sMENUS40.MSG",languagedir);
  1246.     if (!exist(s))
  1247.       sprintf(s,"%sMENUS40.MSG", syscfg.gfilesdir);
  1248.     read_message1(&menus2[i],0,0,&next,s);
  1249.   } else
  1250.     if ((okansi()) && VALIDM(menus1,i)) {
  1251.       sprintf(s,"%sMENUSANS.MSG",languagedir);
  1252.       if (!exist(s))
  1253.         sprintf(s,"%sMENUSANS.MSG", syscfg.gfilesdir);
  1254.       read_message1(&menus1[i],0,0,&next,s);
  1255.     } else {
  1256.       sprintf(s,"%sMENUS.MSG",languagedir);
  1257.       if (!exist(s))
  1258.         sprintf(s,"%sMENUS.MSG",syscfg.gfilesdir);
  1259.       if (VALIDM(menus,i))
  1260.         read_message1(&menus[i],0,0,&next,s);
  1261.     }
  1262. #ifdef RIPDRIVE
  1263.   rd_con();
  1264. #endif
  1265. }
  1266.  
  1267.  
  1268. void delmail(int f, int loc)
  1269. {
  1270.   mailrec m,m1;
  1271.   userrec u;
  1272.   int rm,i,t,otf;
  1273.  
  1274.   sh_lseek(f,((long) loc) * ((long) sizeof(mailrec)), SEEK_SET);
  1275.   sh_read(f,(void *)&m,sizeof(mailrec));
  1276.  
  1277.   if ((m.touser==0) && (m.tosys==0))
  1278.     return;
  1279.  
  1280.   rm=1;
  1281.   if (m.status & status_multimail) {
  1282.     t=filelength(f)/sizeof(mailrec);
  1283.     otf=0;
  1284.     for (i=0; i<t; i++)
  1285.       if (i!=loc) {
  1286.         sh_lseek(f,((long)i)*((long)sizeof(mailrec)),SEEK_SET);
  1287.         sh_read(f,(void *)&m1,sizeof(mailrec));
  1288.         if ((m.msg.stored_as==m1.msg.stored_as) && (m.msg.storage_type==m1.msg.storage_type) && (m1.daten!=0xffffffff))
  1289.           otf=1;
  1290.       }
  1291.     if (otf)
  1292.       rm=0;
  1293.   }
  1294.  
  1295.   if (rm)
  1296.     remove_link(&m.msg,"EMAIL");
  1297.  
  1298.   if (m.tosys==0) {
  1299.     read_user(m.touser,&u);
  1300.     if (u.waiting) {
  1301.       --u.waiting;
  1302.       write_user(m.touser,&u);
  1303.     }
  1304.     if (m.touser==1)
  1305.       --fwaiting;
  1306.   }
  1307.  
  1308.   sh_lseek(f,((long) loc) * ((long) sizeof(mailrec)), SEEK_SET);
  1309.   m.touser=0;
  1310.   m.tosys=0;
  1311.   m.daten=0xffffffff;
  1312.   m.msg.storage_type=0;
  1313.   m.msg.stored_as=0xffffffff;
  1314.   sh_write(f,(void *)&m,sizeof(mailrec));
  1315.   mailcheck=1;
  1316. }
  1317.  
  1318. void remove_post(void)
  1319. {
  1320.   int i,any,abort;
  1321.   char s[161];
  1322.   userrec tu;
  1323.  
  1324.   if (!iscan(cursub)) {
  1325.     nl();
  1326.     pl(get_string(1195));
  1327.     return;
  1328.   }
  1329.   if (curlsub<0) {
  1330.     nl();
  1331.     pl(get_string(668));
  1332.     nl();
  1333.     return;
  1334.   }
  1335. #ifdef RIPDRIVE
  1336.   rd_coff();
  1337. #endif
  1338.   any=0;
  1339.   abort=0;
  1340.   nln(2);
  1341.   outstr(get_string(723));
  1342.   pl(subboards[curlsub].name);
  1343.   nl();
  1344.   for (i=1; (i<=nummsgs) && (!abort); i++) {
  1345.     if ((get_post(i)->ownersys==0) && (get_post(i)->owneruser==usernum)) {
  1346.       any=1;
  1347.       sprintf(s,"%u: %s",i,get_post(i)->title);
  1348.       pla(s,&abort);
  1349.     }
  1350.   }
  1351. #ifdef RIPDRIVE
  1352.   rd_con();
  1353. #endif
  1354.   if (!any) {
  1355.     pl(get_string(5));
  1356.     if (!cs())
  1357.       return;
  1358.   }
  1359.   nl();
  1360.   prt(2,get_string(724));
  1361.   input(s,5);
  1362.   i=atoi(s);
  1363.   open_sub(1);
  1364.   if ((i>0) && (i<=nummsgs)) {
  1365.     if (((get_post(i)->ownersys==0) && (get_post(i)->owneruser==usernum)) || (lcs())) {
  1366.       if ((get_post(i)->owneruser==usernum) && (get_post(i)->ownersys==0)) {
  1367.         read_user(get_post(i)->owneruser,&tu);
  1368.         if ((tu.inact & inact_deleted)==0) {
  1369.           if (date_to_daten(tu.firston) < get_post(i)->daten) {
  1370.             if (tu.msgpost) {
  1371.               tu.msgpost--;
  1372.               write_user(get_post(i)->owneruser,&tu);
  1373.             }
  1374.           }
  1375.         }
  1376.       }
  1377.       sprintf(s,get_stringx(1,39),get_post(i)->title,subboards[curlsub].name);
  1378.       sysoplog(s);
  1379.       delete(i);
  1380.       nl();
  1381.       pl(get_string(725));
  1382.       nl();
  1383.     }
  1384.   }
  1385.   close_sub();
  1386. }
  1387.  
  1388.  
  1389.  
  1390. int external_edit(char *fn1, char *direc, int ednum, int numlines, char *dest, char *title, int flags)
  1391. {
  1392.   char s[255],s1[161],fn[128],s3[81],sx1[21],sx2[21],sx3[21],cdir1[81];
  1393.   int i,filethere,mod,newtl;
  1394.   struct ftime ftimep,ftimep1;
  1395.   FILE *f;
  1396.  
  1397.  
  1398.   if ((ednum>=numed) || (!okansi())) {
  1399.     nl();
  1400.     pl(get_string(726));
  1401.     nl();
  1402.     return(0);
  1403.   }
  1404.   if (incom)
  1405.     strcpy(s1,(editors[ednum].filename));
  1406.   else
  1407.     strcpy(s1,(editors[ednum].filenamecon));
  1408.   if (s1[0]==0) {
  1409.     nl();
  1410.     pl(get_string(726));
  1411.     nl();
  1412.     return(0);
  1413.   }
  1414.  
  1415.   make_abs_cmd(s1);
  1416.  
  1417.   get_dir(cdir1,0);
  1418.   cd_to(direc);
  1419.  
  1420.   _chmod("editor.inf",1,0);
  1421.   unlink("editor.inf");
  1422.   _chmod("result.ed",1,0);
  1423.   unlink("result.ed");
  1424.  
  1425.   strcpy(s3,fn1);
  1426.   stripfn1(s3);
  1427.   if (direc[0]) {
  1428.     cd_to(direc);
  1429.     get_dir(fn,1);
  1430.     cd_to(direc);
  1431.   } else
  1432.     fn[0]=0;
  1433.   strcat(fn,s3);
  1434.   filethere=exist(fn);
  1435.   if (filethere) {
  1436.     i=sh_open1(fn,O_RDONLY | O_BINARY);
  1437.     getftime(i,&ftimep);
  1438.     sh_close(i);
  1439.   }
  1440.   itoa(thisuser.screenchars,sx1,10);
  1441.   if (screenlinest>defscreenbottom-topline)
  1442.     newtl=0;
  1443.   else
  1444.     newtl=topline;
  1445.   if (using_modem)
  1446.     itoa(thisuser.screenlines,sx2,10);
  1447.   else
  1448.     itoa(defscreenbottom+1-newtl,sx2,10);
  1449.   itoa(numlines,sx3,10);
  1450.   stuff_in(s,s1,fn,sx1,sx2,sx3,"");
  1451.  
  1452.   if ((f=fsh_open("EDITOR.INF","wt"))!=NULL) {
  1453.     if (irt_name[0])
  1454.       flags |= 2;
  1455.     if (irt[0])
  1456.       flags |= 4;
  1457.     fprintf(f,"%s\n%s\n%u\n%s\n%s\n%u\n%u\n%u\n%u\n",
  1458.       title,
  1459.       dest,
  1460.       usernum,
  1461.       thisuser.name,
  1462.       thisuser.realname,
  1463.       thisuser.sl,
  1464.       flags,
  1465.       topline,
  1466.       thisuser.language);
  1467.     fsh_close(f);
  1468.   }
  1469.   if (flags&1) {
  1470.     /* disable tag lines */
  1471.     f=fsh_open("disable.tag","w");
  1472.     if (f>0) fsh_close(f);
  1473.   } else {
  1474.     unlink("disable.tag");
  1475.   }
  1476.   if (!irt[0]) {
  1477.     unlink("quotes.txt");
  1478.     unlink("quotes.ind");
  1479.   }
  1480.  
  1481.   in_fsed=1;
  1482. #ifdef RIPDRIVE
  1483.   if (rd_on()) {
  1484.     localrip_deactivate();
  1485.     prt(2,get_string(1006));
  1486.     mpl(60);
  1487.     pl(title);
  1488.   }
  1489. #endif
  1490.   extern_prog(s, sysinfo.spawn_opts[5]);
  1491. #ifdef RIPDRIVE
  1492.   if (rd_on()) {
  1493.     localrip_activate(sysinfo.ripdir, sysinfo.ripdir);
  1494.     sprintf(s,"%sEDIT%d.RIP",languagedir,thisuser.defed);
  1495.     if (exist(s)) {
  1496.       ripcode=1;
  1497.       maybeprint(s,2);
  1498.       ripcode=0;
  1499.     } else {
  1500.       rip_cls();
  1501.       printmenu(320);
  1502.     }
  1503.     prt(2,get_string(1006));
  1504.     mpl(60);
  1505.     pl(title);
  1506.   }
  1507. #endif
  1508.   cd_to(direc);
  1509.   in_fsed=0;
  1510.   unlink("editor.inf");
  1511.   unlink("disable.tag");
  1512.   if (!wfc)
  1513.     topscreen();
  1514.   mod=0;
  1515.   if (!filethere) {
  1516.     mod=exist(fn);
  1517.   } else {
  1518.     i=sh_open1(fn,O_RDONLY | O_BINARY);
  1519.     if (i>0) {
  1520.       getftime(i,&ftimep1);
  1521.       sh_close(i);
  1522.       if ((ftimep.ft_year!=ftimep1.ft_year) ||
  1523.           (ftimep.ft_month!=ftimep1.ft_month) ||
  1524.           (ftimep.ft_day!=ftimep1.ft_day) ||
  1525.           (ftimep.ft_hour!=ftimep1.ft_hour) ||
  1526.           (ftimep.ft_min!=ftimep1.ft_min) ||
  1527.           (ftimep.ft_tsec!=ftimep1.ft_tsec))
  1528.         mod=1;
  1529.     }
  1530.   }
  1531.   cd_to(cdir1);
  1532.   return(mod);
  1533. }
  1534.  
  1535. #define LINELEN 79
  1536.  
  1537. #define NL {if (!cp) fsh_write(pfx,1,pfxlen,f);fsh_write("\r\n",1,2,f); cp=ns=ctlc=0;}
  1538. #define FLSH {if (ss1) { if (cp && (l3+cp>=LINELEN)) NL else if (ns) cp+=fsh_write(" ",1,1,f);\
  1539.               if (!cp) {if (ctld) fprintf(f,"\x04%c",ctld);ctld=0;cp=fsh_write(pfx,1,pfxlen,f);}\
  1540.               fsh_write(ss1,1,l2,f); cp+=l3; ss1=NULL;l2=l3=0;ns=1;}}
  1541.  
  1542. void grab_quotes(messagerec *m, char *aux)
  1543. {
  1544.   char *ss,*ss1;
  1545.   long l,l1,l2,l3;
  1546.   FILE *f;
  1547.   char *pfx;
  1548.   int cp=0,ctla=0,ctlc=0,ns=0,ctld=0;
  1549.   int pfxlen;
  1550.   char q_txt[81],q_ind[81];
  1551.  
  1552.   sprintf(q_txt,"%squotes.txt",syscfgovr.tempdir);
  1553.   sprintf(q_ind,"%squotes.ind",syscfgovr.tempdir);
  1554.  
  1555.   _chmod(q_txt,1,0);
  1556.   unlink(q_txt);
  1557.   _chmod(q_ind,1,0);
  1558.   unlink(q_ind);
  1559.   if (quotes_nrm)
  1560.     bbsfree(quotes_nrm);
  1561.   if (quotes_ind)
  1562.     bbsfree(quotes_ind);
  1563.  
  1564.   quotes_nrm=quotes_ind=NULL;
  1565.   quotes_nrm_l=quotes_ind_l=0;
  1566.  
  1567.   if (m && aux) {
  1568.  
  1569.     pfx=get_stringx(1,102);
  1570.     pfxlen=strlen(pfx);
  1571.  
  1572.     ss=readfile(m, aux, &l);
  1573.  
  1574.     if (ss) {
  1575.       quotes_nrm=ss;
  1576.       quotes_nrm_l=l;
  1577.  
  1578.       f=fsh_open(q_txt, "wb");
  1579.       if (f) {
  1580.         fsh_write(ss, 1, l, f);
  1581.         fsh_close(f);
  1582.       }
  1583.  
  1584.       f=fsh_open(q_ind, "wb");
  1585.       if (f) {
  1586.         l3=l2=0;
  1587.         ss1=NULL;
  1588.         for (l1=0; l1<l; l1++) {
  1589.           if (ctld==-1)
  1590.             ctld=ss[l1];
  1591.           else switch(ss[l1]) {
  1592.             case 1:
  1593.               ctla=1;
  1594.               break;
  1595.             case 2:
  1596.               break;
  1597.             case 3:
  1598.               if (!ss1)
  1599.                 ss1=ss+l1;
  1600.               l2++;
  1601.               ctlc=1;
  1602.               break;
  1603.             case 4:
  1604.               ctld=-1;
  1605.               break;
  1606.             case '\n':
  1607.               if (ctla) {
  1608.                 ctla=0;
  1609.               } else {
  1610.                 FLSH;
  1611.                 NL;
  1612.               }
  1613.               break;
  1614.             case ' ':
  1615.             case '\r':
  1616.               if (ss1) {
  1617.                 FLSH;
  1618.               } else {
  1619.                 if (ss[l1]==' ') {
  1620.                   if (cp+1>=LINELEN)
  1621.                     NL;
  1622.                   if (!cp) {
  1623.                     if (ctld)
  1624.                       fprintf(f,"\x04%c",ctld);
  1625.                     ctld=0;
  1626.                     cp=fsh_write(pfx,1,pfxlen,f);
  1627.                   }
  1628.                   cp++;
  1629.                   fsh_write(" ",1,1,f);
  1630.                 }
  1631.               }
  1632.               break;
  1633.             default:
  1634.               if (!ss1)
  1635.                 ss1=ss+l1;
  1636.               l2++;
  1637.               if (ctlc)
  1638.                 ctlc=0;
  1639.               else
  1640.                 l3++;
  1641.               break;
  1642.           }
  1643.         }
  1644.         FLSH;
  1645.         if (cp)
  1646.           fsh_write("\r\n",1,2,f);
  1647.         fsh_close(f);
  1648. #ifdef SAVE_IN_MEM
  1649.         ff=sh_open1(q_ind,O_RDONLY|O_BINARY);
  1650.         if (ff>0) {
  1651.           quotes_ind_l=filelength(ff);
  1652.           quotes_ind=(char *)malloca(quotes_ind_l);
  1653.           if (quotes_ind) {
  1654.             sh_read(ff,quotes_ind, quotes_ind_l);
  1655.           } else
  1656.             quotes_ind_l=0;
  1657.           sh_close(ff);
  1658.         }
  1659. #else
  1660.         bbsfree(quotes_nrm);
  1661.         quotes_nrm=NULL;
  1662.         quotes_nrm_l=0;
  1663. #endif
  1664.       }
  1665.     }
  1666.   }
  1667. }
  1668.  
  1669.