aboutsummaryrefslogtreecommitdiff
path: root/archival
diff options
context:
space:
mode:
Diffstat (limited to 'archival')
-rw-r--r--archival/cpio.c52
-rw-r--r--archival/libarchive/get_header_ar.c6
2 files changed, 57 insertions, 1 deletions
diff --git a/archival/cpio.c b/archival/cpio.c
index f525419b8..7149782d7 100644
--- a/archival/cpio.c
+++ b/archival/cpio.c
@@ -38,6 +38,20 @@
38//config: depends on FEATURE_CPIO_O 38//config: depends on FEATURE_CPIO_O
39//config: help 39//config: help
40//config: Passthrough mode. Rarely used. 40//config: Passthrough mode. Rarely used.
41//config:
42//config:config FEATURE_CPIO_IGNORE_DEVNO
43//config: bool "Support --ignore-devno like GNU cpio"
44//config: default y
45//config: depends on FEATURE_CPIO_O && LONG_OPTS
46//config: help
47//config: Optionally ignore device numbers when creating archives.
48//config:
49//config:config FEATURE_CPIO_RENUMBER_INODES
50//config: bool "Support --renumber-inodes like GNU cpio"
51//config: default y
52//config: depends on FEATURE_CPIO_O && LONG_OPTS
53//config: help
54//config: Optionally renumber inodes when creating archives.
41 55
42//applet:IF_CPIO(APPLET(cpio, BB_DIR_BIN, BB_SUID_DROP)) 56//applet:IF_CPIO(APPLET(cpio, BB_DIR_BIN, BB_SUID_DROP))
43 57
@@ -75,6 +89,12 @@
75//usage: "\n -R USER[:GRP] Set owner of created files" 89//usage: "\n -R USER[:GRP] Set owner of created files"
76//usage: "\n -L Dereference symlinks" 90//usage: "\n -L Dereference symlinks"
77//usage: "\n -0 NUL terminated input" 91//usage: "\n -0 NUL terminated input"
92//usage: IF_FEATURE_CPIO_IGNORE_DEVNO(
93//usage: "\n --ignore-devno"
94//usage: )
95//usage: IF_FEATURE_CPIO_RENUMBER_INODES(
96//usage: "\n --renumber-inodes"
97//usage: )
78 98
79/* GNU cpio 2.9 --help (abridged): 99/* GNU cpio 2.9 --help (abridged):
80 100
@@ -162,17 +182,22 @@ enum {
162 IF_FEATURE_CPIO_P(OPTBIT_PASSTHROUGH,) 182 IF_FEATURE_CPIO_P(OPTBIT_PASSTHROUGH,)
163 IF_LONG_OPTS( OPTBIT_QUIET ,) 183 IF_LONG_OPTS( OPTBIT_QUIET ,)
164 IF_LONG_OPTS( OPTBIT_2STDOUT ,) 184 IF_LONG_OPTS( OPTBIT_2STDOUT ,)
185 IF_FEATURE_CPIO_IGNORE_DEVNO(OPTBIT_IGNORE_DEVNO,)
186 IF_FEATURE_CPIO_RENUMBER_INODES(OPTBIT_RENUMBER_INODES,)
165 OPT_CREATE = IF_FEATURE_CPIO_O((1 << OPTBIT_CREATE )) + 0, 187 OPT_CREATE = IF_FEATURE_CPIO_O((1 << OPTBIT_CREATE )) + 0,
166 OPT_FORMAT = IF_FEATURE_CPIO_O((1 << OPTBIT_FORMAT )) + 0, 188 OPT_FORMAT = IF_FEATURE_CPIO_O((1 << OPTBIT_FORMAT )) + 0,
167 OPT_PASSTHROUGH = IF_FEATURE_CPIO_P((1 << OPTBIT_PASSTHROUGH)) + 0, 189 OPT_PASSTHROUGH = IF_FEATURE_CPIO_P((1 << OPTBIT_PASSTHROUGH)) + 0,
168 OPT_QUIET = IF_LONG_OPTS( (1 << OPTBIT_QUIET )) + 0, 190 OPT_QUIET = IF_LONG_OPTS( (1 << OPTBIT_QUIET )) + 0,
169 OPT_2STDOUT = IF_LONG_OPTS( (1 << OPTBIT_2STDOUT )) + 0, 191 OPT_2STDOUT = IF_LONG_OPTS( (1 << OPTBIT_2STDOUT )) + 0,
192 OPT_IGNORE_DEVNO = IF_FEATURE_CPIO_IGNORE_DEVNO((1 << OPTBIT_IGNORE_DEVNO)) + 0,
193 OPT_RENUMBER_INODES = IF_FEATURE_CPIO_RENUMBER_INODES((1 << OPTBIT_RENUMBER_INODES)) + 0,
170}; 194};
171 195
172#define OPTION_STR "it0uvdmLF:R:" 196#define OPTION_STR "it0uvdmLF:R:"
173 197
174struct globals { 198struct globals {
175 struct bb_uidgid_t owner_ugid; 199 struct bb_uidgid_t owner_ugid;
200 ino_t next_inode;
176} FIX_ALIASING; 201} FIX_ALIASING;
177#define G (*(struct globals*)bb_common_bufsiz1) 202#define G (*(struct globals*)bb_common_bufsiz1)
178void BUG_cpio_globals_too_big(void); 203void BUG_cpio_globals_too_big(void);
@@ -206,6 +231,9 @@ static NOINLINE int cpio_o(void)
206 struct inodes_s *next; 231 struct inodes_s *next;
207 struct name_s *names; 232 struct name_s *names;
208 struct stat st; 233 struct stat st;
234#if ENABLE_FEATURE_CPIO_RENUMBER_INODES
235 ino_t mapped_inode;
236#endif
209 }; 237 };
210 238
211 struct inodes_s *links = NULL; 239 struct inodes_s *links = NULL;
@@ -260,6 +288,10 @@ static NOINLINE int cpio_o(void)
260 l = xzalloc(sizeof(*l)); 288 l = xzalloc(sizeof(*l));
261 l->st = st; 289 l->st = st;
262 l->next = links; 290 l->next = links;
291#if ENABLE_FEATURE_CPIO_RENUMBER_INODES
292 if (option_mask32 & OPT_RENUMBER_INODES)
293 l->mapped_inode = ++G.next_inode;
294#endif
263 links = l; 295 links = l;
264 break; 296 break;
265 } 297 }
@@ -278,6 +310,11 @@ static NOINLINE int cpio_o(void)
278 free(line); 310 free(line);
279 continue; 311 continue;
280 } 312 }
313#if ENABLE_FEATURE_CPIO_RENUMBER_INODES
314 else if (option_mask32 & OPT_RENUMBER_INODES) {
315 st.st_ino = ++G.next_inode;
316 }
317#endif
281 } else { /* line == NULL: EOF */ 318 } else { /* line == NULL: EOF */
282 next_link: 319 next_link:
283 if (links) { 320 if (links) {
@@ -285,6 +322,10 @@ static NOINLINE int cpio_o(void)
285 st = links->st; 322 st = links->st;
286 name = links->names->name; 323 name = links->names->name;
287 links->names = links->names->next; 324 links->names = links->names->next;
325#if ENABLE_FEATURE_CPIO_RENUMBER_INODES
326 if (links->mapped_inode)
327 st.st_ino = links->mapped_inode;
328#endif
288 /* GNU cpio is reported to emit file data 329 /* GNU cpio is reported to emit file data
289 * only for the last instance. Mimic that. */ 330 * only for the last instance. Mimic that. */
290 if (links->names == NULL) 331 if (links->names == NULL)
@@ -304,6 +345,11 @@ static NOINLINE int cpio_o(void)
304 } 345 }
305 } 346 }
306 347
348#if ENABLE_FEATURE_CPIO_IGNORE_DEVNO
349 if (option_mask32 & OPT_IGNORE_DEVNO)
350 st.st_dev = st.st_rdev = 0;
351#endif
352
307 bytes += printf("070701" 353 bytes += printf("070701"
308 "%08X%08X%08X%08X%08X%08X%08X" 354 "%08X%08X%08X%08X%08X%08X%08X"
309 "%08X%08X%08X%08X" /* GNU cpio uses uppercase hex */ 355 "%08X%08X%08X%08X" /* GNU cpio uses uppercase hex */
@@ -379,6 +425,12 @@ int cpio_main(int argc UNUSED_PARAM, char **argv)
379 "null\0" No_argument "0" 425 "null\0" No_argument "0"
380 "quiet\0" No_argument "\xff" 426 "quiet\0" No_argument "\xff"
381 "to-stdout\0" No_argument "\xfe" 427 "to-stdout\0" No_argument "\xfe"
428#if ENABLE_FEATURE_CPIO_IGNORE_DEVNO
429 "ignore-devno\0" No_argument "\xfd"
430#endif
431#if ENABLE_FEATURE_CPIO_RENUMBER_INODES
432 "renumber-inodes\0" No_argument "\xfc"
433#endif
382 ; 434 ;
383#endif 435#endif
384 436
diff --git a/archival/libarchive/get_header_ar.c b/archival/libarchive/get_header_ar.c
index 3a19d6ff7..6bd897392 100644
--- a/archival/libarchive/get_header_ar.c
+++ b/archival/libarchive/get_header_ar.c
@@ -92,8 +92,12 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle)
92 /* Only size is always present, the rest may be missing in 92 /* Only size is always present, the rest may be missing in
93 * long filename pseudo file. Thus we decode the rest 93 * long filename pseudo file. Thus we decode the rest
94 * after dealing with long filename pseudo file. 94 * after dealing with long filename pseudo file.
95 *
96 * GNU binutils in deterministic mode hard codes mode to 0644 (NOT
97 * 0100644). AR archives can only contain files, so force file
98 * mode.
95 */ 99 */
96 typed->mode = read_num(ar.formatted.mode, 8, sizeof(ar.formatted.mode)); 100 typed->mode = read_num(ar.formatted.mode, 8, sizeof(ar.formatted.mode)) | S_IFREG;
97 typed->gid = read_num(ar.formatted.gid, 10, sizeof(ar.formatted.gid)); 101 typed->gid = read_num(ar.formatted.gid, 10, sizeof(ar.formatted.gid));
98 typed->uid = read_num(ar.formatted.uid, 10, sizeof(ar.formatted.uid)); 102 typed->uid = read_num(ar.formatted.uid, 10, sizeof(ar.formatted.uid));
99 typed->mtime = read_num(ar.formatted.date, 10, sizeof(ar.formatted.date)); 103 typed->mtime = read_num(ar.formatted.date, 10, sizeof(ar.formatted.date));