Mercurial > hg > toybox
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 } |