Mercurial > hg > toybox
annotate toys/pending/cpio.c @ 1135:581c35250cff draft
Minor drive-by cleanups to cpio. Whitespace, curly brackets, replace %4 with &3, turn a switch/case into if/else.
author | Rob Landley <rob@landley.net> |
---|---|
date | Sun, 01 Dec 2013 14:34:05 -0600 |
parents | 977f0a4dc562 |
children | 10d4dd6621cb |
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 |
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
7 * |
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
8 * http://pubs.opengroup.org/onlinepubs/7908799/xcu/cpio.html |
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
9 |
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
10 USE_CPIO(NEWTOY(cpio, "H:iotuF:", 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
|
11 |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
12 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
|
13 bool "cpio" |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
14 default n |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
15 help |
1121
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
16 usage: cpio { -iu | -o | -t } [-H FMT] [-F 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
|
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 copy files into and out of an archive |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
19 -i extract from archive into file system (stdin is an archive) |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
20 -o create archive (stdin is a list of files, stdout is an archive) |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
21 -t list files (stdin is an archive, stdout is a list of files) |
1121
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
22 -u always overwrite files (current default) |
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
23 -H FMT write archive in specified format: |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
24 newc SVR4 new character format (default) |
1121
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
25 -F ARCHIVE read from or write to 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
|
26 */ |
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
|
27 |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
28 #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
|
29 #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
|
30 |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
31 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
|
32 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
|
33 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
|
34 ) |
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 /* Iterate through a list of files, read from stdin. |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
37 * No users need rw. |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
38 */ |
1098 | 39 void loopfiles_stdin(void (*function)(int fd, char *name, struct stat st)) |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
40 { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
41 int fd; |
1098 | 42 struct stat st; |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
43 char *name = toybuf; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
44 |
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
|
45 while (name) { |
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 memset(toybuf, 0, sizeof(toybuf)); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
47 name = fgets(toybuf, sizeof(toybuf) - 1, stdin); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
48 |
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
|
49 if (name) { |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
50 if (toybuf[strlen(name) - 1] == '\n' ) { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
51 toybuf[strlen(name) - 1 ] = '\0'; |
1098 | 52 if (lstat(name, &st) == -1) continue; |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
53 fd = open(name, O_RDONLY); |
1098 | 54 if (fd > 0 || !S_ISREG(st.st_mode)) { |
55 function(fd, name, st); | |
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 close(fd); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
57 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
58 errno = 0; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
59 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
60 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
61 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
62 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
63 |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
64 struct newc_header { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
65 char c_magic[6]; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
66 char c_ino[8]; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
67 char c_mode[8]; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
68 char c_uid[8]; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
69 char c_gid[8]; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
70 char c_nlink[8]; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
71 char c_mtime[8]; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
72 char c_filesize[8]; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
73 char c_devmajor[8]; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
74 char c_devminor[8]; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
75 char c_rdevmajor[8]; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
76 char c_rdevminor[8]; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
77 char c_namesize[8]; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
78 char c_check[8]; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
79 }; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
80 |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
81 void write_cpio_member(int fd, char *name, struct stat buf) |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
82 { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
83 char ahdr[sizeof(struct newc_header) + 1]; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
84 struct newc_header *hdr = (struct newc_header *)ahdr; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
85 size_t out = 0; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
86 unsigned int n = 0x00000000, nlen = strlen(name) + 1; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
87 |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
88 memset(hdr, '0', sizeof(struct newc_header)); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
89 if (S_ISDIR(buf.st_mode) || S_ISBLK(buf.st_mode) || S_ISCHR(buf.st_mode) |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
90 || S_ISFIFO(buf.st_mode) || S_ISSOCK(buf.st_mode)) |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
91 buf.st_size = 0; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
92 snprintf((char *)(hdr), sizeof(struct newc_header)+1, |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
93 "070701%08X%08X" "%08X%08X" |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
94 "%08X%08X%08X" |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
95 "%08X%08X" "%08X%08X%08X00000000", |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
96 (unsigned int)(buf.st_ino), buf.st_mode, buf.st_uid, buf.st_gid, |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
97 buf.st_nlink, (uint32_t)(buf.st_mtime), (uint32_t)(buf.st_size), |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
98 major(buf.st_dev), minor(buf.st_dev), |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
99 major(buf.st_rdev), minor(buf.st_rdev), nlen); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
100 write(1, hdr, sizeof(struct newc_header)); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
101 write(1, name, nlen); |
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
|
102 if ((nlen + 2) & 3) write(1, &n, 4 - ((nlen + 2) & 3)); |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
103 if (S_ISLNK(buf.st_mode)) { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
104 ssize_t llen = readlink(name, toybuf, sizeof(toybuf) - 1); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
105 if (llen > 0) { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
106 toybuf[llen] = '\0'; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
107 write(1, toybuf, buf.st_size); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
108 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
109 } else if (buf.st_size) { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
110 for (; (lseek(fd, 0, SEEK_CUR) < (uint32_t)(buf.st_size));) { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
111 out = read(fd, toybuf, sizeof(toybuf)); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
112 if (out > 0) write(1, toybuf, out); |
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
|
113 if (errno || out < sizeof(toybuf)) break; |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
114 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
115 } |
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
|
116 if (buf.st_size & 3) write(1, &n, 4 - (buf.st_size & 3)); |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
117 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
118 |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
119 //convert hex to uint; mostly to allow using bits of non-terminated strings |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
120 unsigned int htou(char * hex) |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
121 { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
122 unsigned int ret = 0, i = 0; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
123 |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
124 for (;(i < 8 && hex[i]);) { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
125 ret *= 16; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
126 switch(hex[i]) { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
127 case '0': |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
128 break; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
129 case '1': |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
130 case '2': |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
131 case '3': |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
132 case '4': |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
133 case '5': |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
134 case '6': |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
135 case '7': |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
136 case '8': |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
137 case '9': |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
138 ret += hex[i] - '1' + 1; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
139 break; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
140 case 'A': |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
141 case 'B': |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
142 case 'C': |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
143 case 'D': |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
144 case 'E': |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
145 case 'F': |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
146 ret += hex[i] - 'A' + 10; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
147 break; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
148 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
149 i++; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
150 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
151 return ret; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
152 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
153 |
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
|
154 // Read one cpio record. Returns 0 for last record, 1 for "continue". |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
155 int read_cpio_member(int fd, int how) |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
156 { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
157 uint32_t nsize, fsize; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
158 mode_t mode = 0; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
159 int pad, ofd = 0; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
160 struct newc_header hdr; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
161 char *name; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
162 dev_t dev = 0; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
163 |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
164 xreadall(fd, &hdr, sizeof(struct newc_header)); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
165 nsize = htou(hdr.c_namesize); |
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
|
166 xreadall(fd, name = xmalloc(nsize), nsize); |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
167 if (!strcmp("TRAILER!!!", name)) return 0; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
168 fsize = htou(hdr.c_filesize); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
169 mode += htou(hdr.c_mode); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
170 pad = 4 - ((nsize + 2) % 4); // 2 == sizeof(struct newc_header) % 4 |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
171 if (pad < 4) xreadall(fd, toybuf, pad); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
172 pad = 4 - (fsize % 4); |
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
|
173 |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
174 if (how & 1) { |
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
|
175 if (S_ISDIR(mode)) ofd = mkdir(name, mode); |
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
|
176 else if (S_ISLNK(mode)) { |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
177 memset(toybuf, 0, sizeof(toybuf)); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
178 if (fsize < sizeof(toybuf)) { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
179 pad = readall(fd, toybuf, fsize); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
180 if (pad < fsize) error_exit("short archive"); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
181 pad = 4 - (fsize % 4); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
182 fsize = 0; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
183 if (symlink(toybuf, name)) { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
184 perror_msg("could not write link %s", name); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
185 toys.exitval |= 1; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
186 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
187 } else { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
188 perror_msg("link too long: %s", name); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
189 toys.exitval |= 1; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
190 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
191 } else if (S_ISBLK(mode)||S_ISCHR(mode)||S_ISFIFO(mode)||S_ISSOCK(mode)) { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
192 dev = makedev(htou(hdr.c_rdevmajor),htou(hdr.c_rdevminor)); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
193 ofd = mknod(name, mode, dev); |
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
|
194 } else ofd = creat(name, mode); |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
195 if (ofd == -1) { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
196 error_msg("could not create %s", name); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
197 toys.exitval |= 1; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
198 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
199 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
200 errno = 0; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
201 if (how & 2) puts(name); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
202 while (fsize) { |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
203 int i; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
204 memset(toybuf, 0, sizeof(toybuf)); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
205 i = readall(fd, toybuf, (fsize>sizeof(toybuf)) ? sizeof(toybuf) : fsize); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
206 if (i < 1) error_exit("archive too short"); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
207 if (ofd > 0) writeall(ofd, toybuf, i); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
208 fsize -= i; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
209 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
210 if (pad < 4) xreadall(fd, toybuf, pad); |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
211 return 1; |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
212 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
213 |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
214 void read_cpio_archive(int fd, int how) |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
215 { |
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
|
216 for(;;) if (!read_cpio_member(fd, how)) return; |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
217 } |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
218 |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
219 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
|
220 { |
1121
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
221 if (TT.archive) { |
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
222 if (toys.optflags & (FLAG_i|FLAG_t)) { |
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
223 xclose(0); |
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
224 xopen(TT.archive, O_RDONLY); |
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
225 } else if (toys.optflags & FLAG_o) { |
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
226 xclose(1); |
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
227 xcreate(TT.archive, O_CREAT|O_WRONLY|O_TRUNC, 0755); |
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
228 } |
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
229 } |
977f0a4dc562
Support -F, and ignore -u since that's what we do anyway.
Isaac Dunham <ibid.ag@gmail.com>
parents:
1098
diff
changeset
|
230 |
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
|
231 if (toys.optflags & FLAG_t) read_cpio_archive(0, 2); |
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
|
232 else if (toys.optflags & FLAG_i) read_cpio_archive(0, 1); |
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
|
233 else if (toys.optflags & FLAG_o) { |
1098 | 234 loopfiles_stdin(write_cpio_member); |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
235 write(1, "07070100000000000000000000000000000000000000010000000000000000" |
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
236 "000000000000000000000000000000000000000B00000000TRAILER!!!\0\0\0", 124); |
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
|
237 } else error_exit("must use one of -iot"); |
1087
b73a61542297
I've finally gotten 'cpio' into a shape where it could be useable.
Isaac Dunham <ibid.ag@gmail.com>
parents:
diff
changeset
|
238 } |