# HG changeset patch # User Rob Landley # Date 1394757762 18000 # Node ID 8451065c5a19b1f1f788fc13f330584723048f90 # Parent 10d4dd6621cbc745cf5b78b9e48773718b105cba Cleanup cpio: fiddle with help text, make option parsing require/exclude -iot combinations, move loopfiles_stdin() down after write_cpio_member() so we can hardwire it instead of using a function pointer that only ever has one value. diff -r 10d4dd6621cb -r 8451065c5a19 toys/pending/cpio.c --- a/toys/pending/cpio.c Tue Mar 11 21:10:45 2014 -0500 +++ b/toys/pending/cpio.c Thu Mar 13 19:42:42 2014 -0500 @@ -9,23 +9,28 @@ * (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:diotuF:", TOYFLAG_BIN)) +USE_CPIO(NEWTOY(cpio, "H:di|o|t|uF:[!iot][!dot][!uot]", TOYFLAG_BIN)) config CPIO bool "cpio" default n help - usage: cpio { -i[du] | -o | -t } [-H FMT] [-F ARCHIVE] + usage: cpio {-o|-t|-i[du]} [-H FMT] [-F ARCHIVE] + + copy files into and out of a "newc" format cpio 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 (default) - -H FMT write archive in specified format: - newc SVR4 new character format (default) - -F ARCHIVE read from or write to ARCHIVE + Actions: + -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) + -i extract from archive into file system (stdin is an archive) + + Extract options: + -d create leading directories when extracting an archive + -u always overwrite files (default) + + Other options: + -H FMT archive format (ignored, only newc supported) + -F ARCHIVE read from or write to ARCHIVE file */ #define FOR_cpio @@ -36,35 +41,6 @@ char *fmt; ) -/* Iterate through a list of files, read from stdin. - * No users need rw. - */ -void loopfiles_stdin(void (*function)(int fd, char *name, struct stat st)) -{ - int fd; - struct stat st; - char *name = toybuf; - - while (name) { - memset(toybuf, 0, sizeof(toybuf)); - name = fgets(toybuf, sizeof(toybuf) - 1, stdin); - - if (name) { - if (toybuf[strlen(name) - 1] == '\n' ) { - toybuf[strlen(name) - 1 ] = '\0'; - 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); - close(fd); - } - errno = 0; - } - } - } -} - struct newc_header { char c_magic[6]; char c_ino[8]; @@ -120,6 +96,35 @@ if (buf.st_size & 3) write(1, &n, 4 - (buf.st_size & 3)); } +/* Iterate through a list of files, read from stdin. + * No users need rw. + */ +void loopfiles_stdin(void) +{ + int fd; + struct stat st; + char *name = toybuf; + + while (name) { + memset(toybuf, 0, sizeof(toybuf)); + name = fgets(toybuf, sizeof(toybuf) - 1, stdin); + + if (name) { + if (toybuf[strlen(name) - 1] == '\n' ) { + toybuf[strlen(name) - 1 ] = '\0'; + 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)) { + write_cpio_member(fd, name, st); + close(fd); + } + errno = 0; + } + } + } +} + //convert hex to uint; mostly to allow using bits of non-terminated strings unsigned int htou(char * hex) { @@ -238,7 +243,7 @@ if (toys.optflags & FLAG_t) read_cpio_archive(0, 2); else if (toys.optflags & FLAG_i) read_cpio_archive(0, 1); else if (toys.optflags & FLAG_o) { - loopfiles_stdin(write_cpio_member); + loopfiles_stdin(); write(1, "07070100000000000000000000000000000000000000010000000000000000" "000000000000000000000000000000000000000B00000000TRAILER!!!\0\0\0", 124); } else error_exit("must use one of -iot");