2 * Copyright (c)2004 The DragonFly Project. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
16 * Neither the name of the DragonFly Project nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 * OF THE POSSIBILITY OF SUCH DAMAGE.
36 * Functions for working with configuration files.
37 * Inspired by (but not derived from) sysinstall's variable.c
38 * $Id: confed.c,v 1.16 2005/02/06 21:05:18 cpressey Exp $
51 #include "libaura/mem.h"
52 #include "libaura/dict.h"
53 #include "libdfui/system.h"
57 #include "functions.h"
60 * Create a new, empty set of in-memory config variable settings.
65 struct config_vars *cvs;
67 AURA_MALLOC(cvs, config_vars);
69 cvs->d = aura_dict_new(1, AURA_DICT_SORTED_LIST);
75 * Deallocate the memory used by a set of config variable settings.
78 config_vars_free(struct config_vars *cvs)
83 aura_dict_free(cvs->d);
85 AURA_FREE(cvs, config_vars);
89 * Get the value of a configuration variable in a set of settings
90 * and return it, or a (constant) 0-length string if not found.
93 config_var_get(const struct config_vars *cvs, const char *name)
98 aura_dict_fetch(cvs->d, name, strlen(name) + 1, &rv, &rv_len);
106 * Set the value of a configuration variable. If the named variable
107 * does not exist within the given set, a new one is created.
110 config_var_set(struct config_vars *cvs, const char *name, const char *value)
112 aura_dict_store(cvs->d,
113 name, strlen(name) + 1,
114 value, strlen(value) + 1);
119 * Write a set of configuration variable settings to a file.
122 config_vars_write(const struct config_vars *cvs, int config_type, const char *fmt, ...)
128 int conf_written = 0;
131 size_t rk_len, rv_len;
134 vasprintf(&filename, fmt, args);
137 if ((f = fopen(filename, "a")) == NULL)
141 strlcpy(tstr, ctime(&t), 256);
142 if (strlen(tstr) > 0)
143 tstr[strlen(tstr) - 1] = '\0';
145 switch (config_type) {
148 aura_dict_rewind(cvs->d);
149 while (!aura_dict_eof(cvs->d)) {
150 if (! conf_written) {
153 fprintf(f, "# -- BEGIN %s "
154 "Installer automatically generated "
155 "configuration -- #\n",
156 OPERATING_SYSTEM_NAME);
157 fprintf(f, "# -- Written on %s -- #\n", tstr);
159 aura_dict_get_current_key(cvs->d, &rk, &rk_len),
160 aura_dict_fetch(cvs->d, rk, rk_len, &rv, &rv_len);
161 fprintf(f, "%s=\"%s\"\n", (char *)rk, (char *)rv);
162 aura_dict_next(cvs->d);
165 fprintf(f, "# -- END of %s Installer "
166 "automatically generated configuration -- #\n",
167 OPERATING_SYSTEM_NAME);
170 case CONFIG_TYPE_RESOLV:
171 aura_dict_rewind(cvs->d);
172 while (!aura_dict_eof(cvs->d)) {
173 aura_dict_get_current_key(cvs->d, &rk, &rk_len),
174 aura_dict_fetch(cvs->d, rk, rk_len, &rv, &rv_len);
175 fprintf(f, "%s\t\t%s\n", (char *)rk, (char *)rv);
176 aura_dict_next(cvs->d);
189 * Read variables from a file.
190 * Returns 1 if the variables could be read successfully, 0 if not.
193 config_vars_read(struct i_fn_args *a, struct config_vars *cvs,
194 int config_type __unused, const char *fmt, ...)
196 struct commands *cmds;
197 char *filename, *tmp_filename, line[1024], *value;
202 vasprintf(&filename, fmt, args);
205 asprintf(&tmp_filename, "%sextract_vars", a->tmp);
206 script = fopen(tmp_filename, "w");
211 fprintf(script, "set | %susr/bin/sort >%senv.before\n", a->os_root, a->tmp);
212 fprintf(script, ". %s%s\n", a->os_root, filename);
213 fprintf(script, "set | %susr/bin/sort >%senv.after\n", a->os_root, a->tmp);
214 fprintf(script, "%susr/bin/comm -1 -3 %senv.before %senv.after | \\\n",
215 a->os_root, a->tmp, a->tmp);
216 fprintf(script, " %susr/bin/awk -F= '{ print $1 }' | \\\n", a->os_root);
217 fprintf(script, " while read __VARNAME; do\n");
218 fprintf(script, " echo -n ${__VARNAME}=\n");
219 fprintf(script, " eval echo ' $'${__VARNAME}\n");
220 fprintf(script, " done\n");
221 fprintf(script, "%sbin/rm -f %senv.before %senv.after\n",
222 a->os_root, a->tmp, a->tmp);
225 cmds = commands_new();
226 command_add(cmds, "%sbin/sh %sextract_vars >%sextracted_vars.txt",
227 a->os_root, a->tmp, a->tmp);
228 temp_file_add(a, "extracted_vars.txt");
229 if (!commands_execute(a, cmds)) {
236 * Delete the script immediately.
238 asprintf(&tmp_filename, "%sextract_vars", a->tmp);
239 (void)unlink(tmp_filename); /* not much we can do if it fails */
242 asprintf(&tmp_filename, "%sextracted_vars.txt", a->tmp);
243 f = fopen(tmp_filename, "r");
247 while (fgets(line, 1024, f) != NULL) {
248 if (strlen(line) > 0)
249 line[strlen(line) - 1] = '\0';
250 /* split line at first = */
251 for (value = line; *value != '=' && *value != '\0'; value++)
257 config_var_set(cvs, line, value);