3 # Patch managed by http://www.holgerschurig.de/patcher.html
6 --- genext2fs-1.3.orig/genext2fs.c~autosize.patch
7 +++ genext2fs-1.3.orig/genext2fs.c
9 // ext2 filesystem generator for embedded systems
10 // Copyright (C) 2000 Xavier Bestel <xavier.bestel@free.fr>
12 +// 'du' portions taken from coreutils/du.c in busybox:
13 +// Copyright (C) 1999,2000 by Lineo, inc. and John Beppu
14 +// Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org>
15 +// Copyright (C) 2002 Edward Betts <edward@debian.org>
17 // This program is free software; you can redistribute it and/or
18 // modify it under the terms of the GNU General Public License
19 // as published by the Free Software Foundation; version
24 +#include <sys/types.h>
27 +#define HASH_SIZE 311 /* Should be prime */
28 +#define hash_inode(i) ((i) % HASH_SIZE)
30 +typedef struct ino_dev_hash_bucket_struct {
31 + struct ino_dev_hash_bucket_struct *next;
35 +} ino_dev_hashtable_bucket_t;
37 +static ino_dev_hashtable_bucket_t *ino_dev_hashtable[HASH_SIZE];
40 + unsigned long nblocks;
41 + unsigned long ninodes;
44 +int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name)
46 + ino_dev_hashtable_bucket_t *bucket;
48 + bucket = ino_dev_hashtable[hash_inode(statbuf->st_ino)];
49 + while (bucket != NULL) {
50 + if ((bucket->ino == statbuf->st_ino) &&
51 + (bucket->dev == statbuf->st_dev))
53 + if (name) *name = bucket->name;
56 + bucket = bucket->next;
61 +/* Add statbuf to statbuf hash table */
62 +void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name)
66 + ino_dev_hashtable_bucket_t *bucket;
68 + i = hash_inode(statbuf->st_ino);
69 + s = name ? strlen(name) : 0;
70 + bucket = malloc(sizeof(ino_dev_hashtable_bucket_t) + s);
71 + bucket->ino = statbuf->st_ino;
72 + bucket->dev = statbuf->st_dev;
74 + strcpy(bucket->name, name);
76 + bucket->name[0] = '\0';
77 + bucket->next = ino_dev_hashtable[i];
78 + ino_dev_hashtable[i] = bucket;
81 +/* Clear statbuf hash table */
82 +void reset_ino_dev_hashtable(void)
85 + ino_dev_hashtable_bucket_t *bucket;
87 + for (i = 0; i < HASH_SIZE; i++) {
88 + while (ino_dev_hashtable[i] != NULL) {
89 + bucket = ino_dev_hashtable[i]->next;
90 + free(ino_dev_hashtable[i]);
91 + ino_dev_hashtable[i] = bucket;
96 +static int count_ino_in_hashtable(void)
101 + for (i = 0; i < HASH_SIZE; i++) {
102 + ino_dev_hashtable_bucket_t *bucket = ino_dev_hashtable[i];
103 + while (bucket != NULL) {
105 + bucket = bucket->next;
114 @@ -1178,6 +1267,38 @@
118 +void stats_from_dir(struct stats *stats)
121 + struct dirent *dent;
123 + if(!(dh = opendir(".")))
124 + perror_msg_and_die(".");
125 + while((dent = readdir(dh)))
127 + if((!strcmp(dent->d_name, ".")) || (!strcmp(dent->d_name, "..")))
129 + lstat(dent->d_name, &st);
130 + if (S_ISLNK(st.st_mode)) {
132 + } else if (S_ISDIR(st.st_mode)) {
133 + if(chdir(dent->d_name) < 0)
134 + perror_msg_and_die(dent->d_name);
136 + stats_from_dir(stats);
139 + if (!is_in_ino_dev_hashtable(&st, NULL)) {
140 + add_to_ino_dev_hashtable(&st, NULL);
141 + stats->nblocks += (st.st_blocks >> 1);
147 + reset_ino_dev_hashtable();
150 // adds a tree of entries to the filesystem from current dir
151 void add2fs_from_dir(filesystem *fs, uint32 this_nod)
153 @@ -1436,7 +1557,6 @@
154 free_blocks_per_group = nbblocks_per_group - overhead_per_group;
156 nbblocks = nbblocks_per_group * nbgroups + 1;
159 if(!(fs = (filesystem*)calloc(nbblocks, BLOCKSIZE)))
160 error_msg_and_die("not enough memory for filesystem");
161 @@ -1891,6 +2011,7 @@
162 Regular files must exist in the target root directory. If a char,
163 block, fifo, or directory does not exist, it will be created.
166 static int interpret_table_entry(filesystem *fs, char *line)
168 char type, *name = NULL, *tmp, *dir, *bname;
169 @@ -2026,6 +2147,52 @@
173 +static int stats_from_table_entry(char *line, struct stats *stats)
175 + char type, *name = NULL, *tmp, *dir, *bname;
176 + unsigned long mode = 0755, uid = 0, gid = 0, major = 0, minor = 0;
177 + unsigned long start = 0, increment = 1, count = 0;
180 + if (sscanf (line, "%" SCANF_PREFIX "s %c %lo %lu %lu %lu %lu %lu %lu %lu",
181 + SCANF_STRING(name), &type, &mode, &uid, &gid, &major, &minor,
182 + &start, &increment, &count) < 0)
187 + if (!strcmp(name, "/")) {
188 + error_msg_and_die("Device table entries require absolute paths");
191 + tmp = xstrdup(name);
192 + bname = xstrdup(basename(tmp));
204 + for (i = start; i < count; i++) {
205 + asprintf(&dname, "%s%lu", bname, i);
219 static int parse_device_table(filesystem *root, FILE * file)
222 @@ -2070,6 +2237,45 @@
226 +static int stats_from_dev_table(FILE *file, struct stats *stats)
232 + /* Looks ok so far. The general plan now is to read in one
233 + * line at a time, check for leading comment delimiters ('#'),
234 + * then try and parse the line as a device table. If we fail
235 + * to parse things, try and help the poor fool to fix their
236 + * device table with a useful error msg... */
238 + while (getline(&line, &length, file) != -1) {
239 + /* First trim off any whitespace */
240 + int len = strlen(line);
242 + /* trim trailing whitespace */
243 + while (len > 0 && isspace(line[len - 1]))
244 + line[--len] = '\0';
245 + /* trim leading whitespace */
246 + memmove(line, &line[strspn(line, " \n\r\t\v")], len);
248 + /* How long are we after trimming? */
249 + len = strlen(line);
251 + /* If this is NOT a comment line, try to interpret it */
252 + if (len && *line != '#') {
253 + if (stats_from_table_entry(line, stats))
267 c-file-style: "linux"
268 @@ -2112,6 +2318,8 @@
272 + int tmp_nbblocks = -1;
273 + int tmp_nbinodes = -1;
276 char * dopt[MAX_DOPT];
277 @@ -2128,6 +2336,7 @@
280 FILE *devtable = NULL;
281 + struct stats stats;
284 while((c = getopt(argc, argv, "x:d:b:i:r:g:e:zvhD:f:qUP")) != EOF)
285 @@ -2184,6 +2393,7 @@
290 if(optind < (argc - 1))
291 error_msg_and_die("too many arguments");
292 if(optind == (argc - 1))
293 @@ -2201,6 +2411,46 @@
299 + for(i = 0; i < didx; i++)
303 + stat(dopt[i], &st);
304 + switch(st.st_mode & S_IFMT)
307 + if(!(pdir = getcwd(0, GETCWD_SIZE)))
308 + perror_msg_and_die(dopt[i]);
309 + if(chdir(dopt[i]) < 0)
310 + perror_msg_and_die(dopt[i]);
311 + stats_from_dir(&stats);
312 + if(chdir(pdir) < 0)
313 + perror_msg_and_die(pdir);
317 + error_msg_and_die("%s is neither a file nor a directory", dopt[i]);
322 + stats_from_dev_table(devtable, &stats);
324 + tmp_nbinodes = stats.ninodes + EXT2_FIRST_INO + 1;
325 + tmp_nbblocks = stats.nblocks;
327 + if(tmp_nbblocks > nbblocks)
329 + printf("Number of blocks too low, increasing to %d\n",tmp_nbblocks);
330 + nbblocks = tmp_nbblocks;
332 + if(tmp_nbinodes > nbinodes)
334 + printf("Number of inodes too low, increasing to %d\n",tmp_nbinodes);
335 + nbinodes = tmp_nbinodes;
338 error_msg_and_die("filesystem size unspecified");