Mercurial > hg > toybox
annotate toys/posix/cpio.c @ 1230:c78ffc6c330a draft
More cpio bugfixes from Isaac Dunham.
Fix FLAG_o to actually be 1 like the comment says, don't try to strlen(name) before reading it, pad TRAILER!!! entry correctly.
author | Rob Landley <rob@landley.net> |
---|---|
date | Wed, 26 Mar 2014 06:07:06 -0500 |
parents | 34d4ee60e78f |
children | ee5a6875d695 |
rev | line source |
---|---|
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
1 /* cpio.c - a basic cpio |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
2 * |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
3 * Written 2013 AD by Isaac Dunham; this code is placed under the |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
4 * same license as toybox or as CC0, at your option. |
1121
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
5 * |
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
6 * http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/cpio.html |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
7 * and http://pubs.opengroup.org/onlinepubs/7908799/xcu/cpio.html |
1121
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
8 * |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
9 * Yes, that's SUSv2, the newer standards removed it around the time RPM |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
10 * and initramfs started heavily using this archive format. |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
11 * |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
12 * Modern cpio expanded header to 110 bytes (first field 6 bytes, rest are 8). |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
13 * In order: magic ino mode uid gid nlink mtime filesize devmajor devminor |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
14 * rdevmajor rdevminor namesize check |
1121
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
15 |
1230
c78ffc6c330a
More cpio bugfixes from Isaac Dunham.
Rob Landley <rob@landley.net>
parents:
1229
diff
changeset
|
16 USE_CPIO(NEWTOY(cpio, "duH:i|t|F:v(verbose)o|[!io][!ot]", TOYFLAG_BIN)) |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
17 |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
18 config CPIO |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
19 bool "cpio" |
1229
34d4ee60e78f
Promote cpio out of pending.
Rob Landley <rob@landley.net>
parents:
1228
diff
changeset
|
20 default y |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
21 help |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
22 usage: cpio -{o|t|i} [-v] [--verbose] [-F FILE] [ignored: -du -H newc] |
1221
8451065c5a19
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.
Rob Landley <rob@landley.net>
parents:
1220
diff
changeset
|
23 |
8451065c5a19
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.
Rob Landley <rob@landley.net>
parents:
1220
diff
changeset
|
24 copy files into and out of a "newc" format cpio archive |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
25 |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
26 -F FILE use archive FILE instead of stdin/stdout |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
27 -i extract from archive into file system (stdin=archive) |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
28 -o create archive (stdin=list of files, stdout=archive) |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
29 -t test files (list only, stdin=archive, stdout=list of files) |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
30 -v verbose (list files during create/extract) |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
31 */ |
1135
581c35250cff
Minor drive-by cleanups to cpio. Whitespace, curly brackets, replace %4 with &3, turn a switch/case into if/else.
Rob Landley <rob@landley.net>
parents:
1121
diff
changeset
|
32 |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
33 #define FOR_cpio |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
34 #include "toys.h" |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
35 |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
36 GLOBALS( |
1135
581c35250cff
Minor drive-by cleanups to cpio. Whitespace, curly brackets, replace %4 with &3, turn a switch/case into if/else.
Rob Landley <rob@landley.net>
parents:
1121
diff
changeset
|
37 char *archive; |
581c35250cff
Minor drive-by cleanups to cpio. Whitespace, curly brackets, replace %4 with &3, turn a switch/case into if/else.
Rob Landley <rob@landley.net>
parents:
1121
diff
changeset
|
38 char *fmt; |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
39 ) |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
40 |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
41 // Read strings, tail padded to 4 byte alignment. Argument "align" is amount |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
42 // by which start of string isn't aligned (usually 0). |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
43 static char *strpad(int fd, unsigned len, unsigned align) |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
44 { |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
45 char *str; |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
46 |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
47 align = (align + len) & 3; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
48 if (align) len += (4-align); |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
49 |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
50 xreadall(fd, str = xmalloc(len+1), len); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
51 str[len]=0; // redundant, in case archive is bad |
1221
8451065c5a19
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.
Rob Landley <rob@landley.net>
parents:
1220
diff
changeset
|
52 |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
53 return str; |
1221
8451065c5a19
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.
Rob Landley <rob@landley.net>
parents:
1220
diff
changeset
|
54 } |
8451065c5a19
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.
Rob Landley <rob@landley.net>
parents:
1220
diff
changeset
|
55 |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
56 //convert hex to uint; mostly to allow using bits of non-terminated strings |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
57 unsigned x8u(char *hex) |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
58 { |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
59 unsigned val, inpos = 8, outpos; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
60 char pattern[6]; |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
61 |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
62 while (*hex == '0') { |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
63 hex++; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
64 if (!--inpos) return 0; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
65 } |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
66 // Because scanf gratuitously treats %*X differently than printf does. |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
67 sprintf(pattern, "%%%dX%%n", inpos); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
68 sscanf(hex, pattern, &val, &outpos); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
69 if (inpos != outpos) error_exit("bad header"); |
1220
10d4dd6621cb
Patch from Isaac Dunham to add cpio -d, with a few tweaks by me.
Rob Landley <rob@landley.net>
parents:
1135
diff
changeset
|
70 |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
71 return val; |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
72 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
73 |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
74 void cpio_main(void) |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
75 { |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
76 int afd; |
1223 | 77 |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
78 // Subtle bit: FLAG_o is 1 so we can just use it to select stdin/stdout. |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
79 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
80 afd = toys.optflags & FLAG_o; |
1121
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
81 if (TT.archive) { |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
82 int perm = (toys.optflags & FLAG_o) ? O_CREAT|O_WRONLY|O_TRUNC : O_RDONLY; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
83 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
84 afd = xcreate(TT.archive, perm, 0644); |
1121
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
85 } |
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
86 |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
87 // read cpio archive |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
88 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
89 if (toys.optflags & (FLAG_i|FLAG_t)) for (;;) { |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
90 char *name, *tofree, *data; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
91 unsigned size, mode; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
92 int test = toys.optflags & FLAG_t, err = 0; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
93 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
94 // Read header and name. |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
95 xreadall(afd, toybuf, 110); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
96 tofree = name = strpad(afd, x8u(toybuf+94), 110); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
97 if (!strcmp("TRAILER!!!", name)) break; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
98 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
99 // If you want to extract absolute paths, "cd /" and run cpio. |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
100 while (*name == '/') name++; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
101 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
102 // Align to 4 bytes. Note header is 110 bytes which is 2 bytes over. |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
103 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
104 size = x8u(toybuf+54); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
105 mode = x8u(toybuf+14); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
106 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
107 if (toys.optflags & (FLAG_t|FLAG_v)) puts(name); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
108 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
109 if (!test && strrchr(name, '/') && mkpathat(AT_FDCWD, name, 0, 2)) { |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
110 perror_msg("mkpath '%s'", name); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
111 test++; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
112 } |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
113 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
114 // Consume entire record even if it couldn't create file, so we're |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
115 // properly aligned with next file. |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
116 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
117 if (S_ISDIR(mode)) { |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
118 if (!test) err = mkdir(name, mode); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
119 } else if (S_ISLNK(mode)) { |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
120 data = strpad(afd, size, 0); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
121 if (!test) err = symlink(data, name); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
122 } else if (S_ISREG(mode)) { |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
123 int fd; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
124 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
125 // If write fails, we still need to read/discard data to continue with |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
126 // archive. Since doing so overwrites errno, report error now |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
127 fd = test ? 0 : open(name, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW, mode); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
128 if (fd < 0) { |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
129 perror_msg("create %s", name); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
130 test++; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
131 } |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
132 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
133 data = toybuf; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
134 while (size) { |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
135 if (size < sizeof(toybuf)) data = strpad(afd, size, 0); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
136 else xreadall(afd, toybuf, sizeof(toybuf)); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
137 if (!test) xwrite(fd, data, data == toybuf ? sizeof(toybuf) : size); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
138 if (data != toybuf) { |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
139 free(data); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
140 break; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
141 } |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
142 size -= sizeof(toybuf); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
143 } |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
144 close(fd); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
145 } else if (!test) |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
146 err = mknod(name, mode, makedev(x8u(toybuf+62), x8u(toybuf+70))); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
147 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
148 if (err<0) perror_msg("create '%s'", name); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
149 free(tofree); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
150 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
151 // Output cpio archive |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
152 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
153 } else { |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
154 char *name = 0; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
155 size_t size = 0; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
156 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
157 for (;;) { |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
158 struct stat st; |
1230
c78ffc6c330a
More cpio bugfixes from Isaac Dunham.
Rob Landley <rob@landley.net>
parents:
1229
diff
changeset
|
159 unsigned nlen, error = 0, zero = 0; |
1228
2366f9d73745
Several cpio bugfixes spotted by Isaac Dunham.
Rob Landley <rob@landley.net>
parents:
1227
diff
changeset
|
160 int len, fd = -1; |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
161 ssize_t llen; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
162 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
163 len = getline(&name, &size, stdin); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
164 if (len<1) break; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
165 if (name[len-1] == '\n') name[--len] = 0; |
1230
c78ffc6c330a
More cpio bugfixes from Isaac Dunham.
Rob Landley <rob@landley.net>
parents:
1229
diff
changeset
|
166 nlen = len+1; |
1228
2366f9d73745
Several cpio bugfixes spotted by Isaac Dunham.
Rob Landley <rob@landley.net>
parents:
1227
diff
changeset
|
167 if (lstat(name, &st) |
2366f9d73745
Several cpio bugfixes spotted by Isaac Dunham.
Rob Landley <rob@landley.net>
parents:
1227
diff
changeset
|
168 || (S_ISREG(st.st_mode) && (fd = open(name, O_RDONLY))<0)) |
2366f9d73745
Several cpio bugfixes spotted by Isaac Dunham.
Rob Landley <rob@landley.net>
parents:
1227
diff
changeset
|
169 { |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
170 perror_msg("%s", name); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
171 continue; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
172 } |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
173 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
174 if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) st.st_size = 0; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
175 if (st.st_size >> 32) perror_msg("skipping >2G file '%s'", name); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
176 else { |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
177 llen = sprintf(toybuf, |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
178 "070701%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X", |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
179 (int)st.st_ino, st.st_mode, st.st_uid, st.st_gid, (int)st.st_nlink, |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
180 (int)st.st_mtime, (int)st.st_size, major(st.st_dev), |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
181 minor(st.st_dev), major(st.st_rdev), minor(st.st_rdev), nlen, 0); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
182 xwrite(afd, toybuf, llen); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
183 xwrite(afd, name, nlen); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
184 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
185 // NUL Pad header up to 4 multiple bytes. |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
186 llen = (llen + nlen) & 3; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
187 if (llen) xwrite(afd, &zero, 4-llen); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
188 |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
189 // Write out body for symlink or regular file |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
190 llen = st.st_size; |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
191 if (S_ISLNK(st.st_mode)) { |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
192 if (readlink(name, toybuf, sizeof(toybuf)-1) == llen) |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
193 xwrite(afd, toybuf, llen); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
194 else perror_msg("readlink '%s'", name); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
195 } else while (llen) { |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
196 nlen = llen > sizeof(toybuf) ? sizeof(toybuf) : llen; |
1228
2366f9d73745
Several cpio bugfixes spotted by Isaac Dunham.
Rob Landley <rob@landley.net>
parents:
1227
diff
changeset
|
197 llen -= nlen; |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
198 // If read fails, write anyway (already wrote size in header) |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
199 if (nlen != readall(fd, toybuf, nlen)) |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
200 if (!error++) perror_msg("bad read from file '%s'", name); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
201 xwrite(afd, toybuf, nlen); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
202 } |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
203 llen = st.st_size & 3; |
1228
2366f9d73745
Several cpio bugfixes spotted by Isaac Dunham.
Rob Landley <rob@landley.net>
parents:
1227
diff
changeset
|
204 if (llen) write(afd, &zero, 4-llen); |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
205 } |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
206 close(fd); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
207 } |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
208 free(name); |
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
209 |
1230
c78ffc6c330a
More cpio bugfixes from Isaac Dunham.
Rob Landley <rob@landley.net>
parents:
1229
diff
changeset
|
210 memset(toybuf, 0, sizeof(toybuf)); |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
211 xwrite(afd, toybuf, |
1230
c78ffc6c330a
More cpio bugfixes from Isaac Dunham.
Rob Landley <rob@landley.net>
parents:
1229
diff
changeset
|
212 sprintf(toybuf, "070701%040X%056X%08XTRAILER!!!", 1, 0x0b, 0)+4); |
1227
903acf85bd1d
Most of the remaining cpio cleanup.
Rob Landley <rob@landley.net>
parents:
1223
diff
changeset
|
213 } |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
214 } |