aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archival/libunarchive/get_header_tar.c33
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 */