Support for GNU style long filename and linknames
authorGlenn L McGrath <bug1@ihug.co.nz>
Sun, 15 Sep 2002 16:54:49 +0000 (16:54 -0000)
committerGlenn L McGrath <bug1@ihug.co.nz>
Sun, 15 Sep 2002 16:54:49 +0000 (16:54 -0000)
archival/config.in
archival/libunarchive/get_header_tar.c

index 140e4fb76c9a67a1a4ea0febecef201451d75e64..3de671514f6905768ee54b706088cb69c475dc46 100644 (file)
@@ -20,6 +20,7 @@ if [ "$CONFIG_TAR" = "y" ] ; then
     bool '  Enable -X and --exclude options (exclude files)'   CONFIG_FEATURE_TAR_EXCLUDE
     bool '  Enable -z option'  CONFIG_FEATURE_TAR_GZIP
     bool '  Enable support for old tar header format'  CONFIG_FEATURE_TAR_OLD_FORMAT
+    bool '  Enable support for GNU long filenames' CONFIG_FEATURE_GNUTAR_LONG_FILENAME
 fi
 if [ "$CONFIG_CPIO" = "y" -o "$CONFIG_TAR" = "y" ] ; then
     bool '  Enable tape drive support' CONFIG_FEATURE_UNARCHIVE_TAPE
index 38fb040707637e490abb1a6dd2d03ab29a284b24..e6747b72f22f43b40e588e8d46252e4599c6dd14 100644 (file)
@@ -97,8 +97,19 @@ file_header_t *get_header_tar(FILE * tar_stream)
        }
 
        tar_entry->mode = strtol(tar.formated.mode, NULL, 8);
-#ifdef CONFIG_FEATURE_TAR_OLD_FORMAT
+       tar_entry->uid = strtol(tar.formated.uid, NULL, 8);
+       tar_entry->gid = strtol(tar.formated.gid, NULL, 8);
+       tar_entry->size = strtol(tar.formated.size, NULL, 8);
+       tar_entry->mtime = strtol(tar.formated.mtime, NULL, 8);
+       tar_entry->link_name =
+               strlen(tar.formated.linkname) ? xstrdup(tar.formated.linkname) : NULL;
+       tar_entry->device =
+               (dev_t) ((strtol(tar.formated.devmajor, NULL, 8) << 8) +
+                                strtol(tar.formated.devminor, NULL, 8));
+
+#if defined CONFIG_FEATURE_TAR_OLD_FORMAT || defined CONFIG_FEATURE_GNUTAR_LONG_FILENAME
        switch (tar.formated.typeflag) {
+# ifdef CONFIG_FEATURE_TAR_OLD_FORMAT
        case 0:
                tar_entry->mode |= S_IFREG;
                break;
@@ -120,17 +131,35 @@ file_header_t *get_header_tar(FILE * tar_stream)
        case 6:
                tar_entry->mode |= S_IFIFO;
                break;
+# endif
+# ifdef CONFIG_FEATURE_GNUTAR_LONG_FILENAME
+       case 'L': {
+                       char *longname;
+
+                       longname = xmalloc(tar_entry->size + 1);
+                       fread(longname, 1, tar_entry->size, tar_stream);
+                       archive_offset += tar_entry->size;
+                       longname[tar_entry->size] = '\0';
+
+                       tar_entry = get_header_tar(tar_stream);
+                       tar_entry->name = longname;
+                       break;
+               }
+       case 'K': {
+                       char *longname;
+
+                       longname = xmalloc(tar_entry->size + 1);
+                       fread(longname, 1, tar_entry->size, tar_stream);
+                       archive_offset += tar_entry->size;
+                       longname[tar_entry->size] = '\0';
+
+                       tar_entry = get_header_tar(tar_stream);
+                       tar_entry->link_name = longname;
+                       break;
+               }
+# endif
        }
 #endif
-       tar_entry->uid = strtol(tar.formated.uid, NULL, 8);
-       tar_entry->gid = strtol(tar.formated.gid, NULL, 8);
-       tar_entry->size = strtol(tar.formated.size, NULL, 8);
-       tar_entry->mtime = strtol(tar.formated.mtime, NULL, 8);
-       tar_entry->link_name =
-               strlen(tar.formated.linkname) ? xstrdup(tar.formated.linkname) : NULL;
-       tar_entry->device =
-               (dev_t) ((strtol(tar.formated.devmajor, NULL, 8) << 8) +
-                                strtol(tar.formated.devminor, NULL, 8));
 
        return (tar_entry);
 }