comparison toys/pending/cpio.c @ 1221:8451065c5a19 draft

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.
author Rob Landley <rob@landley.net>
date Thu, 13 Mar 2014 19:42:42 -0500
parents 10d4dd6621cb
children bb9d19136eeb
comparison
equal deleted inserted replaced
1220:10d4dd6621cb 1221:8451065c5a19
7 * 7 *
8 * http://pubs.opengroup.org/onlinepubs/7908799/xcu/cpio.html 8 * http://pubs.opengroup.org/onlinepubs/7908799/xcu/cpio.html
9 * (Yes, that's SUSv2, the newer standards removed it around the time RPM 9 * (Yes, that's SUSv2, the newer standards removed it around the time RPM
10 * and initramfs started heavily using this archive format. Go figure.) 10 * and initramfs started heavily using this archive format. Go figure.)
11 11
12 USE_CPIO(NEWTOY(cpio, "H:diotuF:", TOYFLAG_BIN)) 12 USE_CPIO(NEWTOY(cpio, "H:di|o|t|uF:[!iot][!dot][!uot]", TOYFLAG_BIN))
13 13
14 config CPIO 14 config CPIO
15 bool "cpio" 15 bool "cpio"
16 default n 16 default n
17 help 17 help
18 usage: cpio { -i[du] | -o | -t } [-H FMT] [-F ARCHIVE] 18 usage: cpio {-o|-t|-i[du]} [-H FMT] [-F ARCHIVE]
19 19
20 copy files into and out of an archive 20 copy files into and out of a "newc" format cpio archive
21 -d create leading directories when extracting an archive 21
22 -i extract from archive into file system (stdin is an archive) 22 Actions:
23 -o create archive (stdin is a list of files, stdout is an archive) 23 -o create archive (stdin is a list of files, stdout is an archive)
24 -t list files (stdin is an archive, stdout is a list of files) 24 -t list files (stdin is an archive, stdout is a list of files)
25 -u always overwrite files (default) 25 -i extract from archive into file system (stdin is an archive)
26 -H FMT write archive in specified format: 26
27 newc SVR4 new character format (default) 27 Extract options:
28 -F ARCHIVE read from or write to ARCHIVE 28 -d create leading directories when extracting an archive
29 -u always overwrite files (default)
30
31 Other options:
32 -H FMT archive format (ignored, only newc supported)
33 -F ARCHIVE read from or write to ARCHIVE file
29 */ 34 */
30 35
31 #define FOR_cpio 36 #define FOR_cpio
32 #include "toys.h" 37 #include "toys.h"
33 38
34 GLOBALS( 39 GLOBALS(
35 char *archive; 40 char *archive;
36 char *fmt; 41 char *fmt;
37 ) 42 )
38
39 /* Iterate through a list of files, read from stdin.
40 * No users need rw.
41 */
42 void loopfiles_stdin(void (*function)(int fd, char *name, struct stat st))
43 {
44 int fd;
45 struct stat st;
46 char *name = toybuf;
47
48 while (name) {
49 memset(toybuf, 0, sizeof(toybuf));
50 name = fgets(toybuf, sizeof(toybuf) - 1, stdin);
51
52 if (name) {
53 if (toybuf[strlen(name) - 1] == '\n' ) {
54 toybuf[strlen(name) - 1 ] = '\0';
55 if (lstat(name, &st) == -1) verror_msg(name, errno, NULL);
56 if (errno) continue;
57 fd = open(name, O_RDONLY);
58 if (fd > 0 || !S_ISREG(st.st_mode)) {
59 function(fd, name, st);
60 close(fd);
61 }
62 errno = 0;
63 }
64 }
65 }
66 }
67 43
68 struct newc_header { 44 struct newc_header {
69 char c_magic[6]; 45 char c_magic[6];
70 char c_ino[8]; 46 char c_ino[8];
71 char c_mode[8]; 47 char c_mode[8];
116 if (out > 0) write(1, toybuf, out); 92 if (out > 0) write(1, toybuf, out);
117 if (errno || out < sizeof(toybuf)) break; 93 if (errno || out < sizeof(toybuf)) break;
118 } 94 }
119 } 95 }
120 if (buf.st_size & 3) write(1, &n, 4 - (buf.st_size & 3)); 96 if (buf.st_size & 3) write(1, &n, 4 - (buf.st_size & 3));
97 }
98
99 /* Iterate through a list of files, read from stdin.
100 * No users need rw.
101 */
102 void loopfiles_stdin(void)
103 {
104 int fd;
105 struct stat st;
106 char *name = toybuf;
107
108 while (name) {
109 memset(toybuf, 0, sizeof(toybuf));
110 name = fgets(toybuf, sizeof(toybuf) - 1, stdin);
111
112 if (name) {
113 if (toybuf[strlen(name) - 1] == '\n' ) {
114 toybuf[strlen(name) - 1 ] = '\0';
115 if (lstat(name, &st) == -1) verror_msg(name, errno, NULL);
116 if (errno) continue;
117 fd = open(name, O_RDONLY);
118 if (fd > 0 || !S_ISREG(st.st_mode)) {
119 write_cpio_member(fd, name, st);
120 close(fd);
121 }
122 errno = 0;
123 }
124 }
125 }
121 } 126 }
122 127
123 //convert hex to uint; mostly to allow using bits of non-terminated strings 128 //convert hex to uint; mostly to allow using bits of non-terminated strings
124 unsigned int htou(char * hex) 129 unsigned int htou(char * hex)
125 { 130 {
236 } 241 }
237 242
238 if (toys.optflags & FLAG_t) read_cpio_archive(0, 2); 243 if (toys.optflags & FLAG_t) read_cpio_archive(0, 2);
239 else if (toys.optflags & FLAG_i) read_cpio_archive(0, 1); 244 else if (toys.optflags & FLAG_i) read_cpio_archive(0, 1);
240 else if (toys.optflags & FLAG_o) { 245 else if (toys.optflags & FLAG_o) {
241 loopfiles_stdin(write_cpio_member); 246 loopfiles_stdin();
242 write(1, "07070100000000000000000000000000000000000000010000000000000000" 247 write(1, "07070100000000000000000000000000000000000000010000000000000000"
243 "000000000000000000000000000000000000000B00000000TRAILER!!!\0\0\0", 124); 248 "000000000000000000000000000000000000000B00000000TRAILER!!!\0\0\0", 124);
244 } else error_exit("must use one of -iot"); 249 } else error_exit("must use one of -iot");
245 } 250 }