home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / W / DEVBBS.ZIP / MSGBASE.C < prev    next >
Text File  |  1992-08-25  |  42KB  |  1,713 lines

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