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

  1. /***********************************************************
  2.     extract.c -- extract file from archive
  3. ***********************************************************/
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <farstr.h>
  7. #include <stdlib.h>
  8. #include <io.h>
  9. #include <dos.h>
  10. #include <direct.h>
  11. #include "lh.h"
  12. #include "intrface.h"
  13. #include "errmes.h"
  14. #include "disp.h"
  15.  
  16. static char methods[10][5] = {
  17.     "-lh0-", "-lh1-", "-lh2-", "-lh3-", "-lh4-", 
  18.     "-lh5-", "-lzs-", "-lz5-", "-lz4-", "\0\0\0\0\0"
  19. };
  20.  
  21. /*******************************
  22.     test the file name which
  23.     should be melted
  24. *******************************/
  25. static char tstdir(char *name)
  26. {
  27.     char *p, *q, yn;
  28.     int absent;
  29.     struct find_t srchbuf;
  30.  
  31.     p = name;
  32.     if (*p && p[1] == ':')                /* skip a drive name */
  33.         p += 2;
  34.     if (*p == DELIM)                    /* skip a root mark('\') */
  35.         p++;
  36.     yn = flg_m ? 'Y' : 'N';
  37.     q = p;
  38.     while ((p = strchr(p, DELIM)) != NULL) {    /* skip to next '\' */
  39.         if (*q != '.') {
  40.             *p = '\0';
  41.             absent = _dos_findfirst(name, 0x17, &srchbuf);
  42.             if (absent) {    
  43.                 if (yn == 'N') {
  44.                     *p = DELIM;
  45.                     eprintf("'%s' : %s", name, MKDIR);
  46.                     *p = '\0';
  47.                     yn = getyn();
  48.                 }
  49.                 if (yn == 'N') {
  50.                     return 'S';
  51.                 } else {
  52.                     if (makedir(name)) {            /* make directory */
  53.                         error(MKDIRERR, name);
  54.                     }
  55.                 }
  56.             } else {
  57.                 if ((srchbuf.attrib & 0x10) == 0) {
  58.                     error(MKDIRERR, name);    /* if the name isn't directory */
  59.                 }
  60.             }
  61.             *p = DELIM;
  62.         }
  63.         q = ++p;
  64.     }
  65.     if (! _dos_findfirst(name, 0x17, &srchbuf)) {
  66.         /* already exists */
  67.         if (flg_c == 0 && 
  68.             dos2unix((struct ftime *)&srchbuf.wr_time) >= hpb.utc) yn = 'S';
  69.         switch (flg_m) {
  70.         case 0:
  71.             if (yn != 'S') {
  72.                 eprintf("'%s' %s", name, OVERWT);
  73.                 yn = (getyn() == 'Y') ? 'O' : 'S';
  74.                 break;
  75.             }
  76.         case 1:
  77.             if (yn == 'S') {
  78.                 skipdisp(NEWFILE);
  79.                 break;
  80.             }
  81.             yn = 'O';
  82.             break;
  83.         case 2:
  84.             yn = 'R';
  85.             break;
  86.         }
  87.         if (yn != 'O') {
  88.             return yn;
  89.         }
  90.         if (srchbuf.attrib & 0x01 && 
  91.             srchbuf.attrib != hpb.attr && !flg_a) {
  92.                                 /* if the file is read-only, */
  93.                                 /* attributes must match */
  94.             skipdisp(RDONLY);
  95.             return 'S';
  96.         }
  97.         if (srchbuf.attrib & 0x10) {
  98.             skipdisp(SAMEDIR);
  99.             return 'S';
  100.         }
  101.         if (srchbuf.attrib & 0x07)
  102.             _dos_setfileattr(name, 0x20);    /* reset attributes */
  103.     }
  104.     return 'O';
  105. }
  106.  
  107. static int rename_ext(char *name)
  108. {
  109.     int i;
  110.     char *p, *q;
  111.     struct find_t srchbuf;
  112.  
  113.     p = strrchr(name, '.');
  114.     q = strrchr(name, DELIM);
  115.     if (p <= q) p = name + strlen(name);
  116.     for (i = 0; i <= 999; i++) {
  117.         sprintf(p, ".%03d", i);
  118.         if (_dos_findfirst(name, 0x17, &srchbuf)) return 1;
  119.     }
  120.     return 0;
  121. }
  122.  
  123. void extract(char far *bdir)
  124. {
  125.     char *path;
  126.     int method;
  127.  
  128.     memcpy(methods[9], hpb.method, 5);
  129.     for (method = 0; memcmp(hpb.method, methods[method], 5); method++);
  130.     if (method == 9) {
  131.         skipdisp(METHODERR);
  132.         return;
  133.     }
  134.  
  135.     switch (cmd) {
  136.     case 'E':
  137.         if ((hpb.attr & 0x06) && flg_a == 0) {
  138.             skipdisp(SPECIALATTR);
  139.             return;
  140.         }
  141.         form_path(hpb.pathname);
  142.         hpb.filename = getfilename(hpb.pathname);
  143.         path = (flg_x) ? hpb.pathname : hpb.filename;
  144.         far_strcpy(filename3, bdir);
  145.         if (path[1] == ':') path += 2;
  146.         if (*(unsigned char *)path == DELIM) {
  147.             if (filename3[1] == ':') {
  148.                 filename3[2] = '\0';
  149.             } else {
  150.                 *filename3 = '\0';
  151.             }
  152.         }
  153.         strcat(filename3, path);
  154.  
  155.         switch (tstdir(filename3)) {
  156.         case 'R':
  157.             if (rename_ext(filename3)) break;
  158.             skipdisp(NOMOREEXT);
  159.         case 'S':
  160.             return;
  161.         }
  162.         if (diskspace(filename3) < hpb.original) {
  163.             skipdisp(DISKFULL);
  164.             return;
  165.         }
  166.         file3 = mywopen(filename3, MKFILEERR);
  167.         regdisp("Melting ", filename3);
  168.         break;
  169.     case 'P':
  170.         file3 = fdopen(dup(1), "wb");
  171.         regdisp("Melting", NULL);
  172.         fprintf(file3, "\r\n<< %s >>\r\n\r\n", hpb.filename);
  173.         fflush(file3);
  174.         break;
  175.     case 'T':
  176.         if (hpb.level < 0) {
  177.             skipdisp(NOCRC);
  178.             return;
  179.         }
  180.         regdisp("Testing", NULL);
  181.         file3 = NULL;
  182.         break;
  183.     }
  184.  
  185.     interface.method = method;
  186.     interface.dicbit = 13; /* method + 8; */
  187.     interface.infile = file1;
  188.     interface.outfile = file3;
  189.     interface.original = hpb.original;
  190.     interface.packed = hpb.packed;
  191.  
  192.     switch (method) {
  193.     case 8:
  194.         method = 0;
  195.         break;
  196.     case 6:
  197.         interface.dicbit = 11;
  198.         break;
  199.     case 1:
  200.     case 4:
  201.     case 7:
  202.         interface.dicbit = 12;
  203.         break;
  204.     }
  205.  
  206.     disp(cmd == 'P' && !outredir, cmd != 'P' && outredir);
  207.     initdisp();
  208.  
  209.     if (method) {
  210.         decode(&interface);
  211.     } else {
  212.         copyfile(file1, file3, hpb.original, 1);
  213.     }
  214.  
  215.     if (file3) {
  216. #if 0
  217.         if (fflush(file3)) error(WTERR, filename3);
  218. #else
  219.         fflush(file3);
  220. #endif
  221.         setfiletime(file3, hpb.utc);
  222.         fclose(file3);
  223.         file3 = NULL;
  224.     }
  225.     if (hpb.level >= 0 && crc != hpb.filecrc) {
  226.         errorlevel = 1;
  227.         eprintf("\rCRC err\n");
  228.         if (cmd == 'E') {
  229.             if (flg_m == 0) {
  230.                 eprintf(MAYDELETE);
  231.                 if (getyn() == 'Y')
  232.                     remove(filename3);
  233.             } else {
  234.                 remove(filename3);
  235.             }
  236.         }
  237.         if (flg_m == 0) {
  238.             eprintf(MAYCONT);
  239.             if (getyn() != 'Y')
  240.                 error(CTRLBRK, NULL);
  241.         }
  242.     } else {
  243.         if (cmd == 'T') {
  244.             enddisp("Test OK");
  245.         } else {
  246.             if (cmd != 'P' || outredir) enddisp("Melted ");
  247.         }
  248.         if (cmd == 'E' && flg_a) {
  249.             _dos_setfileattr(filename3, hpb.attr);
  250.         }
  251.     }
  252. }
  253.  
  254. void extract_internal(FILE *f, char *p)
  255. {
  256.     interface.method = 5;
  257.     interface.dicbit = 13;
  258.     interface.infile = NULL;
  259.     interface.outfile = f ? fdopen(dup(fileno(f)), "wb") : f;
  260.     interface.original = *(ushort *)(p + 2);
  261.     interface.packed = *(ushort *)p;
  262.     interface.blkcnt = -1;
  263.     interface.internal = (char *)(p + 4);
  264.     disp(1, 0);
  265.     initdisp();
  266.     decode(&interface);
  267. }
  268.