diff --git a/zdev/src/chzdev.c b/zdev/src/chzdev.c index 1605a939..17ae8cd1 100644 --- a/zdev/src/chzdev.c +++ b/zdev/src/chzdev.c @@ -195,7 +195,7 @@ static struct opts_conflict conflict_list[] = { OPTS_CONFLICT(OPT_ONLINE, OPT_OFFLINE), OPTS_CONFLICT(OPT_SITE, - OPT_TYPE, OPT_EXPORT, OPT_IMPORT, 0), + OPT_TYPE, 0), OPTS_CONFLICT(OPT_QUIET, OPT_VERBOSE), OPTS_CONFLICT(OPT_AUTO_CONF, diff --git a/zdev/src/export.c b/zdev/src/export.c index a8aaccc1..b6f2bedb 100644 --- a/zdev/src/export.c +++ b/zdev/src/export.c @@ -21,6 +21,8 @@ #include "setting.h" #include "subtype.h" +static int import_site_id = SITE_FALLBACK; + struct export_header { export_t type; config_t config; @@ -28,13 +30,28 @@ struct export_header { char *id; }; +static bool header_str_to_config(const char *config_str, config_t *config) +{ + int site; + + if (strstr(config_str, "site")) { + if (sscanf(config_str, "site%d", &site) == 1) { + import_site_id = site; + *config = config_persistent; + return true; + } + } + import_site_id = SITE_FALLBACK; + return str_to_config(config_str, config); +} + static struct export_header *header_new(const char *config_str, const char *type, const char *id) { config_t config; struct export_header *hdr; - if (!str_to_config(config_str, &config)) + if (!header_str_to_config(config_str, &config)) return NULL; hdr = misc_malloc(sizeof(struct export_header)); if (!id) @@ -130,6 +147,14 @@ static void export_write_comment(FILE *fd) fprintf(fd, "# Generated by chzdev\n"); } +static const char *site_specific_header(config_t config) +{ + if (global_site_id != SITE_FALLBACK) + return misc_asprintf("site%d", global_site_id); + else + return config_to_str(config); +} + /* Write an export file header. */ static void write_header(FILE *fd, config_t config, const char *type, const char *id, int *first_ptr) @@ -143,9 +168,9 @@ static void write_header(FILE *fd, config_t config, const char *type, } if (id) - fprintf(fd, "[%s %s %s]\n", config_to_str(config), type, id); + fprintf(fd, "[%s %s %s]\n", site_specific_header(config), type, id); else - fprintf(fd, "[%s %s]\n", config_to_str(config), type); + fprintf(fd, "[%s %s]\n", site_specific_header(config), type); } static int count_exportable(struct device *dev, config_t config) @@ -154,7 +179,7 @@ static int count_exportable(struct device *dev, config_t config) struct setting *s; int count; - list = device_get_setting_list(dev, config, SITE_FALLBACK); + list = device_get_setting_list(dev, config, global_site_id); if (!list) return 0; count = 0; @@ -408,7 +433,11 @@ static exit_code_t handle_header(const char *filename, int lineno, dev->active.exists = 1; } if (SCOPE_PERSISTENT(hdr->config)) { - setting_list_clear(dev->persistent.settings); + if (import_site_id != SITE_FALLBACK) + setting_list_clear(dev->site_specific[import_site_id].settings); + else + setting_list_clear(dev->persistent.settings); + dev->persistent.exists = 1; } if (SCOPE_AUTOCONF(hdr->config)) { @@ -502,7 +531,8 @@ static bool empty_device(struct device *dev) return false; if (util_list_is_empty(&dev->active.settings->list) && util_list_is_empty(&dev->persistent.settings->list) && - util_list_is_empty(&dev->autoconf.settings->list)) + util_list_is_empty(&dev->autoconf.settings->list) && + import_site_id == SITE_FALLBACK) return true; return false; } @@ -574,8 +604,9 @@ exit_code_t export_read(FILE *fd, const char *filename, ptrlist_add(objects, object_new(export_devtype, dt)); } else if (dev) { - ptrlist_add(objects, object_new(export_device, - dev)); + if (global_site_id == import_site_id) + ptrlist_add(objects, object_new(export_device, + dev)); } } else if (parse_setting(l, &key, &value)) { /* Found =. */ @@ -584,8 +615,10 @@ exit_code_t export_read(FILE *fd, const char *filename, "valid section\n"); rc = EXIT_FORMAT_ERROR; } else { - rc = handle_setting(filename, lineno, key, - value, dt, dev, config); + if (global_site_id == import_site_id || + import_site_id == SITE_FALLBACK) + rc = handle_setting(filename, lineno, key, + value, dt, dev, config); } free(key); free(value);