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);