home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / PEEK_222.ZIP / PEEKSRC.ZIP / PEEK2.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-18  |  34.9 KB  |  1,194 lines

  1. /* Peeker 2.22 copyright (c) 1988/89/90/91/92 by M. Kimes */
  2.  
  3. #include "peeker.h"
  4.  
  5. extern int _fastcall doswap (char far *, char far *);
  6.  
  7. char * _fastcall myfgets (char *str,size_t num,int handle);
  8. int cdecl     ffprintf (int handle,char *string,...);
  9. void          hitreturn(void);
  10. void _fastcall   cls (void);
  11. char _fastcall   inkey (void);
  12. char _fastcall   carrchk (void);
  13. char _fastcall   fossil (char function, char arg);
  14. char _fastcall   printm (char *text);
  15. char * _fastcall stripcr(char *);
  16. void cdecl    deinitialize (void);
  17. char *        genin (char length,char password,char caps,char hot,char type);
  18. ulong _fastcall  getxbbstime(void);
  19. char *        fidodate(void);
  20. char *        getdttm(void);
  21. char _fastcall   specialkey(char);
  22. char          view (int,char *);
  23. void          filesbbs(char *);
  24. void          extract(char *);
  25. void _fastcall   killall(void);
  26. int  _fastcall   findfile(char *,char *);
  27. int  cdecl    break_handler(void);
  28. char _fastcall   readtext(char *,char *,int,char);
  29. char _fastcall   printg(char *);
  30. char _fastcall   skip_blanks(int fp);
  31. char _fastcall   checkarchivers(char *);
  32. void          chat(void);
  33. void          printinfo(void);
  34. void cdecl    bugprint(char *,...);
  35. void _fastcall   spawnit(char *);
  36. int  cdecl    printfm(char *,...);
  37. char * _fastcall stristr(char *,char *);
  38. char _fastcall   first_non_white (char *a);
  39. int _fastcall    _wherex (void);
  40. int _fastcall    _wherey (void);
  41. void _fastcall   _sleep (int secs);
  42. void _fastcall   cursor (int x, int y);
  43. void _fastcall   curr_cursor (int *x, int *y);
  44. char * _fastcall avatar2ansi (int avatarcode);
  45. char * _fastcall assign (char *d,char *a);
  46. char * _fastcall add_backslash (char *d);
  47. void _fastcall   stat_line (void);
  48. void _fastcall   time_line (void);
  49. void _fastcall   set_mtask(void);
  50. extern void _fastcall (*pause_mtask)(void);
  51. int  _fastcall ansi_out(char *str);
  52. void _fastcall   load_colors(void);
  53.  
  54. struct _archiver {
  55.     char ext[5];
  56.     char move[41];
  57.     char extract[41];
  58.     char list[41];
  59.     char error[41];
  60.     char aname[13];
  61.     char ename[13];
  62.     char id[25];
  63.     char pick[2];
  64.     int  skip;
  65.     int  errline;
  66. };
  67.  
  68. struct _archiver *archiver;
  69.  
  70. struct _directories {
  71.     char *path;
  72.     char *name;
  73. };
  74. struct _directories *dirs[200];
  75.  
  76. char   last_file[13]="";
  77. char   graphics = 0;
  78. word   timelimit = 30;
  79. word   baud = 0;
  80. char   pauser = 0;
  81. char   numlines = 24;
  82. word   lines = 0;
  83. int    seclvl = 5;
  84. ulong  startt = 0;
  85. char   commport = 0;
  86. struct time starter;
  87. struct ffblk filestat;
  88. union  REGS rg;
  89. char   *directory = NULL;
  90. char   *flsearch = NULL;
  91. char   *xtract_dir = NULL;
  92. char   *home_dir = NULL;
  93. char   files_bbs[13] = "FILES.BBS";
  94. char   jumped = 0;
  95. char   tmpnm[7] = "";
  96. char   exok = 0;
  97. char   fbbs = 1;
  98. char   help = 1;
  99. char   exitstuff = 1;
  100. char   username[36] = "I Dunno Who It Is";
  101. char   width = 80;
  102. char   track_dls = 0;
  103. char   chatting = 0;
  104. char   chatted = 0;
  105. char   numarcs = 0;
  106. char   numdirs = 0;
  107. char   debug = 0;
  108. char   *ctlfile = NULL;
  109. char   *reader = NULL;
  110. char   limittries = 0;
  111. char   *peek_now = NULL;
  112. char   useswapdisk = 'C';
  113. char   LIMEMS = 0;
  114. char   swap = 0;
  115. char   buffer[256];
  116. long   maxarc = 0;
  117. long   totalsize = 0;
  118. char   building = 0;
  119. char   swapname[14];
  120. char   cleanup = 1;
  121. int    colors[] = {15,9,11,14,12,9,11,12,3,11,11,11,9,15,14,14,9,14,12,14,15,
  122.                    14,12,14,13,14};
  123.  
  124. extern unsigned _Cdecl _stklen = 8192;    /* Stack length */
  125.  
  126.  
  127.  
  128. void cdecl main(int argc,char *argv[]) {
  129.  
  130.   char s[134];
  131.   char dostring[256];
  132.   char choice,settask = 0;
  133.   char ext[5];
  134.   char *p;
  135.   int  register x;
  136.   int  register y;
  137.   int  fp;
  138.   FILE *fptr;
  139.   struct stat f;
  140.   char error = 0,amenu = 1,gmenu = 1;
  141.  
  142.  
  143.   set_screensize(1);
  144.   ansi_out("\x1b[0m\x1b[2J");
  145.   gettime(&starter);
  146.   ctrlbrk(break_handler);
  147.  
  148.   if (argc == 2 && !stricmp(argv[1],"H")) {
  149. GiveHelp:
  150.     ansi_out("\x1b[0;1;37m\x1b[2J\r\nPeeker v2.22 -- an XBBS Utility.\x1b[0m");
  151.     printinfo();
  152.     ansi_out("\r\nUsage:  PEEKER.EXE args...\r\n");
  153.     ansi_out("! (turns on debug mode)\r\n");
  154.     ansi_out("#<#> (limits # of tries on wildcard to <#> (0-255)) \r\n");
  155.     ansi_out("L<screen lines>\r\n");
  156.     ansi_out("W<screen width>\r\n");
  157.     ansi_out("T<time in minutes>\r\n");
  158.     ansi_out("D<D:\\Path to files directory>\r\n");
  159.     ansi_out("F<name of files.bbs-type file>\r\n");
  160.     ansi_out("A<name of flsearch.ctl-type file>\r\n");
  161.     ansi_out("B<baudrate (0-38400...?)>\r\n");
  162.     ansi_out("G<graphics (0 or 1)>\r\n");
  163.     ansi_out("C<commport (0=COM1)>\r\n");
  164.     ansi_out("S<security level>\r\n");
  165.     ansi_out("X<D:\\Path to extraction directory>\r\n");
  166.     ansi_out("H<D:\\Path to home directory>\r\n");
  167.     ansi_out("R<track d/l's by timestamp (0 or 1)>\r\n");
  168.     ansi_out("V<videomode (0 = direct video, 1 = BIOS)>\r\n");
  169.     ansi_out("M (no multitasker timeslicing)\r\n");
  170.     ansi_out("N<control file name>\r\n");
  171.     ansi_out("E<Filename> (External reader to use locally)\r\n");
  172.     ansi_out("P<Filename> (D:\\Path\\File to peek at on entry)\r\n");
  173.     ansi_out("I<EMS or D:> (Activate swap to EMS or disk)\r\n");
  174.     ansi_out("U<User_Name) (Set user's name if ONLINE.XBS/USERINFO.XBS not available)\r\n");
  175.     ansi_out("Z<maxK> (Set Build archive's maximum component size--0 disables)\r\n");
  176.     cleanup = 0;
  177.     exit(0);
  178.   }
  179.  
  180.   for (x = 1;x < argc;x++) {
  181.     if(*argv[x] == '-' || *argv[x] == '/')
  182.      memmove(argv[x],&argv[x][1],strlen(argv[x]));
  183.     switch (toupper(*argv[x])) {
  184.         case 'L':   numlines = (char)atoi(&argv[x][1]);
  185.                     break;
  186.  
  187.         case 'W':   width = (char)atoi(&argv[x][1]);
  188.                     break;
  189.  
  190.         case 'D':   directory = assign(directory,&argv[x][1]);
  191.                     break;
  192.  
  193.         case 'F':   strncpy(files_bbs,&argv[x][1],12);
  194.                     files_bbs[12] = 0;
  195.                     break;
  196.  
  197.         case 'A':   flsearch = assign(flsearch,&argv[x][1]);
  198.                     break;
  199.  
  200.         case 'B':   baud = (word)atoi(&argv[x][1]);
  201.                     break;
  202.  
  203.         case 'G':   if(atoi(&argv[x][1])) graphics = 1;
  204.                     break;
  205.  
  206.         case 'C':   commport = (char)atoi(&argv[x][1]);
  207.                     break;
  208.  
  209.         case 'S':   seclvl = atoi(&argv[x][1]);
  210.                     break;
  211.  
  212.         case 'X':   xtract_dir = assign(xtract_dir,&argv[x][1]);
  213.                     break;
  214.  
  215.         case 'H':   home_dir = assign(home_dir,&argv[x][1]);
  216.                     break;
  217.  
  218.         case 'R':   if (atoi(&argv[x][1])) track_dls = 1;
  219.                     break;
  220.  
  221.         case 'T':   timelimit = atoi(&argv[x][1]);
  222.                     break;
  223.  
  224.         case '!':   debug = 1;
  225.                     break;
  226.  
  227.         case 'V':   usebios = atoi(&argv[x][1]);
  228.                     break;
  229.  
  230.         case 'M':   settask = 1;
  231.                     break;
  232.  
  233.         case 'N':   ctlfile = assign(ctlfile,&argv[x][1]);
  234.                     break;
  235.  
  236.         case 'E':   reader = assign(reader,&argv[x][1]);
  237.                     break;
  238.  
  239.         case '#':   limittries = (char)atoi(&argv[x][1]);
  240.                     break;
  241.  
  242.         case 'P':   peek_now = assign(peek_now,&argv[x][1]);
  243.                     break;
  244.  
  245.         case 'I':   if (!stricmp(&argv[x][1],"EMS")) LIMEMS = 1;
  246.                     else if (argv[x][1]) useswapdisk = argv[x][1];
  247.                     swap = 1;
  248.                     break;
  249.  
  250.         case 'U':   strncpy(username,&argv[x][1],36);
  251.                     username[35] = 0;
  252.                     if((p = strchr(username,'_')) != NULL) p = " ";
  253.                     break;
  254.  
  255.         case 'Z':   maxarc = (long)(atol(&argv[x][1]) * 1024L);
  256.                     break;
  257.  
  258.         case '?':   goto GiveHelp;
  259.  
  260.         default:    ansi_out("\r\nUnknown argument `");
  261.                     ansi_out(argv[x]);
  262.                     ansi_out("'\r\n");
  263.                     _sleep(1);
  264.     }
  265.   }
  266.  
  267.   if(!settask) set_mtask();
  268.  
  269.   fossil(INIT,0);
  270.   atexit(deinitialize);
  271.  
  272.   stat_line();
  273.  
  274.   if(!ctlfile || !*ctlfile) ctlfile = assign(ctlfile,"PEEKER.CTL");
  275.  
  276.   if (directory && *directory) {
  277.     if (directory[strlen(directory) - 1] == '\\') directory[strlen(directory) - 1] = 0;
  278.   }
  279.  
  280.   if (xtract_dir && *xtract_dir) xtract_dir = add_backslash(xtract_dir);
  281.  
  282.   if (home_dir && *home_dir) home_dir = add_backslash(home_dir);
  283.   if (!home_dir || !*home_dir) {
  284.     getcurdir(0,s);
  285.     sprintf(dostring,"%c:\\%s\\",getdisk() + 'A',s);
  286.     home_dir = assign(home_dir,dostring);
  287.     if(!home_dir) {
  288.       bugprint("Out of memory");
  289.       cleanup = 0;
  290.       exit(1);
  291.     }
  292.   }
  293.  
  294.   load_colors();
  295.  
  296.   sprintf(dostring,"%sPEEKER.HLP",home_dir);
  297.   help = stat(dostring,&f);
  298.   if(help) if(searchpath("PEEKER.HLP") != NULL) help = 0;
  299.  
  300.   sprintf(dostring,"%s%s",home_dir,"PEEKER.MNU");
  301.   amenu = stat(dostring,&f);
  302.   if(amenu) if(searchpath("PEEKER.MNU") != NULL) amenu = 0;
  303.  
  304.   sprintf(dostring,"%s%s",home_dir,"PEEKER.MNG");
  305.   gmenu = stat(dostring,&f);
  306.   if(gmenu) if(searchpath("PEEKER.MNG") != NULL) gmenu = 0;
  307.  
  308.   sprintf(dostring,"%sPEEKER.EXT",home_dir);
  309.   exitstuff = stat(dostring,&f);
  310.   if(exitstuff) if(searchpath("PEEKER.EXT") != NULL) exitstuff = 0;
  311.  
  312.   if (directory && *directory) {
  313.         sprintf(dostring,"%s\\%s",directory,files_bbs);
  314.   }
  315.   else strcpy(dostring,files_bbs);
  316.   fbbs = stat(dostring,&f);
  317.  
  318.   if ((fp = _open("USERINFO.XBS",O_RDONLY | O_BINARY | O_DENYNONE)) != -1) {
  319.         myfgets(username,36,fp);
  320.         username[36] = 0;
  321.         _close(fp);
  322.         stripcr(username);
  323.   }
  324.   else {
  325.         if ((fp = _open("ONLINE.XBS",O_RDONLY | O_BINARY | O_DENYNONE)) != -1) {
  326.             myfgets(username,36,fp);
  327.             username[36] = 0;
  328.             _close(fp);
  329.         }
  330.   }
  331.   if (!*username) strcpy(username,"I Dunno Who It Is");
  332.   username[31] = 0;
  333.  
  334.   if (stat(ctlfile,&f)) {
  335.     printm("\r\nControl file not found.");
  336. CtlError:
  337.     bugprint("Error w/ Control file %s",ctlfile);
  338.     printm("\r\nPlease notify the SysOp.\r\n");
  339.     cleanup = 0;
  340.     exit(3);
  341.   }
  342.  
  343.   if (f.st_size % (long)sizeof(struct _archiver)) {
  344.     printm("\r\nError in Control file");
  345.     goto CtlError;
  346.   }
  347.   numarcs = (int)(f.st_size / (long)sizeof(struct _archiver));
  348.   if(!numarcs) {
  349.     printm("\r\nI don't seem to have access to any archive types!\r\n");
  350.     cleanup = 0;
  351.     exit(1);
  352.   }
  353.   if ((fp = _open(ctlfile,O_RDONLY | O_DENYNONE | O_BINARY)) == -1) {
  354.     printm("\r\nUnable to open Control file");
  355.     bugprint("Can't open \"%s\"",ctlfile);
  356.     goto CtlError;
  357.   }
  358.   archiver = (struct _archiver *)malloc((word)(sizeof(struct _archiver) * numarcs));
  359.     if(!archiver) {
  360.     bugprint("Out of memory");
  361.     cleanup = 0;
  362.     exit(4);
  363.   }
  364.   if (_read(fp,archiver,sizeof(struct _archiver) * numarcs) != sizeof(struct _archiver) * numarcs) {
  365.     printm("\r\nError reading Control file");
  366.     goto CtlError;
  367.   }
  368.   _close(fp);
  369.  
  370.   PurgeIn();
  371.   if (peek_now && *peek_now) {
  372.     if(flsearch) free(flsearch);
  373.     flsearch = NULL;
  374.     p = strrchr(peek_now,'\\');
  375.     if (p) {
  376.         *p = 0;
  377.         directory = assign(directory,peek_now);
  378.         p++;
  379.         strcpy(peek_now,p);
  380.     }
  381.   }
  382.   if (directory && *directory) directory = add_backslash(directory);
  383.   if (peek_now && *peek_now) {
  384.     if(flsearch) free(flsearch);
  385.     flsearch = NULL;
  386.   }
  387.  
  388.   if (flsearch && *flsearch) {
  389.       if ((fp = _open(flsearch,O_RDONLY | O_BINARY | O_DENYNONE)) != -1) {
  390.          printm("\r\nReading directories...");
  391.          while (!eof(fp) && numdirs < 200) {
  392.             if (myfgets(dostring,256,fp) == NULL) break;
  393.             dostring[256] = 0;
  394.             if (*dostring == '\n' || *dostring == ';') continue;
  395.             dirs[numdirs] = (struct _directories *)malloc(sizeof(struct _directories));
  396.             if(!dirs[numdirs]) {
  397.                 bugprint("Out of memory");
  398.                 cleanup = 0;
  399.                 exit(4);
  400.             }
  401.             stripcr(dostring);
  402.             dirs[numdirs]->path = strdup(strtok(dostring," "));
  403.             if(!dirs[numdirs]->path) {
  404.               free(dirs[numdirs]);
  405.               bugprint("Out of memory");
  406.               continue;
  407.             }
  408.             dirs[numdirs]->path = add_backslash(dirs[numdirs]->path);
  409.             if ((word)atoi(strtok(0," ")) > seclvl) continue;
  410.             dirs[numdirs]->name = strdup(strtok(0," "));
  411.             if(!dirs[numdirs]->name) {
  412.               free(dirs[numdirs]->path);
  413.               free(dirs[numdirs]);
  414.               bugprint("Out of memory");
  415.               continue;
  416.             }
  417.             while((p = strchr(dirs[numdirs]->name,'_')) != NULL) *p = ' ';
  418.             printm(".");
  419.             numdirs++;
  420.          }
  421.          _close(fp);
  422.       }
  423.       else bugprint("Unable to open FLSEARCH file");
  424.   }
  425.  
  426.   if (!numdirs && (!directory && !*directory)) {
  427.     printm("\r\nYou don't have access to any directories.\r\n");
  428.     bugprint("Check user's security level or pass a Ddir argument.");
  429.     bugprint("PEEKER H for brief help, or RTFM if required.");
  430.     cleanup = 0;
  431.     exit(0);
  432.   }
  433.  
  434.   if (xtract_dir && *xtract_dir) {
  435.      if (xtract_dir[1] == ':') {
  436.         setdisk(toupper(*xtract_dir) - 'A');
  437.         if (xtract_dir[strlen(xtract_dir) - 1] == '\\') xtract_dir[strlen(xtract_dir) - 1] = 0;
  438.         if (!chdir (xtract_dir)) {
  439.             exok = 1;
  440.             if (*xtract_dir) {
  441.                 xtract_dir = add_backslash(xtract_dir);
  442.             }
  443.             killall();
  444.         }
  445.         else {
  446.           free(xtract_dir);
  447.           xtract_dir = NULL;
  448.         }
  449.      }
  450.   }
  451.  
  452.   getxbbstime();
  453.   ansi_out("\x1b[0m");
  454.   cls();
  455.   if(graphics) printm(avatar2ansi(colors[0]));
  456.   printm("\r\nPeeker v2.22 -- an XBBS Utility.");
  457.   printinfo();
  458.   if (debug) {
  459.     bugprint("\b \b\x1b[1A\04Handling %d archivers",numarcs);
  460.     if (numdirs) {
  461.         bugprint("\b \b\x1b[1A\04Handling %d directories",numdirs);
  462.     }
  463.   }
  464.  
  465.   if (peek_now && *peek_now) {
  466.     if(directory && *directory)
  467.       sprintf(dostring,"%s%s",directory,peek_now);
  468.     else strcpy(dostring,peek_now);
  469.     if (!findfirst(dostring,&filestat,0)) {
  470.         peek_now = assign(peek_now,filestat.ff_name);
  471.         strcpy(s,peek_now);
  472.         printfm("\r\nPeeking at %s...\r\n",peek_now);
  473.         goto DoPeekNow;
  474.     }
  475.     printfm("\r\nCan't find file `%s'\r\n",peek_now);
  476.     cleanup = 0;
  477.     exit(0);
  478.   }
  479.  
  480.   for(;;) {
  481.     if (peek_now && *peek_now) {
  482.          if(exok) {
  483.              if(xtract_dir && *xtract_dir && exok) killall();
  484.              if(!error) {
  485.                 printfm("\r\nExtract from %s? (y-N) ",peek_now);
  486.                  if(*genin(1,0,1,1,YESNO) == 'Y') {
  487.                     extract(peek_now);
  488.                  }
  489.              }
  490.          }
  491.          if(error) {
  492.            cleanup = 0;
  493.            exit(99);
  494.          }
  495.          exit(0);
  496.     }
  497.  
  498.     printm("\r\n");
  499.     stat_line();
  500.     if(graphics) printm(avatar2ansi(colors[1]));
  501.     printfm("\r\n%u mins\r\n",(timelimit - (word)(getxbbstime()) / 60L));
  502.     if(graphics) printm(avatar2ansi(colors[2]));
  503.     printm(" ");
  504.  
  505.     if(!amenu) {
  506.  
  507.         char *menufile = "PEEKER.MNU";
  508.  
  509.         if(graphics && !gmenu) menufile = "PEEKER.MNG";
  510.         if (exok) sprintf(s,"%s%s",home_dir,menufile);
  511.         else strcpy(s,menufile);
  512.         printm("\r\n");
  513.         if (stat(s,&f)) {
  514.           if(searchpath(menufile) != NULL) strcpy(s,searchpath(menufile));
  515.           if (stat(s,&f)) {
  516.             goto NoMenu;
  517.           }
  518.         }
  519.         if (!f.st_size) {
  520.           goto NoMenu;
  521.         }
  522.         if((fp = _open(s,O_RDONLY | O_BINARY | O_DENYNONE)) == -1) {
  523.           goto NoMenu;
  524.         }
  525.         pauser = 0;
  526.  
  527.         while (!eof(fp)) {
  528.           if (myfgets(s,131,fp) == NULL) break;
  529.           s[131] = 0;
  530.           stripcr(s);
  531.           if(s[strlen(s) - 1] != ';') strcat(s,"\r\n");
  532.           else s[strlen(s) - 1] = 0; /* strip off cr/lf on lines ending w/ ; */
  533.           printm(s);
  534.         }
  535.         _close(fp);
  536.     }
  537.     else {
  538. NoMenu:
  539.       if (!fbbs) printm("[L]ist files");
  540.       printm(" [C]ontents");
  541.       if (exok) printm(" [E]xtract");
  542.       if (!help) printm(" [H]elp");
  543.       if (maxarc) printm(" [B]uild");
  544.       printm(" [A]NSI [Q]uit: [Q] ");
  545.     }
  546.  
  547.     choice = *genin(1,0,1,1,ALPHA);
  548.  
  549.     switch (choice) {
  550.         case 'A': graphics = 1 - graphics;
  551.                   printm("NSI ");
  552.                   graphics ? printm("on") : printm("off");
  553.                   if (!graphics) printm("\r\n\x1b[0m\b \b\b \b\b \b\b \b");
  554.                   break;
  555.  
  556.         case 'L': if (!fbbs) {
  557.                     printm("ist\r\n");
  558.                     filesbbs(files_bbs);
  559.                     if (xtract_dir && *xtract_dir) killall();
  560.                   }
  561.                   else printm(BACKSPACE);
  562.                   break;
  563.  
  564.         case 'C': printm("ontents\r\nFile to list: ");
  565.                   *last_file = 0;
  566.                   if (findfile(dostring,s)) break;
  567. DoPeekNow:
  568.                   if (!stricmp(s,"FILES.BBS") || !stricmp(s,files_bbs)) {
  569.                     printm("\r\nThat's not an archive; try [L]ist.\r\n");
  570.                     break;
  571.                   }
  572.                   strcpy(tmpnm,"XXXXXX");
  573.                   if (mktemp(tmpnm) == NULL) {
  574.                         printm("\r\nUnable to create temporary file.\r\n");
  575.                         break;
  576.                   }
  577.                   *ext = 0;
  578.                   if ((p = strrchr(s,'.')) != NULL) strcpy(ext,&p[1]);
  579.                   for(x = 0;x < numarcs;x++) if (!stricmp(ext,archiver[x].ext)) break;
  580.                   if (x == numarcs) x = 0;
  581.                   if (!checkarchivers(archiver[x].aname)) break;
  582.                   if (xtract_dir && *xtract_dir) {
  583.                   if (!stat(s,&f)) {
  584.                       sprintf(dostring,"%s %s",archiver[x].list,s);
  585.                     }
  586.                     else if(directory)
  587.                       sprintf(dostring,"%s %s%s",archiver[x].list,directory,s);
  588.                     else sprintf(dostring,"%s %s",archiver[x].list,s);
  589.                   }
  590.                   else if(directory)
  591.                     sprintf(dostring,"%s %s%s",archiver[x].list,directory,s);
  592.                     else sprintf(dostring,"%s %s",archiver[x].list,s);
  593. SkipDir:
  594.                   printm("\r\nHold on, getting contents...");
  595.                   if((fptr = freopen(tmpnm,"w",stdout)) == NULL) {
  596.                     printm("\r\nFatal error...bye now...\r\n");
  597.                     bugprint("Aw, shit, can't redirect stdout\r\n");
  598.                     exit(1);
  599.                   }
  600.                   spawnit(dostring);
  601.                   fclose(fptr);
  602.                   freopen("CON","w",stdout);
  603.                   setbuf(stdout,NULL);
  604.                   for (y = 0;y < 28;y++) printm(BACKSPACE);
  605.                   strcpy(last_file,s);
  606.                   error = view(x,s);
  607.                   break;
  608.  
  609.         case 0:   printm("Q");
  610.         case 'Q': printm("uit\r\n");
  611.                   exit(0);
  612.  
  613.         case 'H': if (!help) {
  614.                       printm("elp\r\n");
  615.                       if (exok) sprintf(s,"%sPEEKER.HLP",home_dir);
  616.                       else strcpy(s,"PEEKER.HLP");
  617.                       printm("\r\n");
  618.                       if (stat(s,&f)) {
  619.                         if(searchpath("PEEKER.HLP") != NULL) strcpy(s,searchpath("PEEKER.HLP"));
  620.                         if (stat(s,&f)) {
  621. NoHelp:
  622.                            printm("Sorry, no help available...\r\n");
  623.                            break;
  624.                         }
  625.                       }
  626.                       if (!f.st_size) goto NoHelp;
  627.                       if((fp = _open(s,O_RDONLY | O_BINARY | O_DENYNONE)) == -1)
  628.                         goto NoHelp;
  629.                       if(graphics) printm(avatar2ansi(colors[3]));
  630.                       pauser = 1;
  631.  
  632.                       while ((inkey() != ' ') && (!eof(fp))) {
  633.                         if (myfgets(s,81,fp) == NULL) break;
  634.                         s[80] = 0;
  635.                         stripcr(s);
  636.                         if (strlen(s) >= width) lines++;
  637.                         strcat(s,"\r\n");
  638.                         if (printm(s)) break;
  639.                       }
  640.                       pauser = 0;
  641.                       _close(fp);
  642.                   }
  643.                   else printm(BACKSPACE);
  644.                   break;
  645.  
  646.         case 'E': if (exok && xtract_dir && *xtract_dir) {
  647.                     printm("xtract\r\n");
  648.                     extract(NULL);
  649.                   }
  650.                   else printm(BACKSPACE);
  651.                   break;
  652.  
  653.         case 'B':
  654.                   if (exok && maxarc && xtract_dir && *xtract_dir) {
  655.                     killall();
  656.                     printm("uild\r\n");
  657.                     building = 1;
  658.                     extract(NULL);
  659.                     building = 0;
  660.                   }
  661.                   else printm(BACKSPACE);
  662.                   break;
  663.  
  664.         default:  printm(BACKSPACE);
  665.     }
  666.   }
  667. }
  668.  
  669.  
  670. void cdecl bugprint (char *text,...)
  671.  
  672. {
  673.  
  674.  va_list ap;
  675.  va_start(ap,text);
  676.  vsprintf(buffer,text,ap);
  677.  va_end(ap);
  678.  ansi_out("\r\n\04");
  679.  ansi_out(buffer);
  680.  ansi_out("\r\n");
  681.  
  682. }
  683.  
  684.  
  685.  
  686. void printinfo (void)
  687.  
  688. {
  689.   bugprint("Copyright (c) 1988/89/90/91/92 by M. Kimes");
  690.   bugprint("Compiled: %s  %s",__DATE__,__TIME__);
  691. }
  692.  
  693.  
  694.  
  695. char _fastcall checkarchivers (char *fname)
  696.  
  697. {
  698.  
  699.   if (!searchpath(fname)) {
  700.         printm("\r\nSorry, I don't have access to that archiver/dearchiver.\r\n");
  701.         return 0;
  702.   }
  703.   return 1;
  704. }
  705.  
  706.  
  707.  
  708. int _fastcall findfile (char *dostring,char *s) {
  709.  
  710.   struct ffblk f;
  711.   char smart[40]="\r\nDid you mean ";
  712.   word register x=0;
  713.   char temp[13];
  714.   char numtries=0;
  715.   char temporary;
  716.  
  717.  
  718.       if (numdirs) directory = assign(directory,dirs[0]->path);
  719.  
  720.       if(*last_file) printfm("[%s]  ",last_file);
  721.       strcpy(s,genin(13,0,1,0,FLEW));
  722.       if (!*s) {
  723.             if(!*last_file) return 1;
  724.             strcpy(s,last_file);
  725.       }
  726.       if ((strchr(s,'.') == NULL) && (strlen(s) < 9)) {
  727.         if ((strlen(s) < 8) && (s[strlen(s) - 1] != '*')) {
  728.             strcat(s,"*.*");
  729.             printm("*.*");
  730.         }
  731.         else {
  732.             strcat(s,".*");
  733.             printm(".*");
  734.         }
  735.       }
  736.       strcpy(temp,s);
  737.       if (!findfirst(s,&f,0) && xtract_dir && *xtract_dir && !building) {
  738.           if ((strchr(s,'?')) || (strchr(s,'*'))) {
  739.               if (!stricmp(f.ff_name,"FILES.BBS") || !stricmp(f.ff_name,files_bbs)) goto ReTry;
  740.               if(directory) sprintf(dostring,"%s%s",directory,f.ff_name);
  741.               else strcpy(dostring,f.ff_name);
  742.               printfm("%s%s? (Y-n)",smart,f.ff_name);
  743.               temporary = *genin(1,0,1,1,YESNO);
  744.               if (temporary == 'Y') {
  745.                  strcpy(s,f.ff_name);
  746.                  return 0;
  747.               }
  748.           }
  749.           else {
  750.             strcpy(s,f.ff_name);
  751.             return 0;
  752.           }
  753.       }
  754.       else if (xtract_dir && *xtract_dir && !building) killall();
  755. ReTry:
  756.       if(directory) sprintf(dostring,"%s%s",directory,temp);
  757.       else strcpy(dostring,temp);
  758.       if (findfirst(dostring,&f,0)) {
  759.         if (++x<numdirs) {
  760.             directory = assign(directory,dirs[x]->path);
  761.             numtries=0;
  762.             goto ReTry;
  763.         }
  764.         else {
  765.             if (!stricmp(smart,"\r\nHow about ")) goto Cant2;
  766.             if(graphics) printm(avatar2ansi(colors[4]));
  767.             printfm("\r\nCan't find %s\r\n",temp);
  768.             return 1;
  769.         }
  770.       }
  771.       else if (numdirs) {
  772.             if(graphics) printm(avatar2ansi(colors[5]));
  773.             printfm("\r\nIn Area: %s",dirs[x]->name);
  774.             if(graphics) printm(avatar2ansi(colors[6]));
  775.       }
  776.       if ((strchr(dostring,'?')) || (strchr(dostring,'*'))) {
  777. FindLoop:
  778.           if (!stricmp(f.ff_name,"FILES.BBS") || !stricmp(f.ff_name,files_bbs)) goto SkipIt;
  779.           strcpy(s,f.ff_name);
  780.           if(directory) sprintf(dostring,"%s%s",directory,s);
  781.           else strcpy(dostring,s);
  782.           printfm("%s%s? (Y-n-q) ",smart,s);
  783.           temporary = *genin(1,0,1,1,YESNOQ);
  784.           if (temporary == 'Q') return 1;
  785.           if (temporary == 'N') {
  786. SkipIt:
  787.             if (findnext(&f)) {
  788.                 if (++x<numdirs) {
  789.                     directory = assign(directory,dirs[x]->path);
  790.                     numtries = 0;
  791.                     goto ReTry;
  792.                 }
  793.                 else {
  794. Cant2:
  795.                     if(graphics) printm(avatar2ansi(colors[7]));
  796.                     printm("\r\nNo more matching files.\r\n");
  797.                     return 1;
  798.                 }
  799.             }
  800.             numtries++;
  801.             if ((limittries) && (numtries>limittries)) {
  802.                 printm("\r\nWell, try to be a little more specific.\r\n");
  803.                 return 1;
  804.             }
  805.             strcpy(smart,"\r\nHow about ");
  806.             goto FindLoop;
  807.           }
  808.       }
  809.       return 0;
  810. }
  811.  
  812.  
  813. int cdecl break_handler(void) {
  814.  
  815.    deinitialize();
  816.    return 0;
  817. }
  818.  
  819.  
  820. void extract (char *file) {
  821.  
  822.   char fname[14];
  823.   char s[81];
  824.   char dostring[256];
  825.   char ext[5];
  826.   char extfiles[10][14];
  827.   int  register x;
  828.   int  fp;
  829.   char temp = 0;
  830.   char arcstring[37] = "";
  831.   int type = 0;
  832.   struct ffblk f;
  833.   char *p;
  834.  
  835. ReDo:
  836.   extfiles[9][0] = 0;
  837.   if(file == NULL) {
  838.       if(graphics) printm(avatar2ansi(colors[8]));
  839.       if(building) printfm("\r\n%ld bytes total component size allowed.",maxarc);
  840.       if(building && totalsize) {
  841.             printfm("\r\n%ld bytes extracted so far.",totalsize);
  842.             printm("\r\nHit [Enter] alone to create archive.");
  843.             *last_file = 0;
  844.       }
  845.       printm("\r\nFile to extract from: ");
  846.       if (findfile(dostring,s)) {
  847.             if(building && totalsize) {
  848.                 if(!*s) goto DoneBuilding;
  849.                 else goto ReDo;
  850.             }
  851.             return;
  852.       }
  853.       if (!stricmp(s,"FILES.BBS")) {
  854.         printm("\r\nFILES.BBS isn't an archive.\r\n");
  855.         if(building)goto ReDo;
  856.         else return;
  857.       }
  858.   } else strcpy(s,file);
  859.   totalsize = 0;
  860.   strcpy(fname,s);
  861.   if(graphics) printm(avatar2ansi(colors[9]));
  862.   printm("\r\nYou may specify up to nine files to extract (wildcards acceptable).\r\n");
  863.   printm("\r\nHit [Enter] alone when finished.\r\n");
  864.   for (x = 0;x < 9;x++) {
  865.       printfm("\r\nFilename #%d: ",x+1);
  866.       strcpy(extfiles[x],genin(13,0,1,0,FLEW));
  867.       if (!*extfiles[x]) {
  868.         break;
  869.       }
  870.   }
  871.   if (!*extfiles[0] || extfiles[x] == NULL) {
  872.     if(building) goto ReDo;
  873.     else return;
  874.   }
  875.   if(graphics) printm(avatar2ansi(colors[10]));
  876.   printm("\r\nHang on, extracting files...\r\n");
  877.  
  878.   *ext = 0;
  879.   if ((p = strrchr(fname,'.')) != NULL) strcpy(ext,&p[1]);
  880.   *dostring = 0;
  881.  
  882.   for (x = 0;x < numarcs;x++) if (!stricmp(ext,archiver[x].ext)) break;
  883.   if (x == numarcs) type = 0;
  884.   else type = x;
  885.   if (!checkarchivers(archiver[type].ename)) return;
  886.   if (xtract_dir && *xtract_dir) if (!findfirst(fname,&f,0)) {
  887.       sprintf(dostring,"%s %s",archiver[type].extract,fname);
  888.       goto SkipCurDir;
  889.   }
  890.   if(directory)
  891.     sprintf(dostring,"%s %s%s",archiver[type].extract,directory,fname);
  892.   else sprintf(dostring,"%s %s",archiver[type].extract,fname);
  893. SkipCurDir:
  894.   for (x = 0;x < 9;x++) {
  895.     if (!*extfiles[x] || !extfiles[x]) break;
  896.     strcat(dostring," ");
  897.     strcat(dostring,extfiles[x]);
  898.     if (strlen(dostring) > 132) {
  899.         dostring[132] = 0;
  900.         printm("\r\nString overflowed DOS command line limit...all files may not extract\r\n");
  901.         break;
  902.     }
  903.   }
  904.   spawnit(dostring);
  905.   if (xtract_dir && *xtract_dir) unlink(fname);
  906.   if(graphics) printm(avatar2ansi(colors[11]));
  907.   x = findfirst("*.*",&filestat,0);
  908.   if (x) {
  909.     printm("\r\nAttempt failed.\r\n");
  910.     if(building)goto ReDo;
  911.     else return;
  912.   }
  913.   sprintf(dostring,"%sXBBS.LOG",home_dir);
  914.   if((fp=_open(dostring,O_RDWR | O_BINARY | O_DENYWRITE | O_APPEND))==-1)
  915.    fp = creat(dostring,S_IWRITE);
  916.   if(fp != -1) {
  917.     temp++;
  918.     lseek(fp,0L,SEEK_END);
  919.   }
  920.     printm("\r\nExtracted files");
  921.     if(building) printm(" so far");
  922.     printm(":\r\n");
  923.     if (temp) ffprintf(fp,"Extracted files:\r\r\n");
  924.     while (!x) {
  925.     printfm("%-13s -- %lu bytes\r\n",filestat.ff_name,filestat.ff_fsize);
  926.     if (temp) ffprintf(fp,"%-13s -- %lu bytes\r\n",filestat.ff_name,filestat.ff_fsize);
  927.     totalsize += filestat.ff_fsize;
  928.     x = findnext(&filestat);
  929.   }
  930.   if(totalsize && temp)ffprintf(fp,"%lu bytes total\r\n",totalsize);
  931.   if(temp)_close(fp);
  932.   if(!building)totalsize=0;
  933.   else {
  934.     if(totalsize<maxarc) goto ReDo;
  935.     else printm("\r\nMaxed out for this trip...\r\n");
  936.   }
  937. DoneBuilding:
  938.   unlink("PEEKAT.ME");
  939.   if((fp=_open("PEEKAT.ME",O_RDWR | O_BINARY | O_DENYWRITE))==-1)
  940.    fp=creat("PEEKAT.ME",S_IWRITE);
  941.   if(fp!=-1) {
  942.     ffprintf(fp,"This is your PEEKER-prepared archive extracted from ");
  943.     if(!building)ffprintf(fp,fname);
  944.     else ffprintf(fp,"various files");
  945.     ffprintf(fp,".\r\n");
  946.     _close(fp);
  947.   }
  948.  
  949.   strset(arcstring,0);
  950.   printm("\r\n\r\nDo you want your files:\r\n");
  951.   for (x=0;x<numarcs;x++) {
  952.     if (searchpath(archiver[x].aname) && *archiver[x].pick) {
  953.         if(*archiver[x].id && *archiver[x].pick && *archiver[x].pick!=' ') {
  954.             printm(archiver[x].id);
  955.             strcat(arcstring,archiver[x].pick);
  956.             printm("\r\n");
  957.         }
  958.     }
  959.   }
  960.   strcat(arcstring,"Q");
  961.   printm(" -> ");
  962. ReTryThat:
  963.   x = (*genin(1,0,1,1,ALPHANUM));
  964.   if (x == 'Q') {
  965.     printm("uit\r\n");
  966.     killall();
  967.     return;
  968.   }
  969.   if (!x) x = archiver[0].pick[0];
  970.   type = x;
  971.   for (x = 0;x < numarcs;x++) {
  972.     if (type == archiver[x].pick[0]) {
  973.         type = x;
  974.         break;
  975.     }
  976.   }
  977.   if (type >= numarcs) {
  978.     if (debug) bugprint("Can't find selected archiver!");
  979.     printm("\07\r\nTry again: ");
  980.     goto ReTryThat;
  981.   }
  982.   sprintf(dostring,"%s XFILE.%s *.*",archiver[type].move,archiver[type].ext);
  983.   if(graphics) printm(avatar2ansi(colors[12]));
  984.   printm("\r\nPlease hold, recombining files...\r\n");
  985.   spawnit(dostring);
  986.   if (findfirst("XFILE.*",&filestat,0)) {
  987.     printm("\r\nAttempt failed.\r\n");
  988.     killall();
  989.     return;
  990.   }
  991.   if(graphics) printm(avatar2ansi(colors[13]));
  992.   printfm("\07\r\n%s (%lu bytes) is now ready for downloading.\r\n",filestat.ff_name,filestat.ff_fsize);
  993.   if (exitstuff) hitreturn();
  994.   if (!exitstuff) {
  995.       sprintf(dostring,"%sPEEKER.EXT",home_dir);
  996.       if((fp = _open(dostring,O_RDONLY | O_BINARY | O_DENYNONE))==-1) {
  997.         if(searchpath("PEEKER.EXT") != NULL) strcpy(dostring,searchpath("PEEKER.EXT"));
  998.         if((fp = _open(dostring,O_RDONLY | O_BINARY | O_DENYNONE))==-1) {
  999.             bugprint("Can't open %s",dostring);
  1000.             hitreturn();
  1001.             cleanup = 0;
  1002.             exit(100);
  1003.         }
  1004.       }
  1005.       myfgets(s,81,fp);
  1006.       if (strlen(s)) s[strlen(s) - 1] = 0;
  1007.       if (strlen(s)>36) s[36] = 0;
  1008.       strcpy(arcstring,s);
  1009.       while (!eof(fp) && myfgets(s,81,fp)) printm(s);
  1010.       _close(fp);
  1011.       if (!*arcstring) {
  1012.         hitreturn();
  1013.         cleanup = 0;
  1014.         exit (100);
  1015.       }
  1016.       printm("\r\nPlease select: ");
  1017. TryAgain:
  1018.       x = (*genin(1,0,1,1,ALPHANUM));
  1019.       if ((strchr(arcstring,x) == NULL) || (!x)) {
  1020.         printm(BACKSPACE);
  1021.         printm("\07");
  1022.         goto TryAgain;
  1023.       }
  1024.       cleanup = 0;
  1025.       exit((char)x);
  1026.   }
  1027.   cleanup = 0;
  1028.   exit (100);
  1029. }
  1030.  
  1031.  
  1032.  
  1033. void _fastcall spawnit (char *a) {
  1034.  
  1035.    char *e[26];
  1036.    char *p;
  1037.    char *pp;
  1038.    register word x;
  1039.    int level = 0;
  1040.    union REGS r;
  1041.    struct time dos_time;
  1042.  
  1043.  
  1044.    if (debug) bugprint(a);
  1045.    {
  1046.      int oldx,oldy;
  1047.  
  1048.      curr_cursor(&oldx,&oldy);
  1049.      cursor(0,maxy - 1);
  1050.      ansi_out("\x1b[0m\x1b[K");
  1051.      cursor(oldx,oldy);
  1052.    }
  1053.    if (swap) {
  1054.         p = strtok(a," ");
  1055.         if (!p) return;
  1056.         if (!strchr(p,':') && !strchr(p,'\\')) p = searchpath(a);
  1057.         if (!p) {
  1058.             bugprint("No filename to execute.");
  1059.             return;
  1060.         }
  1061.         if(!strchr(p,'.')) {
  1062.             bugprint("No extension on filename.");
  1063.             return;
  1064.         }
  1065.         pp = strchr(p,'.');
  1066.         if(stricmp(pp,".COM") && stricmp(pp,".EXE")) {
  1067.             bugprint("Invalid filename extension.");
  1068.             return;
  1069.         }
  1070.         pp = strtok(0,"\r\n");
  1071.         if (!pp) pp = "";
  1072.         gettime(&dos_time);
  1073.         sprintf(swapname,"%02u%02u%02uPE.EKR",dos_time.ti_hour,dos_time.ti_min,dos_time.ti_sec);
  1074.         level = doswap(p,pp);
  1075.         if (level != (-1)) goto Getlevel;
  1076.         else {
  1077.           if(!debug) bugprint("Couldn't swap");
  1078.             for (x = 0;x < 26;x++) e[x]=NULL;
  1079.             e[0] = p;
  1080.             e[1] = strtok(pp," ");
  1081.             for(x = 2;(e[x] = strtok(0," "));x++) if(x == 25) break;
  1082.             goto DoSpawn;
  1083.           }
  1084.         }
  1085.         for (x = 0;x < 26;x++) e[x] = NULL;
  1086.         e[0] = strtok(a," ");
  1087.         for (x = 1;(e[x] = strtok(0," "));x++) if (x == 25) break;
  1088. DoSpawn:
  1089.         level = (int)spawnvp(P_WAIT,a,e);
  1090. Getlevel:
  1091.         if (!level) {
  1092.          r.h.ah = 77;
  1093.          int86(33,&r,&r);
  1094.          level = (int)r.h.al;
  1095.         }
  1096. Nolevel:
  1097.    set_screensize(1);
  1098.    validate_cursor();
  1099.    stat_line();
  1100.    if (debug) {
  1101.        bugprint("Exit status: %hu",level);
  1102.    }
  1103. }
  1104.  
  1105.  
  1106.  
  1107. void _fastcall killall (void) {
  1108.  
  1109.   char killstring[133];
  1110.   char tempstring[142];
  1111.   struct ffblk f;
  1112.  
  1113.  
  1114.   if (xtract_dir && *xtract_dir) {
  1115.       sprintf(killstring,"%s*.*",xtract_dir);
  1116.       while (!findfirst(killstring,&f,0)) {
  1117.          sprintf(tempstring,"%s%s",xtract_dir,f.ff_name);
  1118.          unlink(tempstring);
  1119.       }
  1120.   }
  1121.  
  1122. }
  1123.  
  1124.  
  1125. ulong _fastcall getxbbstime (void) {
  1126.  
  1127.   int hour,min,sec;
  1128.   struct time dos_time;
  1129.   static ulong xbbs_time = 1L,lasttime = 0L;
  1130.   static int warned;
  1131.  
  1132.  
  1133.  gettime(&dos_time);
  1134.  hour = dos_time.ti_hour - starter.ti_hour;
  1135.  min = dos_time.ti_min - starter.ti_min;
  1136.  sec = dos_time.ti_sec - starter.ti_sec;
  1137.  if (dos_time.ti_hour < starter.ti_hour) hour += 24;
  1138.  xbbs_time = (long)((long)hour * 3600L) + ((long)min * 60L) + (long)sec;
  1139.  
  1140.  if(lasttime != xbbs_time) {
  1141.    lasttime = xbbs_time;
  1142.  
  1143.    if (warned && (((long)timelimit * 60L) > ((xbbs_time + 1L) + 120L)))
  1144.     warned = 0;
  1145.    else if(!warned) {
  1146.      if ((((long)timelimit * 60L) < (xbbs_time + 120L))) {
  1147.  
  1148.         char tempause;
  1149.  
  1150.         warned++;
  1151.         tempause = pauser;
  1152.         pauser = 2;
  1153.         printfm("\r\nWARNING: %ld minutes remaining.\r\n",((long)timelimit - (xbbs_time) / 60L));
  1154.         pauser = tempause;
  1155.      }
  1156.    }
  1157.  
  1158.    if (((long)timelimit * 60L) < (xbbs_time + 1L)) {
  1159.       timelimit = (word)(xbbs_time / 60L) + 4;
  1160.       pauser = 0;
  1161.       printm("\r\nSorry, time to logoff...\r\n");
  1162.       FlushOut();
  1163.       _sleep(1);
  1164.       exit(0);
  1165.    }
  1166.  
  1167.    time_line();
  1168.  }
  1169.  
  1170. juststarting:
  1171.  
  1172.   return xbbs_time;
  1173. }
  1174.  
  1175.  
  1176. void hitreturn(void) {
  1177.  
  1178.   int register x;
  1179.  
  1180.  
  1181.   startt = getxbbstime();
  1182.   lines = 0;
  1183.   printm("\r\n[Enter] to continue...");
  1184.   while ((getxbbstime() - startt) < 241) {
  1185.     if (inkey() == '\r') goto HeDid;
  1186.     (*pause_mtask)();
  1187.   }
  1188.   bugprint("User time-out...");
  1189.   exit (2);
  1190. HeDid:
  1191.  
  1192.   lines = 0;
  1193. }
  1194.