home *** CD-ROM | disk | FTP | other *** search
/ PC World 1997 November / PCWorld_1997-11_cd.bin / software / sharware / utility / PACKERS / LZH / LHASRC.EXE / MN.C < prev    next >
C/C++ Source or Header  |  1991-03-03  |  9KB  |  445 lines

  1. /***********************************************************
  2.     mn.c -- main module of LH
  3. ***********************************************************/
  4. #include <ctype.h>
  5. #include <stdio.h>
  6. #include <io.h>
  7. #include <dos.h>
  8. #include <errno.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include <time.h>
  12. #include "lh.h"
  13. #include "errmes.h"
  14. #include "intrface.h"
  15. #include "disp.h"
  16.  
  17. #define SECURITY 0
  18.  
  19. #define CRCPOLY  0xA001  /* CRC-16 */
  20.  
  21. char work[4096];
  22. char lhtmp1[] = "LHTMP)1(.LZH";
  23. char lhtmp2[] = "LHTMP)2(.LZH";
  24. FILE *inredir = NULL, *response = NULL;
  25. int  outredir;
  26. int  paramcount = -2;
  27. char cmd;
  28. int  cmdupdate;
  29. char *env;
  30. char workdir[MAX_PATH];
  31. #if 0
  32. char *pager = "LESS";
  33. char *keyword = "";
  34. #endif
  35. char arcname[MAX_PATH];
  36. char filename1[MAX_PATH];
  37. char filename2[MAX_PATH];
  38. char filename3[MAX_PATH];
  39. FILE *file1, *file2, *file3;
  40. int errorlevel = 0;
  41.  
  42. static time_t arcstamp;
  43.  
  44. /*******************************
  45.         display usages
  46. *******************************/
  47. void usage(void)
  48. {
  49.     extract_internal(stdout, use);
  50.     exit(2);
  51. }
  52.  
  53. void update_arcstamp(void)
  54. {
  55.     if (arcstamp < hpb.utc) arcstamp = hpb.utc;
  56. }
  57.  
  58. static void set_arcstamp(FILE *f)
  59. {
  60.     if (flg_t) setfiletime(f, arcstamp);
  61. }
  62.  
  63. static char *readword(FILE *file)
  64. {
  65.     char *p;
  66.     int c;
  67.  
  68.     while (((c = getc(file)) & 0xff) <= ' ');
  69.     if (c < 0) {
  70.         fclose(file);
  71.         return NULL;
  72.     }
  73.     p = work;
  74.     do {
  75.         *p++ = c;
  76.     } while ((c = getc(file)) > ' ');
  77.     *p++ = '\0';
  78.     return work;
  79. }
  80.  
  81. static void disparcname(char *title)
  82. {
  83.     FILE *f;
  84.  
  85.     f = (cmd == 'L') ? stdout : stderr;
  86.     if (flg_n == 0) {
  87.         fprintf(f, "\n%s archive : %s\n\n", title, arcname);
  88.     }
  89. }
  90.  
  91. static int executecmd(void)
  92. {
  93.     int modified, err;
  94.     char far *bdir, *path;
  95.     ulong size0, size;
  96.     uchar c;
  97.  
  98.     make_crctable(CRCPOLY);
  99.     err = 0;
  100.     arcstamp = 0;
  101.     modified = 0;
  102.     strcpy(filename1, arcname);
  103.     if (cmdupdate) {
  104.         strcpy(backpath(filename1), lhtmp1);
  105.         if (remove(filename1) && errno != ENOENT)
  106.             error(RDONLY, filename1);
  107.         rename(arcname, filename1);
  108.     }
  109.     file1 = myeopen(filename1, "rb", NULL);
  110.     if (cmdupdate || cmd == 'S') {
  111.         if (file1 == NULL) {
  112.             fclose(mywopen(arcname, MKFILEERR));
  113.             remove(arcname);
  114.         }
  115.         if (flg_w) {
  116.             strcpy(filename2, workdir);
  117.             convdelim(filename2, DELIM);
  118.             c = filename2[strlen(filename2) - 1];
  119.             if (c != DELIM && c != ':') strcat(filename2, DELIMSTR);
  120.             strcat(filename2, lhtmp2);
  121.         } else {
  122.             strcpy(filename2, arcname);
  123.             strcpy(backpath(filename2), lhtmp2);
  124.         }
  125.         file2 = mywopen(filename2, NULL);
  126.         if (file2 == NULL) {
  127.             file2 = mywopen(lhtmp2, NULL);
  128.             if (file2 == NULL)
  129.                 error(MKTMPERR, filename2);
  130.             strcpy(filename2, lhtmp2);
  131.         }
  132.         setvbuf(file2, NULL, _IOFBF, 0x2000);
  133.     } else {
  134.         setvbuf(file1, NULL, _IOFBF, 0x2000);
  135.     }
  136.     switch (cmd) {
  137.     case 'V':
  138.         flg_x = 1;
  139.         cmd = 'L';
  140.     case 'L':
  141.         disparcname("Listing of");
  142.         initlist();
  143.         break;
  144.     case 'A':
  145.         flg_c = 1;
  146.         cmd = 'U';
  147.     case 'U':
  148.     case 'M':
  149.         if (file1) {
  150.             disparcname("Updating");
  151.         } else {
  152.             disparcname("Creating");
  153.         }
  154.         mklist();
  155.         break;
  156.     case 'F':
  157.         disparcname("Freshening");
  158.         break;
  159.     case 'D':
  160.         disparcname("Deleting from");
  161.         break;
  162.     case 'P':
  163.     case 'E':
  164.         disparcname("Extracting from");
  165.         break;
  166.     case 'T':
  167.         disparcname("Testing");
  168.         break;
  169.     case 'S':
  170.         disparcname("Making SFX of");
  171.         initsfx();
  172.         break;
  173.     }
  174.  
  175. /************/
  176.     if (file1) {
  177.         size0 = inithdr();
  178.         if (cmd == 'T' && 
  179.             stricmp(arcname + strlen(arcname) - 4, ".LZH") == 0 && 
  180.             size0 != 0) {
  181.             eprintf(EXTRADATA);
  182.         }
  183.         if (cmdupdate) {
  184.             rewind(file1);
  185.             copyfile(file1, file2, size0, 0);
  186.         }
  187.         while (file1 && (path = gethdr(&err)) != NULL) {
  188.             bdir = matchpat(path);
  189.             switch (cmd) {
  190.             case 'L':
  191.                 if (bdir) {
  192.                     list();
  193.                 }
  194.                 break;
  195.             case 'U':
  196.             case 'M':
  197.                 modified += append();
  198.                 break;
  199.             case 'F':
  200.                 modified += freshen(bdir);
  201.                 break;
  202.             case 'D':
  203.                 if (bdir) {
  204.                     dispalone("Deleted");
  205.                     eprintf("\n");
  206.                     modified++;
  207.                 } else {
  208.                     copylzh();
  209.                 }
  210.                 break;
  211.             case 'E':
  212.             case 'P':
  213.             case 'T':
  214.                 if (bdir) {
  215.                     extract(bdir);
  216.                 }
  217.                 break;
  218.             case 'S':
  219.                 if (bdir) {
  220.                     if (copysfx()) modified++;
  221.                 }
  222.                 break;
  223.             }
  224.             free(path);
  225.         }
  226.     } else {
  227.         size0 = 0;
  228.         if (!cmdupdate) error(NOARCERR, arcname);
  229.     }
  230.  
  231.     /************/
  232.  
  233.     if (!err) {
  234.         switch (cmd) {
  235.         case 'L':
  236.             endlist(getfiletime(file1));
  237.             break;
  238.         case 'U':
  239.         case 'M':
  240.             modified += endappend();
  241.             break;
  242.         case 'S':
  243.             makesfx(bdir);
  244.             break;
  245.         }
  246.     }
  247. #if SECURITY
  248.     if (cmd == 'T') {
  249.         extern int security(void);
  250.  
  251.         if (security()) return 1;
  252.     }
  253. #endif
  254.     if (err) error(BROKENARC, arcname);
  255.     if (cmd == 'M') deletefiles();
  256.     if (cmdupdate || (cmd == 'S' && file2)) {
  257.         putc('\0', file2);
  258.         size = ftell(file2);
  259.         fflush(file2);
  260.         if (ferror(file2)) error(WTERR, filename2);
  261.         set_arcstamp(file2);
  262.         fclose(file2);
  263.         if (file1) {
  264.             set_arcstamp(file1);
  265.             fclose(file1);
  266.         }
  267.         if (modified == 0) {
  268.             rename(filename1, arcname);    /* restore the old archive */
  269.             remove(filename2);
  270.         } else {
  271.             if (rename(filename2, arcname)) {
  272.                 if (diskspace(filename1) < size) error(COPYERR, NULL);
  273.                 eprintf("Copying TMP to ARC ... ");
  274.                 rename(filename1, arcname);
  275.                 file1 = mywopen(arcname, COPYERR);
  276.                 file2 = myropen(filename2);
  277.                 copyfile(file2, file1, size, 0);
  278. #if 0
  279.                 if (fflush(file1)) error(WTERR, filename2);
  280. #endif
  281.                 set_arcstamp(file1);
  282.                 fclose(file1);
  283.                 fclose(file2);
  284.                 remove(filename2);
  285.                 eprintf("done.\n");
  286.             } else {
  287.                 if (cmd != 'S') remove(filename1);
  288.             }
  289.             if (size - size0 <= 1) remove(arcname);
  290.         }
  291.     } else {
  292.         fclose(file1);
  293.     }
  294.     return 0;
  295. }
  296.  
  297. static int execute(void)
  298. {
  299.     struct find_t findbuf;
  300.     int nofile;
  301.     int testflag;
  302.  
  303.     testflag = 0;
  304.     nofile = _dos_findfirst(arcname, 0x07, &findbuf);
  305.     if (nofile && strchr("AUM", cmd) == NULL)
  306.         error(NOARCERR, arcname);
  307.     if (cmdupdate) {
  308.         if (strpbrk(arcname, "*?")) error(NOARCERR, arcname);
  309.                     /* when updating archive, wild cards can't used */
  310.         if (!nofile && findbuf.attrib & 0x01)
  311.             error(RDONLY, arcname);
  312.         executecmd();
  313.     } else {
  314.         do {
  315.             backpath(arcname);
  316.             strcat(arcname, findbuf.name);
  317.             testflag |= executecmd();
  318.         } while (!_dos_findnext(&findbuf));
  319.     }
  320.     if (cmd != 'L' && testflag == 0) tstpat();
  321. }
  322.  
  323. int main(int argc, char *argv[])
  324. {
  325.     uchar c, *p, *q;
  326.     int i;
  327.     static fileinputflag = 0;
  328.     static char far *basedir = "";
  329.  
  330.     initbreak();
  331.     getswchar();
  332.     initpat();
  333.     if ((p = getenv("TMP")) != NULL 
  334.         && (p = strtok(p, " \t")) != NULL) {
  335.         strcpy(workdir, p);
  336.         flg_w = 1;
  337.     }
  338.     if ((env = getenv("LHA")) == NULL)
  339.         env = getenv("LHARC");
  340.     if (!isatty(0)) {
  341.         fileinputflag = 1;
  342.         inredir = fdopen(dup(0), "rt");
  343.         fclose(stdin);
  344.         fopen("con", "rt");             /* open stdin */
  345.     }
  346.     outredir = !isatty(1);
  347.     argc--;
  348.     argv++;
  349.     while (1) {
  350.         if (env) {
  351.             while (*env && (uchar)*env <= ' ') env++;
  352.             if (*env == '\0') {
  353.                 env = NULL;
  354.                 continue;
  355.             }
  356.             p = env;
  357.             while (*env > ' ') env++;
  358.             if (*env) {
  359.                 *env++ = '\0';
  360.             }
  361.         } else if (response) {
  362.             fileinputflag = 1;
  363.             if ((p = readword(response)) == NULL) {
  364.                 response = NULL;
  365.                 continue;
  366.             }
  367.         } else if (argc) {
  368.             argc--;
  369.             p = *argv++;
  370.         } else if (inredir == NULL || (p = readword(inredir)) == NULL) {
  371.             break;
  372.         }
  373.  
  374.         if (*p == swchar && swchar != '-' || *p == '-' && !flg_at) {
  375.             p++;
  376.             getopt(p);
  377.             continue;
  378.         } else if (*p == '@' && !flg_at) {
  379.             if (!response) {
  380.                 p++;
  381.                 if ((response = fopen(p, "rt")) == NULL)
  382.                     error(RDERR, p);
  383.                 continue;
  384.             }
  385.         }
  386.  
  387.         if (paramcount == -2) {
  388.             /* get command */
  389.             cmd = toupper(*p);
  390.             if (p[1] != '\0' || !strchr("EXTDLVAUMFPS", cmd)) {
  391.                 cmd = 'L';
  392.                 paramcount++;
  393.             }
  394.             /* command updating archive? */
  395.             cmdupdate = (int)strchr("AUMFD", cmd);
  396.             /* command 'X' = 'E -x1m1' */
  397.             if (cmd == 'X') {
  398.                 cmd = 'E';
  399.                 flg_x = flg_m = 1;
  400.             }
  401.         }
  402.         if (paramcount == -1) {
  403.             /* get archive name */
  404.             i = strlen(p);
  405.             strcpy(arcname, p);
  406.         } else if (paramcount >= 0) {
  407.             convdelim(p, DELIM);
  408.             c = p[strlen(p) - 1];
  409.             if (c == DELIM || c == ':') {
  410.                 basedir = strcmp(p, "." DELIMSTR) ? regbdir(p) : "";
  411.                 continue;
  412.             } else {
  413.                 regpat(p, basedir);
  414.             }
  415.         }
  416.         paramcount++;
  417.     }
  418.     if (paramcount == -2) usage();
  419.     if (paramcount == -1) error(NOARCNMERR, NULL);
  420.     if (paramcount == 0) {
  421.         if (cmd == 'D' || fileinputflag) {
  422.             error(NOFNERR, NULL);
  423.         }
  424.         regpat("+", basedir);
  425.     }
  426.     if (flg_o) flg_h = 0;
  427.  
  428.     p = convdelim(arcname, DELIM);
  429.     if ((q = strchr(p, '.')) == NULL) {
  430.         strcat(arcname, ".LZH");    /* if no extension */
  431.     } else if (stricmp(".LZH", q) && cmdupdate) {
  432.         if (flg_m == 0) {
  433.             eprintf(NOTLZH, arcname);
  434.             c = getyn();        /* if the extension is not '.LZH' */
  435.             if (c == 'N') {
  436.                 return(2);
  437.             }
  438.         }
  439.         flg_h = 0;
  440.     }
  441.  
  442.     execute();
  443.     return errorlevel;
  444. }
  445.