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