home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / msdos / opus / fvsrc620.arc / FVIEW.C < prev    next >
C/C++ Source or Header  |  1989-05-25  |  35KB  |  1,124 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /* Copyright 1989, Doug Boone.  FidoNet 119/5                               */
  4. /*                              (916) 893-9019 Data                         */
  5. /*                              (916) 891-0748 voice                        */
  6. /*                              P.O. Box 5108, Chico, CA. 95928             */
  7. /*                                                                          */
  8. /* This program is not for sale. It is for the free use with Opus systems.  */
  9. /* You may not sell it in ANY way. If you have an access charge to your     */
  10. /* Bulletin Board, consider this to be like Opus, you can ONLY make it      */
  11. /* available for download in an open area, where non-members can get access */
  12. /*                                                                          */
  13. /* If you need to modify this source code, please send me a copy of the     */
  14. /* changes you've made so that everyone can share in the updates.           */
  15. /*                                                                          */
  16. /* "Don't rip me off!" -- Tom Jennings, FidoNet's founder                   */
  17. /*                                                                          */
  18. /*--------------------------------------------------------------------------*/
  19.  
  20. #include    <stdio.h>
  21. #include    <string.h>
  22. #include    <ctype.h>
  23. #include    <stdlib.h>
  24. #include    <time.h>
  25. #include    <dos.h>
  26. #ifdef TURBOC
  27. #include    <dir.h>
  28. #include    <alloc.h>
  29. #else
  30. #include    <malloc.h>
  31. #endif
  32. #include    <io.h>
  33. #include    <fcntl.h>
  34. #include    <dos.h>
  35. #include    <conio.h>
  36. #include    <errno.h>
  37. #include    <sys\types.h>
  38. #include    <sys\stat.h>
  39. #include    <opus.h>
  40. #include    <process.h>
  41. #include    <signal.h>
  42. #include    "archdr.h"
  43. #include    "fview.h"
  44. #define     VER     "06.20"
  45.  
  46. #ifdef BOTH
  47. #define DOLZH
  48. #define PAKIT
  49. #endif
  50.  
  51. extern  int unzip(char *,char *);
  52. extern    int    unpak(char *,char *);
  53. extern  int unlzh(char *,char *);
  54.  
  55. void main(int argc, char *argv[])
  56. {
  57.     int     i;
  58.     char    *result;
  59.     char    Log_path[MAX_PATH];
  60.     long    now;
  61.  
  62. #ifdef TURBOC
  63.     struct  dfree  *space;
  64. #else
  65.     struct  diskfree_t  space;
  66. #endif
  67.  
  68.     signal(SIGINT,handler);        /* Set the ^C handler to internal */
  69.     tzset();         /* We're going to play with the time so..... */
  70.     *Sys_Path = EOS;
  71.     sdisplay = locputs;        /* set ptrs to local functions */
  72.     get_a_char = getch;
  73.     chk_keyboard = kbhit;
  74.     time(&quit_time);        /* Get the current time */
  75. #ifdef  TDEBUG
  76.     quit_time += 1800L;        /* 30 minutes while debugging */
  77. #else
  78.     quit_time += 300L;        /* Otherwise, five minutes */
  79. #endif
  80.     strcpy(dearc_path,"C:\\Dearc\\");        /* Set defaults */
  81.     strcpy(Log_path,"Fview");
  82.  
  83.     for (i=1; i<argc; i++) {
  84.         result = strupr(argv[i]);
  85.         if ((result = strstr(argv[i],".CTL")) != NULL) {
  86.             flags |= OPUS_10;
  87.             result--;
  88.             if (isxdigit(*result))
  89.                 if (isdigit(*result))
  90.                     task = *result -'0';
  91.                 else
  92.                     task = *result - 'A' + 10;
  93.             else
  94.                 task = 0;
  95. #ifdef SDEBUG
  96.             fprintf(Log_fp,"FVIEW Task = %d  %s\n",task,result);
  97.             printf("Task = %d  Result = %s\n",task,result);
  98. #endif
  99.             }
  100.         result = argv[i];
  101. #ifdef SDEBUG
  102.         printf("%03i   %s\n",i,argv[i]);
  103.         fprintf(Log_fp,"FVIEW Arg: %2d  %s\n",i,argv[i]);
  104. #endif
  105.  
  106.         if (*result == '-' ||
  107.             *result == '/') {
  108.             result++;
  109.             switch(*result) {
  110.  
  111.                 case 'B':   baud = atoi(++result);
  112.                             flags |= FOSSIL;
  113.                             break;
  114.  
  115.                 case '0':   flags |= OPUS_10;
  116.                             break;
  117.  
  118.                 case 'D':    strcpy(dearc_path,++result);
  119.                             break;
  120.  
  121.                 case 'L':    strcpy(Log_path,++result);
  122.                             break;
  123.  
  124.                 case 'S':   strcpy(Sys_Path,++result);
  125.                             break;
  126.  
  127.                 case 'G':    flags |= DEBUG;
  128.                             break;
  129.  
  130.                 case 'N':    flags |= NO_SHOW;
  131.                             break;
  132.  
  133.                 case 'P':   port = atoi(++result);
  134.                             flags |= FOSSIL;
  135.                             break;
  136.  
  137.                 case 'T':    task = atoi(++result);
  138.                             break;
  139.  
  140.                 case 'W':    flags |= WATCH;
  141.                             break;
  142.  
  143.                 }        /* End of switch */
  144.             }        /* End of reading params */
  145.         }        /* End of first for() loop searching for params */
  146.     check_cfg(Log_path);
  147.     result = getenv("FVIEW");
  148.     if (*result != EOS)
  149.         parse_env(result,Log_path);
  150.     strcat(Log_path,".Log");
  151.     Log_fp = fopen(Log_path,"at");
  152.     time(&now);
  153.     fprintf(Log_fp,"FVIEW Coming online %s",ctime(&now));
  154.     if (flags & DEBUG)  {
  155.         for (i=0;i<argc;i++)
  156.             fprintf(Log_fp,"ARG %02d = %s\n",i,argv[i]);
  157. #ifdef TURBOC
  158.         fprintf(Log_fp,"Free Memory = %u\n",coreleft());
  159. #else
  160.         fprintf(Log_fp,"Free Memory = %u\n",_memavl());
  161. #endif
  162.         }
  163.  
  164.     if ((i = strlen(Sys_Path)) > 0) {
  165.         if (Sys_Path[--i] != '\\')
  166.             strcat(Sys_Path,"\\");
  167.         }
  168.  
  169.     i = strlen(dearc_path)-1;
  170.     if (dearc_path[i] == '\\')
  171.         dearc_path[i] = EOS;
  172.  
  173.             /* Check to see if there's actually free disk space */
  174.  
  175. #ifdef TURBOC
  176.     space = (struct dfree *) malloc(sizeof(struct dfree));
  177.     getdfree(dearc_path[0]-'@',space);
  178.     dearc_free = space->df_avail;
  179.     dearc_free *= space->df_bsec;
  180.     dearc_free *= space->df_sclus;
  181.     dearc_free /= 1024L;
  182.     free(space);
  183. #else
  184.     if (_dos_getdiskfree(dearc_path[0]-'@',&space) == 0) {
  185.         dearc_free = (long) space.avail_clusters;
  186.         dearc_free *= (long) space.sectors_per_cluster;
  187.         dearc_free *= (long) space.bytes_per_sector;
  188.         } 
  189. #endif
  190.  
  191.     if (flags & DEBUG)
  192.         fprintf(Log_fp,"Free space in dearc directory = %ld\n",dearc_free);
  193.     if (task > 1) {
  194.         sprintf(apath,"%s\\%02X",dearc_path,task);
  195.         strcpy(dearc_path,apath);
  196.         }
  197.     if (flags & DEBUG)
  198.         fprintf(Log_fp,"FVIEW Dearc path = %s\n",dearc_path);
  199.  
  200.     if ((i = access(dearc_path,04)) != 0) {
  201.         fprintf(Log_fp,"FVIEW ERROR Can't access %s Exitting\n",dearc_path);
  202.         sdisplay("\nSorry, Sysop hasn't configured this properly yet.\n");
  203.         terminate(5);
  204.         }
  205.  
  206.     if (flags & OPUS_10)
  207.         get_path("lastuse");
  208.     else
  209.         get_path("lastus");
  210.  
  211.     if (flags & FOSSIL)
  212.         load_fossil();
  213.  
  214. /*--------------------------------------------------------------------------*/
  215. /* This is the loop where the actual work is done. Everything until here    */
  216. /* was just initialization.                                                 */
  217. /*--------------------------------------------------------------------------*/
  218.     do {
  219.         line %= (screen -2);
  220.         i = get_names();
  221.         if (quit_time < time(NULL))
  222.             ctrl_err = 0;
  223.         } while (i && ctrl_err);
  224.     terminate(0);
  225. }
  226.  
  227.  
  228. /*--------------------------------------------------------------------------*/
  229. /* Get the current file area path                                           */
  230. /*--------------------------------------------------------------------------*/
  231.  
  232. void get_path(char *result)
  233. {
  234.     struct  _sys    *system;
  235.     FILE    *infp;
  236.     char    luser[MAX_PATH];
  237.  
  238.     system = (struct _sys *) malloc(sizeof(struct _sys));
  239.  
  240.     if (task == 0)
  241.         sprintf(luser,"%sLASTUSER.BBS",Sys_Path);
  242.     else {
  243.         if (flags & OPUS_10)
  244.             sprintf(luser,"%s%s%X.BBS",Sys_Path,result,task);
  245.         else
  246.             sprintf(luser,"%s%s%02X.BBS",Sys_Path,result,task);
  247.         }
  248.  
  249.     if (flags & DEBUG)
  250.         fprintf(Log_fp,"Reading %s\n",luser);
  251.     if ((infp = fopen(luser,"rb")) == NULL) {
  252.         fprintf(Log_fp,"Can't open lastuser.bbs %s\n",luser);
  253.         fclose(infp);
  254.         terminate(1);
  255.         }
  256.     fread(last,sizeof(struct _usr),1,infp);
  257.     fclose(infp);
  258.     fprintf(Log_fp,"FVIEW User = %s\n",last[0].name);
  259.     screen = (int)last[0].len;
  260.  
  261.     if (last[0].help == 0x06) {
  262.         help();
  263.         if (!(flags & NO_SHOW))
  264.             list_help();
  265.         }
  266.  
  267.     if (last[0].Bits & MORE_PROMPT)
  268.         flags |= WANTS_MORE;
  269.  
  270.     if (last[0].files >0) {
  271.         if (flags & OPUS_10)
  272.             sprintf(apath,"SYSTEM%d.BBS",last[0].files);
  273.         else
  274.             sprintf(apath,"SYSTEM%X.BBS",last[0].files);
  275.         }
  276.     else
  277.         strcpy(apath,"SYSTEM.BBS");
  278.     strcat(Sys_Path,apath);
  279.     if ((infp = fopen(Sys_Path,"rb")) == NULL)
  280.         terminate(2);
  281.     fread(system,sizeof(struct _sys),1,infp);
  282.     fclose(infp);
  283.     strcpy(file_path,system->filepath);
  284.     fprintf(Log_fp,"FVIEW Area = %03d  FilePath = %s\n",last[0].files,file_path);
  285.     free(system);
  286.     return;
  287. }
  288.  
  289. /*--------------------------------------------------------------------------*/
  290. /* If user is on remotely, load the FOSSIL                                  */
  291. /*--------------------------------------------------------------------------*/
  292.  
  293. void load_fossil(void)
  294. {
  295. #ifdef SDEBUG
  296.     printf("Loading FOSSIL\n");
  297. #endif
  298.     if (flags & FOSSIL) {
  299.         if (CkFossilCD()) {
  300.             GetDriverInfo();
  301.             Comm_Purge_out();
  302.             Comm_Purge_in();
  303.             if (flags & WATCH)
  304.                 Comm_Watch(1);        /* turn FOSSIL watchdog on */
  305.             sdisplay = fosputs;        /* set ptrs to fossil functions */
  306.             get_a_char = Comm_Receive;
  307.             chk_keyboard = Comm_Char_Avail;
  308.             }        /* End of succesful FOSSIL install */
  309.         }        /* End of installing FOSSIL */
  310. }
  311.  
  312. /* ====================================================================
  313.  * common termination routine
  314.  * restore environment and exit to dos
  315.  * ====================================================================
  316.  */
  317. void terminate(int stat)
  318. {
  319.     char    temp[80];
  320.     long    now;
  321.  
  322.     flags &= ~MORE;
  323.     sprintf(temp,"\n\n Sysop of 119/5 Thanks you for using FView v. %s : %s\n\n",VER,__DATE__);
  324.     if (!(flags & FOSSIL))
  325.         sdisplay(temp);
  326.     unlink(mbr_path);
  327.     if(flags & FOSSIL) {
  328.         if (Comm_CD())
  329.             sdisplay(temp);
  330.         Comm_Purge_out();
  331.         Comm_Purge_in();
  332.         if (flags & WATCH)
  333.             Comm_Watch(0);        /* turn FOSSIL watchdog off */
  334.         }
  335.     time(&now);
  336.     fprintf(Log_fp,"FVIEW Exiting(%u) %s\n",stat,ctime(&now));
  337.     fclose(Log_fp);
  338.     signal(SIGINT,SIG_DFL);
  339.     exit(stat);
  340. }
  341.  
  342. /*--------------------------------------------------------------------------*/
  343. /* Look at each matching archive file, get full names                       */
  344. /*--------------------------------------------------------------------------*/
  345.  
  346. void file_name(char *start)
  347. {
  348.     int     done;
  349.     int     success;
  350.     long    now;
  351. #ifdef TURBOC
  352.     struct  ffblk   ffblk;
  353. #else
  354.     struct  find_t  cfile;
  355. #endif
  356.     char    name[MAX_PATH];
  357.     char    temp_path[MAX_PATH];
  358.     int     infile;        /* file handle */
  359.     char    *firstchar;
  360.     char    *result;
  361.  
  362.     if (flags & DEBUG)
  363.         fprintf(Log_fp,"In filename(): %s\n",start);
  364.  
  365.     if ((firstchar = (char *) malloc(2)) == NULL) {
  366.         fprintf(Log_fp,"Failed to allocate memory for FIRSTCHAR\n");
  367.         return;
  368.         }
  369.     result = strrchr(start,'\\');
  370.     if (result != NULL)
  371.         *++result = '\0';
  372.     else if ((result = strrchr(start,':')) != NULL)
  373.             *++result = '\0';
  374.     else result = start;
  375.     if (strncmp(result,".",1)==0)
  376.         strcpy(result,"*.*");
  377.     strcpy(temp_path,file_path);
  378.     strcpy(apath,file_path);
  379.     strcat(temp_path,result);
  380. #ifdef TURBOC
  381.     done = findfirst(temp_path,&ffblk,0);
  382. #else
  383.     done = _dos_findfirst(temp_path,_A_NORMAL,&cfile);
  384. #endif
  385.     while (ctrl_err && done == 0) {
  386.         strcpy(name,file_path);
  387.  
  388. #ifdef TURBOC
  389.         strcat(name,ffblk.ff_name);
  390. #else
  391.         strcat(name,cfile.name);
  392. #endif
  393.         time(&now);
  394.         fprintf(Log_fp,"FVIEW %s %s",name,ctime(&now));
  395.         if (flags & FOSSIL && !(Comm_CD()))
  396.             terminate(3);
  397.         infile = open(name,O_RDONLY|O_BINARY);
  398.         if (infile > 0)
  399.             success = read(infile,firstchar,2);
  400.         close(infile);
  401.         flags &= ~0xf000;
  402.         switch(toupper(firstchar[0])) {
  403.             case 0x1a   :   flags |= ARC;        /* Get archive members */
  404.                                success = lstarc(name);
  405.                                                 /* Get text inside archive */
  406.                             if ((success == 0) && (flags & VIEW) &&
  407.                                 !(flags & NO_SHOW))
  408.                                 success = get_mbr_name(name);
  409.                             break;
  410.  
  411.             case 'Z'    :   flags |= ZOO;
  412.                             success = do_zoo(name);
  413.                             break;
  414.  
  415.             case 'P'    :   flags |= ZIP;
  416.                             success = do_zip(name);
  417.                             if (success == 0 && flags & VIEW &&
  418.                                 !(flags & NO_SHOW))
  419.                                 success = get_mbr_name(name);
  420.                             break;
  421.  
  422.             case 'M'    :   play("%s is an EXE file, not an archive\n",
  423. #ifdef TURBOC
  424.                                 ffblk.ff_name);
  425. #else
  426.                                 cfile.name);
  427. #endif
  428.                             break;
  429.  
  430.             default     :   success = read_lzh(name);
  431. #ifdef DOLZH
  432.                             if (success == 0 && flags & VIEW &&
  433.                                 !(flags & NO_SHOW))
  434.                                 success = get_mbr_name(name);
  435.                             else {
  436. #endif
  437.                                 if (success < 0)
  438.                                       success = read_dwc(name);
  439. #ifdef DOLZH
  440.  
  441.                                 }
  442. #endif
  443.                             break;
  444.             }
  445.         if (success < 0) {
  446. #ifdef TURBOC
  447.             sprintf(temp_path,"\n%s Not an archive file\n\n",ffblk.ff_name);
  448. #else
  449.             sprintf(temp_path,"\n%s Not an archive file\n\n",cfile.name);
  450. #endif
  451.             sdisplay(temp_path);
  452.             }
  453. #ifdef TURBOC
  454.         done = findnext(&ffblk);
  455. #else
  456.         done = _dos_findnext(&cfile);
  457. #endif
  458.         if (FOSSIL & flags && !(Comm_CD()))
  459.             done = 1;
  460.         if (success == -1 && ctrl_err == 0) {
  461.             ctrl_err = 1;
  462.             done = 1;
  463.             }
  464.         if (!(ctrl_err))
  465.             done = 1;
  466.         }        /* end of findfirst/findnext loop */
  467.     free(firstchar);
  468.     return;
  469. }
  470.  
  471. /*--------------------------------------------------------------------------*/
  472. /* Get archive/file name(s) from user                                       */
  473. /*--------------------------------------------------------------------------*/
  474.  
  475. int get_names(void)
  476. {
  477.     char    *temp;
  478.     char    *buf;
  479.     char    fname[50];
  480.  
  481.     if (flags & DEBUG)
  482.         fprintf(Log_fp,"Getting names, File-Path = %s\n",file_path);
  483.  
  484.     temp = (char *) malloc(50);
  485.     buf = temp;
  486.     *mbr = EOS;
  487.     memset(temp,'\0',50);
  488.     ctrl_err = 1;
  489.     if (time(NULL) > quit_time)
  490.         terminate(1);
  491.     sdisplay("\n\n  Contents of which file? [ ? for help]  ");
  492.     get_string(temp);
  493.  
  494.     if ((strlen(temp) == 0) ||
  495.         (stricmp(temp,"quit") == 0)) {
  496.         free(temp);
  497.         return(0);
  498.         }
  499.  
  500.     if (flags & WANTS_MORE)
  501.         flags |= MORE;
  502.  
  503.     line %= (screen-2);
  504.  
  505.     if (stricmp(temp,"help") == 0) {
  506.         help();
  507.         if (!(flags & NO_SHOW))
  508.             list_help();
  509.         return(1);
  510.         }
  511.  
  512.     if (strlen(temp) == 1) {
  513.         switch(*temp) {
  514.             case 'Q':   free(temp);return(0);
  515.  
  516.             case 'V':
  517.             case 'L':   flags |= VIEW;
  518.                         file_name(++buf);
  519.                         ctrl_err = 1;
  520.                         return(1);
  521.  
  522.             case 'H':
  523.             case '?':
  524.             default :   help();
  525.                         if (!(flags & NO_SHOW))
  526.                             list_help();
  527.                         return(1);
  528.             }
  529.         }
  530.     buf = strchr(temp,' ');
  531.     if (buf != NULL) {
  532.         if (temp[1] == ' ') {
  533.             if (*temp == 'V' || *temp == 'L') {
  534.                 flags |= VIEW;
  535.                 strcpy(fname,++buf);
  536.                 if ((buf=strchr(fname,' ')) != NULL) {
  537.                     *buf = EOS;
  538.                     strcpy(mbr,++buf);
  539.                     }
  540.                 file_name(fname);
  541.                 ctrl_err = 1;
  542.                 return(1);
  543.                 }
  544.             }
  545.         else {
  546.             flags |= VIEW;
  547.             *buf = EOS;
  548.             ++buf;
  549.             strcpy(mbr,buf);
  550.             file_name(temp);
  551.             ctrl_err = 1;
  552.             return(1);
  553.             }
  554.         }
  555.     else {
  556.         flags &= ~VIEW;
  557.         file_name(temp);
  558.         ctrl_err = 1;
  559.         }
  560.     return(1);
  561. }
  562.  
  563. /*--------------------------------------------------------------------------*/
  564. /* Control Break handler                                                    */
  565. /*--------------------------------------------------------------------------*/
  566.  
  567. void handler(void)
  568. {
  569.  
  570.     signal(SIGINT,SIG_IGN);
  571.     ctrl_err = 0;
  572.     if (flags & FOSSIL) {
  573.         Comm_Purge_in();
  574.         Comm_Purge_out();
  575.         }
  576.     signal(SIGINT,handler);
  577. }
  578.  
  579. void help(void)
  580. {
  581.     sdisplay("\n\n This program will list the contents of any of the existing archive\n");
  582.     sdisplay(" format.  You need to specify a file name, and wildcards will be allowed.\n");
  583.     sdisplay(" Pres <ENTER> or type 'quit' when done and you'll be returned to the BBS.\n\n");
  584.     if (time(NULL) > quit_time)
  585.         terminate(1);
  586.     return;
  587. }
  588.  
  589. void list_help(void)
  590. {
  591.     sdisplay(" If you want to see a text file WITHIN an archive, start the line with a \n");
  592.     sdisplay(" 'V' followed by a space character, then the file name. You'll be prompted\n");
  593.     sdisplay(" for a member name. Only '*'-type wildcards here. Or, you can give an archive\n");
  594.     sdisplay(" name and the internal files you'd like listed.  Something like this:\n\n");
  595.     sdisplay("        Contents of which file?  V *.ARC\n        Contents of which file? ARCVIEW.* ARCVIEW.C\n");
  596.     sdisplay("        Contents of which file?  *.ARC *.DOC\n        Contents of which file? *.* READ.ME\n\n");
  597.     if (time(NULL) > quit_time)
  598.         terminate(1);
  599.     return;
  600. }
  601.  
  602. /*--------------------------------------------------------------------------*/
  603. /* Print out the list of file names inside an archive that's already been   */
  604. /* read in. Used for getting the name of the text file to display.          */
  605. /*--------------------------------------------------------------------------*/
  606.  
  607. void short_list(char *infile)
  608. {
  609.     int     i = 0;
  610.  
  611.     ctrl_err = 1;
  612.     if (time(NULL) > quit_time)
  613.         terminate(1);
  614.     play("\nList of files in %s\n\n",infile);
  615.     do {
  616.         play(" %14s %5ik    ",member[i].name,member[i].size);
  617.         i++;
  618.         if ((i % 3) == 0)
  619.             sendbyte('\n');
  620.         } while (i <= mem_used);
  621.     sendbyte('\n');
  622.     return;
  623. }
  624. /*--------------------------------------------------------------------------*/
  625. /* Get the name of a member of an archive from a user                       */
  626. /*--------------------------------------------------------------------------*/
  627.  
  628. int get_mbr_name(char *name)
  629. {
  630.     char    *buf;
  631.     char    *get_file;
  632.     int     i;
  633.     int     test = 0;
  634.  
  635. #ifdef DOLZH
  636.     if (!(flags & (ARC|ZIP|LZH))) {
  637. #else
  638.     if (!(flags & (ARC|ZIP))) {
  639. #endif
  640.         sdisplay("\nSorry, Can't handle this type of file.\n\n");
  641.         return(1);
  642.         }
  643.  
  644.     get_file = (char *)malloc(20);
  645.     do {
  646.         if (time(NULL) > quit_time)
  647.             terminate(1);
  648.         if (strlen(mbr) == 0) {
  649.             short_list(name);
  650.             sdisplay("\nWhich file?  [QUIT to stop. ? for help]   ");
  651.             get_string(get_file);
  652.             }
  653.         else
  654.             strcpy(get_file,mbr);
  655.  
  656.         if (strlen(get_file) < 1) {
  657.             free(get_file);
  658.             ctrl_err = 1;
  659.             return(1);
  660.             }
  661.         else if ((strstr(get_file,".COM")) != NULL ||
  662.             (strstr(get_file,".ARC")) != NULL ||
  663.             (strstr(get_file,".ZIP")) != NULL ||
  664.             (strstr(get_file,".PAK")) != NULL ||
  665.             (strstr(get_file,".ZOO")) != NULL ||
  666.             (strstr(get_file,".EXE")) != NULL ||
  667.             (strstr(get_file,".OBJ")) != NULL) {
  668.             play("Can't list %s\n",get_file);
  669.             free(get_file);
  670.             return(1);
  671.             }
  672.         else if (strcmp(get_file,"QUIT") == 0) {
  673.             free(get_file);
  674.             ctrl_err = 0;
  675.             return(0);
  676.             }
  677.         else if (strcmp(get_file,"HELP") == 0) 
  678.              list_help();
  679.  
  680.         else if (strchr(get_file,'*') != NULL) {
  681.             if ((test = do_wild(name,get_file)) == -1) {
  682.                 free(get_file);
  683.                 return(0);
  684.                 }
  685.             else
  686.                 continue;
  687.             }
  688.         else {
  689.             for (i=0;i<=mem_used;i++) {
  690.                 ctrl_err = 1;
  691.                 if (time(NULL) > quit_time) {
  692.                     ctrl_err = 0;
  693.                     return(0);
  694.                     }
  695.                 if (validate(get_file,member[i].name)) {
  696.                     test++;
  697.                     show_file(name,member[i].name);
  698.                     ctrl_err = 1;
  699.                     }
  700.                 }
  701.             *mbr = EOS;
  702.             *get_file = EOS;
  703.             }        /* No wildcards */
  704.         } while (get_file && ctrl_err);
  705.  
  706.     if (test == 0) {
  707.         if ((buf = strrchr(name,'\\')) != NULL)
  708.             play("No matches found in %s\n",buf);
  709.         else
  710.             play("No matches found in %s\n",name);
  711.         }
  712.     free(get_file);
  713.     ctrl_err = 1;
  714.     return(1);
  715. }
  716.  
  717. /*--------------------------------------------------------------------------*/
  718. /* Deal with wildcard requests by prompting users for each archive          */
  719. /*--------------------------------------------------------------------------*/
  720.  
  721. do_wild(char *name, char *get_file)
  722. {
  723.  
  724.     int     i;
  725.     int     test = 0;
  726.     char    ch;
  727.     char    *check;
  728.  
  729.     check = strrchr(name,'\\');
  730.     check++;
  731.     for (i=0;i<=mem_used;i++) {
  732.         ctrl_err = 1;
  733.         if (validate(get_file,member[i].name)) {
  734.             test++;
  735.             if (dearc_free > member[i].size) {
  736.                 if (time(NULL) > quit_time)
  737.                     terminate(1);
  738.                 if (strlen(mbr) != 0) {
  739.                     play("\n List %14s in %s?\n\n",member[i].name,check);
  740.                     sdisplay("      Y)ES (default)          N)o             S)top this archive\n");
  741.                     sdisplay("      E)nd wildcards          Q)uit to OPUS    ");
  742.                     if (!ctrl_err)
  743.                         ch = 'E';
  744.                     else
  745.                         ch = (char) get_a_char();
  746.                     sendbyte('\n');
  747.                     switch(ch) {
  748.                         case 'Q':
  749.                         case 'q':     terminate(0);
  750.                                       break;
  751.                         case 'S':
  752.                         case 's':     ctrl_err = 1;
  753.                                       return(-1);
  754.                         case 'E':
  755.                         case 'e':     ctrl_err = 0;
  756.                                       *mbr = EOS;
  757.                                       *name = EOS;
  758.                                       return(-1);
  759.  
  760.                         case 'n':
  761.                         case 'N':     continue;
  762.  
  763.                         default :     show_file(name,member[i].name);
  764.                                       break;
  765.                         }        /* Do we really want to do this? */
  766.                     }
  767.                 else
  768.                     show_file(name,member[i].name);
  769.                 }        /* There's enough free disk space */
  770.             else  {
  771.                 fprintf(Log_fp,"Not enough disk space to unpack %s : %ldK\n",
  772.                     member[i].name,member[i].size);
  773.                 sdisplay("Sorry, can't unpack that file, too large...\n");
  774.                 if (time(NULL) > quit_time)
  775.                     terminate(1);
  776.                 }
  777.             }        /* End of validating file name */
  778.         }        /* End of FOR loop */
  779.     ctrl_err = 0;
  780.     return(test);
  781. }
  782.  
  783. /*--------------------------------------------------------------------------*/
  784. /* Shell to un-archive a file                                               */
  785. /*--------------------------------------------------------------------------*/
  786.  
  787. void show_file(char *name,char *member)
  788. {
  789.     int     result = 100;
  790.     char    get_file[MAX_PATH];
  791.  
  792.  
  793.     sdisplay("\nWorking.....\n");
  794.     sprintf(get_file,"%s\\%s",dearc_path,member);
  795.     if (flags & WANTS_MORE)
  796.         flags |= MORE;
  797.     line %= (screen -2);
  798.     ctrl_err = 1;
  799.     if (flags & DEBUG) {
  800.  
  801. #ifdef TURBOC
  802.         fprintf(Log_fp,"Free Memory = %u\n",coreleft());
  803. #else
  804.         fprintf(Log_fp,"Free Memory = %u\n",_memavl());
  805. #endif
  806.         fprintf(Log_fp,"Output = %s\nInput = %s\nMember = %20s  Flag = %04X\n",
  807.             get_file,name,member,flags);
  808.         }
  809.     if (flags & ARC)
  810. #ifdef PAKIT
  811.                     result = unpak(name,get_file); 
  812. #else
  813.                     result = spawnlp(P_WAIT,"pak.exe","pak.exe",
  814.                         "ewa",name,get_file,NULL);
  815. #endif
  816.     else if (flags & ZIP)
  817.                     result = unzip(name,get_file);
  818.  
  819. #ifdef DOLZH
  820.     else if (flags & LZH)
  821.                     result = unlzh(name,get_file);
  822. #endif
  823.  
  824.     if (result == 0)
  825.         list_file(get_file);
  826.     else {
  827.         play("Error reading %s from %s\n",member,name);
  828.         fprintf(Log_fp,"Error %02d Reading %s from %s\n",result,member,name);
  829.         if (result <0)
  830.             terminate(errno);
  831.         }
  832.     unlink(get_file);
  833.     return;
  834. }
  835.  
  836. /*--------------------------------------------------------------------------*/
  837. /* List the actual text that has been pulled out of the archive             */
  838. /*--------------------------------------------------------------------------*/
  839.  
  840. void list_file(char *name)
  841. {
  842.     char    *one_line;
  843.     char    *result;
  844.     int     count;
  845.     FILE    *infp;
  846.     long    now;
  847.  
  848.     time(&now);
  849.     fprintf(Log_fp,"FVIEW Listing %s %s",name,ctime(&now));
  850.     
  851.     if ((infp = fopen(name,"rt")) != NULL) {
  852.  
  853.         one_line = (char *) malloc(100);
  854.         do {
  855.             count = 0;
  856.             result = one_line;
  857.             do {
  858.                 *result = (char) fgetc(infp);
  859.                 if (*result == '\n' || *result == '\r')
  860.                     count = 81;
  861.                 else if (!isprint(*result))
  862.                     *result = ' ';
  863.                 result++;
  864.                 count++;
  865.                 } while (*result != '\n' && count < 81);
  866.             *result = EOS;
  867.             sdisplay(one_line);
  868.             } while(ctrl_err && result && !feof(infp));
  869.         free(one_line);
  870.         fclose(infp);
  871.         }
  872.     return;
  873. }
  874.  
  875. /*--------------------------------------------------------------------------*/
  876. /* Validate that the name of a member of an archive that a user has asked   */
  877. /* to read actually exists. You can't pass "*.*" to the unarchive program!  */
  878. /*--------------------------------------------------------------------------*/
  879.  
  880. int validate(char *name,char *target)
  881.  
  882. {
  883.     char    *pt1;
  884.     char    *pt2;
  885.     char    real[14];
  886.     char    ext[4];
  887.     int     m1 = 0;
  888.     int     l1;
  889.     int     l2;
  890.  
  891.     if (flags & FOSSIL && !(Comm_CD()))
  892.         terminate(3);
  893.  
  894.     if ((strstr(target,".COM")) != NULL ||
  895.         (strstr(target,".ARC")) != NULL ||
  896.         (strstr(target,".ZIP")) != NULL ||
  897.         (strstr(target,".PAK")) != NULL ||
  898.         (strstr(target,".ZOO")) != NULL ||
  899.         (strstr(target,".EXE")) != NULL ||
  900.         (strstr(target,".OBJ")) != NULL)
  901.             return(0);        /* Can't deal with these */
  902.  
  903.     if (strcmp(name,"*.*") == 0)
  904.         return(1);
  905.  
  906.     if (strcmp(name,target) == 0)
  907.         return(1);
  908.  
  909.     strcpy(real,name);        /* Work on a copy, not the original */
  910.  
  911. /* Match root name */
  912.     if ((pt1 = strchr(real,'.')) != NULL) {        /* Parse file name */
  913.         *pt1 = EOS;
  914.         strcpy(ext,++pt1);
  915.         }
  916.     if ((pt1 = strchr(real,'*')) != NULL) {
  917.         if (real[0] != '*') {
  918.             *pt1 = EOS;
  919.             l1 = strlen(real);
  920.             if (strnicmp(real,target,l1) != 0)
  921.                 return(0);
  922.             else
  923.                 m1 = 1;
  924.             }
  925.         else
  926.             m1 = 1;
  927.         }
  928.     else {
  929.         l1 = strlen(real);
  930.         if (strchr(target,'.') != NULL) {
  931.             l2 = 0;
  932.             pt2 = target;
  933.             while (*pt2++ != '.')
  934.                 l2++;
  935.             }
  936.         else
  937.             l2 = strlen(target);
  938.  
  939.         if (l1 >= l2)
  940.             l1 = l2;
  941.         if (strnicmp(real,target,l1) != 0)
  942.             return(0);
  943.         else
  944.             m1 = 1;
  945.         }        /* End of matching filename */
  946.  
  947. /* Try matching extensions */
  948.     if ((pt1 = strchr(ext,'*')) != NULL) {
  949.         if (ext[0] == '*' && m1 == 1)
  950.             return(1);
  951.         else {
  952.             *pt1 = EOS;
  953.             l1 = strlen(ext);
  954.             if ((pt1 = strchr(target,'.')) != NULL) {
  955.                 pt1++;
  956.                 if ((strnicmp(ext,pt1,l1) == 0) && m1 == 1)
  957.                     return(1);
  958.                 else
  959.                     return(0);
  960.                 }
  961.             if (strlen(ext) == 0 && m1 == 1)
  962.                 return(1);
  963.             else
  964.                 return(0);
  965.             }
  966.         }        /* End of wildcard in Extension */
  967.     else {
  968.         if ((pt1 = strchr(target,'.')) != NULL) {
  969.             pt1++;
  970.             l1 = strlen(pt1);
  971.             if ((strnicmp(ext,pt1,l1) == 0) && m1 == 1)
  972.                 return(1);
  973.             else
  974.                 return(0);
  975.             }
  976.         else
  977.             if (strlen(ext) == 0 && m1 == 1)
  978.                 return(1);
  979.         return(0);
  980.         }
  981. }
  982. /*--------------------------------------------------------------------------*/
  983. /* Get a string of characters from a remote user.                           */
  984. /*--------------------------------------------------------------------------*/
  985.  
  986. void    get_string(char *buf)
  987. {
  988.     char    ch = EOS;
  989.     char    *start;
  990.  
  991.     start = buf;        /* Used to prevent user BS past start of line */
  992.  
  993.     if (!ctrl_err)
  994.         return;
  995.     while((ch = (char) get_a_char()) != '\r') {
  996.         ch = toupper(ch);
  997.         if (ch != 0x08) {
  998.             *buf++ = ch;
  999.             sendbyte(ch);
  1000.             }
  1001.         else if (buf>start) {
  1002.             ch = ' ';
  1003.             sendbyte(ch);
  1004.             sendbyte(0x08);
  1005.             sendbyte(0x08);
  1006.             sendbyte(ch);
  1007.             sendbyte(0x08);
  1008.             *--buf = EOS;
  1009.             }
  1010.         }
  1011.     *buf++ = EOS;
  1012.     sendbyte('\n');
  1013.     return;
  1014. }
  1015.  
  1016. /*--------------------------------------------------------------------------*/
  1017. /* Check for the existence of a CFG file 1.03 people                        */
  1018. /*--------------------------------------------------------------------------*/
  1019. void    check_cfg(char *Log)
  1020. {
  1021.     FILE    *cfg;
  1022.     char    *result;
  1023.     char    *check;
  1024.     char    *aline;
  1025.  
  1026.     if ((cfg = fopen("FVIEW.CFG","rt")) == NULL)
  1027.         return;
  1028.     aline = (char *) malloc(120);
  1029.     do {
  1030.         result = fgets(aline,80,cfg);
  1031.         check = strrchr(aline,'\n');
  1032.         *check = EOS;
  1033.         if ((check = strchr(aline,';')) != NULL)
  1034.             *check = EOS;
  1035.         if (strlen(aline) > 0) {
  1036.             if (strnicmp(aline,"Log",3) == 0) {
  1037.                 check = get_next(aline);
  1038.                 strcpy(Log,check);
  1039.                 }
  1040.             else if (strnicmp(aline,"dearc",5) == 0) {
  1041.                 check = get_next(aline);
  1042.                 strcpy(dearc_path,check);
  1043.                 }
  1044.             else if (strnicmp(aline,"System",6) == 0) {
  1045.                 check = get_next(aline);
  1046.                 strcpy(Sys_Path,check);
  1047.                 }
  1048.             else if (strnicmp(aline,"noshow",6) == 0) 
  1049.                 flags |= NO_SHOW;
  1050.             else if (strnicmp(aline,"debug",5) == 0)
  1051.                 flags |= DEBUG;
  1052.             else if (strnicmp(aline,"watch",5) == 0)
  1053.                 if (flags & FOSSIL)
  1054.                     flags |= WATCH;
  1055.             }        /* End of getting matches for flags */
  1056.         } while(result != NULL && !feof(cfg));
  1057.     free(aline);
  1058.     fclose(cfg);
  1059.     return;
  1060. }
  1061.  
  1062. /*--------------------------------------------------------------------------*/
  1063. /* Parse lines in CFG file if needed                                        */
  1064. /*--------------------------------------------------------------------------*/
  1065.  
  1066. char *get_next(char *line)
  1067. {
  1068.     char    *test;
  1069.     char    *test1;
  1070.  
  1071.     test = line;
  1072.     while (!isspace(*test) && (++test));
  1073.     while (isspace(*test) && (++test));
  1074.     test1 = test;
  1075.     while (!isspace(*test1) && (++test1));
  1076.     *test1 = EOS;
  1077.     return(test);
  1078. }
  1079. /*--------------------------------------------------------------------------*/
  1080. /* If user has a "SET FVIEW=...." in environment                            */
  1081. /*--------------------------------------------------------------------------*/
  1082. void    parse_env(char *env,char *Log)
  1083. {
  1084.     char    *test1;
  1085.  
  1086.     test1 = env;
  1087.     while(*env && *env > 0x1f) {
  1088.         while (!isspace(*test1) && (++test1));
  1089.         *test1 = EOS;
  1090.         ++test1;
  1091.         if (*env == '-' ||
  1092.             *env == '/') {
  1093.             env++;
  1094.             switch(toupper(*env)) {
  1095.  
  1096.                 case '0':   flags |= OPUS_10;
  1097.                             break;
  1098.  
  1099.                 case 'D':    strcpy(dearc_path,++env);
  1100.                             break;
  1101.  
  1102.                 case 'L':    strcpy(Log,++env);
  1103.                             break;
  1104.  
  1105.                 case 'S':   strcpy(Sys_Path,++env);
  1106.                             break;
  1107.  
  1108.                 case 'G':    flags |= DEBUG;
  1109.                             break;
  1110.  
  1111.                 case 'N':    flags |= NO_SHOW;
  1112.                             break;
  1113.  
  1114.                 case 'W':    flags |= WATCH;
  1115.                             break;
  1116.  
  1117.                 }        /* End of switch */
  1118.             }        /* end of finding '-' */
  1119.         env = test1;
  1120.         }        /* end of while(env) loop */
  1121.     return;
  1122. }
  1123.  
  1124.