|
1 |
| -/* dracut-install.c -- install files and executables |
| 1 | +/* skipcpio.c |
2 | 2 |
|
3 | 3 | Copyright (C) 2012 Harald Hoyer
|
4 | 4 | Copyright (C) 2012 Red Hat, Inc. All rights reserved.
|
|
28 | 28 | #include <string.h>
|
29 | 29 |
|
30 | 30 | #define CPIO_MAGIC "070701"
|
| 31 | + |
31 | 32 | #define CPIO_END "TRAILER!!!"
|
32 | 33 | #define CPIO_ENDLEN (sizeof(CPIO_END) - 1)
|
33 | 34 |
|
34 | 35 | #define CPIO_ALIGNMENT 4
|
35 | 36 |
|
| 37 | +#define ALIGN_UP(n, a) (((n) + (a) - 1) & (~((a) - 1))) |
| 38 | + |
| 39 | +#define pr_err(fmt, ...) \ |
| 40 | + fprintf(stderr, "ERROR: %s:%d:%s(): " fmt, __FILE__, __LINE__, \ |
| 41 | + __func__, ##__VA_ARGS__) |
| 42 | + |
36 | 43 | struct cpio_header {
|
37 | 44 | char c_magic[6];
|
38 | 45 | char c_ino[8];
|
@@ -62,110 +69,135 @@ union buf_union {
|
62 | 69 |
|
63 | 70 | static union buf_union buf;
|
64 | 71 |
|
65 |
| -#define ALIGN_UP(n, a) (((n) + (a) - 1) & (~((a) - 1))) |
66 |
| - |
67 | 72 | int main(int argc, char **argv)
|
68 | 73 | {
|
69 |
| - FILE *f; |
70 | 74 | size_t s;
|
| 75 | + long pos = 0; |
| 76 | + FILE *f = NULL; |
| 77 | + char *fname = NULL; |
| 78 | + int ret = EXIT_FAILURE; |
| 79 | + unsigned long filesize; |
| 80 | + unsigned long filename_length; |
71 | 81 |
|
72 | 82 | if (argc != 2) {
|
73 | 83 | fprintf(stderr, "Usage: %s <file>\n", argv[0]);
|
74 |
| - exit(1); |
| 84 | + goto end; |
75 | 85 | }
|
76 | 86 |
|
77 |
| - f = fopen(argv[1], "r"); |
78 |
| - |
| 87 | + fname = argv[1]; |
| 88 | + f = fopen(fname, "r"); |
79 | 89 | if (f == NULL) {
|
80 |
| - fprintf(stderr, "Cannot open file '%s'\n", argv[1]); |
81 |
| - exit(1); |
| 90 | + pr_err("Cannot open file '%s'\n", fname); |
| 91 | + goto end; |
82 | 92 | }
|
83 | 93 |
|
84 |
| - s = fread(&buf.cpio, sizeof(buf.cpio), 1, f); |
85 |
| - if (s <= 0) { |
86 |
| - fprintf(stderr, "Read error from file '%s'\n", argv[1]); |
87 |
| - fclose(f); |
88 |
| - exit(1); |
| 94 | + if ((fread(&buf.cpio, sizeof(buf.cpio), 1, f) != 1) || |
| 95 | + ferror(f)) { |
| 96 | + pr_err("Read error from file '%s'\n", fname); |
| 97 | + goto end; |
89 | 98 | }
|
90 |
| - fseek(f, 0, SEEK_SET); |
91 |
| - |
92 |
| - /* check, if this is a cpio archive */ |
93 |
| - if (memcmp(buf.cpio.h.c_magic, CPIO_MAGIC, 6) == 0) { |
94 | 99 |
|
95 |
| - long pos = 0; |
| 100 | + if (fseek(f, 0, SEEK_SET)) { |
| 101 | + pr_err("fseek error on file '%s'\n", fname); |
| 102 | + goto end; |
| 103 | + } |
96 | 104 |
|
97 |
| - unsigned long filesize; |
98 |
| - unsigned long filename_length; |
| 105 | + /* check, if this is a cpio archive */ |
| 106 | + if (memcmp(buf.cpio.h.c_magic, CPIO_MAGIC, 6)) { |
| 107 | + goto cat_rest; |
| 108 | + } |
99 | 109 |
|
100 |
| - do { |
101 |
| - // zero string, spilling into next unused field, to use strtol |
102 |
| - buf.cpio.h.c_chksum[0] = 0; |
103 |
| - filename_length = strtoul(buf.cpio.h.c_namesize, NULL, 16); |
104 |
| - pos = ALIGN_UP(pos + sizeof(struct cpio_header) + filename_length, CPIO_ALIGNMENT); |
105 |
| - |
106 |
| - // zero string, spilling into next unused field, to use strtol |
107 |
| - buf.cpio.h.c_dev_maj[0] = 0; |
108 |
| - filesize = strtoul(buf.cpio.h.c_filesize, NULL, 16); |
109 |
| - pos = ALIGN_UP(pos + filesize, CPIO_ALIGNMENT); |
110 |
| - |
111 |
| - if (filename_length == (CPIO_ENDLEN + 1) |
112 |
| - && strncmp(buf.cpio.filename, CPIO_END, CPIO_ENDLEN) == 0) { |
113 |
| - fseek(f, pos, SEEK_SET); |
114 |
| - break; |
| 110 | + do { |
| 111 | + // zero string, spilling into next unused field, to use strtol |
| 112 | + buf.cpio.h.c_chksum[0] = 0; |
| 113 | + filename_length = strtoul(buf.cpio.h.c_namesize, NULL, 16); |
| 114 | + pos = ALIGN_UP(pos + sizeof(struct cpio_header) + filename_length, CPIO_ALIGNMENT); |
| 115 | + |
| 116 | + // zero string, spilling into next unused field, to use strtol |
| 117 | + buf.cpio.h.c_dev_maj[0] = 0; |
| 118 | + filesize = strtoul(buf.cpio.h.c_filesize, NULL, 16); |
| 119 | + pos = ALIGN_UP(pos + filesize, CPIO_ALIGNMENT); |
| 120 | + |
| 121 | + if (filename_length == (CPIO_ENDLEN + 1) |
| 122 | + && strncmp(buf.cpio.filename, CPIO_END, CPIO_ENDLEN) == 0) { |
| 123 | + if (fseek(f, pos, SEEK_SET)) { |
| 124 | + pr_err("fseek\n"); |
| 125 | + goto end; |
115 | 126 | }
|
| 127 | + break; |
| 128 | + } |
116 | 129 |
|
117 |
| - if (fseek(f, pos, SEEK_SET) != 0) { |
118 |
| - perror("fseek"); |
119 |
| - exit(1); |
120 |
| - } |
| 130 | + if (fseek(f, pos, SEEK_SET)) { |
| 131 | + pr_err("fseek\n"); |
| 132 | + goto end; |
| 133 | + } |
121 | 134 |
|
122 |
| - if (fread(&buf.cpio, sizeof(buf.cpio), 1, f) != 1) { |
123 |
| - perror("fread"); |
124 |
| - exit(1); |
125 |
| - } |
| 135 | + if ((fread(&buf.cpio, sizeof(buf.cpio), 1, f) != 1) || |
| 136 | + ferror(f)) { |
| 137 | + pr_err("fread\n"); |
| 138 | + goto end; |
| 139 | + } |
126 | 140 |
|
127 |
| - if (memcmp(buf.cpio.h.c_magic, CPIO_MAGIC, 6) != 0) { |
128 |
| - fprintf(stderr, "Corrupt CPIO archive!\n"); |
129 |
| - exit(1); |
130 |
| - } |
131 |
| - } while (!feof(f)); |
| 141 | + if (memcmp(buf.cpio.h.c_magic, CPIO_MAGIC, 6)) { |
| 142 | + pr_err("Corrupt CPIO archive!\n"); |
| 143 | + goto end; |
| 144 | + } |
| 145 | + } while (!feof(f)); |
132 | 146 |
|
133 |
| - if (feof(f)) { |
134 |
| - /* CPIO_END not found, just cat the whole file */ |
135 |
| - fseek(f, 0, SEEK_SET); |
136 |
| - } else { |
137 |
| - /* skip zeros */ |
138 |
| - do { |
139 |
| - size_t i; |
| 147 | + if (feof(f)) { |
| 148 | + /* CPIO_END not found, just cat the whole file */ |
| 149 | + if (fseek(f, 0, SEEK_SET)) { |
| 150 | + pr_err("fseek\n"); |
| 151 | + goto end; |
| 152 | + } |
| 153 | + } else { |
| 154 | + /* skip zeros */ |
| 155 | + do { |
| 156 | + size_t i; |
140 | 157 |
|
141 |
| - s = fread(buf.copy_buffer, 1, sizeof(buf.copy_buffer) - 1, f); |
142 |
| - if (s <= 0) |
143 |
| - break; |
| 158 | + s = fread(buf.copy_buffer, 1, sizeof(buf.copy_buffer) - 1, f); |
| 159 | + if (ferror(f)) { |
| 160 | + pr_err("fread\n"); |
| 161 | + goto end; |
| 162 | + } |
144 | 163 |
|
145 |
| - for (i = 0; (i < s) && (buf.copy_buffer[i] == 0); i++) ; |
| 164 | + for (i = 0; (i < s) && (buf.copy_buffer[i] == 0); i++) ; |
146 | 165 |
|
147 |
| - if (buf.copy_buffer[i] != 0) { |
148 |
| - pos += i; |
| 166 | + if (buf.copy_buffer[i]) { |
| 167 | + pos += i; |
149 | 168 |
|
150 |
| - fseek(f, pos, SEEK_SET); |
151 |
| - break; |
| 169 | + if (fseek(f, pos, SEEK_SET)) { |
| 170 | + pr_err("fseek\n"); |
| 171 | + goto end; |
152 | 172 | }
|
| 173 | + break; |
| 174 | + } |
153 | 175 |
|
154 |
| - pos += s; |
155 |
| - } while (!feof(f)); |
156 |
| - } |
| 176 | + pos += s; |
| 177 | + } while (!feof(f)); |
157 | 178 | }
|
| 179 | + |
| 180 | +cat_rest: |
158 | 181 | /* cat out the rest */
|
159 | 182 | while (!feof(f)) {
|
160 | 183 | s = fread(buf.copy_buffer, 1, sizeof(buf.copy_buffer), f);
|
161 |
| - if (s <= 0) |
162 |
| - break; |
| 184 | + if (ferror(f)) { |
| 185 | + pr_err("fread\n"); |
| 186 | + goto end; |
| 187 | + } |
163 | 188 |
|
164 |
| - s = fwrite(buf.copy_buffer, 1, s, stdout); |
165 |
| - if (s <= 0) |
166 |
| - break; |
| 189 | + if (fwrite(buf.copy_buffer, 1, s, stdout) != s) { |
| 190 | + pr_err("fwrite\n"); |
| 191 | + goto end; |
| 192 | + } |
| 193 | + } |
| 194 | + |
| 195 | + ret = EXIT_SUCCESS; |
| 196 | + |
| 197 | +end: |
| 198 | + if (f) { |
| 199 | + fclose(f); |
167 | 200 | }
|
168 |
| - fclose(f); |
169 | 201 |
|
170 |
| - return EXIT_SUCCESS; |
| 202 | + return ret; |
171 | 203 | }
|
0 commit comments