+ pp_script_t *ps, *ps1;
+
+ ps = lookup_pp_script(pscur.name);
+
+ if(ps != (pp_script_t *)0) {
+ conf_parserror(_("script %s already defined at %s:%d"),
+ ps->name, ps->seen.filename, ps->seen.linenum);
+ return;
+ }
+
+ ps = alloc(sizeof(pp_script_t));
+ *ps = pscur;
+ ps->next = NULL;
+ /* add at end of list */
+ if (!pp_script_list)
+ pp_script_list = ps;
+ else {
+ ps1 = pp_script_list;
+ while (ps1->next != NULL) {
+ ps1 = ps1->next;
+ }
+ ps1->next = ps;
+ }
+}
+
+static void
+copy_pp_script(void)
+{
+ pp_script_t *ps;
+ int i;
+
+ ps = lookup_pp_script(tokenval.v.s);
+
+ if(ps == NULL) {
+ conf_parserror(_("script parameter expected"));
+ return;
+ }
+
+ for(i=0; i < PP_SCRIPT_PP_SCRIPT; i++) {
+ if(ps->value[i].seen.linenum) {
+ merge_val_t(&pscur.value[i], &ps->value[i]);
+ }
+ }
+}
+
+static device_config_t *
+read_device_config(
+ char *name,
+ FILE *from,
+ char *fname,
+ int *linenum)
+{
+ int save_overwrites;
+ FILE *saved_conf = NULL;
+ char *saved_fname = NULL;
+
+ if (from) {
+ saved_conf = current_file;
+ current_file = from;
+ }
+
+ if (fname) {
+ saved_fname = current_filename;
+ current_filename = get_seen_filename(fname);
+ }
+
+ if (linenum)
+ current_line_num = *linenum;
+
+ save_overwrites = allow_overwrites;
+ allow_overwrites = 1;
+
+ init_device_config_defaults();
+ if (name) {
+ dccur.name = name;
+ } else {
+ get_conftoken(CONF_IDENT);
+ dccur.name = stralloc(tokenval.v.s);
+ }
+ current_block = g_strconcat("device ", dccur.name, NULL);
+ dccur.seen.block = current_block;
+ dccur.seen.filename = current_filename;
+ dccur.seen.linenum = current_line_num;
+
+ read_block(device_config_var, dccur.value,
+ _("device parameter expected"),
+ (name == NULL), *copy_device_config,
+ "DEVICE", dccur.name);
+ if(!name)
+ get_conftoken(CONF_NL);
+
+ save_device_config();
+
+ allow_overwrites = save_overwrites;
+
+ if (linenum)
+ *linenum = current_line_num;
+
+ if (fname)
+ current_filename = saved_fname;
+
+ if (from)
+ current_file = saved_conf;
+
+ return lookup_device_config(dccur.name);
+}
+
+static void
+get_device_config(
+ void)
+{
+ read_device_config(NULL, NULL, NULL, NULL);
+}
+
+static void
+init_device_config_defaults(
+ void)
+{
+ dccur.name = NULL;
+ conf_init_str(&dccur.value[DEVICE_CONFIG_COMMENT] , "");
+ conf_init_str(&dccur.value[DEVICE_CONFIG_TAPEDEV] , "");
+ conf_init_proplist(&dccur.value[DEVICE_CONFIG_DEVICE_PROPERTY]);
+}
+
+static void
+save_device_config(
+ void)
+{
+ device_config_t *dc, *dc1;
+
+ dc = lookup_device_config(dccur.name);
+
+ if(dc != (device_config_t *)0) {
+ conf_parserror(_("device %s already defined at %s:%d"),
+ dc->name, dc->seen.filename, dc->seen.linenum);
+ return;
+ }
+
+ dc = alloc(sizeof(device_config_t));
+ *dc = dccur;
+ dc->next = NULL;
+ /* add at end of list */
+ if (!device_config_list)
+ device_config_list = dc;
+ else {
+ dc1 = device_config_list;
+ while (dc1->next != NULL) {
+ dc1 = dc1->next;
+ }
+ dc1->next = dc;
+ }
+}
+
+static void
+copy_device_config(void)
+{
+ device_config_t *dc;
+ int i;
+
+ dc = lookup_device_config(tokenval.v.s);
+
+ if(dc == NULL) {
+ conf_parserror(_("device parameter expected"));
+ return;
+ }
+
+ for(i=0; i < DEVICE_CONFIG_DEVICE_CONFIG; i++) {
+ if(dc->value[i].seen.linenum) {
+ merge_val_t(&dccur.value[i], &dc->value[i]);
+ }
+ }
+}
+
+static changer_config_t *
+read_changer_config(
+ char *name,
+ FILE *from,
+ char *fname,
+ int *linenum)
+{
+ int save_overwrites;
+ FILE *saved_conf = NULL;
+ char *saved_fname = NULL;
+
+ if (from) {
+ saved_conf = current_file;
+ current_file = from;
+ }
+
+ if (fname) {
+ saved_fname = current_filename;
+ current_filename = fname;
+ }
+
+ if (linenum)
+ current_line_num = *linenum;
+
+ save_overwrites = allow_overwrites;
+ allow_overwrites = 1;
+
+ init_changer_config_defaults();
+ if (name) {
+ cccur.name = name;
+ } else {
+ get_conftoken(CONF_IDENT);
+ cccur.name = stralloc(tokenval.v.s);
+ }
+ current_block = g_strconcat("changer ", cccur.name, NULL);
+ cccur.seen.block = current_block;
+ cccur.seen.filename = current_filename;
+ cccur.seen.linenum = current_line_num;
+
+ read_block(changer_config_var, cccur.value,
+ _("changer parameter expected"),
+ (name == NULL), *copy_changer_config,
+ "CHANGER", cccur.name);
+ if(!name)
+ get_conftoken(CONF_NL);
+
+ save_changer_config();
+
+ allow_overwrites = save_overwrites;
+
+ if (linenum)
+ *linenum = current_line_num;
+
+ if (fname)
+ current_filename = saved_fname;
+
+ if (from)
+ current_file = saved_conf;
+
+ return lookup_changer_config(cccur.name);
+}
+
+static void
+get_changer_config(
+ void)
+{
+ read_changer_config(NULL, NULL, NULL, NULL);
+}
+
+static void
+init_changer_config_defaults(
+ void)
+{
+ cccur.name = NULL;
+ conf_init_str(&cccur.value[CHANGER_CONFIG_COMMENT] , "");
+ conf_init_str(&cccur.value[CHANGER_CONFIG_TAPEDEV] , "");
+ conf_init_str(&cccur.value[CHANGER_CONFIG_TPCHANGER] , "");
+ conf_init_str(&cccur.value[CHANGER_CONFIG_CHANGERDEV] , "");
+ conf_init_str(&cccur.value[CHANGER_CONFIG_CHANGERFILE] , "");
+ conf_init_proplist(&cccur.value[CHANGER_CONFIG_PROPERTY]);
+ conf_init_proplist(&cccur.value[CHANGER_CONFIG_DEVICE_PROPERTY]);
+}
+
+static void
+save_changer_config(
+ void)
+{
+ changer_config_t *dc, *dc1;