comparison toys/pending/cpio.c @ 1220:10d4dd6621cb draft

Patch from Isaac Dunham to add cpio -d, with a few tweaks by me.
author Rob Landley <rob@landley.net>
date Tue, 11 Mar 2014 21:10:45 -0500
parents 581c35250cff
children 8451065c5a19
comparison
equal deleted inserted replaced
1219:468444e5c7c5 1220:10d4dd6621cb
4 * same license as toybox or as CC0, at your option. 4 * same license as toybox or as CC0, at your option.
5 * 5 *
6 * http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/cpio.html 6 * http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/cpio.html
7 * 7 *
8 * http://pubs.opengroup.org/onlinepubs/7908799/xcu/cpio.html 8 * http://pubs.opengroup.org/onlinepubs/7908799/xcu/cpio.html
9 9 * (Yes, that's SUSv2, the newer standards removed it around the time RPM
10 USE_CPIO(NEWTOY(cpio, "H:iotuF:", TOYFLAG_BIN)) 10 * and initramfs started heavily using this archive format. Go figure.)
11
12 USE_CPIO(NEWTOY(cpio, "H:diotuF:", TOYFLAG_BIN))
11 13
12 config CPIO 14 config CPIO
13 bool "cpio" 15 bool "cpio"
14 default n 16 default n
15 help 17 help
16 usage: cpio { -iu | -o | -t } [-H FMT] [-F ARCHIVE] 18 usage: cpio { -i[du] | -o | -t } [-H FMT] [-F ARCHIVE]
17 19
18 copy files into and out of an archive 20 copy files into and out of an archive
21 -d create leading directories when extracting an archive
19 -i extract from archive into file system (stdin is an archive) 22 -i extract from archive into file system (stdin is an archive)
20 -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)
21 -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)
22 -u always overwrite files (current default) 25 -u always overwrite files (default)
23 -H FMT write archive in specified format: 26 -H FMT write archive in specified format:
24 newc SVR4 new character format (default) 27 newc SVR4 new character format (default)
25 -F ARCHIVE read from or write to ARCHIVE 28 -F ARCHIVE read from or write to ARCHIVE
26 */ 29 */
27 30
47 name = fgets(toybuf, sizeof(toybuf) - 1, stdin); 50 name = fgets(toybuf, sizeof(toybuf) - 1, stdin);
48 51
49 if (name) { 52 if (name) {
50 if (toybuf[strlen(name) - 1] == '\n' ) { 53 if (toybuf[strlen(name) - 1] == '\n' ) {
51 toybuf[strlen(name) - 1 ] = '\0'; 54 toybuf[strlen(name) - 1 ] = '\0';
52 if (lstat(name, &st) == -1) continue; 55 if (lstat(name, &st) == -1) verror_msg(name, errno, NULL);
56 if (errno) continue;
53 fd = open(name, O_RDONLY); 57 fd = open(name, O_RDONLY);
54 if (fd > 0 || !S_ISREG(st.st_mode)) { 58 if (fd > 0 || !S_ISREG(st.st_mode)) {
55 function(fd, name, st); 59 function(fd, name, st);
56 close(fd); 60 close(fd);
57 } 61 }
156 { 160 {
157 uint32_t nsize, fsize; 161 uint32_t nsize, fsize;
158 mode_t mode = 0; 162 mode_t mode = 0;
159 int pad, ofd = 0; 163 int pad, ofd = 0;
160 struct newc_header hdr; 164 struct newc_header hdr;
161 char *name; 165 char *name, *lastdir;
162 dev_t dev = 0; 166 dev_t dev = 0;
163 167
164 xreadall(fd, &hdr, sizeof(struct newc_header)); 168 xreadall(fd, &hdr, sizeof(struct newc_header));
165 nsize = htou(hdr.c_namesize); 169 nsize = htou(hdr.c_namesize);
166 xreadall(fd, name = xmalloc(nsize), nsize); 170 xreadall(fd, name = xmalloc(nsize), nsize);
168 fsize = htou(hdr.c_filesize); 172 fsize = htou(hdr.c_filesize);
169 mode += htou(hdr.c_mode); 173 mode += htou(hdr.c_mode);
170 pad = 4 - ((nsize + 2) % 4); // 2 == sizeof(struct newc_header) % 4 174 pad = 4 - ((nsize + 2) % 4); // 2 == sizeof(struct newc_header) % 4
171 if (pad < 4) xreadall(fd, toybuf, pad); 175 if (pad < 4) xreadall(fd, toybuf, pad);
172 pad = 4 - (fsize % 4); 176 pad = 4 - (fsize % 4);
177
178 if ((toys.optflags&FLAG_d) && (lastdir = strrchr(name, '/')))
179 if (mkpathat(AT_FDCWD, name, 0, 2)) perror_msg("mkpath '%s'", name);
173 180
174 if (how & 1) { 181 if (how & 1) {
175 if (S_ISDIR(mode)) ofd = mkdir(name, mode); 182 if (S_ISDIR(mode)) ofd = mkdir(name, mode);
176 else if (S_ISLNK(mode)) { 183 else if (S_ISLNK(mode)) {
177 memset(toybuf, 0, sizeof(toybuf)); 184 memset(toybuf, 0, sizeof(toybuf));