1*86d7f5d3SJohn Marino /*
2*86d7f5d3SJohn Marino * Copyright (c)2004 The DragonFly Project. All rights reserved.
3*86d7f5d3SJohn Marino *
4*86d7f5d3SJohn Marino * Redistribution and use in source and binary forms, with or without
5*86d7f5d3SJohn Marino * modification, are permitted provided that the following conditions
6*86d7f5d3SJohn Marino * are met:
7*86d7f5d3SJohn Marino *
8*86d7f5d3SJohn Marino * Redistributions of source code must retain the above copyright
9*86d7f5d3SJohn Marino * notice, this list of conditions and the following disclaimer.
10*86d7f5d3SJohn Marino *
11*86d7f5d3SJohn Marino * Redistributions in binary form must reproduce the above copyright
12*86d7f5d3SJohn Marino * notice, this list of conditions and the following disclaimer in
13*86d7f5d3SJohn Marino * the documentation and/or other materials provided with the
14*86d7f5d3SJohn Marino * distribution.
15*86d7f5d3SJohn Marino *
16*86d7f5d3SJohn Marino * Neither the name of the DragonFly Project nor the names of its
17*86d7f5d3SJohn Marino * contributors may be used to endorse or promote products derived
18*86d7f5d3SJohn Marino * from this software without specific prior written permission.
19*86d7f5d3SJohn Marino *
20*86d7f5d3SJohn Marino * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21*86d7f5d3SJohn Marino * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*86d7f5d3SJohn Marino * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*86d7f5d3SJohn Marino * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24*86d7f5d3SJohn Marino * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25*86d7f5d3SJohn Marino * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26*86d7f5d3SJohn Marino * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27*86d7f5d3SJohn Marino * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*86d7f5d3SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29*86d7f5d3SJohn Marino * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30*86d7f5d3SJohn Marino * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31*86d7f5d3SJohn Marino * OF THE POSSIBILITY OF SUCH DAMAGE.
32*86d7f5d3SJohn Marino */
33*86d7f5d3SJohn Marino
34*86d7f5d3SJohn Marino /*
35*86d7f5d3SJohn Marino * confed.c
36*86d7f5d3SJohn Marino * Functions for working with configuration files.
37*86d7f5d3SJohn Marino * Inspired by (but not derived from) sysinstall's variable.c
38*86d7f5d3SJohn Marino * $Id: confed.c,v 1.16 2005/02/06 21:05:18 cpressey Exp $
39*86d7f5d3SJohn Marino */
40*86d7f5d3SJohn Marino
41*86d7f5d3SJohn Marino #include <sys/stat.h>
42*86d7f5d3SJohn Marino
43*86d7f5d3SJohn Marino #include <ctype.h>
44*86d7f5d3SJohn Marino #include <stdarg.h>
45*86d7f5d3SJohn Marino #include <stdio.h>
46*86d7f5d3SJohn Marino #include <stdlib.h>
47*86d7f5d3SJohn Marino #include <string.h>
48*86d7f5d3SJohn Marino #include <time.h>
49*86d7f5d3SJohn Marino #include <unistd.h>
50*86d7f5d3SJohn Marino
51*86d7f5d3SJohn Marino #include "libaura/mem.h"
52*86d7f5d3SJohn Marino #include "libaura/dict.h"
53*86d7f5d3SJohn Marino #include "libdfui/system.h"
54*86d7f5d3SJohn Marino
55*86d7f5d3SJohn Marino #include "confed.h"
56*86d7f5d3SJohn Marino #include "commands.h"
57*86d7f5d3SJohn Marino #include "functions.h"
58*86d7f5d3SJohn Marino
59*86d7f5d3SJohn Marino /*
60*86d7f5d3SJohn Marino * Create a new, empty set of in-memory config variable settings.
61*86d7f5d3SJohn Marino */
62*86d7f5d3SJohn Marino struct config_vars *
config_vars_new(void)63*86d7f5d3SJohn Marino config_vars_new(void)
64*86d7f5d3SJohn Marino {
65*86d7f5d3SJohn Marino struct config_vars *cvs;
66*86d7f5d3SJohn Marino
67*86d7f5d3SJohn Marino AURA_MALLOC(cvs, config_vars);
68*86d7f5d3SJohn Marino
69*86d7f5d3SJohn Marino cvs->d = aura_dict_new(1, AURA_DICT_SORTED_LIST);
70*86d7f5d3SJohn Marino
71*86d7f5d3SJohn Marino return(cvs);
72*86d7f5d3SJohn Marino }
73*86d7f5d3SJohn Marino
74*86d7f5d3SJohn Marino /*
75*86d7f5d3SJohn Marino * Deallocate the memory used by a set of config variable settings.
76*86d7f5d3SJohn Marino */
77*86d7f5d3SJohn Marino void
config_vars_free(struct config_vars * cvs)78*86d7f5d3SJohn Marino config_vars_free(struct config_vars *cvs)
79*86d7f5d3SJohn Marino {
80*86d7f5d3SJohn Marino if (cvs == NULL)
81*86d7f5d3SJohn Marino return;
82*86d7f5d3SJohn Marino
83*86d7f5d3SJohn Marino aura_dict_free(cvs->d);
84*86d7f5d3SJohn Marino
85*86d7f5d3SJohn Marino AURA_FREE(cvs, config_vars);
86*86d7f5d3SJohn Marino }
87*86d7f5d3SJohn Marino
88*86d7f5d3SJohn Marino /*
89*86d7f5d3SJohn Marino * Get the value of a configuration variable in a set of settings
90*86d7f5d3SJohn Marino * and return it, or a (constant) 0-length string if not found.
91*86d7f5d3SJohn Marino */
92*86d7f5d3SJohn Marino const char *
config_var_get(const struct config_vars * cvs,const char * name)93*86d7f5d3SJohn Marino config_var_get(const struct config_vars *cvs, const char *name)
94*86d7f5d3SJohn Marino {
95*86d7f5d3SJohn Marino void *rv;
96*86d7f5d3SJohn Marino size_t rv_len;
97*86d7f5d3SJohn Marino
98*86d7f5d3SJohn Marino aura_dict_fetch(cvs->d, name, strlen(name) + 1, &rv, &rv_len);
99*86d7f5d3SJohn Marino if (rv == NULL)
100*86d7f5d3SJohn Marino return("");
101*86d7f5d3SJohn Marino else
102*86d7f5d3SJohn Marino return(rv);
103*86d7f5d3SJohn Marino }
104*86d7f5d3SJohn Marino
105*86d7f5d3SJohn Marino /*
106*86d7f5d3SJohn Marino * Set the value of a configuration variable. If the named variable
107*86d7f5d3SJohn Marino * does not exist within the given set, a new one is created.
108*86d7f5d3SJohn Marino */
109*86d7f5d3SJohn Marino int
config_var_set(struct config_vars * cvs,const char * name,const char * value)110*86d7f5d3SJohn Marino config_var_set(struct config_vars *cvs, const char *name, const char *value)
111*86d7f5d3SJohn Marino {
112*86d7f5d3SJohn Marino aura_dict_store(cvs->d,
113*86d7f5d3SJohn Marino name, strlen(name) + 1,
114*86d7f5d3SJohn Marino value, strlen(value) + 1);
115*86d7f5d3SJohn Marino return(1);
116*86d7f5d3SJohn Marino }
117*86d7f5d3SJohn Marino
118*86d7f5d3SJohn Marino /*
119*86d7f5d3SJohn Marino * Write a set of configuration variable settings to a file.
120*86d7f5d3SJohn Marino */
121*86d7f5d3SJohn Marino int
config_vars_write(const struct config_vars * cvs,int config_type,const char * fmt,...)122*86d7f5d3SJohn Marino config_vars_write(const struct config_vars *cvs, int config_type,
123*86d7f5d3SJohn Marino const char *fmt, ...)
124*86d7f5d3SJohn Marino {
125*86d7f5d3SJohn Marino FILE *f;
126*86d7f5d3SJohn Marino va_list args;
127*86d7f5d3SJohn Marino char *filename;
128*86d7f5d3SJohn Marino void *rk, *rv;
129*86d7f5d3SJohn Marino size_t rk_len, rv_len;
130*86d7f5d3SJohn Marino
131*86d7f5d3SJohn Marino va_start(args, fmt);
132*86d7f5d3SJohn Marino vasprintf(&filename, fmt, args);
133*86d7f5d3SJohn Marino va_end(args);
134*86d7f5d3SJohn Marino
135*86d7f5d3SJohn Marino if ((f = fopen(filename, "a")) == NULL)
136*86d7f5d3SJohn Marino return(0);
137*86d7f5d3SJohn Marino
138*86d7f5d3SJohn Marino switch (config_type) {
139*86d7f5d3SJohn Marino case CONFIG_TYPE_SH:
140*86d7f5d3SJohn Marino
141*86d7f5d3SJohn Marino aura_dict_rewind(cvs->d);
142*86d7f5d3SJohn Marino while (!aura_dict_eof(cvs->d)) {
143*86d7f5d3SJohn Marino aura_dict_get_current_key(cvs->d, &rk, &rk_len),
144*86d7f5d3SJohn Marino aura_dict_fetch(cvs->d, rk, rk_len, &rv, &rv_len);
145*86d7f5d3SJohn Marino fprintf(f, "%s=\"%s\"\t# via installer configuration\n",
146*86d7f5d3SJohn Marino (char *)rk, (char *)rv);
147*86d7f5d3SJohn Marino aura_dict_next(cvs->d);
148*86d7f5d3SJohn Marino }
149*86d7f5d3SJohn Marino break;
150*86d7f5d3SJohn Marino case CONFIG_TYPE_RESOLV:
151*86d7f5d3SJohn Marino aura_dict_rewind(cvs->d);
152*86d7f5d3SJohn Marino while (!aura_dict_eof(cvs->d)) {
153*86d7f5d3SJohn Marino aura_dict_get_current_key(cvs->d, &rk, &rk_len),
154*86d7f5d3SJohn Marino aura_dict_fetch(cvs->d, rk, rk_len, &rv, &rv_len);
155*86d7f5d3SJohn Marino fprintf(f, "%s\t\t%s\n", (char *)rk, (char *)rv);
156*86d7f5d3SJohn Marino aura_dict_next(cvs->d);
157*86d7f5d3SJohn Marino }
158*86d7f5d3SJohn Marino break;
159*86d7f5d3SJohn Marino default:
160*86d7f5d3SJohn Marino fclose(f);
161*86d7f5d3SJohn Marino return(0);
162*86d7f5d3SJohn Marino }
163*86d7f5d3SJohn Marino
164*86d7f5d3SJohn Marino fclose(f);
165*86d7f5d3SJohn Marino return(1);
166*86d7f5d3SJohn Marino }
167*86d7f5d3SJohn Marino
168*86d7f5d3SJohn Marino /*
169*86d7f5d3SJohn Marino * Read variables from a file.
170*86d7f5d3SJohn Marino * Returns 1 if the variables could be read successfully, 0 if not.
171*86d7f5d3SJohn Marino */
172*86d7f5d3SJohn Marino int
config_vars_read(struct i_fn_args * a,struct config_vars * cvs,int config_type __unused,const char * fmt,...)173*86d7f5d3SJohn Marino config_vars_read(struct i_fn_args *a, struct config_vars *cvs,
174*86d7f5d3SJohn Marino int config_type __unused, const char *fmt, ...)
175*86d7f5d3SJohn Marino {
176*86d7f5d3SJohn Marino struct commands *cmds;
177*86d7f5d3SJohn Marino char *filename, *tmp_filename, line[1024], *value;
178*86d7f5d3SJohn Marino FILE *f, *script;
179*86d7f5d3SJohn Marino va_list args;
180*86d7f5d3SJohn Marino
181*86d7f5d3SJohn Marino va_start(args, fmt);
182*86d7f5d3SJohn Marino vasprintf(&filename, fmt, args);
183*86d7f5d3SJohn Marino va_end(args);
184*86d7f5d3SJohn Marino
185*86d7f5d3SJohn Marino asprintf(&tmp_filename, "%sextract_vars", a->tmp);
186*86d7f5d3SJohn Marino script = fopen(tmp_filename, "w");
187*86d7f5d3SJohn Marino free(tmp_filename);
188*86d7f5d3SJohn Marino if (script == NULL)
189*86d7f5d3SJohn Marino return(0);
190*86d7f5d3SJohn Marino
191*86d7f5d3SJohn Marino fprintf(script, "set | %susr/bin/sort >%senv.before\n", a->os_root, a->tmp);
192*86d7f5d3SJohn Marino fprintf(script, ". %s%s\n", a->os_root, filename);
193*86d7f5d3SJohn Marino fprintf(script, "set | %susr/bin/sort >%senv.after\n", a->os_root, a->tmp);
194*86d7f5d3SJohn Marino fprintf(script, "%susr/bin/comm -1 -3 %senv.before %senv.after | \\\n",
195*86d7f5d3SJohn Marino a->os_root, a->tmp, a->tmp);
196*86d7f5d3SJohn Marino fprintf(script, " %susr/bin/awk -F= '{ print $1 }' | \\\n", a->os_root);
197*86d7f5d3SJohn Marino fprintf(script, " while read __VARNAME; do\n");
198*86d7f5d3SJohn Marino fprintf(script, " echo -n ${__VARNAME}=\n");
199*86d7f5d3SJohn Marino fprintf(script, " eval echo ' $'${__VARNAME}\n");
200*86d7f5d3SJohn Marino fprintf(script, " done\n");
201*86d7f5d3SJohn Marino fprintf(script, "%sbin/rm -f %senv.before %senv.after\n",
202*86d7f5d3SJohn Marino a->os_root, a->tmp, a->tmp);
203*86d7f5d3SJohn Marino fclose(script);
204*86d7f5d3SJohn Marino
205*86d7f5d3SJohn Marino cmds = commands_new();
206*86d7f5d3SJohn Marino command_add(cmds, "%sbin/sh %sextract_vars >%sextracted_vars.txt",
207*86d7f5d3SJohn Marino a->os_root, a->tmp, a->tmp);
208*86d7f5d3SJohn Marino temp_file_add(a, "extracted_vars.txt");
209*86d7f5d3SJohn Marino if (!commands_execute(a, cmds)) {
210*86d7f5d3SJohn Marino commands_free(cmds);
211*86d7f5d3SJohn Marino return(0);
212*86d7f5d3SJohn Marino }
213*86d7f5d3SJohn Marino commands_free(cmds);
214*86d7f5d3SJohn Marino
215*86d7f5d3SJohn Marino /*
216*86d7f5d3SJohn Marino * Delete the script immediately.
217*86d7f5d3SJohn Marino */
218*86d7f5d3SJohn Marino asprintf(&tmp_filename, "%sextract_vars", a->tmp);
219*86d7f5d3SJohn Marino (void)unlink(tmp_filename); /* not much we can do if it fails */
220*86d7f5d3SJohn Marino free(tmp_filename);
221*86d7f5d3SJohn Marino
222*86d7f5d3SJohn Marino asprintf(&tmp_filename, "%sextracted_vars.txt", a->tmp);
223*86d7f5d3SJohn Marino f = fopen(tmp_filename, "r");
224*86d7f5d3SJohn Marino free(tmp_filename);
225*86d7f5d3SJohn Marino if (f == NULL)
226*86d7f5d3SJohn Marino return(0);
227*86d7f5d3SJohn Marino while (fgets(line, 1024, f) != NULL) {
228*86d7f5d3SJohn Marino if (strlen(line) > 0)
229*86d7f5d3SJohn Marino line[strlen(line) - 1] = '\0';
230*86d7f5d3SJohn Marino /* split line at first = */
231*86d7f5d3SJohn Marino for (value = line; *value != '=' && *value != '\0'; value++)
232*86d7f5d3SJohn Marino ;
233*86d7f5d3SJohn Marino if (*value == '\0')
234*86d7f5d3SJohn Marino break;
235*86d7f5d3SJohn Marino *value = '\0';
236*86d7f5d3SJohn Marino value++;
237*86d7f5d3SJohn Marino config_var_set(cvs, line, value);
238*86d7f5d3SJohn Marino }
239*86d7f5d3SJohn Marino fclose(f);
240*86d7f5d3SJohn Marino
241*86d7f5d3SJohn Marino return(1);
242*86d7f5d3SJohn Marino }
243