0001-mkfs.jffs2-add-graft-option.patch (4990B)
1 From 65cefb4cffadbd3b7adb9ff4a80db2914b0da4fd Mon Sep 17 00:00:00 2001 2 From: Daniel Barlow <dan@telent.net> 3 Date: Fri, 31 Mar 2023 23:33:04 +0100 4 Subject: [PATCH] mkfs.jffs2: add --graft option 5 6 Allows creation of image from more than one source directory tree, 7 using --graft src:dest to graft new subtrees into the output. For 8 example 9 10 mkfs.jffs2 -r ./rootfs --graft $HOME/Pictures:/pictures 11 12 to add your photo collection into the filesystem at /pictures 13 without first copying it to rootfs 14 --- 15 jffsX-utils/mkfs.jffs2.c | 76 +++++++++++++++++++++++++++++++++++++++- 16 1 file changed, 75 insertions(+), 1 deletion(-) 17 18 diff --git a/jffsX-utils/mkfs.jffs2.c b/jffsX-utils/mkfs.jffs2.c 19 index bd67634..a33f4b4 100644 20 --- a/jffsX-utils/mkfs.jffs2.c 21 +++ b/jffsX-utils/mkfs.jffs2.c 22 @@ -112,6 +112,14 @@ static int squash_perms = 0; 23 static int fake_times = 0; 24 int target_endian = __BYTE_ORDER; 25 26 +struct graft { 27 + struct graft *next; 28 + const char * source; 29 + const char * dest; 30 + struct stat st; 31 +} * grafts = 0; 32 + 33 + 34 static uint32_t find_hardlink(struct filesystem_entry *e) 35 { 36 struct filesystem_entry *f; 37 @@ -597,6 +605,16 @@ static void cleanup(struct filesystem_entry *dir) 38 } 39 } 40 41 +static void free_grafts(struct graft *graft) 42 +{ 43 + if(graft) { 44 + if(graft->next) free_grafts(graft->next); 45 + free((char *)graft->source); 46 + free((char *)graft); 47 + } 48 +} 49 + 50 + 51 /* Here is where we do the actual creation of the file system */ 52 #include "mtd/jffs2-user.h" 53 54 @@ -1359,6 +1377,7 @@ static void create_target_filesystem(struct filesystem_entry *root) 55 static struct option long_options[] = { 56 {"pad", 2, NULL, 'p'}, 57 {"root", 1, NULL, 'r'}, 58 + {"graft", 1, NULL, 'G'}, 59 {"pagesize", 1, NULL, 's'}, 60 {"eraseblock", 1, NULL, 'e'}, 61 {"output", 1, NULL, 'o'}, 62 @@ -1396,6 +1415,9 @@ static const char helptext[] = 63 " not specified, the output is padded to the end of\n" 64 " the final erase block\n" 65 " -r, -d, --root=DIR Build file system from directory DIR (default: cwd)\n" 66 +" -G, --graft=SOURCE:DEST Add contents of SOURCE directory at DEST in image.\n" 67 +" May be given more than once. DEST must exist in\n" 68 +" root DIR or a previous graft. \n" 69 " -s, --pagesize=SIZE Use page size (max data node size) SIZE.\n" 70 " Set according to target system's memory management\n" 71 " page size (default: 4KiB)\n" 72 @@ -1430,6 +1452,25 @@ static const char helptext[] = 73 " -V, --version Display version information\n" 74 " -i, --incremental=FILE Parse FILE and generate appendage output for it\n\n"; 75 76 +static int add_graft(const char * source, const char *dest) 77 +{ 78 + struct graft * graft; 79 + struct stat st; 80 + 81 + if (stat(source, &st)) { 82 + errmsg_die("bad graft source '%s'", source); 83 + } 84 + 85 + if(!grafts) grafts = calloc(sizeof (struct graft), 1); 86 + for(graft = grafts; graft->next; graft = graft->next) 87 + ; 88 + graft->source = source; 89 + graft->dest = dest; 90 + memcpy((void *) &(graft->st), (void *) &st, sizeof st); 91 + graft->next = calloc(sizeof (struct graft), 1); 92 + return 0; 93 +} 94 + 95 static int load_next_block(void) { 96 97 int ret; 98 @@ -1579,7 +1620,7 @@ int main(int argc, char **argv) 99 jffs2_compressors_init(); 100 101 while ((opt = getopt_long(argc, argv, 102 - "D:d:r:s:o:qUPfh?vVe:lbp::nc:m:x:X:Lty:i:", long_options, &c)) >= 0) 103 + "D:d:r:G:s:o:qUPfh?vVe:lbp::nc:m:x:X:Lty:i:", long_options, &c)) >= 0) 104 { 105 switch (opt) { 106 case 'D': 107 @@ -1598,6 +1639,18 @@ int main(int argc, char **argv) 108 rootdir = xstrdup(optarg); 109 break; 110 111 + case 'G': 112 + if(strchr(optarg, ':')) { 113 + char * src_name, * dest_name; 114 + src_name = xstrdup(optarg); 115 + dest_name = strchr(src_name, ':'); 116 + *dest_name = '\0'; 117 + dest_name++; 118 + add_graft(src_name, dest_name); 119 + } else 120 + errmsg_die("bad graft specification '%s', expecting source:dest", 121 + optarg); 122 + break; 123 case 's': 124 page_size = strtol(optarg, NULL, 0); 125 warn_page_size = 0; /* set by user, so don't need to warn */ 126 @@ -1784,13 +1837,34 @@ int main(int argc, char **argv) 127 parse_image(); 128 129 root = recursive_add_host_directory(NULL, "/", cwd); 130 + for(struct graft *g = grafts; g && g->source; g=g->next) { 131 + char *tmp = xstrdup(g->dest); 132 + struct filesystem_entry * entry = 133 + find_filesystem_entry(root, dirname(tmp), S_IFDIR); 134 + free(tmp); 135 + if(!entry) 136 + errmsg_die("missing directory %s for graft point %s", 137 + g->dest, g->source); 138 139 + if (S_ISDIR(g->st.st_mode)) { 140 + recursive_add_host_directory(entry, g->dest, g->source); 141 + } else { 142 + add_host_filesystem_entry(g->dest, 143 + g->source, 144 + g->st.st_uid, 145 + g->st.st_gid, 146 + g->st.st_mode, 147 + g->st.st_rdev, 148 + entry); 149 + } 150 + } 151 if (devtable) 152 parse_device_table(root, devtable); 153 154 create_target_filesystem(root); 155 156 cleanup(root); 157 + free_grafts(grafts); 158 159 if (rootdir != default_rootdir) 160 free(rootdir); 161 -- 162 2.38.1 163