Loading mkbootfs/mkbootfs.c +158 −21 Original line number Diff line number Diff line #include <error.h> #include <errno.h> #include <getopt.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> Loading @@ -7,11 +10,14 @@ #include <sys/types.h> #include <sys/stat.h> #include <sys/sysmacros.h> #include <dirent.h> #include <stdarg.h> #include <fcntl.h> #include <linux/kdev_t.h> #include <private/android_filesystem_config.h> #include <private/fs_config.h> Loading @@ -21,7 +27,6 @@ ** an explanation of this file format ** - dotfiles are ignored ** - directories named 'root' are ignored ** - device notes, pipes, etc are not supported (error) */ static void die(const char* why, ...) { Loading Loading @@ -86,6 +91,10 @@ static void fix_stat(const char *path, struct stat *s) fs_config(path, is_dir, target_out_path, &s->st_uid, &s->st_gid, &st_mode, &capabilities); s->st_mode = (typeof(s->st_mode)) st_mode; } if (S_ISREG(s->st_mode) || S_ISDIR(s->st_mode) || S_ISLNK(s->st_mode)) { s->st_rdev = 0; } } static void _eject(struct stat *s, char *out, int olen, char *data, unsigned datasize) Loading Loading @@ -115,8 +124,8 @@ static void _eject(struct stat *s, char *out, int olen, char *data, unsigned dat datasize, 0, // volmajor 0, // volminor 0, // devmajor 0, // devminor, major(s->st_rdev), minor(s->st_rdev), olen + 1, 0, out, Loading Loading @@ -267,6 +276,9 @@ static void _archive(char *in, char *out, int ilen, int olen) size = readlink(in, buf, 1024); if(size < 0) die("cannot read symlink '%s'", in); _eject(&s, out, olen, buf, size); } else if(S_ISBLK(s.st_mode) || S_ISCHR(s.st_mode) || S_ISFIFO(s.st_mode) || S_ISSOCK(s.st_mode)) { _eject(&s, out, olen, NULL, 0); } else { die("Unknown '%s' (mode %d)?\n", in, s.st_mode); } Loading Loading @@ -327,34 +339,159 @@ static void read_canned_config(char* filename) fclose(f); } static void devnodes_desc_error(const char* filename, unsigned long line_num, const char* msg) { error(EXIT_FAILURE, 0, "failed to read nodes desc file '%s' line %lu: %s", filename, line_num, msg); } int main(int argc, char *argv[]) static int append_devnodes_desc_dir(char* path, char* args) { if (argc == 1) { fprintf(stderr, "usage: %s [-d TARGET_OUTPUT_PATH] [-f CANNED_CONFIGURATION_PATH] DIRECTORIES...\n", argv[0]); exit(1); struct stat s; if (sscanf(args, "%o %d %d", &s.st_mode, &s.st_uid, &s.st_gid) != 3) return -1; s.st_mode |= S_IFDIR; _eject(&s, path, strlen(path), NULL, 0); return 0; } argc--; argv++; static int append_devnodes_desc_nod(char* path, char* args) { int minor, major; struct stat s; char dev; if (argc > 1 && strcmp(argv[0], "-d") == 0) { target_out_path = argv[1]; argc -= 2; argv += 2; if (sscanf(args, "%o %d %d %c %d %d", &s.st_mode, &s.st_uid, &s.st_gid, &dev, &major, &minor) != 6) return -1; s.st_rdev = MKDEV(major, minor); switch (dev) { case 'b': s.st_mode |= S_IFBLK; break; case 'c': s.st_mode |= S_IFCHR; break; default: return -1; } _eject(&s, path, strlen(path), NULL, 0); return 0; } if (argc > 1 && strcmp(argv[0], "-f") == 0) { read_canned_config(argv[1]); argc -= 2; argv += 2; static void append_devnodes_desc(const char* filename) { FILE* f = fopen(filename, "re"); if (!f) error(EXIT_FAILURE, errno, "failed to open nodes description file '%s'", filename); char *line, *args, *type, *path; unsigned long line_num = 0; size_t allocated_len; while (getline(&line, &allocated_len, f) != -1) { char* type; line_num++; if (*line == '#') continue; if (!(type = strtok(line, " \t"))) { devnodes_desc_error(filename, line_num, "a type is missing"); } if(argc == 0) die("no directories to process?!"); if (*type == '\n') continue; if (!(path = strtok(NULL, " \t"))) { devnodes_desc_error(filename, line_num, "a path is missing"); } if (!(args = strtok(NULL, "\n"))) { devnodes_desc_error(filename, line_num, "args are missing"); } if (!strcmp(type, "dir")) { if (append_devnodes_desc_dir(path, args)) { devnodes_desc_error(filename, line_num, "bad arguments for dir"); } } else if (!strcmp(type, "nod")) { if (append_devnodes_desc_nod(path, args)) { devnodes_desc_error(filename, line_num, "bad arguments for nod"); } } else { devnodes_desc_error(filename, line_num, "type unknown"); } } free(line); fclose(f); } static const struct option long_options[] = { { "dirname", required_argument, NULL, 'd' }, { "file", required_argument, NULL, 'f' }, { "help", no_argument, NULL, 'h' }, { "nodes", required_argument, NULL, 'n' }, { NULL, 0, NULL, 0 }, }; static void usage(void) { fprintf(stderr, "Usage: mkbootfs [-n FILE] [-d DIR|-F FILE] DIR...\n" "\n" "\t-d, --dirname=DIR: fs-config directory\n" "\t-f, --file=FILE: Canned configuration file\n" "\t-h, --help: Print this help\n" "\t-n, --nodes=FILE: Dev nodes description file\n" "\nDev nodes description:\n" "\t[dir|nod] [perms] [uid] [gid] [c|b] [minor] [major]\n" "\tExample:\n" "\t\t# My device nodes\n" "\t\tdir dev 0755 0 0\n" "\t\tnod dev/null 0600 0 0 c 1 5\n" ); } int main(int argc, char *argv[]) { int opt, unused; while ((opt = getopt_long(argc, argv, "hd:f:n:", long_options, &unused)) != -1) { switch (opt) { case 'd': target_out_path = argv[optind - 1]; break; case 'f': read_canned_config(argv[optind - 1]); break; case 'h': usage(); return 0; case 'n': append_devnodes_desc(argv[optind - 1]); break; default: usage(); die("Unknown option %s", argv[optind - 1]); } } int num_dirs = argc - optind; argv += optind; if (num_dirs <= 0) { usage(); die("no directories to process?!"); } while(argc-- > 0){ while(num_dirs-- > 0){ char *x = strchr(*argv, '='); if(x != 0) { *x++ = 0; Loading Loading
mkbootfs/mkbootfs.c +158 −21 Original line number Diff line number Diff line #include <error.h> #include <errno.h> #include <getopt.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> Loading @@ -7,11 +10,14 @@ #include <sys/types.h> #include <sys/stat.h> #include <sys/sysmacros.h> #include <dirent.h> #include <stdarg.h> #include <fcntl.h> #include <linux/kdev_t.h> #include <private/android_filesystem_config.h> #include <private/fs_config.h> Loading @@ -21,7 +27,6 @@ ** an explanation of this file format ** - dotfiles are ignored ** - directories named 'root' are ignored ** - device notes, pipes, etc are not supported (error) */ static void die(const char* why, ...) { Loading Loading @@ -86,6 +91,10 @@ static void fix_stat(const char *path, struct stat *s) fs_config(path, is_dir, target_out_path, &s->st_uid, &s->st_gid, &st_mode, &capabilities); s->st_mode = (typeof(s->st_mode)) st_mode; } if (S_ISREG(s->st_mode) || S_ISDIR(s->st_mode) || S_ISLNK(s->st_mode)) { s->st_rdev = 0; } } static void _eject(struct stat *s, char *out, int olen, char *data, unsigned datasize) Loading Loading @@ -115,8 +124,8 @@ static void _eject(struct stat *s, char *out, int olen, char *data, unsigned dat datasize, 0, // volmajor 0, // volminor 0, // devmajor 0, // devminor, major(s->st_rdev), minor(s->st_rdev), olen + 1, 0, out, Loading Loading @@ -267,6 +276,9 @@ static void _archive(char *in, char *out, int ilen, int olen) size = readlink(in, buf, 1024); if(size < 0) die("cannot read symlink '%s'", in); _eject(&s, out, olen, buf, size); } else if(S_ISBLK(s.st_mode) || S_ISCHR(s.st_mode) || S_ISFIFO(s.st_mode) || S_ISSOCK(s.st_mode)) { _eject(&s, out, olen, NULL, 0); } else { die("Unknown '%s' (mode %d)?\n", in, s.st_mode); } Loading Loading @@ -327,34 +339,159 @@ static void read_canned_config(char* filename) fclose(f); } static void devnodes_desc_error(const char* filename, unsigned long line_num, const char* msg) { error(EXIT_FAILURE, 0, "failed to read nodes desc file '%s' line %lu: %s", filename, line_num, msg); } int main(int argc, char *argv[]) static int append_devnodes_desc_dir(char* path, char* args) { if (argc == 1) { fprintf(stderr, "usage: %s [-d TARGET_OUTPUT_PATH] [-f CANNED_CONFIGURATION_PATH] DIRECTORIES...\n", argv[0]); exit(1); struct stat s; if (sscanf(args, "%o %d %d", &s.st_mode, &s.st_uid, &s.st_gid) != 3) return -1; s.st_mode |= S_IFDIR; _eject(&s, path, strlen(path), NULL, 0); return 0; } argc--; argv++; static int append_devnodes_desc_nod(char* path, char* args) { int minor, major; struct stat s; char dev; if (argc > 1 && strcmp(argv[0], "-d") == 0) { target_out_path = argv[1]; argc -= 2; argv += 2; if (sscanf(args, "%o %d %d %c %d %d", &s.st_mode, &s.st_uid, &s.st_gid, &dev, &major, &minor) != 6) return -1; s.st_rdev = MKDEV(major, minor); switch (dev) { case 'b': s.st_mode |= S_IFBLK; break; case 'c': s.st_mode |= S_IFCHR; break; default: return -1; } _eject(&s, path, strlen(path), NULL, 0); return 0; } if (argc > 1 && strcmp(argv[0], "-f") == 0) { read_canned_config(argv[1]); argc -= 2; argv += 2; static void append_devnodes_desc(const char* filename) { FILE* f = fopen(filename, "re"); if (!f) error(EXIT_FAILURE, errno, "failed to open nodes description file '%s'", filename); char *line, *args, *type, *path; unsigned long line_num = 0; size_t allocated_len; while (getline(&line, &allocated_len, f) != -1) { char* type; line_num++; if (*line == '#') continue; if (!(type = strtok(line, " \t"))) { devnodes_desc_error(filename, line_num, "a type is missing"); } if(argc == 0) die("no directories to process?!"); if (*type == '\n') continue; if (!(path = strtok(NULL, " \t"))) { devnodes_desc_error(filename, line_num, "a path is missing"); } if (!(args = strtok(NULL, "\n"))) { devnodes_desc_error(filename, line_num, "args are missing"); } if (!strcmp(type, "dir")) { if (append_devnodes_desc_dir(path, args)) { devnodes_desc_error(filename, line_num, "bad arguments for dir"); } } else if (!strcmp(type, "nod")) { if (append_devnodes_desc_nod(path, args)) { devnodes_desc_error(filename, line_num, "bad arguments for nod"); } } else { devnodes_desc_error(filename, line_num, "type unknown"); } } free(line); fclose(f); } static const struct option long_options[] = { { "dirname", required_argument, NULL, 'd' }, { "file", required_argument, NULL, 'f' }, { "help", no_argument, NULL, 'h' }, { "nodes", required_argument, NULL, 'n' }, { NULL, 0, NULL, 0 }, }; static void usage(void) { fprintf(stderr, "Usage: mkbootfs [-n FILE] [-d DIR|-F FILE] DIR...\n" "\n" "\t-d, --dirname=DIR: fs-config directory\n" "\t-f, --file=FILE: Canned configuration file\n" "\t-h, --help: Print this help\n" "\t-n, --nodes=FILE: Dev nodes description file\n" "\nDev nodes description:\n" "\t[dir|nod] [perms] [uid] [gid] [c|b] [minor] [major]\n" "\tExample:\n" "\t\t# My device nodes\n" "\t\tdir dev 0755 0 0\n" "\t\tnod dev/null 0600 0 0 c 1 5\n" ); } int main(int argc, char *argv[]) { int opt, unused; while ((opt = getopt_long(argc, argv, "hd:f:n:", long_options, &unused)) != -1) { switch (opt) { case 'd': target_out_path = argv[optind - 1]; break; case 'f': read_canned_config(argv[optind - 1]); break; case 'h': usage(); return 0; case 'n': append_devnodes_desc(argv[optind - 1]); break; default: usage(); die("Unknown option %s", argv[optind - 1]); } } int num_dirs = argc - optind; argv += optind; if (num_dirs <= 0) { usage(); die("no directories to process?!"); } while(argc-- > 0){ while(num_dirs-- > 0){ char *x = strchr(*argv, '='); if(x != 0) { *x++ = 0; Loading