home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / BBS / MISC / XSRC_117.ZIP / MSETUP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-15  |  43.2 KB  |  1,955 lines

  1. /* MSETUP -- a program for setting up customized MSGAREAS.XBS files
  2.              copyright (c) 1990 by M. Kimes.
  3.              It's free-for-the-asking.  Created from DOORSKEL.C  */
  4.  
  5. /********************** Miscellaneous notes: *****************************
  6.  
  7.     This program creates a MSGAREAS.### (where the ### is the node number
  8.     of the calling XBBS) containing only the areas the user has requested
  9.     to have access to.  It creates a datafile called MSETUP.USR which
  10.     contains struct _msetup entries, one per user.  There are no provisions
  11.     for deleting entries from the file; someone needs to add to this program
  12.     to do that, or write a separate utility (possibly something that compares
  13.     the names in MSETUP.USR with those in USERS.BBS and deletes any not found
  14.     in USERS.BBS).
  15.  
  16. *************************************************************************/
  17.  
  18.  
  19. #include "msgg.h"   /* XBBS include file */
  20.  
  21. #define PROGRAM_NAME "XBBS user message area setup"
  22. #define COPY_RIGHT "Copyright (c) 1990 by M. Kimes -- All Rights Reserved"
  23.  
  24. #define XBBS "UseIt"
  25.  
  26. /* Function declarations */
  27.  
  28. #ifdef XBBS
  29.     void pascal getonline(void);
  30.     void pascal readconfig(void);
  31.     void pascal prepare(void);
  32.     void pascal saveconfig(void);
  33. #endif
  34.  
  35. #ifndef NOREADFILE
  36.     char   pascal readtext(char *,char);
  37.     char * pascal write_line (char **text,word linelen);
  38.     void   pascal strip_blanklines (char *hold);
  39. #endif
  40.  
  41. void   pascal hitreturn(void);
  42. void pascal do_fboard (void);
  43. void   pascal cls (void);
  44. void   cdecl  debug_print(char *,...);
  45. char * pascal addtolog(char *);
  46. char   pascal inkey (void);
  47. char   pascal carrchk (void);
  48. char   pascal fossil (char function, char arg);
  49. char   pascal printm (char *text);
  50. void   pascal checkpos(void);
  51. void   cdecl  deinitialize (void);
  52. char * pascal genin (char length,char password,char caps,char hot,char type);
  53. void   pascal print_stat();
  54. char * pascal fidodate (void);
  55. ulong  pascal getxbbstime(void);
  56. char   pascal specialkey(char);
  57. int    cdecl  break_handler(void);
  58. char   pascal printg(char *);
  59. char   pascal skip_blanks(FILE *fp);
  60. void   pascal chat(void);
  61. void   pascal printinfo(void);
  62. void   pascal printhelp(void);
  63. char * pascal lstrip(char *);
  64. char * pascal rstrip(char *);
  65. int    cdecl  printfm(char *,...);
  66. char * pascal stripcr(char *);
  67. void   pascal load_msgareas (char *file);
  68. void   pascal display_current (char enable,int lorange, int hirange);
  69. word   pascal load_user (void);
  70. void   pascal save_user (word numuser);
  71. int    pascal edit_areas (void);
  72. int    pascal do_bits (int x,char what);
  73.  
  74. int    pascal mainloop(void);   /* Change as required */
  75.  
  76.  
  77. /* Global variables */
  78.  
  79.  
  80. #ifdef XBBS
  81.     struct _config conf;
  82.     struct _user user;
  83.     word userno;
  84.     struct time timeon;
  85.     char timer_off;
  86.     word hold_time;
  87.     char age;
  88.     char pages;
  89.     struct _mboard mboard;
  90.     struct _fboard fboard;
  91.     struct _events event[10];
  92.     char variable[10][82];
  93. #endif
  94.  
  95. /* NOTE DEFAULTS! */
  96.  
  97. char   debug_mode=0;
  98. char   graphics=0;
  99. word   timelimit=30;
  100. word   baud=0;
  101. char   numlines=24;
  102. word   seclvl=5;
  103. ulong  startt=0;
  104. char   sysopin=0;
  105. char   fastANSI=0;
  106. char   commport=0;
  107. struct time starter;
  108. union  REGS rg;
  109. char   logfile[133]="XBBS.LOG";
  110. char   username[36]="A. Ghost";
  111. char   width=80;
  112. char   fast=0;
  113. char   chatting=0;
  114. char   chatted=0;
  115. char   nodenumber=1;
  116. char   system_name[64]="";
  117. char   sysop[36]="";
  118.  
  119. struct _msetup {
  120.     unsigned long userid;
  121.     char node;
  122.     unsigned char areas[512];
  123. } mset;
  124.  
  125. #define MAXNUMAREA 1024
  126.  
  127. struct _ffboard {
  128.   char       name[47];
  129.   char       flags;
  130.   word         security;
  131.   char       dpath[79];
  132.   char       upath[79];
  133.   char       descr[79];
  134.   signed char age;
  135.   word          userflags;
  136.   char          leechpercent;
  137. };
  138.  
  139. struct _mmboard {
  140.   char       name[48];
  141.   char       forceto[36];
  142.   word       attr;
  143.   word       max;
  144.   word       number;
  145.   word       substat1;
  146.   word       substat2;
  147.   char       descr[79];
  148.   signed char age;
  149.   word       flags;
  150.   word          zone;
  151.   word         net;
  152.   word          node;
  153.   word         point;
  154.   char       yourname[36];
  155.   word         minwrite;
  156. };
  157.  
  158. char pathfile[133]="";
  159. char msgareasfile[133]="";
  160. char filetocreate[133]="";
  161. char fileareasfile[133]="";
  162. char filefiletocreate[133]="";
  163. struct _mmboard huge *marea=NULL;
  164. struct _mmboard huge *currarea=NULL;
  165. word higharea;
  166. word maxareas=0;
  167. char create=0;
  168. char fseclvl=0;
  169. char dofiles=0;
  170.  
  171.  
  172.  
  173. int cdecl main (int argc,char **argv) {
  174.  
  175.     register word x;
  176.     char *p;
  177.  
  178.   /* Please leave this next line in...thanks */
  179.   fputs("\x1b[2J\x1b[0;2;37m\x1b[1;1H\04 Made using M. Kimes' DOORSKEL.C -- MSetup H for help\n",stdout);
  180.  
  181.   directvideo=0;
  182.   gettime(&starter);
  183.   ctrlbrk(break_handler);
  184.  
  185.   if (argc==2 && !strcmp(strupr(argv[1]),"H")) {
  186.     printinfo();
  187.     printhelp();
  188.     exit(0);
  189.   }
  190.   atexit(deinitialize);
  191.  
  192. #ifdef XBBS
  193.     readconfig();
  194.     getonline();
  195. #endif
  196.  
  197. #ifdef DORINFO
  198.     readinfo();
  199. #endif
  200.  
  201.   for (x=1;x<argc;x++) {
  202.     strupr(argv[x]);
  203.     switch (*argv[x]) {
  204.         case 'F':    fastANSI=1;
  205.                     break;
  206.         case 'N':    nodenumber=(char)atoi(&argv[x][1]);
  207.                     break;
  208.         case 'L':     numlines=(char)atoi(&argv[x][1]);
  209.                     break;
  210.         case 'W':    width=(char)atoi(&argv[x][1]);
  211.                     break;
  212.         case 'B':    baud=(word)atoi(&argv[x][1]);
  213.                     break;
  214.         case 'G':    if(atoi(&argv[x][1])) graphics=1;
  215.                     break;
  216.         case 'C':    commport=(char)atoi(&argv[x][1]);
  217.                     break;
  218.         case 'T':   timelimit=atoi(&argv[x][1]);
  219.                     break;
  220.         case 'M':   directvideo=atoi(&argv[x][1]);
  221.                     break;
  222.         case '!':   debug_mode=1;
  223.                     break;
  224.         case 'X':    strcpy(logfile,&argv[x][1]);
  225.                     break;
  226.         case 'A':    strcpy(msgareasfile,&argv[x][1]);
  227.                     break;
  228.         case 'J':   create=1;
  229.                     baud=0;
  230.                     break;
  231.         case '&':   fseclvl=(char)atoi(&argv[x][1]);
  232.                     dofiles=1;
  233.                     break;
  234.         case 'P':    strcpy(pathfile,&argv[x][1]);
  235.                     break;
  236.         case 'S':    strcpy(fileareasfile,&argv[x][1]);
  237.                     break;
  238.         default:    fputs("\nUnknown argument `",stdout);
  239.                     fputs(argv[x],stdout);
  240.                     fputs("'\n",stdout);
  241.                     sleep(1);
  242.     }
  243.   }
  244.   fossil(INIT,0);
  245.   cls();
  246.  
  247.   printg("\x1b[0;1;37m");
  248.   p=PROGRAM_NAME;
  249.   if(baud) while (*p++) while(!fossil(TRANSMIT,*p)) carrchk();
  250.   printinfo();
  251.   printm("\n");
  252.  
  253.   mset.userid=user.id;
  254.   mset.node=user.node;
  255.   for(x=0;x<512;x++) mset.areas[x]=255;
  256.  
  257.   if(!*msgareasfile) sprintf(msgareasfile,"%sMSGAREAS.XBS",conf.messpath);
  258.   if(!*filetocreate) sprintf(filetocreate,"MSGAREAS.%03hu",nodenumber);
  259.  
  260.   return (mainloop());
  261. }
  262.  
  263.  
  264.  
  265. int pascal mainloop (void) {
  266.  
  267.     int register x;
  268.     FILE *fp;
  269.     word numuser;
  270.  
  271.     if(!*msgareasfile) return 1;
  272.     marea=(struct _mmboard huge*)farmalloc((MAXNUMAREA*sizeof(struct _mmboard))+sizeof(struct _mmboard));
  273.     if (marea==NULL) {
  274.         printm("\nCan't allocate enough memory for areas...\n");
  275.         maxareas=0;
  276.         if(dofiles) do_fboard();
  277.         return 1;
  278.     }
  279.     load_msgareas(msgareasfile);
  280.  
  281.     numuser=load_user();
  282.  
  283.     if(!create) {
  284.         if(!edit_areas()) return 2;
  285.         printm("\nSaving...\n");
  286.     }
  287.  
  288.     if(!((fp=fopen(filetocreate,"wb")))) {
  289.         printm("\nUnable to create new file\n");
  290.         hitreturn();
  291.     }
  292.     else {
  293.         for(x=0;x<maxareas;x++) {
  294.             if(do_bits(marea[x].number-1,0)) {
  295.                 fprintf(fp,"%s,%u,%u,%u,%u,%u",marea[x].name,marea[x].attr,marea[x].max,marea[x].number,marea[x].substat1,marea[x].substat2);
  296.                 fprintf(fp,",%s",marea[x].forceto);
  297.                 fprintf(fp,",%s",marea[x].descr);
  298.                 fprintf(fp,",%hd",marea[x].age);
  299.                 fprintf(fp,",%u",marea[x].flags);
  300.                 if(marea[x].zone && marea[x].net) {
  301.                     fprintf(fp,",%u:%u/%01u.%01u",marea[x].zone,marea[x].net,marea[x].node,marea[x].point);
  302.                 }
  303.                 else fprintf(fp,",");
  304.                 fprintf(fp,",%s",marea[x].yourname);
  305.                 fprintf(fp,",%u",marea[x].minwrite);
  306.                 fprintf(fp,"\r\n");
  307.             }
  308.         }
  309.         fprintf(fp,"\r\n");
  310.         fclose(fp);
  311.         baud=0;
  312.         printfm("\n\04Created %s...\n",filetocreate);
  313.     }
  314.  
  315.     if(!create)save_user(numuser);
  316.  
  317.     farfree((struct _mmboard far *)marea);
  318.  
  319.     if(dofiles) do_fboard();
  320.     marea=NULL;
  321.     return 0;
  322. }
  323.  
  324.  
  325.  
  326. void pascal printhelp (void) {  /* Print help screen */
  327.  
  328.     fputs("L<screen lines>\n",stdout);
  329.     fputs("N<nodenumber>\n",stdout);
  330.     fputs("W<screen width>\n",stdout);
  331.     fputs("T<time in minutes>\n",stdout);
  332.     fputs("B<baudrate>\n",stdout);
  333.     fputs("G<1 for graphics>\n",stdout);
  334.     fputs("C<commport (0=COM1)>\n",stdout);
  335.     fputs("X<filename> (Log File)\n",stdout);
  336.     fputs("     Above normally taken from ONLINE.XBS\n",stdout);
  337.     fputs("M<mode (0=direct video, 1=BIOS, 2=DOS)>\n",stdout);
  338.     fputs("F (Fast ANSI writes)\n",stdout);
  339.     fputs("! (Debug mode on)\n",stdout);
  340.     fputs("J (just create MSGAREAS.### in default directory)\n",stdout);
  341.     fputs("A<msgareas file to read> (defaults to messpath\\MSGAREAS.XBS)\n",stdout);
  342.     fputs("&<#> (also create FLSEARCH.### in default directory using sec lvl <#>)\n",stdout);
  343.     fputs("  If the &<#> argument is processed, these are valid:\n",stdout);
  344.     fputs("S<fileareas file to read> (defaults to FLSEARCH.CTL)\n",stdout);
  345.     fputs("P<pathfilename> (D/L Path list file (for Bimodem, etc.) to create\n",stdout);
  346.     fputs("  Note that three files are created: the FLSEARCH.### file, the path file,\n"
  347.           "  and a 'plain' PLSEARCH.### file (without extra XBBS info in it).\n",stdout);
  348. }
  349.  
  350.  
  351.  
  352.  
  353. int cdecl break_handler (void) {  /* Diables ctrl-break */
  354.  
  355.    return 1;
  356.  
  357. }
  358.  
  359. void pascal chat (void) {    /* Cheap chat-mode */
  360.  
  361. char a[3];
  362.  
  363.  printg("\x1b[0;1;33m");
  364.  printm("\n\nChat mode engaged\n\n");
  365.  while (chatting) {
  366.    *a=inkey();
  367.    a[1]=0;
  368.    if (chatting) {
  369.      _AH=3;
  370.      _BH=0;
  371.      geninterrupt(16);
  372.      if (*a==13) printm("\n");
  373.      if ((*a==13) || (*a==' ' && _DL>70)) printm("\n");
  374.      else printm(a);
  375.    }
  376.  }
  377.  printm("\n\nChat mode ended\n\n");
  378.  chatted++;
  379. }
  380.  
  381.  
  382.  
  383. #ifndef NOREADFILE
  384.  
  385. char pascal readtext (char *s,char paged) {  /* Displays a text file
  386.                                                 This thing's got all
  387.                                                 sorts of fancy stuff
  388.                                                 in it if you set paged=1
  389.                                                 Otherwise it does a pretty
  390.                                                 dumb dump (ok for ANSI
  391.                                                 files) */
  392.  
  393.     long place2;
  394.     long place;
  395.     struct ffblk filestat;
  396.     char dostring[181];
  397.     char eof=0;
  398.     word page;
  399.     char a;
  400.     long *pos;
  401.     word scratch;
  402.     FILE *fp;
  403.     register int x;
  404.     char prev=0;
  405.     char *here;
  406.     char *p;
  407.     char *tempo;
  408.     char temp='N';
  409.     char lastpage=0;
  410.     char searchstring[41];
  411.     char holdstring[41];
  412.     char teststring[81];
  413.     char findend=0;
  414.     char printanyway=0;
  415.     char linelen;
  416.     word lines=1;
  417.  
  418.     *searchstring=0;
  419.     *holdstring=0;
  420.  
  421.   if (findfirst(s,&filestat,0)) return 1;
  422.   if (!filestat.ff_fsize) return 1;
  423.   if (!(fp=fopen(s,"rt"))) return 1;
  424.   cls();
  425.   printg("\x1b[0;1;33m");
  426.   page=0;
  427.   place2=ftell(fp);
  428.   if (!paged) {
  429.         printm("\n");
  430.       while (!feof(fp) && !ferror(fp)) {
  431.         if (!fgets(dostring,181,fp)) break;
  432.         if(ftell(fp)<=place2) {
  433.             while(fgetc(fp)=='\n');  /* Guard against Unix files & TC bug */
  434.             continue;
  435.         }
  436.         place2=ftell(fp);
  437.         printm(dostring);
  438.         if(numlines) {
  439.             lines++;
  440.             if(lines>numlines+1) {
  441.                 lines=1;
  442.                 printm("More? (Y/n) ");
  443.                 fossil(FLUSHOUT,0);
  444.                 fossil(PURGEIN,0);
  445.                 linelen=*genin(1,0,1,1,YESNOM);
  446.                 for (x=0;x<12;x++) printm(BACKSPACE);
  447.                 if (linelen == 'N') break;
  448.             }
  449.         }
  450.         a=toupper(inkey());
  451.         if (a=='S' || a==' ') break;
  452.         if (a=='P') sleep(5);
  453.       }
  454.       fclose(fp);
  455.       if (numlines) if (lines>numlines-11) hitreturn();
  456.       return 0;
  457.   }
  458.  
  459. /*
  460.   if (!baud && *reader) {
  461.     fclose(fp);
  462.     sprintf(dostring,"%s %s",reader,s);
  463.     system(dostring);
  464.     return 0;
  465.   }
  466. */
  467.  
  468.   p=strchr(s,':');            /* Strip path off filename for display */
  469.   here=strrchr(s,'\\');
  470.   if(!p && !here) here=s;
  471.   else if (!here) here=&p[1];
  472.   else if (p) here= (p<here) ? &here[1] : &p[1];
  473.   else here++;
  474.  
  475.   pos=(long *)malloc((word)(sizeof(long)*1024));
  476.   if(!pos) {
  477.     fclose(fp);
  478.     printm("\nOut of memory\n");
  479.     exit(4);
  480.   }
  481.  
  482.   printfm(" -=-=Reading: %s=-=-  Page #%u\n",here,page+1);
  483.  
  484.   printg("\x1b[0;1;32m");
  485.   if(skip_blanks(fp)) goto Abort;
  486.   place2=pos[0]=ftell(fp);
  487.   lines=1;
  488.   while (!feof(fp) && !ferror(fp)) {
  489.     if ((*searchstring && !printanyway) || findend) goto Searcher;
  490. Domore:
  491.     if (!fgets(dostring,181,fp)) {
  492.         eof++;
  493.         goto EEOF;
  494.     }
  495.     if(ftell(fp)<=place2) {
  496.         while(fgetc(fp)=='\n');  /* Guard against Unix files & TC bug */
  497.         continue;
  498.     }
  499.     place2=ftell(fp);
  500.     stripcr(dostring);
  501.     while (p=strchr(dostring,'\xc')) memmove(p,&p[1],strlen(&p[1])+1);
  502.     while (p=strchr(dostring,'\x1b')) memmove(p,&p[1],strlen(&p[1])+1);
  503.     if (!*dostring) {
  504.         if (prev) {
  505.             prev=0;
  506.             eof=skip_blanks(fp);
  507.             if (eof) goto EEOF;
  508.             else goto Domore;
  509.         }
  510.         else prev++;
  511.     }
  512.     else prev=0;
  513.     if (*searchstring) {
  514.         strcpy(teststring,dostring);
  515.         strupr(teststring);
  516.         if (strstr(teststring,searchstring)) {
  517.             printg("\x1b[0;1;37m");
  518.             fast=2;
  519.             printm(dostring);
  520.             printg("\x1b[0;1;32m");
  521.             lines++;
  522.         }
  523.         else {
  524.             fast=1;
  525.             printm(dostring);
  526.             lines++;
  527.         }
  528.     }
  529.     else {
  530.         fast=1;
  531.         printm(dostring);
  532.         lines++;
  533.     }
  534.     scratch=strlen(dostring);
  535.     p=dostring;
  536.     while(tempo=strchr(p,'\t')) {
  537.         p=tempo+1;
  538.         scratch+=3;
  539.     }
  540.     if (scratch<79) {
  541.         printm("\n");
  542.         scratch++;
  543.     }
  544.     if (scratch>width) {
  545.         lines++;
  546.     }
  547.     a=toupper(inkey());
  548.     if (a=='S' || a==' ') break;
  549.     if (a=='P' || a=='-') if (page) goto SkipThis;
  550.     if (a=='M') goto Direct;
  551. Searcher:
  552.     if (lastpage) goto EEOF;
  553.     if ((a=='N') || (*searchstring) || (findend)) {
  554.       if (findend) {
  555.         if (++page>1024) page=1;
  556.         pos[page]=ftell(fp);
  557.       }
  558.       place2=place=ftell(fp);
  559. Domore1:
  560.       while (!feof(fp) && !ferror(fp)) {
  561. Domore2:
  562.         if (!fgets(dostring,181,fp)) {
  563.             eof++;
  564.             break;
  565.         }
  566.         if(ftell(fp)<=place2) {
  567.             while(fgetc(fp)=='\n');  /* Guard against Unix files & TC bug */
  568.             continue;
  569.         }
  570.         place2=ftell(fp);
  571.         while (p=strchr(dostring,'\xc')) memmove(p,&p[1],strlen(&p[1])+1);
  572.         while (p=strchr(dostring,'\x1b')) memmove(p,&p[1],strlen(&p[1])+1);
  573.         if (!strcmp(dostring,"\n")) {
  574.             if (prev) {
  575.                 prev=0;
  576.                 eof=skip_blanks(fp);
  577.                 if (eof) break;
  578.                 else goto Domore2;
  579.             }
  580.             else prev++;
  581.         }
  582.         else prev=0;
  583.         if (*searchstring) {
  584.             if (strstr(strupr(dostring),searchstring)) {
  585.                 printanyway++;
  586.                 break;
  587.             }
  588.         }
  589.         lines++;
  590.         scratch=strlen(dostring);
  591.         p=dostring;
  592.         while(tempo=strchr(p,'\t')) {
  593.             p=tempo+1;
  594.             scratch+=3;
  595.         }
  596.         if (scratch<79) {
  597.             scratch++;
  598.         }
  599.         if (scratch>width) lines++;
  600.         if (numlines) if ((lines>=numlines-2) || (feof(fp)) || (eof)) break;
  601.       }
  602.       fossil(PURGEIN,0);
  603.       eof=skip_blanks(fp);
  604.       if (feof(fp) || eof || printanyway) {
  605.         if (*searchstring && !printanyway) {
  606.             printm("\nNot found...\n");
  607.             goto EEOF;
  608.         }
  609.         fseek(fp,place,SEEK_SET);
  610.         clearerr(fp);
  611.         cls();
  612.         printg("\x1b[0;1;33m");
  613.         printfm(" -=-=Reading: %s=-=-  Page #%u\n",here,page+1);
  614.         printg("\x1b[0;1;32m");
  615.         findend=prev=eof=0;
  616.         lastpage=lines=1;
  617.         goto Domore;
  618.       }
  619.       if ((*searchstring || findend) && !eof) {
  620.         if (++page>1024) page=1;
  621.         pos[page]=place=place2=ftell(fp);
  622.         lines=1;
  623.         goto Domore1;
  624.       }
  625.     }
  626. EEOF:
  627.     if (numlines) if ((lines>=numlines-2) || (feof(fp)) || (eof)) {
  628. Direct:
  629.         linelen=0;
  630.         prev=0;
  631.         eof=skip_blanks(fp);
  632.         if (feof(fp) || eof) {
  633.             printg("\x1b[0;1;31m");
  634.             printm(" (END)");
  635.             linelen+=6;
  636.             printg("\x1b[0;1;33m");
  637.             temp='S';
  638.         }
  639.         else {
  640.             if (a=='M' || a=='N') goto SkipThis;
  641.             temp='N';
  642.             printg("\x1b[0;1;33m");
  643.             printm(" [F]ind [E]nd [N]ext [M]ore");
  644.             linelen+=27;
  645.         }
  646.         if (page) {
  647.             printm(" [H]ome [P]rior");
  648.             linelen+=15;
  649.         }
  650.         linelen+=sprintf(dostring," [O]ver [S]top: [%c] ",temp);
  651.         printm(dostring);
  652.         fossil(FLUSHOUT,0);
  653.         pos[page+1]=ftell(fp);
  654. Getitagain:
  655.         fossil(PURGEIN,0);
  656.         a=*genin(1,0,1,1,ALLL);
  657. SkipThis:
  658.         findend=0;
  659.         lastpage=0;
  660.         printanyway=0;
  661.         *searchstring=0;
  662.         switch (a) {
  663.             case 'S':   goto Abort;
  664.             case 'H':   if (!page) {
  665.                             printm(BACKSPACE);
  666.                             printm("\x7");
  667.                             goto Getitagain;
  668.                         }
  669.                         page=0;
  670.                         fseek(fp,0,SEEK_SET);
  671.                         break;
  672.             case 'E':   if (feof(fp) || eof) {
  673.                             printm(BACKSPACE);
  674.                             printm("\x7");
  675.                             goto Getitagain;
  676.                         }
  677.                         findend++;
  678.                         break;
  679.             case 'F':   if (feof(fp) || eof) {
  680.                             printm(BACKSPACE);
  681.                             printm("\x7");
  682.                             goto Getitagain;
  683.                         }
  684.                         printg("\x1b[0;1;35m");
  685.                         printfm("\n Search string: [%s]\n  -> ",holdstring);
  686.                         strcpy(searchstring,genin(40,0,1,0,ALLL));
  687.                         if (!*searchstring) {
  688.                             if (*holdstring) {
  689.                                 strcpy(searchstring,holdstring);
  690.                                 if (++page>1024) page=1;
  691.                                 pos[page]=ftell(fp);
  692.                             }
  693.                         }
  694.                         else strcpy(holdstring,searchstring);
  695.                         fseek(fp,pos[page],SEEK_SET);
  696.                         eof=skip_blanks(fp);
  697.                         break;
  698.             case  0:    if (feof(fp) || eof) goto Abort;
  699.             case 'N':   if (feof(fp) || eof) {
  700.                             printm(BACKSPACE);
  701.                             printm("\x7");
  702.                             goto Getitagain;
  703.                         }
  704.                         a=0;
  705.                         if (++page>1024) page=1;
  706.                         pos[page]=ftell(fp);
  707.                         break;
  708.             case 'O':   fseek(fp,pos[page],SEEK_SET);
  709.                         eof=skip_blanks(fp);
  710.                         break;
  711.             case 'P':
  712.             case '-':   if (page) {
  713.                             fseek(fp,pos[--page],SEEK_SET);
  714.                             eof=skip_blanks(fp);
  715.                             break;
  716.                         }
  717.                         printm(BACKSPACE);
  718.                         printm("\x7");
  719.                         goto Getitagain;
  720.             case 'M':   if (feof(fp) || eof) {
  721.                             printm("\x7");
  722.                             printm(BACKSPACE);
  723.                             goto Getitagain;
  724.                         }
  725.                         for (x=0;x<linelen;x++) printm(BACKSPACE);
  726.                         printg("\x1b[0;1;32m");
  727.                         if (numlines) lines=numlines-3;
  728.                         goto Domore;
  729.             default:    printm(BACKSPACE);
  730.                         goto Getitagain;
  731.         }
  732.         place2=ftell(fp);
  733.         eof=0;
  734.         cls();
  735.         printg("\x1b[0;1;33m");
  736.         if (findend || *searchstring) strcpy(teststring,"Scanning");
  737.         else strcpy(teststring,"Reading");
  738.         printfm(" -=-=%s: %s=-=-  Page #%u\n",teststring,here,page+1);
  739.         printg("\x1b[0;1;32m");
  740.         lines=1;
  741.       }
  742.   }
  743. Abort:
  744.   if(pos) free(pos);
  745.   fclose(fp);
  746.   return 0;
  747.  
  748. }
  749.  
  750.  
  751.  
  752. /*
  753.  
  754. char * pascal write_line (char **text,word linelen) {
  755.  
  756.     static char line[81];
  757.     word register x=0;
  758.     char *p;
  759.     char *pp;
  760.  
  761.     p=*text;
  762.     pp=line;
  763.     *pp=0;
  764.     while(++x<linelen && *p && *p!='\r') {
  765.         *pp++=*p++;
  766.         *pp=0;
  767.     }
  768.     while(*pp==' ' && pp>line) {
  769.         *pp=0;
  770.         --pp;
  771.     }
  772.     if(*p==' ' || *p=='\r') {
  773.         if(*p==' ') *pp=0;
  774.         else p++;
  775.         while(*p==' ') p++;
  776.     }
  777.     else if(x==linelen) {
  778.         while(p>*text && *pp!=' ') {
  779.             *pp=0;
  780.             pp--;
  781.             p--;
  782.         }
  783.         if(p==*text) {
  784.             strncpy(line,*text,linelen);
  785.             line[linelen]=0;
  786.             p=text[linelen];
  787.         }
  788.         else p++;
  789.     }
  790.     *text=p;
  791.     return line;
  792. }
  793.  
  794.  
  795. void pascal strip_blanklines (char *hold) {
  796.  
  797.     char *p;
  798.  
  799.     p=&hold[strlen(hold)-1];
  800.     while(*p=='\r' && p>hold) {
  801.         *p=0;
  802.         p--;
  803.     }
  804. }
  805.  
  806. */
  807.  
  808. #endif
  809.  
  810.  
  811.  
  812. char pascal skip_blanks (FILE *fp) {  /* Skips blank lines, what else? */
  813.  
  814.   ulong pos;
  815.   char temp[81];
  816.   char eof=0;
  817.  
  818.   do {
  819.     pos=ftell(fp);
  820.     if (!fgets(temp,81,fp)) eof++;
  821.     stripcr(temp);
  822.   } while ((!eof) && (!feof(fp)) && (!*temp));
  823.   if (!eof && !feof(fp)) fseek(fp,pos,SEEK_SET);
  824.   return eof;
  825.  
  826. }
  827.  
  828.  
  829.  
  830. char pascal printg (text)    /* Print only if user has graphics set */
  831.  
  832.     char *text;
  833.  
  834. {
  835.  
  836.    if (graphics) return (printm(text));
  837.  
  838. }
  839.  
  840.  
  841.  
  842. char pascal inkey (void)  /* MIMICS BASIC'S INKEY$ FUNCTION */
  843.  
  844. {
  845.  
  846. char arg=0;
  847. static int check=0;
  848.  
  849.    rg.h.ah=11;
  850.    int86(33,&rg,&rg);
  851.    if (rg.h.al!=0) {
  852.         rg.h.ah=8;
  853.         int86(33,&rg,&rg);
  854.         if (rg.h.al!=0)return((char)(rg.h.al));
  855.         rg.h.ah=8;
  856.         int86(33,&rg,&rg);
  857.         arg=specialkey(rg.h.al);
  858.         if (arg) return (arg);
  859.    }
  860.    if (baud) {
  861.       arg=carrchk();
  862.       if (!(arg & 1)) return (0);
  863.       return (fossil(RECVWAIT,arg));
  864.    }
  865.    if (check!=(int)(timelimit-(getxbbstime()/60))) {
  866.        check=(int)(timelimit-(getxbbstime()/60));
  867.    }
  868.    return (0);
  869. }
  870.  
  871.  
  872.  
  873. char pascal specialkey (a)    /* Handles special local-only keys
  874.                                Add anything you like (extended keys) */
  875.  
  876. char a;
  877.  
  878. {
  879.  
  880. char middle[82];
  881. int  drive;
  882. char dir[MAXDIR];
  883.  
  884.   switch (a) {
  885.     case 45:exit (0);      /* QUIT DOOR */
  886.     case 46:if (!chatting) {  /* CHAT */
  887.                 chatting++;
  888.                 chat();
  889.             }
  890.             else chatting=0;
  891.             break;
  892.     case 35:                /* HANG UP */
  893.             fossil(DTR,DOWN);
  894.             exit(1);
  895.     case 36:                /* SysOp SHELL */
  896.             printm("\nThe SysOp has jumped to DOS...please wait...\n");
  897.             fossil(FLUSHOUT,0);
  898.             drive=getdisk();
  899.             getcurdir(++drive,dir);
  900.             fossil(DEINIT,0);
  901.             fputs("\nEXIT to return\n",stdout);
  902.             system ("");
  903.             fossil(INIT,0);
  904.             setdisk (--drive);
  905.             strcpy(middle,"\\");
  906.             strcat(middle,dir);
  907.             chdir(middle);
  908.             printm("\nThe SysOp has returned...please continue...\n");
  909.             chatted++;
  910.             break;
  911.     case 72:                /* MORE TIME */
  912.             timelimit++;
  913.             break;
  914.     case 80:                /* LESS TIME */
  915.             if (timelimit<1) timelimit=0;
  916.             else timelimit--;
  917.             break;
  918.     case 73:return 'P';
  919.     case 81:return 'N';
  920.     case 71:return 'H';
  921.   }
  922.   startt=getxbbstime();
  923.   return 0;
  924. }
  925.  
  926.  
  927.  
  928. void pascal cls (void) { /* MIMICS BASIC'S CLS FUNCTION LOCAL & REMOTE */
  929.  
  930.   char clr_string[]="\x1b[0m\x1b[2J";
  931.   char *p;
  932.  
  933.   if(!graphics)strcpy(clr_string,"\xc");
  934.   p=clr_string;
  935.   if(baud) while (*p++) while(!fossil(TRANSMIT,*p)) carrchk();
  936.   fputs("\x1b[0;2m\x1b[2J",stdout);
  937.   print_stat();
  938. }
  939.  
  940.  
  941. char pascal fossil (function,arg)   /*  HANDLES MOST USEFUL FOSSIL CALLS */
  942.  
  943. char function;
  944. char arg;
  945.  
  946. {
  947.  
  948.   if(!baud) return 0;
  949.   if ((function == FLUSHOUT) && (baud>0))
  950.     {
  951.      do {
  952.        carrchk();
  953.        rg.h.ah=3;
  954.        rg.x.dx=commport;
  955.        int86(20,&rg,&rg);
  956.       }
  957.      while ((rg.h.ah & 64)==0);
  958.      return(0);
  959.     }
  960.  
  961.   if (function == WATCHDOG) rg.h.al = arg;
  962.   if (function == DTR) rg.h.al = arg;
  963.   if (function == TRANSWAIT) rg.h.al = arg;
  964.   if (function == TRANSMIT) rg.h.al = arg;
  965.   if (function == ONOFF) rg.h.al = arg;
  966.  
  967.   rg.x.dx=commport;
  968.   rg.h.ah=function;
  969.   int86(20,&rg,&rg);
  970.  
  971.   if (function == INIT)
  972.     {
  973.      if (rg.x.ax != INITOK)
  974.       {
  975.        fputs("\nFossil not responding...RTFM.\n",stdout);
  976.        exit (3);
  977.       }
  978.      return (0);
  979.     }
  980.  
  981.   if (function == GETSTAT)
  982.     {
  983.       arg = rg.h.ah;
  984.       if (rg.h.al & 128)
  985.        {
  986.         arg |= 128;
  987.     return (arg);
  988.        }
  989.       arg &= 127;
  990.       return (arg);
  991.     }
  992.  
  993.   if (function == RECVWAIT) return (rg.h.al);
  994.   if (function == TRANSMIT) return (rg.x.ax);
  995.  
  996.   return (0);
  997.  
  998. }
  999.  
  1000.  
  1001.  
  1002. void cdecl deinitialize (void)     /*  DEINITIALIZES FOSSIL ON EXIT */
  1003.  
  1004. {
  1005.  
  1006.     register word x;
  1007.  
  1008.  fossil(FLUSHOUT,0);
  1009.  fossil (DEINIT,0);
  1010.  if(marea)free((struct _mmboard far *)marea);
  1011.  marea=NULL;
  1012.  baud=0;
  1013.  fcloseall();
  1014.  printm("\n");
  1015.  fputs("\x1b[0;2;37m\n",stdout);
  1016. }
  1017.  
  1018.  
  1019.  
  1020. char * pascal genin (length,password,caps,hot,type)  /* GENERIC INPUT ROUTINE */
  1021.  
  1022. char length;
  1023. char password;
  1024. char caps;
  1025. char hot;
  1026. char type;
  1027.  
  1028. {
  1029.  
  1030. static char input[257];
  1031. int x=0;
  1032. char one=0;
  1033. char randchr[2];
  1034.  
  1035.  length--;
  1036.  
  1037. AfterChat:
  1038.  
  1039.  strset(input,0);
  1040.  startt=getxbbstime();
  1041.  
  1042.  while ((getxbbstime()-startt)<241 || (chatted!=0)) {
  1043.  
  1044.   one=inkey();
  1045.   if (one == '\r') break;
  1046.  
  1047. Nogo:
  1048.  
  1049.   if (one == 8) {
  1050.       if (x>0) {
  1051.          printm(BACKSPACE);
  1052.          input [--x]=0;
  1053.          if ((type==PHONE) && ((x==2) or (x==5))) printm(BACKSPACE);
  1054.          if ((type==DATE) && ((x==1) or (x==3))) printm(BACKSPACE);
  1055.       }
  1056.       continue;
  1057.   }
  1058.   if ((caps) or (type==YESNO) or (type==YESNOM) or (type==FLE) or (type==FLEW) or (type==FLEPW) or (type==FLEP)) one=toupper(one);
  1059.   if (x <= length) {
  1060.       if (type==NAME) {
  1061.         if((isalpha(one)==0) && (one!=' ') && (one!='.') && (one!='-') or (x==0 && one==' ')) continue;
  1062.         if ((one==' ') && (strchr(input,' ')!=NULL)) continue;
  1063.       }
  1064.       if (type==NEAT) {
  1065.         if((isalnum(one)==0) && (one!=' ') or (x==0 && one==' ')) continue;
  1066.       }
  1067.       if ((type==NEAT) or (type==NAME)) {
  1068.         if(x==0) {
  1069.             one=toupper(one);
  1070.         }
  1071.         else one=tolower(one);
  1072.       }
  1073.       if((type==NEAT) or (type==NAME)) {
  1074.         if((x>0) && ((input[x-1]==' ') or (input[x-1]=='.') or (input[x-1]=='-'))) one=toupper(one);
  1075.       }
  1076.       if ((type==SUBJECT) && (x==0)) one=toupper(one);
  1077.       if ((type==SUBJECT) && (isprint(one)==0)) continue;
  1078.       if ((type==ALLL) && (isprint(one)==0)) continue;
  1079.       if ((type==ALLL) && (one==127)) one=8;
  1080.       if ((type==ALPHA) && (isalpha(one)==0) && (one!=' ')) continue;
  1081.       if (((type==NUM) or (type==PHONE) or (type==DATE)) and (isdigit(one)==0)) continue;
  1082.       if ((type==ALPHANUM) and (isalnum(one)==0) and (one!=' ')) continue;
  1083.       if (((type==YESNO) or (type==YESNOM)) and (one!='Y' and one!='N')) continue;
  1084.       if (type==FLE) {
  1085.          if ((isalnum(one)==0) and (!strchr("._-+=!@#$%^&<>/",one))) continue;
  1086.       }
  1087.       if (type==FLEP) {
  1088.          if ((isalnum(one)==0) and (!strchr("._-+=!@#$%^&<>/\\:",one))) continue;
  1089.       }
  1090.       if (type==FLEW) {
  1091.           if ((isalnum(one)==0) and (!strchr("._-+=!@#$%^&<>/?*",one))) continue;
  1092.       }
  1093.       if (type==FLEPW) {
  1094.         if ((isalnum(one)==0) and (!strchr("._-+=!@#$%^&<>/?*\\:",one))) continue;
  1095.       }
  1096.       if ((type==FLE) or (type==FLEP) or (type==FLEW) or (type==FLEPW)) {
  1097.          if ((one=='.') and (strchr(input,'.')!=NULL)) continue;
  1098.       }
  1099.    }
  1100.    if (chatted>0) {
  1101.     chatted=0;
  1102.     goto AfterChat;
  1103.    }
  1104.  
  1105.    if ((one!=0) and (x <= length)) {
  1106.       input[x]=one;
  1107.       input[++x]=0;
  1108.       if (type==YESNOM) {
  1109.                         return(input);
  1110.       }
  1111.       if (password==0) printm(&input[x-1]);
  1112.       if (password!=0) {
  1113.          randchr[0]=random(10)+33;
  1114.         randchr[1]=0;
  1115.         printm(randchr);
  1116.       }
  1117.       if ((type==PHONE) and ((x==3) or (x==6))) printm("-");
  1118.       if ((type==DATE) and ((x==2) or (x==4))) printm("/");
  1119. AfterCtrl:
  1120.       if ((hot!=0)and(x >= length)) {
  1121.             return (input);
  1122.       }
  1123.       startt=getxbbstime();
  1124.    }
  1125.  
  1126.   }
  1127.   if (chatted) {
  1128.     chatted=0;
  1129.     goto AfterChat;
  1130.   }
  1131.   if ((getxbbstime()-startt)>240) {
  1132.       fputs("\nUser time-out...\n",stdout);
  1133.       exit (2);
  1134.   }
  1135.   return (input);
  1136. }
  1137.  
  1138.  
  1139. char pascal carrchk (void)  /* Checks for carrier */
  1140.  
  1141. {
  1142.    if (baud) {
  1143.      rg.x.dx=commport;
  1144.      rg.h.ah=GETSTAT;
  1145.      int86(20,&rg,&rg);
  1146.      if (!(rg.h.al & 128)) {
  1147.        sleep(1);
  1148.        rg.x.dx=commport;
  1149.        rg.h.ah=GETSTAT;
  1150.        int86(20,&rg,&rg);
  1151.        if (!(rg.h.al & 128)) {
  1152.          fossil(DTR,DOWN);
  1153.          baud=0;
  1154.          fputs("\n\04 Lost carrier...\n",stdout);
  1155.          exit (1);
  1156.        }
  1157.      }
  1158.    return (rg.h.ah);
  1159.    }
  1160.    return 0;
  1161. }
  1162.  
  1163.  
  1164. void pascal hitreturn (void)  /* Pause until [Enter] is pressed */
  1165.  
  1166. {
  1167.  
  1168.   register word x;
  1169.  
  1170.            startt=getxbbstime();
  1171.            printm("\n[Enter] to continue...");
  1172.            while ((getxbbstime()-startt)<241) {
  1173.              if (inkey()==13) goto hedid;
  1174.            }
  1175.            fputs("\n\x4 User time-out...\n",stdout);
  1176.            exit (2);
  1177. hedid:
  1178.            for(x=0;x<22;x++) printm(BACKSPACE);
  1179. }
  1180.  
  1181.  
  1182. ulong pascal getxbbstime (void)  /* GP User Timer */
  1183.  
  1184. {
  1185.  
  1186. static int hour;
  1187. static int min;
  1188. static int sec;
  1189. static int lastsec;
  1190. static int x;
  1191. static int y;
  1192. static struct time dos_time;
  1193. static ulong xbbs_time;
  1194. static int warned;
  1195. static int byebye=0;
  1196.  
  1197.  gettime(&dos_time);
  1198.  
  1199.  hour=dos_time.ti_hour-starter.ti_hour;
  1200.  min=dos_time.ti_min-starter.ti_min;
  1201.  sec=dos_time.ti_sec-starter.ti_sec;
  1202.  
  1203.  if (dos_time.ti_hour<starter.ti_hour) hour=hour+24;
  1204.  
  1205.  xbbs_time=(long)(hour*3600)+(min*60)+sec;
  1206.  
  1207.  if (((timelimit*60)<(xbbs_time+120)) && (warned==0)) {
  1208.     warned++;
  1209.     printfm("\nWARNING: %u minutes remaining.",(timelimit-(xbbs_time)/60));
  1210.    }
  1211.  
  1212.  if (((timelimit*60) > ((xbbs_time+1L)+120L)) && (warned!=0)) warned=0;
  1213.  
  1214.  if ((timelimit*60) < (xbbs_time+1)) {
  1215.     if(byebye) return xbbs_time;
  1216.     byebye=1;
  1217.     timelimit=(word)(xbbs_time/60L)+4;
  1218.     printm("\nSorry, time to logoff...\n");
  1219.     fossil(FLUSHOUT,0);
  1220.     exit(0);
  1221.   }
  1222.  
  1223. juststarting:
  1224.  
  1225.     if(dos_time.ti_sec!=lastsec) {
  1226.         lastsec=dos_time.ti_sec;
  1227.         x=wherex();
  1228.         y=wherey();
  1229.         gotoxy(68,25);
  1230.         textbackground(7);
  1231.         textcolor(0);
  1232.         cprintf("%02d:%02d:%02d|%03u",dos_time.ti_hour,dos_time.ti_min,dos_time.ti_sec,(word)(timelimit-(word)(xbbs_time/60L)));
  1233.         gotoxy(x,y);
  1234.     }
  1235.     return(xbbs_time);
  1236. }
  1237.  
  1238.  
  1239. void pascal printinfo (void)  /* Just prints prog info locally */
  1240.  
  1241. {
  1242.  
  1243.   printf("  %s\n\04 %s\n\04 Compiled: %s  %s\n",PROGRAM_NAME,COPY_RIGHT,__DATE__,__TIME__);
  1244.  
  1245. }
  1246.  
  1247.  
  1248.  
  1249. char * pascal fidodate (void)    /* Builds a Fido(tm) datestring */
  1250.  
  1251. {
  1252.  
  1253.  char months[12][4]={
  1254.     "Jan",
  1255.     "Feb",
  1256.     "Mar",
  1257.     "Apr",
  1258.     "May",
  1259.     "Jun",
  1260.     "Jul",
  1261.     "Aug",
  1262.     "Sep",
  1263.     "Oct",
  1264.     "Nov",
  1265.     "Dec"
  1266.  };
  1267.  static char fdate[20];
  1268.  struct date dos_date;
  1269.  struct time dos_time;
  1270.  
  1271. /* 26 Jul 89  06:23:47 */
  1272.  
  1273.  getdate(&dos_date);
  1274.  gettime(&dos_time);
  1275.  
  1276.  sprintf(fdate,"%02hu %s %02d  %02hu:%02hu:%02hu",dos_date.da_day,months[dos_date.da_mon-1],dos_date.da_year%100,dos_time.ti_hour,dos_time.ti_min,dos_time.ti_sec);
  1277.  return(fdate);
  1278.  
  1279. }
  1280.  
  1281.  
  1282.  
  1283. char * pascal stripcr (char *a)  /* Strips trailing CR's & LF's */
  1284.  
  1285. {
  1286.  
  1287.   while (a[strlen(a)-1]=='\n' || a[strlen(a)-1]=='\r') a[strlen(a)-1]=0;
  1288.   return a;
  1289.  
  1290. }
  1291.  
  1292.  
  1293.  
  1294.  
  1295. char * pascal lstrip (char *a) {    /* Strips leading blanks */
  1296.  
  1297.   while (*a==' ') memmove (a,(a+1),strlen(a));
  1298.   return (a);
  1299. }
  1300.  
  1301.  
  1302.  
  1303. char * pascal rstrip (char *a) {    /* Strips trailing blanks */
  1304.  
  1305.   while (*a && a[strlen(a)-1]==' ') a[strlen(a)-1]=0;
  1306.   return a;
  1307. }
  1308.  
  1309.  
  1310.  
  1311. void cdecl debug_print (char *string,...) {  /* Local-only messages only
  1312.                                                 displayed if debug-mode is
  1313.                                                 turned on by ! argument */
  1314.  
  1315.  word tempbaud;
  1316.  static char buffer[318];
  1317.  
  1318.  va_list ap;
  1319.  va_start(ap,string);
  1320.  vsprintf(buffer,string,ap);
  1321.  va_end(ap);
  1322.  if(debug_mode){
  1323.     tempbaud=baud;
  1324.     baud=0;
  1325.     printm(buffer);
  1326.     baud=tempbaud;
  1327.  }
  1328. }
  1329.  
  1330.  
  1331.  
  1332. int cdecl printfm (char *string,...) {  /* Like printf() for local
  1333.                                            and remote */
  1334.  
  1335.  static char buffer[318];
  1336.  
  1337.  va_list ap;
  1338.  va_start(ap,string);
  1339.  vsprintf(buffer,string,ap);
  1340.  va_end(ap);
  1341.  return(printm(buffer));
  1342. }
  1343.  
  1344.  
  1345.  
  1346. char pascal printm (char *text) {    /* Prints local and remote */
  1347.  
  1348.     char *p;
  1349.  
  1350.     while ((p=strstr(text,"\x1b[2J"))!=NULL) {
  1351.        memmove(&p[1],&p[4],strlen(&p[4])+1);
  1352.        *p='\xc';
  1353.     }
  1354.     while ((p=strchr(text,'\x7')) && !sysopin) memmove(p,&p[1],strlen(&p[1])+1);
  1355.     while (p=strchr(text,'\r')) *p='\n';
  1356.     if (fast) {
  1357.         if(fast==1) {
  1358.             textbackground(0);
  1359.             textcolor(10);
  1360.         }
  1361.         if(fast==2) {
  1362.             textbackground(10);
  1363.             textcolor(0);
  1364.         }
  1365.     }
  1366.     while(*text) {
  1367.         if (*text=='\xc') {           /* Clear screen */
  1368.             cls();
  1369.             text++;
  1370.             continue;
  1371.         }
  1372.         if(*text=='\t') {
  1373.             text++;
  1374.             printm("    ");
  1375.             continue;
  1376.         }
  1377.         if (fast && *text!='\n') {
  1378.             putch(*text);
  1379.         }
  1380.         else if (fastANSI) {
  1381. Again1:
  1382.             _AX=(int)*text;
  1383.             geninterrupt(0x29);
  1384.             if(baud) while (!fossil(TRANSMIT,*text)) carrchk();
  1385.             if (*text=='\n') {
  1386.                 *text='\r';
  1387.                 goto Again1;
  1388.             }
  1389.         }
  1390.         else {
  1391. Again2:
  1392.             _DL=*text;
  1393.             _AH=2;
  1394.             geninterrupt(33);
  1395.             if(baud) while (!fossil(TRANSMIT,*text)) carrchk();
  1396.             if (*text=='\n') {
  1397.                 *text='\r';
  1398.                 goto Again2;
  1399.             }
  1400.         }
  1401.         text++;
  1402.         _AH=3;
  1403.         _BH=0;
  1404.         geninterrupt(16);
  1405.         if (_DH>23) checkpos();
  1406.      }
  1407.      getxbbstime();
  1408.      fast=0;
  1409. }
  1410.  
  1411.  
  1412. void pascal checkpos (void) {       /*  Protect status line */
  1413.  
  1414.         _AH=3;
  1415.         _BH=0;
  1416.         geninterrupt(16);
  1417.         if (_DH>23) {
  1418.             _AH=6;
  1419.             _AL=1;
  1420.             _BH=7;
  1421.             _CH=0;
  1422.             _CL=0;
  1423.             _DH=23;
  1424.             _DL=79;
  1425.             geninterrupt(16);
  1426.             _AH=2;
  1427.             _BH=0;
  1428.             _DL=0;
  1429.             _DH=23;
  1430.             geninterrupt(16);
  1431.         }
  1432. }
  1433.  
  1434.  
  1435.  
  1436.  
  1437. void pascal print_stat (void) {        /* Print status line */
  1438.  
  1439.     int x;
  1440.     int y;
  1441.  
  1442.     x=wherex();
  1443.     y=wherey();
  1444.     gotoxy(1,25);
  1445.     textbackground(7);
  1446.     textcolor(0);
  1447.     cprintf("%-31.31s \04 %31.31s\04             ",PROGRAM_NAME,username);
  1448.     gotoxy(x,y);
  1449. }
  1450.  
  1451.  
  1452.  
  1453. char * pascal addtolog (text)  /* WRITE LOGFILE ENTRIES */
  1454.  
  1455.  char *text;
  1456.  
  1457. {
  1458.  
  1459.  FILE *pf;
  1460.  char p[127];
  1461.  
  1462.  pf = fopen(logfile,"a");
  1463.  if (pf == NULL) return text;
  1464.  fseek(pf,0,SEEK_END);
  1465.  if (text[0]!='*') {
  1466.    strcpy(p,fidodate());
  1467.    p[16]=0;
  1468.    strcat(p,"  ");
  1469.    strncat(p,text,126-strlen(p));
  1470.    p[126]=0;
  1471.  }
  1472.  else {
  1473.         strncpy(p,text,79);
  1474.         p[79]=0;
  1475.  }
  1476.  fputs(p,pf);
  1477.  fputs("\n",pf);
  1478.  fclose(pf);
  1479.  return text;
  1480.  
  1481. }
  1482.  
  1483.  
  1484.  
  1485. #ifdef XBBS
  1486.  
  1487. void pascal readconfig (void)    /* Read CONFIG.BBS */
  1488.  
  1489. {
  1490.  
  1491. FILE *fp;
  1492. char s[15];
  1493.  
  1494.     if (nodenumber!=1) sprintf(s,"config%hu.bbs",nodenumber);
  1495.     else strcpy(s,"config.bbs");
  1496.  
  1497.     if(!(fp=fopen(s,"rb"))) {
  1498. Fatal:
  1499.        perror("\nCONFIG ERROR");
  1500. #ifndef DORINFO
  1501.        exit(1);
  1502. #endif
  1503.     }
  1504.   if (fread(&conf,sizeof(conf),1,fp)!=1) goto Fatal;
  1505.   fclose(fp);
  1506.   strcpy(system_name,conf.system);
  1507.   strcpy(sysop,conf.sysop);
  1508.   commport=conf.commport;
  1509.   strcpy(logfile,conf.logfile);
  1510.   sysopin=conf.sysopin;
  1511.   fastANSI=conf.fastANSI;
  1512.   directvideo=conf.dvideo;
  1513. }
  1514.  
  1515.  
  1516.  
  1517. void pascal getonline (void) {  /* Read ONLINE.XBS */
  1518.  
  1519.   FILE *fp;
  1520.   char s[90];
  1521.   char numnode[4]="";
  1522.  
  1523.   if (nodenumber!=1) sprintf(numnode,"%hu",nodenumber);
  1524.   sprintf(s,"%sonline%s.xbs",conf.homepath,numnode);
  1525.  
  1526.   if (!((fp=fopen(s,"rb")))) {
  1527.     printf("Can't open %s!\n",s);
  1528.     goto FatalError;
  1529.   }
  1530.   else {
  1531.       fread(&user,sizeof(struct _user),1,fp);
  1532.       fread(&userno,sizeof(userno),1,fp);
  1533.       fread(&timelimit,sizeof(timelimit),1,fp);
  1534.       fread(&timeon,sizeof(timeon),1,fp);
  1535.       fread(&starter,sizeof(starter),1,fp);
  1536.       fread(&baud,sizeof(baud),1,fp);
  1537.       fread(&pages,sizeof(pages),1,fp);
  1538.       fread(&age,sizeof(age),1,fp);
  1539.       fread(&timer_off,sizeof(timer_off),1,fp);
  1540.       fread(&hold_time,sizeof(hold_time),1,fp);
  1541.       fread(variable,(sizeof(variable[0])*10),1,fp);
  1542.       fread(&mboard,sizeof(mboard),1,fp);
  1543.       fread(&fboard,sizeof(fboard),1,fp);
  1544.       if (fread(event,(sizeof(struct _events)*10),1,fp)<1) {
  1545.         printf("Came up short!\n");
  1546.         goto FatalError;
  1547.       }
  1548.   }
  1549.   if (ferror(fp)) {
  1550. FatalError:
  1551.          perror("ONLINE READ");
  1552.          fclose(fp);
  1553. #ifndef DORINFO
  1554.          exit(1);
  1555. #endif
  1556.    }
  1557.    fclose(fp);
  1558.    strcpy(username,user.name);
  1559.    seclvl=user.stat[0];
  1560.    width=user.width;
  1561.    numlines=user.length;
  1562.    graphics=user.graphics;
  1563. }
  1564.  
  1565.  
  1566.  
  1567. void pascal prepare (void)        /* Rewrite ONLINE.XBS */
  1568.  
  1569. {
  1570.  
  1571.   FILE *fp;
  1572.   char s[90];
  1573.   char numnode[4]="";
  1574.  
  1575.  if (nodenumber!=1) sprintf(numnode,"%hu",nodenumber);
  1576.  sprintf(s,"%sonline%s.xbs",conf.homepath,numnode);
  1577.  if(!(fp=fopen(s,"wb"))) perror("ONLINE OPEN");
  1578.  else {
  1579.   fwrite(&user,sizeof(struct _user),1,fp);
  1580.   fwrite(&userno,sizeof(userno),1,fp);
  1581.   fwrite(&timelimit,sizeof(timelimit),1,fp);
  1582.   fwrite(&timeon,sizeof(timeon),1,fp);
  1583.   fwrite(&starter,sizeof(starter),1,fp);
  1584.   fwrite(&baud,sizeof(baud),1,fp);
  1585.   fwrite(&pages,sizeof(pages),1,fp);
  1586.   fwrite(&age,sizeof(age),1,fp);
  1587.   fwrite(&timer_off,sizeof(timer_off),1,fp);
  1588.   fwrite(&hold_time,sizeof(hold_time),1,fp);
  1589.   fwrite(variable,sizeof(variable[0]),10,fp);
  1590.   fwrite(&mboard,sizeof(struct _mboard),1,fp);
  1591.   fwrite(&fboard,sizeof(struct _fboard),1,fp);
  1592.   fwrite(event,sizeof(struct _events),10,fp);
  1593.   if (ferror(fp)) perror("ONLINE WRITE");
  1594.   fclose(fp);
  1595.  }
  1596. }
  1597.  
  1598.  
  1599.  
  1600. void pascal saveconfig (void)     /* Rewrite CONFIG.BBS */
  1601.  
  1602. {
  1603.  
  1604.   FILE *fp;
  1605.   char s[14];
  1606.  
  1607.  if (nodenumber!=1) sprintf(s,"config%hu.bbs",nodenumber);
  1608.  else strcpy(s,"config.bbs");
  1609.  
  1610.  if (!(fp=fopen(s,"wb"))) perror("CONFIG OPEN");
  1611.  else {
  1612.    fwrite(&conf,sizeof(conf),1,fp);
  1613.    fclose(fp);
  1614.  }
  1615. }
  1616.  
  1617. #endif
  1618.  
  1619.  
  1620.  
  1621. void pascal load_msgareas (char *file) {
  1622.  
  1623.     FILE *fp;
  1624.     char *p;
  1625.     char *pp;
  1626.     struct ffblk f;
  1627.     static char string[256];
  1628.     word tempareas=0;
  1629.  
  1630.     if(findfirst(file,&f,0)) return;
  1631.     if(!(fp=fopen(file,"rt"))) {
  1632.         printfm("\nCan't open %s\n");
  1633.         hitreturn();
  1634.         return;
  1635.     }
  1636.     while (!feof(fp)) {
  1637.         if (!fgets(string,255,fp)) break;
  1638.         if (*string=='\n' || *string==';') continue;
  1639.         stripcr(string);
  1640.         strncpy(marea[tempareas].name,strtok(string,","),48);
  1641.         marea[tempareas].name[47]=0;
  1642.         marea[tempareas].attr=(word)atoi(strtok(0," ,"));
  1643.         marea[tempareas].max=(word)atoi(strtok(0," ,"));
  1644.         marea[tempareas].number=(word)atoi(strtok(0," ,"));
  1645.         marea[tempareas].substat1=(word)atoi(strtok(0," ,"));
  1646.         marea[tempareas].substat2=(word)atoi(strtok(0," ,"));
  1647.         if(marea[tempareas].substat1>user.stat[0]) continue;
  1648.         pp=strtok(0,"\n");
  1649.         p=NULL;
  1650.         if(pp) {
  1651.             if(*pp!=',') {
  1652.                 p=strtok(pp,",");
  1653.                 pp=strtok(0,"\n");
  1654.             }
  1655.             else pp++;
  1656.         }
  1657.         if(p!=NULL)strncpy(marea[tempareas].forceto,p,36);
  1658.         else *marea[tempareas].forceto=0;
  1659.         marea[tempareas].forceto[35]=0;
  1660.         p=NULL;
  1661.         if(pp && *pp) {
  1662.             if(*pp!=',') {
  1663.                 p=strtok(pp,",");
  1664.                 pp=strtok(0,"\n");
  1665.             }
  1666.             else pp++;
  1667.         }
  1668.         if(!p) strcpy(marea[tempareas].descr,"No Description");
  1669.         else strncpy(marea[tempareas].descr,p,79);
  1670.         marea[tempareas].descr[78]=0;
  1671.         p=NULL;
  1672.         if(pp && *pp) {
  1673.             if(*pp!=',') {
  1674.                 p=strtok(pp,",");
  1675.                 pp=strtok(0,"\n");
  1676.             }
  1677.             else pp++;
  1678.         }
  1679.         if(!p) marea[tempareas].age=0;
  1680.         else marea[tempareas].age=(signed char)atoi(p);
  1681.         p=NULL;
  1682.         if(pp && *pp) {
  1683.             if(*pp!=',') {
  1684.                 p=strtok(pp,",");
  1685.                 pp=strtok(0,"\n");
  1686.             }
  1687.             else pp++;
  1688.         }
  1689.         if(!p)marea[tempareas].flags=0;
  1690.         else marea[tempareas].flags=(word)atol(p);
  1691.         p=NULL;
  1692.         if(pp && *pp) {
  1693.             if(*pp!=',') {
  1694.                 p=strtok(pp,",");
  1695.                 pp=strtok(0,"\n");
  1696.             }
  1697.             else pp++;
  1698.         }
  1699.         if(!p) marea[tempareas].zone=marea[tempareas].net=marea[tempareas].node=marea[tempareas].point=0;
  1700.         else {
  1701.             p=strtok(p,":");
  1702.             marea[tempareas].zone=(word)atol(p);
  1703.             p=strtok(0,"/");
  1704.             marea[tempareas].net=(word)atol(p);
  1705.             p=strtok(0,".");
  1706.             marea[tempareas].node=(word)atol(p);
  1707.             p=strtok(0,"@");
  1708.             marea[tempareas].point=(word)atol(p);
  1709.         }
  1710.         p=NULL;
  1711.         if(pp && *pp) {
  1712.             if(*pp!=',') {
  1713.                 p=strtok(pp,",");
  1714.                 pp=strtok(0,"\n");
  1715.             }
  1716.             else pp++;
  1717.         }
  1718.         if(!p) *marea[tempareas].yourname=0;
  1719.         else {
  1720.             strncpy(marea[tempareas].yourname,p,36);
  1721.             marea[tempareas].yourname[35]=0;
  1722.         }
  1723.         p=NULL;
  1724.         if(*pp && pp) {
  1725.             if(*pp!=',' && *pp!=0) p=strtok(pp,"\n");
  1726.             else if(*pp)p=++pp;
  1727.         }
  1728.         if(!p) marea[tempareas].minwrite=0;
  1729.         else marea[tempareas].minwrite=(word)atol(p);
  1730.  
  1731.         if (marea[tempareas].number>higharea) higharea=marea[tempareas].number;
  1732.         tempareas++;
  1733.     }
  1734.     maxareas=tempareas;
  1735.     fclose(fp);
  1736. }
  1737.  
  1738.  
  1739.  
  1740. void pascal display_current (char enable,int lorange,int hirange) {
  1741.  
  1742.     int register x,y;
  1743.     int register lines=2;
  1744.     char gotone=0;
  1745.  
  1746.     if(enable==1) printm("\n\nCurrently enabled areas:\n\n");
  1747.     else if (enable==2) printm("\n\nCurrently disabled areas:\n\n");
  1748.     else printm("\n\nAll available areas:\n\n");
  1749.     for(x=0;x<maxareas;x++) {
  1750.         if(marea[x].substat1>user.stat[0]) continue;
  1751.         if(marea[x].number<lorange) continue;
  1752.         if(marea[x].number>hirange) continue;
  1753.         if(marea[x].age) {
  1754.             if(marea[x].age>0) {
  1755.                 if(age<(char)marea[x].age) {
  1756.                     continue;
  1757.                 }
  1758.             }
  1759.             else {
  1760.                 if(age>(char)abs(marea[x].age)) {
  1761.                     continue;
  1762.                 }
  1763.             }
  1764.         }
  1765.         if(marea[x].flags) {
  1766.             for(y=0;y<16;y++) {
  1767.                 if(marea[x].flags & (1<<y)) {
  1768.                     if(!(user.attr2 & (1<<y))) {
  1769.                         continue;
  1770.                     }
  1771.                 }
  1772.             }
  1773.         }
  1774.         if(enable==1) {
  1775.             if(do_bits((int)marea[x].number-1,0)!=0) {
  1776.                 lines++;
  1777.                 printfm("%5u.  %s -- %s\n",marea[x].number,marea[x].name,marea[x].descr);
  1778.             }
  1779.         }
  1780.         else if (enable==2) {
  1781.             if(do_bits((int)marea[x].number-1,0)==0) {
  1782.                 lines++;
  1783.                 printfm("%5u.  %s -- %s\n",marea[x].number,marea[x].name,marea[x].descr);
  1784.             }
  1785.         }
  1786.         else {
  1787.             lines++;
  1788.             printfm("%5u.  %s -- %s\n",marea[x].number,marea[x].name,marea[x].descr);
  1789.         }
  1790.         if(lines)gotone=1;
  1791.         if(lines>(int)(user.length-2)) {
  1792.             printm("More? (Y/n) ");
  1793.             if(*genin(1,0,1,1,YESNOM)=='N') {
  1794.                 printm("\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b\n");
  1795.                 return;
  1796.             }
  1797.             printm("\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b");
  1798.             lines=0;
  1799.         }
  1800.     }
  1801.     if(!gotone) printm("None found.\n");
  1802.     if(lines>(int)(user.length-9)) hitreturn();
  1803. }
  1804.  
  1805.  
  1806. word pascal load_user (void) {
  1807.  
  1808.     FILE *fp;
  1809.     int x=0;
  1810.     struct _msetup temp;
  1811.  
  1812.     fp=fopen(searchpath("msetup.usr"),"rb");
  1813.     if(!fp) return 0;    /* Assume new file */
  1814.     while(!feof(fp)) {
  1815.         if(fread(&temp,sizeof(struct _msetup),1,fp)!=1) break;
  1816.         if(temp.userid==mset.userid && temp.node==mset.node) {
  1817.             memcpy(&mset,&temp,sizeof(struct _msetup));
  1818.             break;
  1819.         }
  1820.         x++;
  1821.     }
  1822.     fclose(fp);
  1823.     return x;
  1824. }
  1825.  
  1826.  
  1827. void pascal save_user (word numuser) {
  1828.  
  1829.     FILE *fp;
  1830.  
  1831.     fp=fopen(searchpath("msetup.usr"),"r+b");
  1832.     if(!fp) fp=fopen("msetup.usr","wb");
  1833.     if(!fp) {
  1834.         printm("\nCouldn't create MSETUP.USR!\n");
  1835.         return;
  1836.     }
  1837.     fseek(fp,(long)numuser*(long)sizeof(struct _msetup),SEEK_SET);
  1838.     fwrite(&mset,sizeof(struct _msetup),1,fp);
  1839.     fclose(fp);
  1840. }
  1841.  
  1842.  
  1843. int pascal edit_areas (void) {
  1844.  
  1845.     int register x;
  1846.     char command[7];
  1847.     int bitnum;
  1848.     char hitemp[7]="4096";
  1849.     char lotemp[7]="1";
  1850.     char hi[7];
  1851.     char lo[7];
  1852.     char temp[50];
  1853.  
  1854.   while(1) {
  1855.     printm("\n"
  1856.            "Enter # of area to toggle, or:\n"
  1857.            "Turn [A]ll areas on     Turn All areas [O]ff\n"
  1858.            "[L]ist all areas        List areas o[N]\n"
  1859.            "List areas o[F]f        [R]ange list\n"
  1860.            "[Q]uit (finished)       [H]elp\n"
  1861.            " -> ");
  1862.     strcpy(command,genin(5,0,1,1,ALPHANUM));
  1863.     lstrip(command);
  1864.     rstrip(command);
  1865.     switch ((int)*command) {
  1866.         case 0:        break;
  1867.         case 'A':    for(x=0;x<512;x++) mset.areas[x]=255;
  1868.                     break;
  1869.         case 'O':    for(x=0;x<512;x++) mset.areas[x]=0;
  1870.                     break;
  1871.         case 'L':    display_current(0,1,4095);
  1872.                     break;
  1873.         case 'N':    display_current(1,1,4095);
  1874.                     break;
  1875.         case 'F':    display_current(2,1,4095);
  1876.                     break;
  1877.         case 'R':    printfm("\nStart at #[%s]: ",lotemp);
  1878.                     strcpy(lo,genin(5,0,1,1,NUM));
  1879.                     lstrip(lo);
  1880.                     rstrip(lo);
  1881.                     if(atoi(lo)<1 || atoi(lo)>4096 || !*lo) {
  1882.                         if(*lo) printm("\nInvalid; adjusted to ");
  1883.                         strcpy(lo,lotemp);
  1884.                         printm(lo);
  1885.                     }
  1886.                     strcpy(lotemp,lo);
  1887.                     printfm("\nEnd at # [%s]: ",hitemp);
  1888.                     strcpy(hi,genin(5,0,1,1,NUM));
  1889.                     lstrip(hi);
  1890.                     rstrip(hi);
  1891.                     if(atoi(hi)<atoi(lo) || atoi(hi)>4096 || !*hi) {
  1892.                         if(*hi) printm("\nInvalid; adjusted to ");
  1893.                         strcpy(hi,hitemp);
  1894.                         printm(hi);
  1895.                     }
  1896.                     strcpy(hitemp,hi);
  1897.                     printm("\nList [A]ll, O[N] or O[F]f? [A] ");
  1898.                     *command=*genin(1,0,1,1,ALPHA);
  1899.                     if(*command=='N') display_current(1,atoi(lo),atoi(hi));
  1900.                     else if (*command=='F') display_current(2,atoi(lo),atoi(hi));
  1901.                     else display_current(0,atoi(lo),atoi(hi));
  1902.                     break;
  1903.         case 'Q':   printm("\nSave new settings? (Y/n) ");
  1904.                     if(*genin(1,0,1,1,YESNO)=='N') return 0;
  1905.                     else return 1;
  1906.         case 'H':   readtext(searchpath("MSETUP.HLP"),1);
  1907.                     break;
  1908.         default:    bitnum=atoi(command);
  1909.                     if(bitnum<1 || bitnum>4096) {
  1910.                         printm("\07");
  1911.                         break;
  1912.                     }
  1913.                     strcpy(temp,"Unknown area");
  1914.                     for(x=0;x<maxareas;x++) {
  1915.                         if(marea[x].number==(word)bitnum) {
  1916.                             strcpy(temp,marea[x].name);
  1917.                             break;
  1918.                         }
  1919.                     }
  1920.                     if(do_bits(bitnum-1,3)) printfm("\n\n#%d (%s) toggled on.\n",bitnum,temp);
  1921.                     else printfm("\n\n#%d (%s) toggled off.\n",bitnum,temp);
  1922.                     break;
  1923.     }
  1924.   }
  1925. }
  1926.  
  1927.  
  1928. int pascal do_bits (int x,char what) {
  1929.  
  1930.     int y;
  1931.     char z;
  1932.  
  1933.    if(x<0 || x>4095) {
  1934.         printm("\nInvalid bit #...ignored.\n");
  1935.         return -1;
  1936.    }
  1937.  
  1938.    y=x/8;
  1939.    z=x-(y*8);
  1940.  
  1941. /* printf("\n%d %d %d %d %d",x,y,z,(1<<z),mset.areas[y]); */
  1942.  
  1943.    if (what==1) {            /* Set */
  1944.         mset.areas[y]=mset.areas[y] | (char)(1<<z);
  1945.    }
  1946.    else if (what==2) {        /* ReSet */
  1947.         mset.areas[y]=mset.areas[y] & (char)(~(1<<z));
  1948.    }
  1949.    else if (what==3) {        /* Toggle */
  1950.         if((mset.areas[y] & (char)(1<<z))==0) mset.areas[y]=mset.areas[y] | (char)(1<<z);
  1951.         else mset.areas[y]=mset.areas[y] & (char)(~(1<<z));
  1952.    }
  1953.    return((mset.areas[y] & (char)(1<<z))!=0);    /* Test */
  1954. }
  1955.