Mercurial > hg > toybox
comparison toys/pending/cpio.c @ 1098:46d83f3c7546 draft
Here's a revised cpio.
I've reduced the use of malloc(), dropped an extra function call, and
-at least in theory- allowed proper handling of non-regular files.
(If we have a file we can't read, we still should record it when it's
of a type where file content is ignored).
author | Isaac Dunham <ibid.ag@gmail.com> |
---|---|
date | Sun, 27 Oct 2013 19:11:07 -0500 |
parents | b73a61542297 |
children | 977f0a4dc562 |
comparison
equal
deleted
inserted
replaced
1097:54b2776de2f4 | 1098:46d83f3c7546 |
---|---|
25 ) | 25 ) |
26 | 26 |
27 /* Iterate through a list of files, read from stdin. | 27 /* Iterate through a list of files, read from stdin. |
28 * No users need rw. | 28 * No users need rw. |
29 */ | 29 */ |
30 void loopfiles_stdin(void (*function)(int fd, char *name)) | 30 void loopfiles_stdin(void (*function)(int fd, char *name, struct stat st)) |
31 { | 31 { |
32 int fd; | 32 int fd; |
33 struct stat st; | |
33 char *name = toybuf; | 34 char *name = toybuf; |
34 | 35 |
35 while (name != NULL){ | 36 while (name != NULL){ |
36 memset(toybuf, 0, sizeof(toybuf)); | 37 memset(toybuf, 0, sizeof(toybuf)); |
37 name = fgets(toybuf, sizeof(toybuf) - 1, stdin); | 38 name = fgets(toybuf, sizeof(toybuf) - 1, stdin); |
38 | 39 |
39 if (name != NULL) { | 40 if (name != NULL) { |
40 if (toybuf[strlen(name) - 1] == '\n' ) { | 41 if (toybuf[strlen(name) - 1] == '\n' ) { |
41 toybuf[strlen(name) - 1 ] = '\0'; | 42 toybuf[strlen(name) - 1 ] = '\0'; |
43 if (lstat(name, &st) == -1) continue; | |
42 fd = open(name, O_RDONLY); | 44 fd = open(name, O_RDONLY); |
43 if (fd > 0) { | 45 if (fd > 0 || !S_ISREG(st.st_mode)) { |
44 function(fd, name); | 46 function(fd, name, st); |
45 close(fd); | 47 close(fd); |
46 } | 48 } |
47 errno = 0; | 49 errno = 0; |
48 } | 50 } |
49 } | 51 } |
101 if (out > 0) write(1, toybuf, out); | 103 if (out > 0) write(1, toybuf, out); |
102 if (errno || out < sizeof(toybuf)) break; | 104 if (errno || out < sizeof(toybuf)) break; |
103 } | 105 } |
104 } | 106 } |
105 if (buf.st_size % 4) write(1, &n, 4 - (buf.st_size % 4)); | 107 if (buf.st_size % 4) write(1, &n, 4 - (buf.st_size % 4)); |
106 } | |
107 | |
108 void write_cpio_call(int fd, char *name) | |
109 { | |
110 struct stat buf; | |
111 if (lstat(name, &buf) == -1) return; | |
112 write_cpio_member(fd, name, buf); | |
113 } | 108 } |
114 | 109 |
115 //convert hex to uint; mostly to allow using bits of non-terminated strings | 110 //convert hex to uint; mostly to allow using bits of non-terminated strings |
116 unsigned int htou(char * hex) | 111 unsigned int htou(char * hex) |
117 { | 112 { |
222 | 217 |
223 void cpio_main(void) | 218 void cpio_main(void) |
224 { | 219 { |
225 switch (toys.optflags & (FLAG_i | FLAG_o | FLAG_t)) { | 220 switch (toys.optflags & (FLAG_i | FLAG_o | FLAG_t)) { |
226 case FLAG_o: | 221 case FLAG_o: |
227 loopfiles_stdin(write_cpio_call); | 222 loopfiles_stdin(write_cpio_member); |
228 write(1, "07070100000000000000000000000000000000000000010000000000000000" | 223 write(1, "07070100000000000000000000000000000000000000010000000000000000" |
229 "000000000000000000000000000000000000000B00000000TRAILER!!!\0\0\0", 124); | 224 "000000000000000000000000000000000000000B00000000TRAILER!!!\0\0\0", 124); |
230 break; | 225 break; |
231 case FLAG_i: | 226 case FLAG_i: |
232 read_cpio_archive(0, 1); | 227 read_cpio_archive(0, 1); |