home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / ARCHIVERS / lha208src.lzh / LHA / SRC / lhext.c < prev    next >
Text File  |  1994-02-14  |  10KB  |  390 lines

  1. /*----------------------------------------------------------------------*/
  2. /*                     LHarc Extract Command                            */
  3. /*              This is part of LHarc UNIX Archiver Driver              */
  4. /*                                                                      */
  5. /*              Copyright(C) MCMLXXXIX  Yooichi.Tagawa                  */
  6. /*                                                                      */
  7. /*  V0.00  Original                              1988.05.23  Y.Tagawa   */
  8. /*  V1.00  Fixed                                 1989.09.22  Y.Tagawa   */
  9. /*  V0.03  LHa for UNIX                          1991.12.17  M.Oki      */
  10. /*----------------------------------------------------------------------*/
  11.  
  12. #include "lharc.h"
  13.  
  14. extern int decode_lzhuf ();
  15.  
  16. static boolean
  17. inquire_extract (name)
  18. char *name;
  19. {
  20.     STAT stbuf;
  21.  
  22.     if (stat (name, &stbuf) >= 0)
  23.     {
  24.         if (!is_regularfile (&stbuf))
  25.         {
  26.             error ("Already exist (not a file)", name);
  27.             return FALSE;
  28.         }
  29.  
  30.         if (noexec)
  31.         {
  32.             printf ("EXTRACT %s but file exists.\n", name);
  33.             return FALSE;
  34.         }
  35.         else if (!force)
  36.         {
  37.             if (!isatty(0)) return FALSE;
  38.             switch (inquire ("OverWrite ?(Yes/No/All)", name, "YyNnAa"))
  39.             {
  40.             case 0:
  41.             case 1:              /* Y/y */
  42. #ifdef OSK
  43.                 /* change perms to update in cases of no write perms */
  44.                 chmod(name,S_IREAD | S_IWRITE);
  45. #endif
  46.                 break;
  47.             case 2:
  48.             case 3:              /* N/n */
  49.                 return FALSE;
  50.             case 4:
  51.             case 5:              /* A/a */
  52. #ifdef OSK
  53.                 /* change perms to update in cases of no write perms */
  54.                 chmod(name,S_IREAD | S_IWRITE);
  55. #endif
  56.                 force = TRUE;
  57.                 break;
  58.             }
  59.         }
  60. #ifdef OSK
  61.         else if (force)
  62.         {
  63.             /* change perms to update in cases of no write perms */
  64.             chmod(name,S_IREAD | S_IWRITE);
  65.         }
  66. #endif
  67.     }
  68.  
  69.     if (noexec)
  70.         printf ("EXTRACT %s\n", name);
  71.  
  72.     return TRUE;
  73. }
  74.  
  75. static boolean
  76. make_parent_path (name)
  77. char *name;
  78. {
  79.     char path[FILENAME_LENGTH];
  80.     STAT stbuf;
  81.     register char *p;
  82.  
  83.     /* make parent directory name into PATH for recursive call */
  84.     strcpy (path, name);
  85.     for (p = path + strlen (path); p > path; p--)
  86.         if (p[-1] == '/')
  87.         {
  88.             *--p = '\0';
  89.             break;
  90.         }
  91.  
  92.     if (p == path)
  93.     {
  94.         message ("Why?", "ROOT");
  95.         return FALSE;                     /* no more parent. */
  96.     }
  97.  
  98.     if (stat (path, &stbuf) >= 0)
  99.     {
  100.         if (is_directory (&stbuf))
  101.             return TRUE;
  102.         error ("Not a directory", path);
  103.         return FALSE;
  104.     }
  105.     errno = 0;
  106.  
  107.     if (verbose)
  108.         printf ("Making directory \"%s\".", path);
  109.  
  110.     if (mkdir(path, 0777) >= 0)/* try */
  111.         return TRUE;                     /* successful done. */
  112.     errno = 0;
  113.  
  114.     if (!make_parent_path (path))
  115.         return FALSE;
  116.  
  117.     if (mkdir(path, 0777) < 0)       /* try again */
  118.     {
  119.         message ("Cannot make directory", path);
  120.         return FALSE;
  121.     }
  122.  
  123.     return TRUE;
  124. }
  125.  
  126. static FILE *
  127. open_with_make_path (name)
  128. char *name;
  129. {
  130.     FILE *fp;
  131.  
  132.     if ((fp = fopen (name, WRITE_BINARY)) == NULL)
  133.     {
  134.         errno = 0;
  135.         if (!make_parent_path(name) || (fp = fopen(name,WRITE_BINARY)) == NULL) {
  136.             error ("Cannot extract", name);
  137.         }
  138.         errno = 0;
  139.     }
  140.     return fp;
  141. }
  142.  
  143. static void
  144. adjust_info (name,hdr)
  145. char *name;
  146. LzHeader *hdr;
  147. {
  148.     time_t utimebuf[2];
  149.  
  150.     /* adjust file stamp */
  151.     utimebuf[0] = utimebuf[1] = hdr->unix_last_modified_stamp;
  152.  
  153. #ifdef OSK
  154.     if (hdr->extend_type == EXTEND_UNIX
  155.         || hdr->extend_type == EXTEND_OS68K
  156.         || hdr->extend_type == EXTEND_XOSK)
  157.     {
  158.         if(!getuid())
  159.             chown (name, (hdr->unix_gid << 16) + hdr->unix_uid);
  160.         errno = 0;
  161.     }
  162.     utime (name, utimebuf, hdr->unix_mode);
  163. #else
  164.     utime (name, utimebuf);
  165.  
  166.     if (hdr->extend_type == EXTEND_UNIX
  167.         || hdr->extend_type == EXTEND_OS68K
  168.         || hdr->extend_type == EXTEND_XOSK)
  169.     {
  170. #ifdef NOT_COMPATIBLE_MODE
  171.         Please need your modification in this space.
  172. #else
  173.         chmod (name, hdr->unix_mode);
  174.         if(!getuid())
  175.             chown (name, hdr->unix_uid, hdr->unix_gid);
  176. #endif
  177.         errno = 0;
  178.     }
  179. #endif /* OSK */
  180. }
  181.  
  182. static char *methods[10] =
  183. {
  184.     "-lh0-", "-lh1-", "-lh2-", "-lh3-", "-lh4-",
  185.     "-lh5-", "-lzs-", "-lz5-", "-lz4-", NULL
  186. };
  187.  
  188. static void
  189. extract_one (afp, hdr)
  190. FILE *afp;                                   /* archive file */
  191. LzHeader *hdr;
  192. {
  193.     FILE *fp;                                /* output file */
  194.     char name[257];
  195.     int mcrc;
  196.     int method;
  197.     boolean save_quiet, save_verbose;
  198.     char *q = hdr->name , c;
  199.  
  200.     if ( ignore_directory && rindex(hdr->name,'/') )
  201.     {
  202.         q = (char *)rindex(hdr->name,'/') + 1;
  203.     }
  204.     else
  205.     {
  206.         if ( *q=='/' )
  207.         {
  208.             q++;
  209.             /*
  210.              *  if OSK then strip device name
  211.              */
  212.             if (hdr->extend_type == EXTEND_OS68K
  213.                 || hdr->extend_type == EXTEND_XOSK )
  214.             {
  215.                 do c=(*q++); 
  216.                 while ( c && c!='/' );
  217.                 if ( !c || !*q ) q = ".";       /* if device name only */
  218.             }
  219.         }
  220.     }
  221.  
  222.     if (extract_directory)
  223.         sprintf (name, "%s/%s", extract_directory, q);
  224.     else
  225.         strcpy (name, q);
  226.  
  227. #ifdef OSK
  228.     if ((hdr->unix_mode & OSK_DIRECTORY_PERM) == 0)
  229. #else
  230.     if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_REGULAR)
  231. #endif
  232.     {
  233.         for (method = 0; ; method++)
  234.         {
  235.             if (methods[method] == NULL)
  236.             {
  237.                 error ("Unknown method skiped ...", name);
  238.                 return;
  239.             }
  240.             if (bcmp (hdr->method, methods[method], 5) == 0)
  241.                 break;
  242.         }
  243.  
  244.         reading_filename = archive_name;
  245.         writting_filename = name;
  246.         if (output_to_stdout || verify_mode)
  247.         {
  248.             if (noexec)
  249.             {
  250.                 printf ("%s %s\n", verify_mode ? "VERIFY" : "EXTRACT",name);
  251.                 if (afp == stdin)
  252.                 {
  253.                     int i = hdr->packed_size;
  254.                     while(i--) fgetc(afp);
  255.                 }
  256.                 return;
  257.             }
  258.  
  259.             save_quiet = quiet;
  260.             save_verbose = verbose;
  261.             if (output_to_stdout)
  262.             {
  263.                    if (!quiet)
  264.                     printf ("::::::::\n%s\n::::::::\n", name);
  265.                 quiet = TRUE;
  266.                 verbose = FALSE;
  267.             }
  268.             else if (verify_mode)
  269.             {
  270.                 quiet = FALSE;
  271.                 verbose = TRUE;
  272.             }
  273.  
  274.             mcrc = decode_lzhuf(afp, stdout, hdr->original_size,\
  275.                                 hdr->packed_size, name, method);
  276.             quiet = save_quiet;
  277.             verbose = save_verbose;
  278.         }
  279.         else
  280.         {
  281.             if (!inquire_extract (name))
  282.                 return;
  283.  
  284.             if (noexec)
  285.             {
  286.                 if (afp == stdin)
  287.                 {
  288.                     int i = hdr->packed_size;
  289.                     while(i--) fgetc(afp);
  290.                 }
  291.                 return;
  292.             }
  293.  
  294.             signal (SIGINT, interrupt);
  295.             signal (SIGHUP, interrupt);
  296.  
  297.             unlink (name);
  298.             errno = 0;
  299.             remove_extracting_file_when_interrupt = TRUE;
  300.             if ((fp = open_with_make_path (name)) != NULL)
  301.             {
  302.                 mcrc = decode_lzhuf (afp, fp, hdr->original_size,\
  303.                                      hdr->packed_size, name, method);
  304.                 fclose (fp);
  305.             }
  306.             remove_extracting_file_when_interrupt = FALSE;
  307.             signal (SIGINT, SIG_DFL);
  308.             signal (SIGHUP, SIG_DFL);
  309.  
  310.             if (!fp)
  311.                 return;
  312.         }
  313.  
  314.         errno = 0;
  315.         if (hdr->has_crc && mcrc != hdr->crc)
  316.             error ("CRC error", name);
  317.  
  318.     }
  319. #ifdef OSK
  320.     else if ((hdr->unix_mode & OSK_DIRECTORY_PERM) == OSK_DIRECTORY_PERM)
  321. #else
  322.     else if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_DIRECTORY)
  323. #endif
  324.     {
  325.         if (!ignore_directory && !verify_mode)
  326.         {
  327.             if (noexec)
  328.             {
  329.                 printf ("EXTRACT %s (directory)\n", name);
  330.                 return;
  331.             }
  332.             /* NAME has trailing SLASH '/', (^_^) */
  333.             if (!output_to_stdout && !make_parent_path (name))
  334.                 return;
  335.         }
  336.     }
  337.     else
  338.     {
  339.         error ("Unknown information", name);
  340.     }
  341.  
  342.     if (!output_to_stdout)
  343.         adjust_info (name,hdr);
  344. }
  345.  
  346.  
  347. /*----------------------------------------------------------------------*/
  348. /*                     EXTRACT COMMAND MAIN                             */
  349. /*----------------------------------------------------------------------*/
  350.  
  351. void
  352. cmd_extract ()
  353. {
  354.     LzHeader hdr;
  355.     long pos;
  356.     FILE *afp;
  357.  
  358.     /* open archive file */
  359.     if ((afp = open_old_archive ()) == NULL)
  360.         fatal_error (archive_name);
  361.     if (archive_is_msdos_sfx1 (archive_name))
  362.         skip_msdos_sfx1_code (afp);
  363.  
  364.     /* extract each files */
  365.     while (get_header (afp, &hdr))
  366.     {
  367.         if (need_file (hdr.name))
  368.         {
  369.             pos = ftell (afp);
  370.             extract_one (afp, &hdr);
  371.             fseek (afp, pos + hdr.packed_size, SEEK_SET);
  372.         }
  373.         else
  374.         {
  375.             if (afp != stdin)
  376.                 fseek (afp, hdr.packed_size, SEEK_CUR);
  377.             else
  378.             {
  379.                 int i = hdr.packed_size;
  380.                 while(i--) fgetc(afp);
  381.             }
  382.         }
  383.     }
  384.  
  385.     /* close archive file */
  386.     fclose (afp);
  387.  
  388.     return;
  389. }
  390.