summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cpio/mkbootfs.c90
1 files changed, 88 insertions, 2 deletions
diff --git a/cpio/mkbootfs.c b/cpio/mkbootfs.c
index f67233634..b7eb8c9f8 100644
--- a/cpio/mkbootfs.c
+++ b/cpio/mkbootfs.c
@@ -3,6 +3,7 @@
3#include <stdlib.h> 3#include <stdlib.h>
4#include <unistd.h> 4#include <unistd.h>
5#include <string.h> 5#include <string.h>
6#include <ctype.h>
6 7
7#include <sys/types.h> 8#include <sys/types.h>
8#include <sys/stat.h> 9#include <sys/stat.h>
@@ -34,12 +35,47 @@ void die(const char *why, ...)
34 exit(1); 35 exit(1);
35} 36}
36 37
38struct fs_config_entry {
39 char* name;
40 int uid, gid, mode;
41};
42
43static struct fs_config_entry* canned_config = NULL;
44
45/* Each line in the canned file should be a path plus three ints (uid,
46 * gid, mode). */
47#define CANNED_LINE_LENGTH (PATH_MAX+100)
48
37static int verbose = 0; 49static int verbose = 0;
38static int total_size = 0; 50static int total_size = 0;
39 51
40static void fix_stat(const char *path, struct stat *s) 52static void fix_stat(const char *path, struct stat *s)
41{ 53{
42 fs_config(path, S_ISDIR(s->st_mode), &s->st_uid, &s->st_gid, &s->st_mode); 54 if (canned_config) {
55 // Use the list of file uid/gid/modes loaded from the file
56 // given with -f.
57
58 struct fs_config_entry* empty_path_config = NULL;
59 struct fs_config_entry* p;
60 for (p = canned_config; p->name; ++p) {
61 if (!p->name[0]) {
62 empty_path_config = p;
63 }
64 if (strcmp(p->name, path) == 0) {
65 s->st_uid = p->uid;
66 s->st_gid = p->gid;
67 s->st_mode = p->mode | (s->st_mode & ~07777);
68 return;
69 }
70 }
71 s->st_uid = empty_path_config->uid;
72 s->st_gid = empty_path_config->gid;
73 s->st_mode = empty_path_config->mode | (s->st_mode & ~07777);
74 } else {
75 // Use the compiled-in fs_config() function.
76
77 fs_config(path, S_ISDIR(s->st_mode), &s->st_uid, &s->st_gid, &s->st_mode);
78 }
43} 79}
44 80
45static void _eject(struct stat *s, char *out, int olen, char *data, unsigned datasize) 81static void _eject(struct stat *s, char *out, int olen, char *data, unsigned datasize)
@@ -79,7 +115,7 @@ static void _eject(struct stat *s, char *out, int olen, char *data, unsigned dat
79 115
80 total_size += 6 + 8*13 + olen + 1; 116 total_size += 6 + 8*13 + olen + 1;
81 117
82 if(strlen(out) != olen) die("ACK!"); 118 if(strlen(out) != (unsigned int)olen) die("ACK!");
83 119
84 while(total_size & 3) { 120 while(total_size & 3) {
85 total_size++; 121 total_size++;
@@ -235,11 +271,61 @@ void archive(const char *start, const char *prefix)
235 _archive_dir(in, out, strlen(in), strlen(out)); 271 _archive_dir(in, out, strlen(in), strlen(out));
236} 272}
237 273
274static void read_canned_config(char* filename)
275{
276 int allocated = 8;
277 int used = 0;
278
279 canned_config =
280 (struct fs_config_entry*)malloc(allocated * sizeof(struct fs_config_entry));
281
282 char line[CANNED_LINE_LENGTH];
283 FILE* f = fopen(filename, "r");
284 if (f == NULL) die("failed to open canned file");
285
286 while (fgets(line, CANNED_LINE_LENGTH, f) != NULL) {
287 if (!line[0]) break;
288 if (used >= allocated) {
289 allocated *= 2;
290 canned_config = (struct fs_config_entry*)realloc(
291 canned_config, allocated * sizeof(struct fs_config_entry));
292 }
293
294 struct fs_config_entry* cc = canned_config + used;
295
296 if (isspace(line[0])) {
297 cc->name = strdup("");
298 cc->uid = atoi(strtok(line, " \n"));
299 } else {
300 cc->name = strdup(strtok(line, " \n"));
301 cc->uid = atoi(strtok(NULL, " \n"));
302 }
303 cc->gid = atoi(strtok(NULL, " \n"));
304 cc->mode = strtol(strtok(NULL, " \n"), NULL, 8);
305 ++used;
306 }
307 if (used >= allocated) {
308 ++allocated;
309 canned_config = (struct fs_config_entry*)realloc(
310 canned_config, allocated * sizeof(struct fs_config_entry));
311 }
312 canned_config[used].name = NULL;
313
314 fclose(f);
315}
316
317
238int main(int argc, char *argv[]) 318int main(int argc, char *argv[])
239{ 319{
240 argc--; 320 argc--;
241 argv++; 321 argv++;
242 322
323 if (argc > 1 && strcmp(argv[0], "-f") == 0) {
324 read_canned_config(argv[1]);
325 argc -= 2;
326 argv += 2;
327 }
328
243 if(argc == 0) die("no directories to process?!"); 329 if(argc == 0) die("no directories to process?!");
244 330
245 while(argc-- > 0){ 331 while(argc-- > 0){