diff options
-rw-r--r-- | archival/libunarchive/get_header_tar.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/archival/libunarchive/get_header_tar.c b/archival/libunarchive/get_header_tar.c index fbca0f274..013450a2a 100644 --- a/archival/libunarchive/get_header_tar.c +++ b/archival/libunarchive/get_header_tar.c | |||
@@ -16,6 +16,11 @@ | |||
16 | * FIXME: Better checking required in oldcompatability mode, | 16 | * FIXME: Better checking required in oldcompatability mode, |
17 | * the file db.1.85.tar.gz from sleepycat.com has trailing garbage | 17 | * the file db.1.85.tar.gz from sleepycat.com has trailing garbage |
18 | * GNU tar can handle it, busybox tar reports invalid tar header. | 18 | * GNU tar can handle it, busybox tar reports invalid tar header. |
19 | * | ||
20 | * References: | ||
21 | * GNU tar and star man pages, | ||
22 | * Opengroup's ustar interchange format, | ||
23 | * http://www.opengroup.org/onlinepubs/007904975/utilities/pax.html | ||
19 | */ | 24 | */ |
20 | 25 | ||
21 | #include <stdio.h> | 26 | #include <stdio.h> |
@@ -122,6 +127,14 @@ extern char get_header_tar(archive_handle_t *archive_handle) | |||
122 | 127 | ||
123 | /* Fix mode, used by the old format */ | 128 | /* Fix mode, used by the old format */ |
124 | switch (tar.formated.typeflag) { | 129 | switch (tar.formated.typeflag) { |
130 | /* busybox identifies hard links as being regular files with 0 size and a link name */ | ||
131 | case '1': | ||
132 | file_header->mode &= (S_IFREG | 07777); | ||
133 | break; | ||
134 | case 'x': | ||
135 | case 'g': | ||
136 | bb_error_msg_and_die("pax is not tar"); | ||
137 | break; | ||
125 | #ifdef CONFIG_FEATURE_TAR_OLDGNU_COMPATABILITY | 138 | #ifdef CONFIG_FEATURE_TAR_OLDGNU_COMPATABILITY |
126 | case 0: | 139 | case 0: |
127 | case '0': | 140 | case '0': |
@@ -146,11 +159,11 @@ extern char get_header_tar(archive_handle_t *archive_handle) | |||
146 | case '6': | 159 | case '6': |
147 | file_header->mode |= S_IFIFO; | 160 | file_header->mode |= S_IFIFO; |
148 | break; | 161 | break; |
149 | #endif | 162 | case '7': |
150 | /* hard links are detected as regular files with 0 size and a link name */ | 163 | /* Reserved for high performance files, treat as normal file */ |
151 | case '1': | 164 | file_header->mode |= S_IFREG; |
152 | file_header->mode &= (S_IFREG | 07777); | ||
153 | break; | 165 | break; |
166 | #endif | ||
154 | #ifdef CONFIG_FEATURE_TAR_GNU_EXTENSIONS | 167 | #ifdef CONFIG_FEATURE_TAR_GNU_EXTENSIONS |
155 | case 'L': { | 168 | case 'L': { |
156 | longname = xmalloc(file_header->size + 1); | 169 | longname = xmalloc(file_header->size + 1); |
@@ -169,13 +182,15 @@ extern char get_header_tar(archive_handle_t *archive_handle) | |||
169 | file_header->name = linkname; | 182 | file_header->name = linkname; |
170 | return(get_header_tar(archive_handle)); | 183 | return(get_header_tar(archive_handle)); |
171 | } | 184 | } |
172 | case 'D': | 185 | case 'D': /* GNU dump dir */ |
173 | case 'M': | 186 | case 'M': /* Continuation of multi volume archive*/ |
174 | case 'N': | 187 | case 'N': /* Old GNU for names > 100 characters */ |
175 | case 'S': | 188 | case 'S': /* Sparse file */ |
176 | case 'V': | 189 | case 'V': /* Volume header */ |
177 | bb_error_msg("Ignoring GNU extension type %c", tar.formated.typeflag); | 190 | bb_error_msg("Ignoring GNU extension type %c", tar.formated.typeflag); |
178 | #endif | 191 | #endif |
192 | default: | ||
193 | bb_error_msg("Unknown typeflag: 0x%x", tar.formated.typeflag); | ||
179 | } | 194 | } |
180 | { /* Strip trailing '/' in directories */ | 195 | { /* Strip trailing '/' in directories */ |
181 | /* Must be done after mode is set as '/' is used to check if its a directory */ | 196 | /* Must be done after mode is set as '/' is used to check if its a directory */ |