home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / UTIL / WWIVSOR / MSGBASE.BAK < prev    next >
Text File  |  1996-12-04  |  48KB  |  2,060 lines

  1. #include "vars.h"
  2.  
  3. #pragma hdrstop
  4.  
  5. #include <mem.h>
  6. #include <errno.h>
  7. #include <io.h>
  8. #include "subxtr.h"
  9.  
  10. int hasrip=0;
  11. #ifdef RIPDRIVE
  12.   int special = 0;
  13.   char ripbuffer[255];
  14. #endif
  15.  
  16. #define ALLOW_FULLSCREEN 1
  17. #define EMAIL_STORAGE 2
  18.  
  19. /****************************************************************************/
  20. void describe_area_code(int areacode, char *description)
  21. {
  22.   int f,done=0,i;
  23.   char s[81],*ss,*ss1;
  24.  
  25.   description[0]=0;
  26.   sprintf(s,"%sREGIONS.DAT",syscfg.datadir);
  27.   f=sh_open1(s,O_RDONLY | O_BINARY);
  28.   if (f<1)
  29.     return;
  30.   ss=malloca(filelength(f));
  31.   i=sh_read(f,ss,filelength(f));
  32.   ss[i]=0;
  33.   sh_close(f);
  34.   ss1=strtok(ss,"\r\n");
  35.   while (ss1 && (!done)) {
  36.     i=atoi(ss1);
  37.     if (i) {
  38.       if (i==areacode)
  39.         done=1;
  40.     } else
  41.       strcpy(description,ss1);
  42.     ss1=strtok(NULL,"\r\n");
  43.   }
  44.  
  45.   bbsfree(ss);
  46. }
  47.  
  48.  
  49.  
  50. /****************************************************************************/
  51. static char origin_str[128];
  52. static char origin_str2[81];
  53.  
  54. void setorigin(int sysnum, int usernum)
  55. {
  56.   char s[81],s1[81],st[12];
  57.   net_system_list_rec *csne;
  58.  
  59.   if (net_num_max>1)
  60.     sprintf(s1,"%s - ",net_networks[net_num].name);
  61.   else
  62.     s1[0]=0;
  63.  
  64.   origin_str[0]=0;
  65.   origin_str2[0]=0;
  66.  
  67.   if (sysnum && (net_type == net_type_wwivnet)) {
  68.     csne=next_system(sysnum);
  69.     if (csne) {
  70.       strcpy(st,"");
  71.       if (usernum==1) {
  72.         if (csne->other & other_net_coord)
  73.           strcpy(st,get_string(1189));
  74.         else if (csne->other & other_group_coord)
  75.           sprintf(st,"{GC%d}",csne->group);
  76.         else if (csne->other & other_coordinator)
  77.           strcpy(st,get_string(1190));
  78.       }
  79.  
  80.       describe_area_code(atoi(csne->phone),s);
  81.       if (s[0]) {
  82.         sprintf(origin_str,"%s%s [%s] %s",s1,csne->name,csne->phone,st);
  83.         strcpy(origin_str2,s);
  84.       } else {
  85.         sprintf(origin_str,"%s%s [%s] %s",s1,csne->name,csne->phone,st);
  86.         strcpy(origin_str2,get_string(1007));
  87.       }
  88.     } else {
  89.       strcpy(origin_str,s1);
  90.       strcat(origin_str,get_string(622));
  91.       strcpy(origin_str2,get_string(1007));
  92.     }
  93.   }
  94. }
  95.  
  96.  
  97. int okfsed(void)
  98. {
  99.   int ok;
  100.  
  101.   ok=ALLOW_FULLSCREEN;
  102.   if (!okansi())
  103.     ok=0;
  104.   if (!thisuser.defed)
  105.     ok=0;
  106.   if (thisuser.defed>numed)
  107.     ok=0;
  108.   return(ok);
  109. }
  110.  
  111.  
  112. void remove_link(messagerec *m1, char *aux)
  113. {
  114.   messagerec m;
  115.   char s[81],s1[81];
  116.   int f;
  117.   long csec,nsec;
  118.  
  119.   m=*m1;
  120.   strcpy(s,syscfg.msgsdir);
  121.   switch(m.storage_type) {
  122.     case 0:
  123.     case 1:
  124.       ltoa(m.stored_as,s1,16);
  125.       if (m.storage_type==1) {
  126.         strcat(s,aux);
  127.         strcat(s,"\\");
  128.       }
  129.       strcat(s,s1);
  130.       unlink(s);
  131.       break;
  132.     case 2:
  133.       f=open_file(aux);
  134.       if (f>0) {
  135.         set_gat_section(f,(int) (m.stored_as/2048L));
  136.         csec=m.stored_as % 2048;
  137.         while ((csec>0) && (csec<2048)) {
  138.           nsec=(long) gat[csec];
  139.           gat[csec]=0;
  140.           csec=nsec;
  141.         }
  142.         save_gat(f);
  143.         sh_close(f);
  144.       }
  145.       break;
  146.     default:
  147.       /* illegal storage type */
  148.       break;
  149.   }
  150. }
  151.  
  152.  
  153. int open_file(char *fn)
  154. {
  155.   int f,i;
  156.   char s[81];
  157.  
  158.   read_status();
  159.  
  160.   sprintf(s,"%s%s.DAT",syscfg.msgsdir,fn);
  161.   f=sh_open1(s,O_RDWR | O_BINARY);
  162.   if (f<0) {
  163.     f=sh_open(s,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  164.     for (i=0; i<2048; i++)
  165.       gat[i]=0;
  166.     sh_write(f,(void *)gat,4096);
  167.     strcpy(gatfn,fn);
  168.     chsize(f,4096L + (75L * 1024L));
  169.     gat_section=0;
  170.   }
  171.   if (strcmp(gatfn,fn) || 1) {
  172.     sh_lseek(f,0L,SEEK_SET);
  173.     sh_read(f,(void *)gat,4096);
  174.     strcpy(gatfn,fn);
  175.     gat_section=0;
  176.   }
  177.   return(f);
  178. }
  179.  
  180. #define GATSECLEN (4096L+2048L*512L)
  181. #ifndef MSG_STARTING
  182. #define MSG_STARTING (((long)gat_section)*GATSECLEN + 4096L)
  183. #endif
  184.  
  185.  
  186. void set_gat_section(int f, int section)
  187. {
  188.   long l,l1;
  189.   int i;
  190.  
  191.   if (gat_section!=section) {
  192.     l=filelength(f);
  193.     l1=((long)section)*GATSECLEN;
  194.     if (l<l1) {
  195.       chsize(f,l1);
  196.       l=l1;
  197.     }
  198.     sh_lseek(f,l1,SEEK_SET);
  199.     if (l<(l1+4096L)) {
  200.       for (i=0; i<2048; i++)
  201.         gat[i]=0;
  202.       sh_write(f,(void *)gat, 4096);
  203.     } else {
  204.       sh_read(f,(void *)gat, 4096);
  205.     }
  206.     gat_section=section;
  207.   }
  208. }
  209.  
  210. void save_gat(int f)
  211. {
  212.   long l;
  213.  
  214.   l=((long)gat_section)*GATSECLEN;
  215.   sh_lseek(f,l,SEEK_SET);
  216.   sh_write(f,(void *)gat,4096);
  217.   lock_status();
  218.   status.filechange[filechange_posts]++;
  219.   save_status();
  220. }
  221.  
  222.  
  223. void savefile(char *b, long l1, messagerec *m1, char *aux)
  224. {
  225.   int f,gatp,i5,i4,gati[128],section;
  226.   messagerec m;
  227.   char s[81],s1[81];
  228.   long l2;
  229.  
  230.   m=*m1;
  231.   switch(m.storage_type) {
  232.     case 0:
  233.     case 1:
  234.       lock_status();
  235.       m.stored_as=status.qscanptr++;
  236.       save_status();
  237.       ltoa(m.stored_as,s1,16);
  238.       strcpy(s,syscfg.msgsdir);
  239.       if (m.storage_type==1) {
  240.         strcat(s,aux);
  241.         strcat(s,"\\");
  242.       }
  243.       strcat(s,s1);
  244.       f=sh_open(s,O_RDWR | O_CREAT | O_BINARY,S_IREAD | S_IWRITE);
  245.       sh_write(f, (void *)b,l1);
  246.       sh_close(f);
  247.       break;
  248.     case 2:
  249.       f=open_file(aux);
  250.       if (f>0) {
  251.         for (section=0; section<1024; section++) {
  252.           set_gat_section(f,section);
  253.           gatp=0;
  254.           i5=(int) ((l1 + 511L)/512L);
  255.           i4=1;
  256.           while ((gatp<i5) && (i4<2048)) {
  257.             if (gat[i4]==0)
  258.               gati[gatp++]=i4;
  259.             ++i4;
  260.           }
  261.           if (gatp>=i5) {
  262.             l2=MSG_STARTING;
  263.             gati[gatp]=-1;
  264.             for (i4=0; i4<i5; i4++) {
  265.               sh_lseek(f,l2 + 512L * (long)(gati[i4]),SEEK_SET);
  266.               sh_write(f,(void *)(&b[i4*512]),512);
  267.               gat[gati[i4]]=gati[i4+1];
  268.             }
  269.             save_gat(f);
  270.             break;
  271.           }
  272.         }
  273.         sh_close(f);
  274.       }
  275.       m.stored_as=((long) gati[0]) + ((long)gat_section)*2048L;
  276.       break;
  277.     case 255:
  278.       f=sh_open(aux,O_RDWR | O_CREAT | O_BINARY,S_IREAD | S_IWRITE);
  279.       sh_write(f, (void *)b,l1);
  280.       sh_close(f);
  281.       break;
  282.     default:
  283.       npr(get_stringx(1,36),m.storage_type);
  284.       break;
  285.   }
  286.   bbsfree((void *)b);
  287.   *m1=m;
  288. }
  289.  
  290.  
  291. char *readfile(messagerec *m1, char *aux, long *l)
  292. {
  293.   int f,csec;
  294.   long l1,l2;
  295.   char *b,s[81],s1[81];
  296.   messagerec m;
  297.  
  298.   *l=0L;
  299.   m=*m1;
  300.   switch(m.storage_type) {
  301.     case 0:
  302.     case 1:
  303.       strcpy(s,syscfg.msgsdir);
  304.       ltoa(m.stored_as,s1,16);
  305.       if (m.storage_type==1) {
  306.         strcat(s,aux);
  307.         strcat(s,"\\");
  308.       }
  309.       strcat(s,s1);
  310.       f=sh_open1(s,O_RDONLY | O_BINARY);
  311.       if (f==-1) {
  312.         *l=0L;
  313.         return(NULL);
  314.       }
  315.       l1=filelength(f);
  316.       if ((b=malloca(l1))==NULL) {
  317.         sh_close(f);
  318.         return(NULL);
  319.       }
  320.       sh_read(f,(void *)b,l1);
  321.       sh_close(f);
  322.       *l=l1;
  323.       break;
  324.     case 2:
  325.       f=open_file(aux);
  326.       set_gat_section(f,(int) (m.stored_as/2048L));
  327.       csec=m.stored_as % 2048;
  328.       l1=0;
  329.       while ((csec>0) && (csec<2048)) {
  330.         l1+=512L;
  331.         csec=gat[csec];
  332.       }
  333.       if (!l1) {
  334.         nl();
  335.         pl(get_string(623));
  336.         nl();
  337.         sh_close(f);
  338.         return(NULL);
  339.       }
  340.       if ((b=malloca(l1+3))==NULL) {
  341.         sh_close(f);
  342.         return(NULL);
  343.       }
  344.       csec=m.stored_as % 2048;
  345.       l1=0;
  346.       l2=MSG_STARTING;
  347.       while ((csec>0) && (csec<2048)) {
  348.         sh_lseek(f,l2 + 512L*((long)csec),SEEK_SET);
  349.         l1+=(long)sh_read(f,(void *)(&(b[l1])),512);
  350.         csec=gat[csec];
  351.       }
  352.       sh_close(f);
  353.       l2=l1-512;
  354.       while ((l2<l1) && (b[l2]!=26))
  355.         ++l2;
  356.       *l=l2;
  357.       b[l2+1]=0;
  358.       break;
  359.     case 255:
  360.       f=sh_open1(aux,O_RDONLY | O_BINARY);
  361.       if (f==-1) {
  362.         *l=0L;
  363.         return(NULL);
  364.       }
  365.       l1=filelength(f);
  366.       if ((b=malloca(l1+256L))==NULL) {
  367.         sh_close(f);
  368.         return(NULL);
  369.       }
  370.       sh_read(f,(void *)b,l1);
  371.       sh_close(f);
  372.       *l=l1;
  373.       break;
  374.     default:
  375.       /* illegal storage type */
  376.       *l=0L;
  377.       b=NULL;
  378.       break;
  379.   }
  380.   return(b);
  381. }
  382.  
  383.  
  384. void change_storage(messagerec *oldm, char *olda, messagerec *newm, char *newa)
  385. {
  386.   long len;
  387.   char *b;
  388.  
  389.   b=readfile(oldm,olda,&len);
  390.   remove_link(oldm,olda);
  391.   savefile(b,len,newm,newa);
  392. }
  393.  
  394.  
  395. void load_workspace(char *fnx, int no_edit)
  396. {
  397.   int i;
  398.   long l;
  399.   char *b,s[81];
  400.  
  401.   i=sh_open1(fnx,O_RDONLY | O_BINARY);
  402.   if (i<1) {
  403.     nl();
  404.     pl(get_string(89));
  405.     nl();
  406.     return;
  407.   }
  408.   l=filelength(i);
  409.   if ((b=malloca(l+1024))==NULL) {
  410.     sh_close(i);
  411.     return;
  412.   }
  413.   sh_read(i, (void *) b,l);
  414.   sh_close(i);
  415.   if (b[l-1]!=26)
  416.     b[l++]=26;
  417.   sprintf(s,"%sINPUT.MSG",syscfgovr.tempdir);
  418.   i=sh_open(s,O_RDWR | O_CREAT | O_BINARY,S_IREAD | S_IWRITE);
  419.   sh_write(i, (void *)b,l);
  420.   sh_close(i);
  421.   bbsfree(b);
  422.   if ((no_edit) || (!okfsed()))
  423.     use_workspace=1;
  424.   else
  425.     use_workspace=0;
  426.   nl();
  427.   pl(get_string(624));
  428.   nl();
  429.   if (!use_workspace)
  430.     pl(get_string(625));
  431. }
  432.  
  433.  
  434. void osan(char *s, int *abort, int *next)
  435. {
  436.   int i;
  437.   char ansicode[30];
  438.  
  439.   i=0;
  440.   checkhangup();
  441.   if (hangup)
  442.     *abort=1;
  443.   checka(abort,next);
  444. #ifdef RIPDRIVE
  445.   if (special) {    
  446.     while (s[i]) {
  447.       if (s[i] == 3) {                  // Interpret heart codes
  448.         strcat(ripbuffer, "\x1b[40m");
  449.         makeansi((thisuser.sysstatus & sysstatus_color) ?
  450.         thisuser.colors[s[++i] - '0'] :
  451.         thisuser.bwcolors[s[++i] - '0'],ansicode, 0);
  452.         strcat(ripbuffer, ansicode);
  453.       } else if (s[i] == 15) {
  454.         out_cport(s[i++]);
  455.         if (s[i] == 15) {
  456.           out_cport(s[i++]);
  457.           strcat(ripbuffer, interpret(s[i]));
  458.         }
  459.       } else {
  460.         ripbuffer[strlen(ripbuffer)+1] = 0;
  461.         ripbuffer[strlen(ripbuffer)] = s[i];
  462.       }
  463.       out_cport(s[i]);
  464.       if (s[i])
  465.         i++;
  466.       if (ripcode == 0) {           /* Don't allow abort of RIP menus; */
  467.         checka(abort,next);         /* can cause problems otherwise */
  468.         if (*abort)
  469.           break;
  470.       }
  471.     }
  472.   } else {
  473. #endif
  474.     while ((s[i]) && (!(*abort))) {
  475.       if (ripcode)
  476.         out_cport(s[i++]);
  477.       else {
  478.         outchr(s[i++]);
  479.         checka(abort,next);
  480.       }
  481.     }
  482. #ifdef RIPDRIVE
  483.   }
  484. #endif
  485. }
  486.  
  487.  
  488.  
  489. void addline(char *b, char *s, long *ll)
  490. {
  491.   strcpy(&(b[*ll]),s);
  492.   *ll +=strlen(s);
  493.   strcpy(&(b[*ll]),"\r\n");
  494.   *ll += 2;
  495. }
  496.  
  497.  
  498. #define LEN 161
  499.  
  500. void stuff(char *s, char *old, char *new)
  501. {
  502.   char s1[LEN],*ss;
  503.  
  504.   if (strlen(s)-strlen(old)+strlen(new)>=LEN)
  505.     return;
  506.   ss=strstr(s,old);
  507.   if (ss==NULL)
  508.     return;
  509.   ss[0]=0;
  510.   sprintf(s1,"%s%s%s",s,new,ss+strlen(old));
  511.   strcpy(s,s1);
  512. }
  513.  
  514. static char *preserve_lines[] = {
  515.   "0Usenet References:",
  516.   "0Usenet Message_ID:",
  517.   "0U_WWIV_Thread:",
  518. };
  519.  
  520. void inmsg(messagerec *m1, char *title, int *anony, int needtitle, char *aux, int fsed, char *dest, int flags)
  521. {
  522.   char s[181],s1[181],ro[81],fnx[81],chx,*ss,*ss1, fn1[81], fn2[81],*nd;
  523.   int maxli,curli,done,save,savel,i,i1,i2,i3,i4,i5,setanon,oiia;
  524.   messagerec m;
  525.   long ll,l1;
  526.   char *lin, *b;
  527.   int real_name=0;
  528.   FILE *result, *q_fp;
  529.   struct {char tlen, ttl[81], anon; } fedit_data;
  530.   xtrasubsnetrec *xnp;
  531.   char q_txt[256];
  532.  
  533.   oiia=iia;
  534.   setiia(0);
  535.  
  536.   if ((fsed!=0) && (!okfsed()))
  537.     fsed=0;
  538.   sprintf(fnx,"%sINPUT.MSG",syscfgovr.tempdir);
  539.   if (fsed)
  540.     fsed=1;
  541.   if (use_workspace) {
  542.     if (!exist(fnx))
  543.       use_workspace=0;
  544.     else
  545.       fsed=2;
  546.   }
  547.   if (menu_on()) {
  548.      rip_saveall();
  549.      if (fsed == 0)
  550.        printmenu(2);
  551.      else {
  552.        sprintf(s,"%sEDIT%d.RIP",languagedir,thisuser.defed);
  553.        ripcode = 1;
  554.        maybeprint(s,2);
  555.        ripcode = 0;
  556.      }
  557.      cleared = NEEDCLEAR;
  558.   }
  559.   done=0;
  560.   setanon=0;
  561.   save=0;
  562.   curli=0;
  563.   m=*m1;
  564.  
  565.   if (fsed) {
  566.     if (so())
  567.       maxli=120;
  568.     else if (cs())
  569.       maxli=100;
  570.     else
  571.       maxli=80;
  572.   } else {
  573.     if (actsl<45)
  574.       maxli=30;
  575.     else
  576.       if (actsl<60)
  577.         maxli=50;
  578.       else
  579.         if (actsl<80)
  580.           maxli=60;
  581.         else
  582.           maxli=80;
  583.   }
  584.   if (!fsed) {
  585.     if ((lin=malloca((long)(maxli+10)*LEN))==NULL) {
  586.       m1->stored_as=0xffffffff;
  587.       setiia(oiia);
  588.      if (menu_on())
  589.        rip_restoreall();
  590.       return;
  591.     }
  592.     for (i=0; i<maxli; i++)
  593.       lin[i*LEN]=0;
  594.     ro[0]=0;
  595.   }
  596.  
  597.   nl();
  598.   helpl=6;
  599.   if (okansi()) {
  600.     prt(2,get_string(1006));
  601.     mpl(60);
  602.     inputl(title,60);
  603.   } else {
  604.     pl(get_string(626));
  605.     outstr(get_string(1006));
  606.     inputl(title,60);
  607.   }
  608.   if ((title[0]==0) && (needtitle)) {
  609.     pl(get_string(14));
  610.     m.stored_as=0xffffffff;
  611.     *m1=m;
  612.     if (!fsed)
  613.       bbsfree((void *)lin);
  614.     setiia(oiia);
  615.     if (menu_on())
  616.       rip_restoreall();
  617.     return;
  618.   }
  619.  
  620.   if (!fsed) {
  621.     outstr(get_string(627));
  622.     pln(maxli);
  623.     pl(get_string(628));
  624.     strcpy(s,get_string(629));
  625.     s[thisuser.screenchars]=0;
  626.     pl(s);
  627.  
  628.     while (!done && !hangup) {
  629.       helpl=27;
  630.       while (inli2(s,ro,160,1,curli)) {
  631.         --curli;
  632.         strcpy(ro,&(lin[(curli)*LEN]));
  633.         if (strlen(ro)>thisuser.screenchars-1)
  634.           ro[thisuser.screenchars-2]=0;
  635.       }
  636.       if (hangup)
  637.         done=1;
  638.       savel=1;
  639.       if (s[0]=='/') {
  640.         if (stricmp(s,get_string(942))==0) {
  641.           savel=0;
  642.           printmenu(2);
  643.         }
  644.         if (stricmp(s,get_string(943))==0) {
  645.           savel=0;
  646.           if (okansi())
  647.             i1=0;
  648.           else {
  649.             prt(5,get_string(630));
  650.             i1=yn();
  651.           }
  652.           i2=0;
  653.           for (i=0; (i<curli) && (!i2); i++) {
  654.             if (i1)
  655.               npr("%d:\r\n",i+1);
  656.             strcpy(s1,&(lin[i*LEN]));
  657.             i3=strlen(s1);
  658.             if (s1[i3-1]==1)
  659.               s1[i3-1]=0;
  660.             if (s1[0]==2) {
  661.               strcpy(s1,&(s1[1]));
  662.               i5=0;
  663.               for(i4=0; i4<strlen(s1); i4++)
  664.                 if ((s1[i4]==8) || (s1[i4]==3))
  665.                   --i5;
  666.                 else
  667.                   ++i5;
  668.               for (i4=0; (i4<(thisuser.screenchars-i5)/2) && (!i2); i4++)
  669.                 osan(" ",&i2,&i1);
  670.             }
  671.             pla(s1,&i2);
  672.           }
  673.           if ((!okansi()) || i1) {
  674.             nl();
  675.             pl(get_string(631));
  676.           }
  677.         }
  678.         if ((stricmp(s,get_string(944))==0) || (stricmp(s,get_string(945))==0)) {
  679.           save=1;
  680.           done=1;
  681.           savel=0;
  682.         }
  683.         if ((stricmp(s,get_string(946))==0) || (stricmp(s,get_string(947))==0)) {
  684.           save=1;
  685.           done=1;
  686.           savel=0;
  687.           setanon=1;
  688.         }
  689.         if ((stricmp(s,get_string(948))==0) || (stricmp(s,get_string(949))==0)) {
  690.           save=1;
  691.           done=1;
  692.           savel=0;
  693.           setanon=-1;
  694.         }
  695.         if (stricmp(s,get_string(950))==0) {
  696.           done=1;
  697.           savel=0;
  698.         }
  699.         if (stricmp(s,get_string(951))==0) {
  700.           savel=0;
  701.           curli=0;
  702.           pl(get_string(632));
  703.           nl();
  704.         }
  705.         if (stricmp(s,get_string(952))==0) {
  706.           savel=0;
  707.           if (curli) {
  708.             --curli;
  709.             pl(get_string(633));
  710.           } else {
  711.             pl(get_string(634));
  712.           }
  713.         }
  714.         if (stricmp(s,get_string(953))==0) {
  715.           savel=0;
  716.           helpl=26;
  717.           if (okansi()) {
  718.             prt(2,get_string(326));
  719.             mpl(60);
  720.             inputl(title,60);
  721.           } else {
  722.             pl(get_string(626));
  723.             outstr(get_string(326));
  724.             inputl(title,60);
  725.           }
  726.           pl(get_string(631));
  727.           nl();
  728.         }
  729.         strcpy(s1,s);
  730.         s1[3]=0;
  731.         if (stricmp(s1,get_string(954))==0) {
  732.           s1[0]=2;
  733.           strcpy((&s1[1]),&(s[3]));
  734.           strcpy(s,s1);
  735.         }
  736.         if ((stricmp(s1,get_string(955))==0) && (s[3]=='/') && (curli)) {
  737.           strcpy(s1,&(s[4]));
  738.           ss=strstr(s1,"/");
  739.           if (ss) {
  740.             ss1=&(ss[1]);
  741.             ss[0]=0;
  742.             stuff(&(lin[(curli-1)*LEN]),s1,ss1);
  743.             pl(get_string(635));
  744.             pl(&(lin[(curli-1)*LEN]));
  745.             pl(get_string(956));
  746.           }
  747.           savel=0;
  748.         }
  749.       }
  750.       if (savel) {
  751.         strcpy(&(lin[(curli++)*LEN]),s);
  752.         if (curli==(maxli+1)) {
  753.           nl();
  754.           pl(get_string(636));
  755.           pl(get_string(957));
  756.           nl();
  757.           --curli;
  758.         } else if (curli==maxli) {
  759.           pl(get_string(637));
  760.         } else if ((curli+5)==maxli) {
  761.           pl(get_string(638));
  762.         }
  763.       }
  764.     }
  765.     if (curli==0)
  766.       save=0;
  767.   } else {
  768.     if (fsed==1) {
  769.       sprintf(fn1,"%sfedit.inf",syscfgovr.tempdir);
  770.       sprintf(fn2,"%sresult.ed",syscfgovr.tempdir);
  771.       _chmod(fn1,1,0);
  772.       unlink(fn1);
  773.       _chmod(fn2,1,0);
  774.       unlink(fn2);
  775.       fedit_data.tlen=60;
  776.       strcpy(fedit_data.ttl,title);
  777.       fedit_data.anon=0;
  778.       result=fsh_open(fn1,"wb");
  779.       if (result) {
  780.         fsh_write(&fedit_data, sizeof(fedit_data), 1, result);
  781.         fsh_close(result);
  782.       }
  783.       save=external_edit("INPUT.MSG",syscfgovr.tempdir,(int) (thisuser.defed)-1,
  784.         maxli, dest, title, flags);
  785.       if (save) {
  786.         if ((result=fsh_open(fn2,"rt"))!=NULL) {
  787.           if (fgets(s,80,result)) {
  788.             ss=strchr(s,'\n');
  789.             if (ss) *ss=0;
  790.             setanon=atoi(s);
  791.             if (fgets(title,80,result)) {
  792.               ss=strchr(title,'\n');
  793.               if (ss) *ss=0;
  794.               fsh_close(result);
  795.             }
  796.           }
  797.         } else if ((result=fsh_open(fn1,"rb"))!=NULL) {
  798.           if (fsh_read(&fedit_data, sizeof(fedit_data), 1, result)==1) {
  799.             strcpy(title,fedit_data.ttl);
  800.             setanon=fedit_data.anon;
  801.           }
  802.           fsh_close(result);
  803.         }
  804.       }
  805.       unlink(fn1);
  806.       unlink(fn2);
  807.     } else {
  808.       save=exist(fnx);
  809.       if (save) {
  810.         pl(get_string(639));
  811.       }
  812.       use_workspace=0;
  813.     }
  814.   }
  815.  
  816.  
  817.   if (save) {
  818.     switch(*anony) {
  819.       case 0: /* no anony */
  820.         *anony=0;
  821.         break;
  822.       case anony_enable_anony:
  823.         if (setanon) {
  824.           if (setanon==1)
  825.             *anony=anony_sender;
  826.           else
  827.             *anony=0;
  828.         } else {
  829.           prt(5,get_string(485));
  830.           if (yn())
  831.             *anony=anony_sender;
  832.           else
  833.             *anony=0;
  834.         }
  835.         break;
  836.       case anony_enable_dear_abby:
  837.         nl();
  838.         npr("1. %s\r\n",nam(&thisuser,usernum));
  839.         pl(get_string(640));
  840.         pl(get_string(641));
  841.         nl();
  842.         prt(5,get_string(297));
  843.         chx=onek("\r123");
  844.         switch(chx) {
  845.           case '\r':
  846.           case '1':
  847.             *anony=0;
  848.             break;
  849.           case '2':
  850.             *anony=anony_sender_da;
  851.             break;
  852.           case '3':
  853.             *anony=anony_sender_pp;
  854.         }
  855.         break;
  856.       case anony_force_anony:
  857.         *anony=anony_sender;
  858.         break;
  859.       case anony_real_name:
  860.         real_name=1;
  861.         *anony=0;
  862.         break;
  863.     }
  864.     outstr(get_string(91));
  865.     if (fsed) {
  866.       i5=sh_open1(fnx,O_RDONLY | O_BINARY);
  867.       l1=filelength(i5);
  868.     } else {
  869.       l1=0;
  870.       for (i5=0; i5<curli; i5++) {
  871.         l1 += strlen(&(lin[i5*LEN]));
  872.         l1 += 2;
  873.       }
  874.     }
  875.     l1 += 1024;
  876.     if ((b=malloca(l1))==NULL) {
  877.       sh_close(i5);
  878.       bbsfree(lin);
  879.       pl(get_string(642));
  880.       m1->stored_as=0xffffffff;
  881.       setiia(oiia);
  882.       if (menu_on())
  883.         rip_restoreall();
  884.       return;
  885.     }
  886.  
  887.     l1=0;
  888.     if (real_name)
  889.       addline(b,thisuser.realname,&l1);
  890.     else
  891.       addline(b,nam1(&thisuser,usernum,net_sysnum),&l1);
  892.     time(&ll);
  893.     strcpy(s,ctime(&ll));
  894.     s[strlen(s)-1]=0;
  895.     addline(b,s,&l1);
  896.  
  897.     sprintf(q_txt,"%squotes.txt",syscfgovr.tempdir);
  898.     q_fp=fsh_open(q_txt, "rt");
  899.     if (q_fp) {
  900.       while (fgets(q_txt, sizeof(q_txt)-1, q_fp)) {
  901.         ss1=strchr(q_txt,'\n');
  902.         if (ss1)
  903.           *ss1=0;
  904.         i3=0;
  905.         for (i4=0; i4<sizeof(preserve_lines)/sizeof(preserve_lines[0]); i4++) {
  906.           if (strncmp(preserve_lines[i4], q_txt, strlen(preserve_lines[i4]))==0) {
  907.             i3=1;
  908.             break;
  909.           }
  910.         }
  911.         if (i3) {
  912.           addline(b, q_txt, &l1);
  913.         }
  914.       }
  915.       fsh_close(q_fp);
  916.     }
  917.  
  918.     if (irt[0]) {
  919.       sprintf(s,"%s%s",get_string(940),irt);
  920.       addline(b,s,&l1);
  921.       if (irt_sub[0]) {
  922.         sprintf(s,"%s%s", get_string(1509), irt_sub);
  923.         addline(b,s,&l1);
  924.       }
  925.       if (irt_name[0]) {
  926.         sprintf(s,"%s%s",get_string(941),irt_name);
  927.         addline(b,s,&l1);
  928.       }
  929.       addline(b,"",&l1);
  930.     }
  931.  
  932.     if (fsed) {
  933.       ll=filelength(i5);
  934.       sh_read(i5, (void *) (& (b[l1]) ),ll);
  935.       l1 += ll;
  936.       sh_close(i5);
  937.     } else {
  938.       for (i5=0; i5<curli; i5++)
  939.         addline(b,&(lin[i5*LEN]),&l1);
  940.     }
  941.  
  942.     if (sysinfo.flags & OP_FLAGS_MSG_TAG) {
  943.       if ((xsubs[curlsub].num_nets) && (strcmp(aux,"EMAIL")!=0)
  944.           && (!(subboards[curlsub].anony & anony_no_tag))
  945.           && (strcmp(strupr(irt),strupr(get_string(333)))!=0)) {
  946.         for (i=0; i<xsubs[curlsub].num_nets; i++) {
  947.           xnp=&xsubs[curlsub].nets[i];
  948.           nd=net_networks[xnp->net_num].dir;
  949.           sprintf(s,"%s%s.TAG",nd,xnp->stype);
  950.           if (exist(s))
  951.             break;
  952.           sprintf(s,"%sGENERAL.TAG",nd);
  953.           if (exist(s))
  954.             break;
  955.           sprintf(s,"%s%s.TAG",syscfg.datadir,xnp->stype);
  956.           if (exist(s))
  957.             break;
  958.           sprintf(s,"%sGENERAL.TAG",syscfg.datadir);
  959.           if (exist(s))
  960.             break;
  961.         }
  962.         result=fsh_open(s,"rb");
  963.         if (result) {
  964.           i=0;
  965.           while (!feof(result)) {
  966.             s[0]=0; s1[0]=0;
  967.             fgets(s,180,result);
  968.             if (strlen(s)>1)
  969.               if (s[strlen(s)-2]==13)
  970.                 s[strlen(s)-2]=0;
  971.             if (s[0]!=4)
  972.               sprintf(s1,"%c%c%s",4,i+'2',s);
  973.             else
  974.               strncpy(s1,s,sizeof(s1));
  975.             if (!i)
  976.               addline(b,"1",&l1);
  977.             addline(b,s1,&l1);
  978.             if (i<7)
  979.               i++;
  980.           }
  981.           fsh_close(result);
  982.         }
  983.       }
  984.     }
  985.  
  986.     if (b[l1-1]!=26)
  987.       b[l1++]=26;
  988.     savefile(b,l1,&m,aux);
  989.     if (fsed)
  990.       unlink(fnx);
  991.   } else {
  992.     if (fsed)
  993.       unlink(fnx);
  994.     pl(get_string(14));
  995.     m.stored_as=0xffffffff;
  996.   }
  997.   *m1=m;
  998.   if (!fsed) {
  999.     bbsfree((void *)lin);
  1000.   }
  1001.   charbufferpointer=0;
  1002.   charbuffer[0]=0;
  1003.   setiia(oiia);
  1004.   if (menu_on())
  1005.     rip_restoreall();
  1006.   grab_quotes(NULL, NULL);
  1007. }
  1008.  
  1009.  
  1010.  
  1011. int forwardm(unsigned short *u, unsigned short *s)
  1012. {
  1013.   userrec ur;
  1014.   char *ss;
  1015.   int i,cu,nn;
  1016.  
  1017.   if (*s)
  1018.     return(0);
  1019.   read_user(*u,&ur);
  1020.   if (ur.inact & inact_deleted)
  1021.     return(0);
  1022.   if ((ur.forwardusr==0) && (ur.forwardsys==0))
  1023.     return(0);
  1024.   if (ur.forwardsys) {
  1025.     if ((ur.forwardusr>0) && (ur.forwardusr<32767)) {
  1026.       nn=net_num;
  1027.       set_net_num(ur.net_num);
  1028.       if (!valid_system(ur.forwardsys)) {
  1029.         set_net_num(nn);
  1030.         return(0);
  1031.       }
  1032.       *u=ur.forwardusr;
  1033.       *s=ur.forwardsys;
  1034.       return(1);
  1035.     } else {
  1036.       *u=0;
  1037.       *s=0;
  1038.       return(0);
  1039.     }
  1040.   }
  1041.   cu=ur.forwardusr;
  1042.   if (cu==-1) {
  1043.     pl(get_string(643));
  1044.     if (so()) {
  1045.       pl(get_string(644));
  1046.     } else {
  1047.       *u=0;
  1048.       *s=0;
  1049.     }
  1050.     return(0);
  1051.   }
  1052.   if ((ss=malloca((long) syscfg.maxusers+ 300L))==NULL)
  1053.     return(0);
  1054.   for (i=0; i<syscfg.maxusers+300; i++)
  1055.     ss[i]=0;
  1056.   ss[*u]=1;
  1057.   read_user(cu,&ur);
  1058.   while ((ur.forwardusr) || (ur.forwardsys)) {
  1059.     if (ur.forwardsys) {
  1060.       if (!valid_system(ur.forwardsys))
  1061.         return(0);
  1062.       *u=ur.forwardusr;
  1063.       *s=ur.forwardsys;
  1064.       bbsfree(ss);
  1065.       set_net_num(ur.net_num);
  1066.       return(1);
  1067.     }
  1068.     if (ss[cu]) {
  1069.       bbsfree(ss);
  1070.       return(0);
  1071.     }
  1072.     ss[cu]=1;
  1073.     if (ur.forwardusr==65535) {
  1074.       pl(get_string(643));
  1075.       if (so()) {
  1076.         pl(get_string(644));
  1077.         *u=cu;
  1078.         *s=0;
  1079.       } else {
  1080.         *u=0;
  1081.         *s=0;
  1082.       }
  1083.       bbsfree(ss);
  1084.       return(0);
  1085.     }
  1086.     cu=ur.forwardusr;
  1087.     read_user(cu,&ur);
  1088.   }
  1089.   bbsfree(ss);
  1090.   *s=0;
  1091.   *u=cu;
  1092.   return(1);
  1093. }
  1094.  
  1095.  
  1096. int open_email(int wrt)
  1097. {
  1098.   char s[100];
  1099.   int f,i;
  1100.  
  1101.   sprintf(s,"%sEMAIL.DAT", syscfg.datadir);
  1102.  
  1103.   for (i=0; i<5; i++) {
  1104.     if (wrt)
  1105.       f=sh_open(s, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  1106.     else
  1107.       f=sh_open1(s, O_RDONLY|O_BINARY);
  1108.     if ((f>0) || (errno!=EACCES))
  1109.       break;
  1110.     wait1(9);
  1111.   }
  1112.  
  1113.   return(f);
  1114. }
  1115.  
  1116. void sendout_email(char *title, messagerec *msg, int anony, unsigned un, unsigned sy, int an, unsigned uf, unsigned sf, int fwd, int fnn)
  1117. {
  1118.   mailrec m,m1;
  1119.   net_header_rec nh;
  1120.   int f,len,i,i1;
  1121.   char *b,*b1,s[256],s2[200],s1[200];
  1122.   long len1;
  1123.   userrec ur;
  1124.  
  1125.   strcpy(m.title, title);
  1126.   m.msg=*msg;
  1127.   m.anony=anony;
  1128.   if (sf == net_sysnum)
  1129.     m.fromsys=0;
  1130.   else
  1131.     m.fromsys=sf;
  1132.   m.fromuser=uf;
  1133.   m.tosys=sy;
  1134.   m.touser=un;
  1135.   m.status=0;
  1136.   time((long *)&(m.daten));
  1137.  
  1138.   if (m.fromsys && (net_num_max>1)) {
  1139.     m.status|=status_new_net;
  1140.     m.title[79]=0;
  1141.     m.title[80]=fnn;
  1142.   }
  1143.  
  1144.   if (sy==0) {
  1145.     f=open_email(1);
  1146.     if (f<0) {
  1147.       return;
  1148.     }
  1149.     len=(int) filelength(f)/sizeof(mailrec);
  1150.     if (len==0)
  1151.       i=0;
  1152.     else {
  1153.       i=len-1;
  1154.       sh_lseek(f,((long) (i))*(sizeof(mailrec)), SEEK_SET);
  1155.       sh_read(f,(void *)&m1,sizeof(mailrec));
  1156.       while ((i>0) && (m1.tosys==0) && (m1.touser==0)) {
  1157.         --i;
  1158.         sh_lseek(f,((long) (i))*(sizeof(mailrec)), SEEK_SET);
  1159.         i1=sh_read(f,(void *)&m1,sizeof(mailrec));
  1160.         if (i1==-1)
  1161.           pl(get_string(1193));
  1162.       }
  1163.       if ((m1.tosys) || (m1.touser))
  1164.         ++i;
  1165.     }
  1166.     sh_lseek(f,((long) (i))*(sizeof(mailrec)), SEEK_SET);
  1167.     i1=sh_write(f,(void *)&m,sizeof(mailrec));
  1168.     sh_close(f);
  1169.     if (i1==-1) {
  1170.       pl(get_string(1194));
  1171.     }
  1172.   } else {
  1173.     if ((b=readfile(&(m.msg),"EMAIL",&len1))==NULL)
  1174.       return;
  1175.     remove_link(&(m.msg),"EMAIL");
  1176.     nh.tosys=sy;
  1177.     nh.touser=un;
  1178.     if (sf)
  1179.       nh.fromsys=sf;
  1180.     else
  1181.       nh.fromsys=net_sysnum;
  1182.     nh.fromuser=uf;
  1183.     nh.main_type=main_type_email;
  1184.     nh.minor_type=0;
  1185.     nh.list_len=0;
  1186.     nh.daten=m.daten;
  1187.     nh.method=0;
  1188.     if ((b1=malloca(len1+768))==NULL) {
  1189.       bbsfree(b);
  1190.       return;
  1191.     }
  1192.     i=0;
  1193.     if ((un==0) && (fnn==net_num)) {
  1194.       nh.main_type=main_type_email_name;
  1195.       strcpy(&(b1[i]),net_email_name);
  1196.       i+= strlen(net_email_name)+1;
  1197.     }
  1198.     strcpy(&(b1[i]),m.title);
  1199.     i += strlen(m.title)+1;
  1200.     memmove(&(b1[i]),b,(unsigned int) len1);
  1201.     nh.length=len1+(long)i;
  1202.     if (nh.length > 32760) {
  1203.       outstr(get_string(645));
  1204.       npr("%lu",nh.length-32760L);
  1205.       outstr(get_string(646));
  1206.       nh.length = 32760;
  1207.     }
  1208.     if (fnn!=net_num) {
  1209.       gate_msg(&nh, b1,net_num, net_email_name, NULL, fnn);
  1210.     } else {
  1211.       if (fwd)
  1212.         sprintf(s,"%sP1%s",net_data,nete);
  1213.       else
  1214.         sprintf(s,"%sP0%s",net_data,nete);
  1215.       f=sh_open(s,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  1216.       sh_lseek(f,0L,SEEK_END);
  1217.       sh_write(f,(void *)&nh,sizeof(net_header_rec));
  1218.       sh_write(f,(void *)b1,nh.length);
  1219.       sh_close(f);
  1220.     }
  1221.     bbsfree(b);
  1222.     bbsfree(b1);
  1223.   }
  1224.   s2[0]=0;
  1225.   strcpy(s,get_string(647));
  1226.   if (sy==0) {
  1227.     read_user(un,&ur);
  1228.     ++ur.waiting;
  1229.     write_user(un,&ur);
  1230.     if (un==1)
  1231.       ++fwaiting;
  1232.     if (user_online(un, &i)) {
  1233.       send_inst_sysstr(i, get_string(1510));
  1234.     }
  1235.     if (an) {
  1236.       strcat(s,nam(&ur,un));
  1237.       sysoplog(s);
  1238.     } else {
  1239.       strcpy(s1,s);
  1240.       strcat(s1,nam(&ur,un));
  1241.       sysoplog(s1);
  1242.       strcat(s,get_string(482));
  1243.     }
  1244.   } else {
  1245.     if (net_num_max>1) {
  1246.       if (un==0)
  1247.         sprintf(s1,"%s %s @%u",net_name, net_email_name,sy);
  1248.       else
  1249.         sprintf(s1,"%s %u @%u",net_name, un,sy);
  1250.     } else {
  1251.       if (un==0)
  1252.         sprintf(s1,"%s @%u",net_email_name,sy);
  1253.       else
  1254.         sprintf(s1,"%u @%u",un,sy);
  1255.     }
  1256.     strcat(s,s1);
  1257.     sysoplog(s);
  1258.   }
  1259.   lock_status();
  1260.   if ((un==1) && (sy==0)) {
  1261.     ++status.fbacktoday;
  1262.     ++thisuser.feedbacksent;
  1263.     ++thisuser.fsenttoday1;
  1264.     ++fsenttoday;
  1265.   } else {
  1266.     ++status.emailtoday;
  1267.     ++thisuser.etoday;
  1268.     if (sy==0) {
  1269.       ++thisuser.emailsent;
  1270.     } else {
  1271.       ++thisuser.emailnet;
  1272.     }
  1273.   }
  1274.   save_status();
  1275.   if (!wfc)
  1276.     topscreen();
  1277.   pl(s);
  1278.   if (s2[0])
  1279.     pl(s2);
  1280. }
  1281.  
  1282.  
  1283. int ok_to_mail(unsigned un, unsigned sy, int forceit)
  1284. {
  1285.   userrec ur;
  1286.   slrec ss;
  1287.  
  1288.   ss=syscfg.sl[actsl];
  1289.   if ((sy!=0) && (net_sysnum==0)) {
  1290.     nl();
  1291.     pl(get_string(648));
  1292.     nl();
  1293.     return(0);
  1294.   }
  1295.   if (sy==0) {
  1296.     if (un==0)
  1297.       return(0);
  1298.     read_user(un,&ur);
  1299.     if (((ur.sl==255) && (ur.waiting>(syscfg.maxwaiting * 5))) ||
  1300.         ((ur.sl!=255) && (ur.waiting>syscfg.maxwaiting)) ||
  1301.         (ur.waiting>200)) {
  1302.       if (!forceit) {
  1303.         nl();
  1304.         pl(get_string(340));
  1305.         nl();
  1306.         return(0);
  1307.       }
  1308.     }
  1309.     if (ur.inact & inact_deleted) {
  1310.       nl();
  1311.       pl(get_string(341));
  1312.       nl();
  1313.       return(0);
  1314.     }
  1315.   } else {
  1316.     if (!valid_system(sy)) {
  1317.       nl();
  1318.       pl(get_string(649));
  1319.       nl();
  1320.       return(0);
  1321.     }
  1322.     if (thisuser.restrict & restrict_net) {
  1323.       nl();
  1324.       pl(get_string(650));
  1325.       return(0);
  1326.     }
  1327.   }
  1328.   if (forceit==0) {
  1329.     if ((((un==1) && (sy==0) && ((fsenttoday>=5) || (thisuser.fsenttoday1>=10))) ||
  1330.          (((un!=1) || (sy!=0)) && (thisuser.etoday>=ss.emails))) && (!cs())) {
  1331.       nl();
  1332.       pl(get_string(344));
  1333.       nl();
  1334.       return(0);
  1335.     }
  1336.     if ((restrict_email & thisuser.restrict) && (un!=1)) {
  1337.       nl();
  1338.       pl(get_string(345));
  1339.       nl();
  1340.       return(0);
  1341.     }
  1342.   }
  1343.   return(1);
  1344. }
  1345.  
  1346. void email(unsigned short un, unsigned short sy, int forceit, int anony)
  1347. {
  1348.   int i,an;
  1349.   messagerec msg;
  1350.   char s2[81],t[81];
  1351.   userrec ur;
  1352.   slrec ss;
  1353.   net_system_list_rec *csne;
  1354.  
  1355.  
  1356.   if (freek1(syscfg.msgsdir)<10.0) {
  1357.     nl();
  1358.     pl(get_string(332));
  1359.     nl();
  1360.     return;
  1361.   }
  1362.   nl();
  1363.   ss=syscfg.sl[actsl];
  1364.   if (forwardm(&un,&sy)) {
  1365.     nl();
  1366.     pl(get_string(651));
  1367.     nl();
  1368.     if ((un==0) && (sy==0)) {
  1369.       pl(get_string(652));
  1370.       return;
  1371.     }
  1372.   }
  1373.   if (!un && !sy)
  1374.     return;
  1375.   if (!ok_to_mail(un, sy, forceit))
  1376.     return;
  1377.   if (sy)
  1378.     csne=next_system(sy);
  1379.   if (ss.ability & ability_read_email_anony)
  1380.     an=1;
  1381.   else
  1382.     if (anony & (anony_sender | anony_sender_da | anony_sender_pp))
  1383.       an=0;
  1384.     else
  1385.       an=1;
  1386.   if (sy==0) {
  1387.     set_net_num(0);
  1388.     if (an) {
  1389.       read_user(un,&ur);
  1390.       strcpy(s2,nam(&ur,un));
  1391.     } else
  1392.       strcpy(s2,get_string(482));
  1393.   } else {
  1394.     if (net_num_max>1) {
  1395.       if (un==0)
  1396.         sprintf(s2,"%s %s @%u",net_name, net_email_name,sy);
  1397.       else
  1398.         sprintf(s2,"%s %u @%u",net_name, un,sy);
  1399.     } else {
  1400.       if (un==0)
  1401.         sprintf(s2,"%s @%u",net_email_name,sy);
  1402.       else
  1403.         sprintf(s2,"%u @%u",un,sy);
  1404.     }
  1405.   }
  1406.   outstr(get_string(653));
  1407.   pl(s2);
  1408.   if (ss.ability & ability_email_anony)
  1409.     i=anony_enable_anony;
  1410.   else
  1411.     i=0;
  1412.   if (anony & (anony_receiver_pp | anony_receiver_da))
  1413.     i=anony_enable_dear_abby;
  1414.   if (anony & anony_receiver)
  1415.     i=anony_enable_anony;
  1416.   if ((i==anony_enable_anony) && (thisuser.restrict & restrict_anony))
  1417.     i=0;
  1418.   if (sy!=0) {
  1419.     i=0;
  1420.     anony=0;
  1421.     nl();
  1422.     outstr(get_string(654));
  1423.     pl(csne -> name);
  1424.     outstr(get_string(655));
  1425.     pln(csne->numhops);
  1426.     nl();
  1427.   }
  1428.  
  1429.   write_inst(INST_LOC_EMAIL, (sy==0)?un:0, INST_FLAGS_NONE);
  1430.  
  1431.   msg.storage_type=EMAIL_STORAGE;
  1432.   inmsg(&msg,t,&i,!forceit,"EMAIL",ALLOW_FULLSCREEN, s2, 0);
  1433.   if (msg.stored_as==0xffffffff)
  1434.     return;
  1435.   if (anony & anony_sender)
  1436.     i|=anony_receiver;
  1437.   if (anony & anony_sender_da)
  1438.     i|=anony_receiver_da;
  1439.   if (anony & anony_sender_pp)
  1440.     i|=anony_receiver_pp;
  1441.  
  1442.   sendout_email(t, &msg, i, un, sy, an, usernum, net_sysnum, 0, net_num);
  1443. }
  1444.  
  1445.  
  1446. void imail(unsigned short u, unsigned short s)
  1447. {
  1448.   char s1[81];
  1449.   int i;
  1450.   userrec ur;
  1451.  
  1452.   if (forwardm(&u,&s))
  1453.     pl(get_string(656));
  1454.  
  1455.   if (!u && !s)
  1456.     return;
  1457.  
  1458.   i=1;
  1459.   helpl=0;
  1460.   if (s==0) {
  1461.     read_user(u,&ur);
  1462.     if ((ur.inact & inact_deleted)==0) {
  1463.       sprintf(s1,"%s %s? ",get_string(657), nam(&ur,u));
  1464.       prt(5,s1);
  1465.       if (yn()==0)
  1466.         i=0;
  1467.     } else
  1468.       i=0;
  1469.   } else {
  1470.     sprintf(s1,"%s %s %u @%u ? ",get_string(657), get_string(658), u,s);
  1471.     prt(5,s1);
  1472.     if (yn()==0)
  1473.       i=0;
  1474.   }
  1475.   grab_quotes(NULL, NULL);
  1476.   if (i)
  1477.     email(u,s,0,0);
  1478. }
  1479.  
  1480.  
  1481. void plan(char *s, int *abort, int *next)
  1482. {
  1483.   int i;
  1484.  
  1485.   i=0;
  1486.   checkhangup();
  1487.   if (hangup)
  1488.     *abort=1;
  1489.   checka(abort,next);
  1490.   while ((s[i]) && (!(*abort))) {
  1491.     outchr(s[i++]);
  1492.     checka(abort,next);
  1493.   }
  1494.   if (!(*abort))
  1495.     nl();
  1496. }
  1497.  
  1498.  
  1499. #define buf_size 512
  1500.  
  1501. #define STR_1002 (E_C?1002:1369)
  1502. #define STR_661 (E_C?661:1370)
  1503. #define STR_662 (E_C?662:1374)
  1504. #define STR_1008 (E_C?1008:1375)
  1505.  
  1506. void read_message1(messagerec *m1, char an, int readit, int *next, char *fn)
  1507. {
  1508.   char n[205],d[81],s[205],s1[81],s2[81],*ss,ch;
  1509.   int f,abort,done,end,cur,p,p1,printit,ctrla,centre,i,i1,ansi,ctrld;
  1510.   messagerec m;
  1511.   char *buf;
  1512.   long len,l1;
  1513.  
  1514.   hasrip=0;
  1515.   if ((buf=malloca(buf_size))==NULL)
  1516.     return;
  1517.   ss=NULL;
  1518.   ansi=0;
  1519.   m=*m1;
  1520.   *next=0;
  1521.   f=-1;
  1522.   done=0;
  1523.   cur=0;
  1524.   end=0;
  1525.   abort=0;
  1526.   ctrld=0;
  1527.   switch(m.storage_type) {
  1528.     case 0:
  1529.     case 1:
  1530.     case 2:
  1531.       ss=readfile(&m,fn,&len);
  1532.       if (m.storage_type!=2) {
  1533.         strcpy(s,syscfg.msgsdir);
  1534.         ltoa(m.stored_as,s1,16);
  1535.         if (m.storage_type==1) {
  1536.           strcat(s,fn);
  1537.           strcat(s,"\\");
  1538.         }
  1539.         strcat(s,s1);
  1540.         strcpy(s2,get_string(659));
  1541.         strcat(s2,s1);
  1542.         if (so())
  1543.           pl(s2);
  1544.         else {
  1545.           strcat(s2,"\r\n");
  1546.           outs(s2);
  1547.         }
  1548.       }
  1549.       if (ss==NULL) {
  1550.         plan(get_string(89),&abort,next);
  1551.         nl();
  1552.         bbsfree(buf);
  1553.         return;
  1554.       }
  1555.       p=0;
  1556.       while ((ss[p]!=13) && ((long)p<len) && (p<200))
  1557.         n[p]=ss[p++];
  1558.       n[p]=0;
  1559.       ++p;
  1560.       p1=0;
  1561.       if (ss[p]==10)
  1562.         ++p;
  1563.       while ((ss[p+p1]!=13) && ((long)p+p1<len) && (p1<60))
  1564.         d[p1]=ss[(p1++)+p];
  1565.       d[p1]=0;
  1566.       cur=p+p1+1;
  1567.       break;
  1568.     case 255:
  1569.       strcpy(s,fn);
  1570.       f=sh_open1(s,O_RDONLY | O_BINARY);
  1571.       if (f==-1) {
  1572.         plan(get_string(89),&abort,next);
  1573.         nl();
  1574.         bbsfree(buf);
  1575.         return;
  1576.       }
  1577.       sh_lseek(f,m.stored_as,SEEK_SET);
  1578.       end=sh_read(f,(void *)buf,buf_size);
  1579.       break;
  1580.     default:
  1581.       /* illegal storage type */
  1582.       nl();
  1583.       pl(get_string(660));
  1584.       nl();
  1585.       bbsfree(buf);
  1586.       return;
  1587.   }
  1588. #ifdef RIPDRIVE
  1589.   *ripbuffer = 0;         // Clear out
  1590. #endif
  1591.  
  1592.   irt_name[0]=0;
  1593.   if (m.storage_type!=255) {
  1594.     g_flags |= g_flag_disable_mci;
  1595.     switch(an) {
  1596.       default:
  1597.       case 0:
  1598.         osan("8│7[1Name7]3: ",&abort,next);
  1599.         ansic_x(sysinfo.msg_color);
  1600.         plan(n,&abort,next);
  1601.         strcpy(irt_name,n);
  1602.         osan("8│7[1Date7]3: ",&abort,next);
  1603.         ansic_x(sysinfo.msg_color);
  1604.         plan(d,&abort,next);
  1605.         if (origin_str[0]) {
  1606.           osan("8│7[1From7]3: ",&abort,next);
  1607.           plan(origin_str,&abort,next);
  1608.         }
  1609.         if (origin_str2[0]) {
  1610.           osan("8│7[1Location7]3: ",&abort,next);
  1611.           plan(origin_str2,&abort,next);
  1612.         }
  1613.         break;
  1614.       case anony_sender:
  1615.         if (readit) {
  1616.           osan("8│7[1Name7]3: ",&abort,next);
  1617.           ansic_x(sysinfo.msg_color);
  1618.           sprintf(s,"<<< %s >>>",n);
  1619.           plan(s,&abort,next);
  1620.           osan("8│7[1Date7]3: ",&abort,next);
  1621.           ansic_x(sysinfo.msg_color);
  1622.           plan(d,&abort,next);
  1623.         } else {
  1624.           osan("8│7[1Name7]3: ",&abort,next);
  1625.           ansic_x(sysinfo.msg_color);
  1626.           plan("7>1UNKNOWN7<3: ",&abort,next);
  1627.           osan("8│7[1Date7]3: ",&abort,next);
  1628.           ansic_x(sysinfo.msg_color);
  1629.           plan("7>1UNKNOWN7<3: ",&abort,next);
  1630.         }
  1631.         break;
  1632.       case anony_sender_da:
  1633.       case anony_sender_pp:
  1634.         if (an==anony_sender_da) {
  1635.           osan(get_string(STR_1002),&abort,next);
  1636.           ansic_x(sysinfo.msg_color);
  1637.           plan(get_string(663),&abort,next);
  1638.         } else {
  1639.           osan(get_string(STR_1002),&abort,next);
  1640.           ansic_x(sysinfo.msg_color);
  1641.           plan(get_string(664),&abort,next);
  1642.         }
  1643.         if (readit) {
  1644.           osan(get_string(STR_1002),&abort,next);
  1645.           ansic_x(sysinfo.msg_color);
  1646.           plan(n,&abort,next);
  1647.           osan(get_string(STR_661),&abort,next);
  1648.           plan(d,&abort,next);
  1649.         } else {
  1650.           osan(get_string(STR_661),&abort,next);
  1651.           ansic_x(sysinfo.msg_color);
  1652.           plan(get_string(482),&abort,next);
  1653.         }
  1654.         break;
  1655.     }
  1656.     if (rip_on()) {
  1657.       sprintf(s,"!|w000%c271610|#\r ", smally);
  1658.       lines_listed = 0;
  1659.       comstr(s);
  1660.     }
  1661.   outstr("8└─────────────────────────────────∙∙∙ ∙  ∙   ·    ·\r\n");
  1662.   outstr("             9─────────────══════════════════════════════────────────");
  1663.   } else {
  1664.     g_flags &= ~g_flag_disable_mci;
  1665.   }
  1666.   nl();
  1667.   p=0;
  1668.   p1=0;
  1669.   done=0;
  1670.   printit=0;
  1671.   ctrla=0;
  1672.   centre=0;
  1673.   l1=(long) cur;
  1674.  
  1675.   while ((!done) && (!abort) && (!hangup)) {
  1676.     switch(m.storage_type) {
  1677.       case 0:
  1678.       case 1:
  1679.       case 2:
  1680.         ch=ss[l1];
  1681.         if (l1>=len)
  1682.           ch=26;
  1683.         break;
  1684.       case 255:
  1685.         if (cur>=end) {
  1686.           cur=0;
  1687.           end=sh_read(f,(void *)buf,buf_size);
  1688.           if (end==0)
  1689.             buf[0]=26;
  1690.         }
  1691.         if ((buf[cur]=='`') && (m.stored_as) && (cur>0) && (buf[cur-1]==10))
  1692.           buf[cur]=26;
  1693.         ch=buf[cur];
  1694.         break;
  1695.     }
  1696.     if (ch==26)
  1697.       done=1;
  1698.     else {
  1699.       if (hasrip==1)
  1700.         if (ch=='|') {
  1701.           hasrip=2;
  1702.           tmp_disable_pause(1);     // Don't pause in RIPscrip mode
  1703.         } else
  1704.           hasrip=0;
  1705.       if (ch == 1 || ch == '!' || ch == 2)
  1706.         hasrip = 1;
  1707.       if (ch!=10) {
  1708.         if ((ch==13) || (!ch)) {
  1709.           printit=1;
  1710.         } else if (ch==1)
  1711.           ctrla=1;
  1712.         else if (ch==2)
  1713.           centre=1;
  1714.         else if (ch==4)
  1715.           ctrld=1;
  1716.         else if (ctrld==1) {
  1717.           if ((ch>='0') && (ch<='9')) {
  1718.             if (thisuser.optional_val<(ch-'0'))
  1719.               ctrld=0;
  1720.             else
  1721.               ctrld=-1;
  1722.           } else
  1723.             ctrld=0;
  1724.         } else {
  1725.           if (ch==27) {
  1726.             if ((topline) && (screenbottom==24) && (!ansi))
  1727.               set_protect(0);
  1728.             ansi=1;
  1729.             lines_listed=0;
  1730.           }
  1731.           s[p++]=ch;
  1732.           if ((ch==3) || (ch==8))
  1733.             --p1;
  1734.           else
  1735.             ++p1;
  1736.           if ((ch==32) && (!centre))
  1737.             printit=1;
  1738.         }
  1739.  
  1740.         if ((printit) || (ansi) || (p1>=80)) {
  1741.           if (centre && (ctrld!=-1)) {
  1742.             i1=(thisuser.screenchars-WhereX()-p1)/2;
  1743.             for (i=0; (i<i1) && (!abort) && (!hangup); i++) {
  1744. #ifdef RIPDRIVE
  1745.               if (rd_on() && (ripcode || (hasrip == 2)))
  1746.                 special = -1;
  1747. #endif
  1748.               osan(" ",&abort,next);
  1749. #ifdef RIPDRIVE
  1750.               special = 0;
  1751. #endif
  1752.             }
  1753.           }
  1754.           if (p) {
  1755.             if (ctrld!=-1) {
  1756.               if ((WhereX() + p1 >= thisuser.screenchars) && (!centre) && (!ansi)) {
  1757. #ifdef RIPDRIVE
  1758.                 if (rd_on() && (ripcode || (hasrip == 2))) {
  1759.                   strcat(ripbuffer, "\n");
  1760.                   remstr("\r\n");
  1761.                 } else
  1762. #endif
  1763.                   nl();
  1764.               }
  1765.               s[p]=0;
  1766. #ifdef RIPDRIVE
  1767.               if (rd_on() && (ripcode || (hasrip == 2)))
  1768.                 special = -1;
  1769. #endif
  1770.               osan(s,&abort,next);
  1771. #ifdef RIPDRIVE
  1772.               special = 0;
  1773. #endif
  1774.               if ((ctrla) && (s[p-1]!=32) && (!ansi)) {
  1775.                 if (WhereX()<(thisuser.screenchars)-1) {
  1776. #ifdef RIPDRIVE
  1777.                   if (rd_on() && (ripcode || (hasrip == 2))) {
  1778.                     strcat(ripbuffer, " ");
  1779.                     out_cport(' ');
  1780.                   } else
  1781. #endif
  1782.                     outchr(32);
  1783.                 } else {
  1784. #ifdef RIPDRIVE
  1785.                   if (rd_on() && (ripcode || (hasrip == 2))) {
  1786.                     strcat(ripbuffer, "\n");
  1787.                     remstr("\r\n");
  1788.                   } else
  1789. #endif
  1790.                     nl();
  1791.                 }
  1792.                 checka(&abort,next);
  1793.               }
  1794.             }
  1795.             p1=0;
  1796.             p=0;
  1797.           }
  1798.           centre=0;
  1799.         }
  1800.         if (ch==13) {
  1801.           if (ctrla==0) {
  1802.             if (ctrld!=-1) {
  1803. #ifdef RIPDRIVE
  1804.               if (rd_on() && (ripcode || (hasrip == 2))) {
  1805.                 rd_str(ripbuffer);
  1806.                 *ripbuffer = 0;
  1807.                 remstr("\r\n");
  1808.               } else {
  1809. #endif
  1810.                 if (ripcode)
  1811.                   out_cport('\r');
  1812.                 else
  1813.                   nl();
  1814. #ifdef RIPDRIVE                  
  1815.               }
  1816. #endif                  
  1817.               checka(&abort,next);
  1818.             }
  1819.           } else
  1820.             ctrla=0;
  1821.           if (printit)
  1822.             ctrld=0;
  1823.         }
  1824.         printit=0;
  1825.       } else
  1826.         ctrld=0;
  1827.     }
  1828.     ++cur;
  1829.     ++l1;
  1830.   }
  1831.   if ((!abort) && (p)) {
  1832.     s[p]=0;
  1833.     pl(s);
  1834.   }
  1835.   ansic(0);
  1836.   nl();
  1837.   if (f!=-1)
  1838.     sh_close(f);
  1839.   if ((m.storage_type==255) && (abort))
  1840.     *next=1;
  1841.   if ((express) && (abort) && (!(*next)))
  1842.     expressabort=1;
  1843.   bbsfree(buf);
  1844.   if (ss!=NULL)
  1845.     bbsfree(ss);
  1846. #ifdef RIPDRIVE
  1847.   tmp_disable_pause(0);
  1848. #endif
  1849.   if ((ansi) && (topdata) && (useron))
  1850.     topscreen();
  1851.   g_flags &= ~g_flag_disable_mci;
  1852.   outstr("             9─────────────══════════════════════════════────────────");
  1853.  
  1854. }
  1855.  
  1856.  
  1857. int maybeprint(char *fn, int force)
  1858. {
  1859.   char s[81],s1[81];
  1860.   messagerec m;
  1861.   int next,i;
  1862.  
  1863.   for (i=0; i<3; i++) {
  1864.     switch(i) {
  1865.       case 0: strcpy(s,languagedir); break;
  1866.       case 1: strcpy(s,syscfg.gfilesdir); break;
  1867.       case 2: s[0]=0; break;
  1868.     }
  1869.     m.stored_as=0L;
  1870.     m.storage_type=255;
  1871.     strcat(s,fn);
  1872.     if (strchr(s,'.')==NULL) {
  1873.       if (thisuser.sysstatus & sysstatus_ansi) {
  1874.         if (thisuser.sysstatus & sysstatus_color) {
  1875.           strcpy(s1,s);
  1876.           strcat(s1,".ANS");
  1877.           if (exist(s1))
  1878.             strcat(s,".ANS");
  1879.         }
  1880.         if (strchr(s,'.')==NULL) {
  1881.           strcpy(s1,s);
  1882.           strcat(s1,".B&W");
  1883.           if (exist(s1))
  1884.             strcat(s,".B&W");
  1885.           else
  1886.             strcat(s,".MSG");
  1887.         }
  1888.       } else
  1889.         strcat(s,".MSG");
  1890.     }
  1891.     if (exist(s))
  1892.       break;
  1893.   }
  1894.   next=0;
  1895.   if (force) {
  1896.     read_message1(&m,0,0,&next,s);
  1897.   } else {
  1898.     if (exist(s)) {
  1899.       printfile(fn);
  1900.       next=1;
  1901.     }
  1902.   }
  1903.   return(next);
  1904. }
  1905.  
  1906.  
  1907. int printfile(char *fn)
  1908. {
  1909.   return(maybeprint(fn, 1));
  1910. }
  1911.  
  1912. int existprint(unsigned char *fn)
  1913. {
  1914.   return(maybeprint(fn, 0));
  1915. }
  1916.  
  1917. void read_message(int n, int *next, int *val)
  1918. {
  1919.   char s[100];
  1920.   postrec p;
  1921.   int abort,a,nn;
  1922.   slrec ss;
  1923.  
  1924.   nl();
  1925.   abort=0;
  1926.   *next=0;
  1927.   msgheader(1);
  1928.   if (E_C) {
  1929.     sprintf(s,"1%u/%u0",n,nummsgs);
  1930.     strcat(s,charstr(12-strlen(stripcolors(s)),'.'));
  1931.     strcat(s," 2");
  1932.   } else {
  1933.     outchr(12);
  1934.     outstr("8┌────────────────────────────────────────────∙∙∙ ∙  ∙   ·    ·\r\n");
  1935.     sprintf(s,"8│7[1%u7/1%u7]3: ",n,nummsgs);
  1936.   }
  1937.   osan(s,&abort,next);
  1938.   ansic_x(sysinfo.msg_color);
  1939.   p=*get_post(n);
  1940.   if (p.status & (status_unvalidated | status_delete)) {
  1941.     plan(get_string(665),&abort,next);
  1942.     if (!lcs())
  1943.       return;
  1944.     *val |= 1;
  1945.     osan(s,&abort,next);
  1946.     ansic_x(sysinfo.msg_color);
  1947.   }
  1948.   strcpy(irt,p.title);
  1949.   irt_name[0]=0;
  1950.   plan(p.title,&abort,next);
  1951.   if ((p.status & status_no_delete) && (lcs())) {
  1952.     if (E_C) {
  1953.       plan(get_string(666),&abort,next);
  1954.     } else {
  1955.       plan(get_string(1376),&abort,next);
  1956.     }
  1957.   }
  1958.   if (p.status & status_pending_net) {
  1959.     if (E_C) {
  1960.       plan("8│7-----1Not Network Validated",&abort,next);
  1961.     } else {
  1962.       plan("8│7-----1Not Network Validated",&abort,next);
  1963.     }
  1964.     *val |= 2;
  1965.   }
  1966.   if (!abort) {
  1967.     ss=syscfg.sl[actsl];
  1968.     if ((lcs()) || (ss.ability & ability_read_post_anony))
  1969.       a=1;
  1970.     else
  1971.       a=0;
  1972.     nn=net_num;
  1973.  
  1974.     if (p.status & status_post_new_net)
  1975.       set_net_num(p.title[80]);
  1976.     setorigin(p.ownersys, p.owneruser);
  1977.     read_message1(&(p.msg),(p.anony & 0x0f),a,next,(subboards[curlsub].filename));
  1978.  
  1979.     if (nn!=net_num)
  1980.       set_net_num(nn);
  1981.  
  1982.     ++thisuser.msgread;
  1983.     ++msgreadlogon;
  1984.   } else
  1985.     if ((express) && (!(*next)))
  1986.       expressabort=1;
  1987.   if (p.qscan>qsc_p[curlsub])
  1988.     qsc_p[curlsub]=p.qscan;
  1989.   if (p.qscan>=status.qscanptr) {
  1990.     lock_status();
  1991.     if (p.qscan>=status.qscanptr)
  1992.       status.qscanptr=p.qscan+1;
  1993.     save_status();
  1994.   }
  1995. }
  1996.  
  1997. void lineadd(messagerec *m1, char *sx, char *aux)
  1998. {
  1999.   messagerec m;
  2000.   char s1[81],s[81],s2[181],*b;
  2001.   int f,i,j,new;
  2002.  
  2003.   strcpy(s2,sx);
  2004.   strcat(s2,"\r\n\x1a");
  2005.   m=*m1;
  2006.   strcpy(s,syscfg.msgsdir);
  2007.   switch(m.storage_type) {
  2008.     case 0:
  2009.     case 1:
  2010.       ltoa(m.stored_as,s1,16);
  2011.       if (m.storage_type==1) {
  2012.         strcat(s,aux);
  2013.         strcat(s,"\\");
  2014.       }
  2015.       strcat(s,s1);
  2016.       f=sh_open1(s,O_RDWR | O_BINARY);
  2017.       if (f>0) {
  2018.         sh_lseek(f,-1L,SEEK_END);
  2019.         sh_write(f,(void *)s2,strlen(s2));
  2020.         sh_close(f);
  2021.       }
  2022.       break;
  2023.     case 2:
  2024.       f=open_file(aux);
  2025.       set_gat_section(f,m.stored_as/2048);
  2026.       new=1;
  2027.       while ((new<2048) && (gat[new]!=0))
  2028.         ++new;
  2029.       i=(int)(m.stored_as % 2048);
  2030.       while (gat[i]!=65535)
  2031.         i=gat[i];
  2032.       if ((b=malloca(2048))==NULL) {
  2033.         sh_close(f);
  2034.         return;
  2035.       }
  2036.       sh_lseek(f,MSG_STARTING + ((long)i)*512L,SEEK_SET);
  2037.       sh_read(f,(void *)b,512);
  2038.       j=0;
  2039.       while ((j<512) && (b[j]!=26))
  2040.         ++j;
  2041.       strcpy(&(b[j]),s2);
  2042.       sh_lseek(f,MSG_STARTING + ((long)i)*512L,SEEK_SET);
  2043.       sh_write(f,(void *)b,512);
  2044.       if (((j+strlen(s2))>512) && (new!=2048)) {
  2045.         sh_lseek(f,MSG_STARTING + ((long)new)*512L,SEEK_SET);
  2046.         sh_write(f,(char *)b+512,512);
  2047.         gat[new]=65535;
  2048.         gat[i]=new;
  2049.         save_gat(f);
  2050.       }
  2051.       bbsfree((void *)b);
  2052.       sh_close(f);
  2053.       break;
  2054.     default:
  2055.       /* illegal storage type */
  2056.       break;
  2057.   }
  2058. }
  2059.  
  2060.