char *cfg_dir;
};
+struct conf_file_stat {
+ char *name;
+ struct stat stat;
+ struct list_item list;
+};
static const char *const syslinux_conf_files[] = {
"/boot/syslinux/syslinux.cfg",
"f2",
"f3",
"f4",
- "f5"
+ "f5",
"f6",
"f7",
"f8",
static void syslinux_finalize(struct conf_context *conf)
{
struct syslinux_options *state = conf->parser_info;
- struct syslinux_boot_option *syslinux_opt;
+ struct syslinux_boot_option *syslinux_opt, *tmp;
struct discover_context *dc = conf->dc;
struct discover_boot_option *d_opt;
bool implicit_image = true;
discover_context_add_boot_option(dc, d_opt);
continue;
+
fail:
talloc_free(d_opt);
}
+
+ list_for_each_entry_safe(&state->processed_options, syslinux_opt, tmp, list)
+ talloc_free(syslinux_opt);
+ list_init(&state->processed_options);
}
static int syslinux_parse(struct discover_context *dc)
{
+ struct conf_file_stat *confcmp, *confdat;
+ struct list processed_conf_files;
struct syslinux_options *state;
const char * const *filename;
struct conf_context *conf;
+ struct stat statbuf;
char *cfg_dir;
int len, rc;
char *buf;
conf->parser_info = state = talloc_zero(conf, struct syslinux_options);
list_init(&state->processed_options);
+ list_init(&processed_conf_files);
+
/*
* set the global defaults
* by spec 'default' defaults to 'linux' and
conf_set_global_option(conf, "append", "");
for (filename = syslinux_conf_files; *filename; filename++) {
+ /*
+ * guard against duplicate entries in case-insensitive
+ * filesystems, mainly vfat boot partitions
+ */
+ rc = parser_stat_path(dc, dc->device, *filename, &statbuf);
+ if (rc)
+ continue;
+
+ rc = 0;
+
+ list_for_each_entry(&processed_conf_files, confcmp, list) {
+ if (confcmp->stat.st_ino == statbuf.st_ino) {
+ pb_log("conf file %s is a path duplicate of %s..skipping\n",
+ *filename, confcmp->name);
+ rc = 1;
+ break;
+ }
+ }
+
+ if (rc)
+ continue;
+
rc = parser_request_file(dc, dc->device, *filename, &buf, &len);
if (rc)
continue;
+ confdat = talloc_zero(conf, struct conf_file_stat);
+ confdat->stat = statbuf;
+ confdat->name = talloc_strdup(confdat, *filename);
+ list_add(&processed_conf_files, &confdat->list);
+
/*
* save location of root config file for possible
* INCLUDE directives later