aboutsummaryrefslogtreecommitdiff
path: root/archival/libunarchive/get_header_tar.c
diff options
context:
space:
mode:
Diffstat (limited to 'archival/libunarchive/get_header_tar.c')
-rw-r--r--archival/libunarchive/get_header_tar.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/archival/libunarchive/get_header_tar.c b/archival/libunarchive/get_header_tar.c
index b5cae9f12..68f7b2b9b 100644
--- a/archival/libunarchive/get_header_tar.c
+++ b/archival/libunarchive/get_header_tar.c
@@ -111,25 +111,6 @@ char get_header_tar(archive_handle_t *archive_handle)
111 bb_error_msg_and_die("invalid tar header checksum"); 111 bb_error_msg_and_die("invalid tar header checksum");
112 } 112 }
113 113
114#ifdef CONFIG_FEATURE_TAR_GNU_EXTENSIONS
115 if (longname) {
116 file_header->name = longname;
117 longname = NULL;
118 }
119 else if (linkname) {
120 file_header->name = linkname;
121 linkname = NULL;
122 } else
123#endif
124 {
125 file_header->name = xstrndup(tar.name, sizeof(tar.name));
126 if (tar.prefix[0]) {
127 char *temp = file_header->name;
128 file_header->name = concat_path_file(tar.prefix, temp);
129 free(temp);
130 }
131 }
132
133 /* getOctal trashes subsequent field, therefore we call it 114 /* getOctal trashes subsequent field, therefore we call it
134 * on fields in reverse order */ 115 * on fields in reverse order */
135#define GET_OCTAL(a) getOctal((a), sizeof(a)) 116#define GET_OCTAL(a) getOctal((a), sizeof(a))
@@ -148,6 +129,24 @@ char get_header_tar(archive_handle_t *archive_handle)
148 file_header->mode = 07777 & GET_OCTAL(tar.mode); 129 file_header->mode = 07777 & GET_OCTAL(tar.mode);
149#undef GET_OCTAL 130#undef GET_OCTAL
150 131
132#ifdef CONFIG_FEATURE_TAR_GNU_EXTENSIONS
133 if (longname) {
134 file_header->name = longname;
135 longname = NULL;
136 }
137 else if (linkname) {
138 file_header->name = linkname;
139 linkname = NULL;
140 } else
141#endif
142 { /* we trash mode[0] here, it's ok */
143 tar.name[sizeof(tar.name)] = '\0';
144 if (tar.prefix[0])
145 file_header->name = concat_path_file(tar.prefix, tar.name);
146 else
147 file_header->name = xstrdup(tar.name);
148 }
149
151 /* Set bits 12-15 of the files mode */ 150 /* Set bits 12-15 of the files mode */
152 switch (tar.typeflag) { 151 switch (tar.typeflag) {
153 /* busybox identifies hard links as being regular files with 0 size and a link name */ 152 /* busybox identifies hard links as being regular files with 0 size and a link name */
@@ -209,10 +208,12 @@ char get_header_tar(archive_handle_t *archive_handle)
209 /* Strip trailing '/' in directories */ 208 /* Strip trailing '/' in directories */
210 /* Must be done after mode is set as '/' is used to check if its a directory */ 209 /* Must be done after mode is set as '/' is used to check if its a directory */
211 cp = last_char_is(file_header->name, '/'); 210 cp = last_char_is(file_header->name, '/');
212 if (cp) *cp = '\0';
213 211
214 if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { 212 if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) {
215 archive_handle->action_header(archive_handle->file_header); 213 archive_handle->action_header(archive_handle->file_header);
214 /* Note that we kill the '/' only after action_header() */
215 /* (like GNU tar 1.15.1: verbose mode outputs "dir/dir/") */
216 if (cp) *cp = '\0';
216 archive_handle->flags |= ARCHIVE_EXTRACT_QUIET; 217 archive_handle->flags |= ARCHIVE_EXTRACT_QUIET;
217 archive_handle->action_data(archive_handle); 218 archive_handle->action_data(archive_handle);
218 llist_add_to(&(archive_handle->passed), file_header->name); 219 llist_add_to(&(archive_handle->passed), file_header->name);