home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / WWIV2.ZIP / MSGBASE.C < prev    next >
Text File  |  1995-12-11  |  41KB  |  1,858 lines

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