aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toys/pending/cpio.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/toys/pending/cpio.c b/toys/pending/cpio.c
index e0ed8e85..61f475b9 100644
--- a/toys/pending/cpio.c
+++ b/toys/pending/cpio.c
@@ -6,20 +6,23 @@
* http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/cpio.html
*
* http://pubs.opengroup.org/onlinepubs/7908799/xcu/cpio.html
+ * (Yes, that's SUSv2, the newer standards removed it around the time RPM
+ * and initramfs started heavily using this archive format. Go figure.)
-USE_CPIO(NEWTOY(cpio, "H:iotuF:", TOYFLAG_BIN))
+USE_CPIO(NEWTOY(cpio, "H:diotuF:", TOYFLAG_BIN))
config CPIO
bool "cpio"
default n
help
- usage: cpio { -iu | -o | -t } [-H FMT] [-F ARCHIVE]
+ usage: cpio { -i[du] | -o | -t } [-H FMT] [-F ARCHIVE]
copy files into and out of an archive
+ -d create leading directories when extracting an archive
-i extract from archive into file system (stdin is an archive)
-o create archive (stdin is a list of files, stdout is an archive)
-t list files (stdin is an archive, stdout is a list of files)
- -u always overwrite files (current default)
+ -u always overwrite files (default)
-H FMT write archive in specified format:
newc SVR4 new character format (default)
-F ARCHIVE read from or write to ARCHIVE
@@ -49,7 +52,8 @@ void loopfiles_stdin(void (*function)(int fd, char *name, struct stat st))
if (name) {
if (toybuf[strlen(name) - 1] == '\n' ) {
toybuf[strlen(name) - 1 ] = '\0';
- if (lstat(name, &st) == -1) continue;
+ if (lstat(name, &st) == -1) verror_msg(name, errno, NULL);
+ if (errno) continue;
fd = open(name, O_RDONLY);
if (fd > 0 || !S_ISREG(st.st_mode)) {
function(fd, name, st);
@@ -158,7 +162,7 @@ int read_cpio_member(int fd, int how)
mode_t mode = 0;
int pad, ofd = 0;
struct newc_header hdr;
- char *name;
+ char *name, *lastdir;
dev_t dev = 0;
xreadall(fd, &hdr, sizeof(struct newc_header));
@@ -171,6 +175,9 @@ int read_cpio_member(int fd, int how)
if (pad < 4) xreadall(fd, toybuf, pad);
pad = 4 - (fsize % 4);
+ if ((toys.optflags&FLAG_d) && (lastdir = strrchr(name, '/')))
+ if (mkpathat(AT_FDCWD, name, 0, 2)) perror_msg("mkpath '%s'", name);
+
if (how & 1) {
if (S_ISDIR(mode)) ofd = mkdir(name, mode);
else if (S_ISLNK(mode)) {