home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / UTIL / WWIVE / MYWIVE.ZIP / MSGBASE.C < prev    next >
Text File  |  1993-05-31  |  41KB  |  1,694 lines

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