home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / Dloads / OTHERUTI / WWIV412S.ZIP / MSGBASE.C < prev    next >
C/C++ Source or Header  |  1990-08-12  |  36KB  |  1,636 lines

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