]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/genext2fs/genext2fs-1.3/autosize.patch
OE tree imported from monotone branch org.openembedded.oz354fam083 at revision 8b12e3...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / genext2fs / genext2fs-1.3 / autosize.patch
1
2 #
3 # Patch managed by http://www.holgerschurig.de/patcher.html
4 #
5
6 --- genext2fs-1.3.orig/genext2fs.c~autosize.patch
7 +++ genext2fs-1.3.orig/genext2fs.c
8 @@ -4,6 +4,11 @@
9  // ext2 filesystem generator for embedded systems
10  // Copyright (C) 2000 Xavier Bestel <xavier.bestel@free.fr>
11  //
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>
16 +//
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
20 @@ -79,9 +84,93 @@
21  #include <ctype.h>
22  #include <errno.h>
23  #include <fcntl.h>
24 +#include <sys/types.h>
25 +#include <getopt.h>
26 +
27 +#define HASH_SIZE      311             /* Should be prime */
28 +#define hash_inode(i)  ((i) % HASH_SIZE)
29 +
30 +typedef struct ino_dev_hash_bucket_struct {
31 +       struct ino_dev_hash_bucket_struct *next;
32 +       ino_t ino;
33 +       dev_t dev;
34 +       char name[1];
35 +} ino_dev_hashtable_bucket_t;
36 +
37 +static ino_dev_hashtable_bucket_t *ino_dev_hashtable[HASH_SIZE];
38 +
39 +struct stats {
40 +       unsigned long nblocks;
41 +       unsigned long ninodes;
42 +};
43 +
44 +int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name)
45 +{
46 +       ino_dev_hashtable_bucket_t *bucket;
47 +
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))
52 +               {
53 +                       if (name) *name = bucket->name;
54 +                       return 1;
55 +               }
56 +               bucket = bucket->next;
57 +       }
58 +       return 0;
59 +}
60 +
61 +/* Add statbuf to statbuf hash table */
62 +void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name)
63 +{
64 +       int i;
65 +       size_t s;
66 +       ino_dev_hashtable_bucket_t *bucket;
67 +    
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;
73 +       if (name)
74 +               strcpy(bucket->name, name);
75 +       else
76 +               bucket->name[0] = '\0';
77 +       bucket->next = ino_dev_hashtable[i];
78 +       ino_dev_hashtable[i] = bucket;
79 +}
80 +
81 +/* Clear statbuf hash table */
82 +void reset_ino_dev_hashtable(void)
83 +{
84 +       int i;
85 +       ino_dev_hashtable_bucket_t *bucket;
86 +
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;
92 +               }
93 +       }
94 +}
95  
96 +static int count_ino_in_hashtable(void)
97 +{
98 +       long count = 0;
99 +       int i;
100  
101 +       for (i = 0; i < HASH_SIZE; i++) {
102 +               ino_dev_hashtable_bucket_t *bucket = ino_dev_hashtable[i];
103 +               while (bucket != NULL) {
104 +                       count++;
105 +                       bucket = bucket->next;
106 +               }
107 +       }
108  
109 +       return count;
110 +}
111  
112  // block size
113  
114 @@ -1178,6 +1267,38 @@
115         return n;
116  }
117  
118 +void stats_from_dir(struct stats *stats)
119 +{
120 +       DIR *dh;
121 +       struct dirent *dent;
122 +       struct stat st;
123 +       if(!(dh = opendir(".")))
124 +               perror_msg_and_die(".");
125 +       while((dent = readdir(dh)))
126 +       {
127 +               if((!strcmp(dent->d_name, ".")) || (!strcmp(dent->d_name, "..")))
128 +                       continue;
129 +               lstat(dent->d_name, &st);
130 +               if (S_ISLNK(st.st_mode)) {
131 +                       stats->ninodes++;
132 +               } else if (S_ISDIR(st.st_mode)) {
133 +                       if(chdir(dent->d_name) < 0)
134 +                               perror_msg_and_die(dent->d_name);
135 +                       stats->ninodes++;
136 +                       stats_from_dir(stats);
137 +                       chdir("..");
138 +               } else {
139 +                       if (!is_in_ino_dev_hashtable(&st, NULL)) {
140 +                               add_to_ino_dev_hashtable(&st, NULL);
141 +                               stats->nblocks += (st.st_blocks >> 1);
142 +                               stats->ninodes++;
143 +                       }
144 +               }
145 +       }
146 +       closedir(dh);
147 +       reset_ino_dev_hashtable();
148 +}
149 +
150  // adds a tree of entries to the filesystem from current dir
151  void add2fs_from_dir(filesystem *fs, uint32 this_nod)
152  {
153 @@ -1436,7 +1557,6 @@
154                 free_blocks_per_group = nbblocks_per_group - overhead_per_group;
155         }
156         nbblocks = nbblocks_per_group * nbgroups + 1;
157 -       
158  
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.
164  */
165 +
166  static int interpret_table_entry(filesystem *fs, char *line)
167  {
168         char type, *name = NULL, *tmp, *dir, *bname;
169 @@ -2026,6 +2147,52 @@
170         return 0;
171  }
172  
173 +static int stats_from_table_entry(char *line, struct stats *stats)
174 +{
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;
178 +       inode *entry;
179 +
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) 
183 +       {
184 +               return 1;
185 +       }
186 +
187 +       if (!strcmp(name, "/")) {
188 +               error_msg_and_die("Device table entries require absolute paths");
189 +       }
190 +
191 +       tmp = xstrdup(name);
192 +       bname = xstrdup(basename(tmp));
193 +       free(tmp);
194 +       switch (type) {
195 +               case 'd':
196 +                       stats->ninodes++;
197 +                       break;
198 +               case 'c':
199 +               case 'b':
200 +                       if (count > 0) {
201 +                               dev_t rdev;
202 +                               char *dname;
203 +                               unsigned long i;
204 +                               for (i = start; i < count; i++) {
205 +                                       asprintf(&dname, "%s%lu", bname, i);
206 +                                       stats->ninodes++;
207 +                                       free(dname);
208 +                               }
209 +                       } else {
210 +                               stats->ninodes++;
211 +                       }
212 +                       break;
213 +       }
214 +       free(bname);
215 +       free(name);
216 +       return 0;
217 +}
218 +
219  static int parse_device_table(filesystem *root, FILE * file)
220  {
221         char *line;
222 @@ -2070,6 +2237,45 @@
223         return status;
224  }
225  
226 +static int stats_from_dev_table(FILE *file, struct stats *stats)
227 +{
228 +       char *line;
229 +       int status = 0;
230 +       size_t length = 0;
231 +
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... */
237 +       line = NULL;
238 +       while (getline(&line, &length, file) != -1) {
239 +               /* First trim off any whitespace */
240 +               int len = strlen(line);
241 +
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);
247 +
248 +               /* How long are we after trimming? */
249 +               len = strlen(line);
250 +
251 +               /* If this is NOT a comment line, try to interpret it */
252 +               if (len && *line != '#') {
253 +                       if (stats_from_table_entry(line, stats))
254 +                               status = 1;
255 +               }
256 +
257 +               free(line);
258 +               line = NULL;
259 +       }
260 +       fclose(file);
261 +
262 +       return status;
263 +}
264 +
265  /*
266  Local Variables:
267  c-file-style: "linux"
268 @@ -2112,6 +2318,8 @@
269         int nbblocks = -1;
270         int nbinodes = -1;
271         int nbresrvd = -1;
272 +       int tmp_nbblocks = -1;
273 +       int tmp_nbinodes = -1;
274         char * fsout = "-";
275         char * fsin = 0;
276         char * dopt[MAX_DOPT];
277 @@ -2128,6 +2336,7 @@
278         int c;
279         struct stat sb;
280         FILE *devtable = NULL;
281 +       struct stats stats;
282  
283         app_name = argv[0];
284         while((c = getopt(argc, argv, "x:d:b:i:r:g:e:zvhD:f:qUP")) != EOF)
285 @@ -2184,6 +2393,7 @@
286                         default:
287                                 exit(1);
288                 }
289 +
290         if(optind < (argc - 1))
291                 error_msg_and_die("too many arguments");
292         if(optind == (argc - 1))
293 @@ -2201,6 +2411,46 @@
294         }
295         else
296         {
297 +               stats.ninodes = 0;
298 +               stats.nblocks = 0;
299 +               for(i = 0; i < didx; i++)
300 +               {
301 +                       struct stat st;
302 +                       char *pdir;
303 +                       stat(dopt[i], &st);
304 +                       switch(st.st_mode & S_IFMT)
305 +                       {
306 +                               case S_IFDIR:
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);
314 +                                       free(pdir);
315 +                                       break;
316 +                               default:
317 +                                       error_msg_and_die("%s is neither a file nor a directory", dopt[i]);
318 +                       }
319 +               }
320 +       
321 +               if(devtable)
322 +                       stats_from_dev_table(devtable, &stats);
323 +       
324 +               tmp_nbinodes = stats.ninodes + EXT2_FIRST_INO + 1;
325 +               tmp_nbblocks = stats.nblocks;
326 +       
327 +               if(tmp_nbblocks > nbblocks)
328 +               {
329 +                       printf("Number of blocks too low, increasing to %d\n",tmp_nbblocks);
330 +                       nbblocks = tmp_nbblocks;
331 +               }
332 +               if(tmp_nbinodes > nbinodes)
333 +               {
334 +                       printf("Number of inodes too low, increasing to %d\n",tmp_nbinodes);
335 +                       nbinodes = tmp_nbinodes;
336 +               }
337                 if(nbblocks == -1)
338                         error_msg_and_die("filesystem size unspecified");
339                 if(nbinodes == -1)