X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=helper%2Fappliance.c;h=c4d0b32117eedefb0604b2e3cdc723d67c61de61;hb=2e1e2d686ca8f819c202d2ed4e8a5c5758451f26;hp=4cbebf4d46cd6fe2f1b615e5915ac7d68fd4192f;hpb=0f89ba0654de234429042ffcc91c8a0de94ec98b;p=febootstrap.git diff --git a/helper/appliance.c b/helper/appliance.c index 4cbebf4..c4d0b32 100644 --- a/helper/appliance.c +++ b/helper/appliance.c @@ -77,6 +77,7 @@ create_appliance (const char *hostcpu, iterate_inputs (inputs, nr_inputs, writer); + writer->wr_file ("/lib/modules"); /* Kernel modules (3). */ add_kernel_modules (whitelist, modpath, writer); @@ -123,27 +124,33 @@ iterate_inputs (char **inputs, int nr_inputs, struct writer *writer) } } +static int +string_compare (const void *p1, const void *p2) +{ + return strcmp (* (char * const *) p1, * (char * const *) p2); +} + static void iterate_input_directory (const char *dirname, int dirfd, struct writer *writer) { - char path[PATH_MAX]; - strcpy (path, dirname); - size_t len = strlen (dirname); - path[len++] = '/'; - - char *inputs[] = { path }; - DIR *dir = fdopendir (dirfd); if (dir == NULL) error (EXIT_FAILURE, errno, "fdopendir: %s", dirname); + char **entries = NULL; + size_t nr_entries = 0, nr_alloc = 0; + struct dirent *d; while ((errno = 0, d = readdir (dir)) != NULL) { if (d->d_name[0] == '.') /* ignore ., .. and any hidden files. */ continue; - strcpy (&path[len], d->d_name); - iterate_inputs (inputs, 1, writer); + /* Ignore *~ files created by editors. */ + size_t len = strlen (d->d_name); + if (len > 0 && d->d_name[len-1] == '~') + continue; + + add_string (&entries, &nr_entries, &nr_alloc, d->d_name); } if (errno != 0) @@ -151,6 +158,27 @@ iterate_input_directory (const char *dirname, int dirfd, struct writer *writer) if (closedir (dir) == -1) error (EXIT_FAILURE, errno, "closedir: %s", dirname); + + add_string (&entries, &nr_entries, &nr_alloc, NULL); + + /* Visit directory entries in order. In febootstrap <= 2.8 we + * didn't impose any order, but that led to some difficult + * heisenbugs. + */ + sort (entries, string_compare); + + char path[PATH_MAX]; + strcpy (path, dirname); + size_t len = strlen (dirname); + path[len++] = '/'; + + char *inputs[] = { path }; + + size_t i; + for (i = 0; entries[i] != NULL; ++i) { + strcpy (&path[len], entries[i]); + iterate_inputs (inputs, 1, writer); + } } /* Copy kernel modules. @@ -169,6 +197,9 @@ static void add_kernel_modules (const char *whitelist_file, const char *modpath, struct writer *writer) { + if (verbose) + print_timestamped_message ("adding kernel modules"); + char **whitelist = NULL; if (whitelist_file != NULL) whitelist = load_file (whitelist_file); @@ -253,7 +284,9 @@ add_hostfiles (const char *hostfiles_file, struct writer *writer) if (strchr (hostfile, '*') || strchr (hostfile, '?')) { char *dirname = xstrdup (hostfile); char *patt = strrchr (dirname, '/'); - assert (patt); + if (!patt) + error (EXIT_FAILURE, 0, "%s: line %zu: invalid pattern\n(is this file a supermin appliance hostfiles file?)", + hostfiles_file, i+1); *patt++ = '\0'; char **files = read_dir (dirname);