installer: Tone down the comments around the installer's rc.conf settings.
[dragonfly.git] / usr.sbin / installer / libinstaller / confed.c
CommitLineData
337ad0df
DH
1/*
2 * Copyright (c)2004 The DragonFly Project. All rights reserved.
21c1c48a 3 *
337ad0df
DH
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
21c1c48a 7 *
337ad0df
DH
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
21c1c48a 10 *
337ad0df
DH
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
14 * distribution.
21c1c48a 15 *
337ad0df
DH
16 * Neither the name of the DragonFly Project nor the names of its
17 * contributors may be used to endorse or promote products derived
21c1c48a
SW
18 * from this software without specific prior written permission.
19 *
337ad0df
DH
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
21c1c48a 31 * OF THE POSSIBILITY OF SUCH DAMAGE.
337ad0df
DH
32 */
33
34/*
35 * confed.c
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 $
39 */
40
41#include <sys/stat.h>
42
43#include <ctype.h>
44#include <stdarg.h>
45#include <stdio.h>
46#include <stdlib.h>
47#include <string.h>
48#include <time.h>
49#include <unistd.h>
50
bc3d4063
SW
51#include "libaura/mem.h"
52#include "libaura/dict.h"
53#include "libdfui/system.h"
337ad0df
DH
54
55#include "confed.h"
56#include "commands.h"
57#include "functions.h"
58
59/*
60 * Create a new, empty set of in-memory config variable settings.
61 */
62struct config_vars *
63config_vars_new(void)
64{
65 struct config_vars *cvs;
66
67 AURA_MALLOC(cvs, config_vars);
68
69 cvs->d = aura_dict_new(1, AURA_DICT_SORTED_LIST);
70
71 return(cvs);
72}
73
74/*
75 * Deallocate the memory used by a set of config variable settings.
76 */
77void
78config_vars_free(struct config_vars *cvs)
79{
80 if (cvs == NULL)
81 return;
82
83 aura_dict_free(cvs->d);
84
85 AURA_FREE(cvs, config_vars);
86}
87
88/*
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.
91 */
92const char *
93config_var_get(const struct config_vars *cvs, const char *name)
94{
95 void *rv;
96 size_t rv_len;
97
98 aura_dict_fetch(cvs->d, name, strlen(name) + 1, &rv, &rv_len);
99 if (rv == NULL)
100 return("");
101 else
102 return(rv);
103}
104
105/*
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.
108 */
109int
110config_var_set(struct config_vars *cvs, const char *name, const char *value)
111{
112 aura_dict_store(cvs->d,
113 name, strlen(name) + 1,
114 value, strlen(value) + 1);
115 return(1);
116}
117
118/*
119 * Write a set of configuration variable settings to a file.
120 */
121int
10f4bf95
SW
122config_vars_write(const struct config_vars *cvs, int config_type,
123 const char *fmt, ...)
337ad0df
DH
124{
125 FILE *f;
126 va_list args;
127 char *filename;
337ad0df
DH
128 void *rk, *rv;
129 size_t rk_len, rv_len;
130
131 va_start(args, fmt);
132 vasprintf(&filename, fmt, args);
133 va_end(args);
134
135 if ((f = fopen(filename, "a")) == NULL)
136 return(0);
137
337ad0df
DH
138 switch (config_type) {
139 case CONFIG_TYPE_SH:
140
141 aura_dict_rewind(cvs->d);
142 while (!aura_dict_eof(cvs->d)) {
337ad0df
DH
143 aura_dict_get_current_key(cvs->d, &rk, &rk_len),
144 aura_dict_fetch(cvs->d, rk, rk_len, &rv, &rv_len);
10f4bf95
SW
145 fprintf(f, "%s=\"%s\"\t# via installer configuration\n",
146 (char *)rk, (char *)rv);
337ad0df
DH
147 aura_dict_next(cvs->d);
148 }
337ad0df
DH
149 break;
150 case CONFIG_TYPE_RESOLV:
151 aura_dict_rewind(cvs->d);
152 while (!aura_dict_eof(cvs->d)) {
153 aura_dict_get_current_key(cvs->d, &rk, &rk_len),
154 aura_dict_fetch(cvs->d, rk, rk_len, &rv, &rv_len);
155 fprintf(f, "%s\t\t%s\n", (char *)rk, (char *)rv);
156 aura_dict_next(cvs->d);
157 }
158 break;
159 default:
160 fclose(f);
161 return(0);
162 }
21c1c48a 163
337ad0df
DH
164 fclose(f);
165 return(1);
166}
167
168/*
169 * Read variables from a file.
170 * Returns 1 if the variables could be read successfully, 0 if not.
171 */
172int
173config_vars_read(struct i_fn_args *a, struct config_vars *cvs,
174 int config_type __unused, const char *fmt, ...)
175{
176 struct commands *cmds;
177 char *filename, *tmp_filename, line[1024], *value;
178 FILE *f, *script;
179 va_list args;
180
181 va_start(args, fmt);
182 vasprintf(&filename, fmt, args);
183 va_end(args);
184
185 asprintf(&tmp_filename, "%sextract_vars", a->tmp);
186 script = fopen(tmp_filename, "w");
187 free(tmp_filename);
188 if (script == NULL)
189 return(0);
21c1c48a 190
337ad0df
DH
191 fprintf(script, "set | %susr/bin/sort >%senv.before\n", a->os_root, a->tmp);
192 fprintf(script, ". %s%s\n", a->os_root, filename);
193 fprintf(script, "set | %susr/bin/sort >%senv.after\n", a->os_root, a->tmp);
194 fprintf(script, "%susr/bin/comm -1 -3 %senv.before %senv.after | \\\n",
195 a->os_root, a->tmp, a->tmp);
196 fprintf(script, " %susr/bin/awk -F= '{ print $1 }' | \\\n", a->os_root);
197 fprintf(script, " while read __VARNAME; do\n");
198 fprintf(script, " echo -n ${__VARNAME}=\n");
199 fprintf(script, " eval echo ' $'${__VARNAME}\n");
200 fprintf(script, " done\n");
201 fprintf(script, "%sbin/rm -f %senv.before %senv.after\n",
202 a->os_root, a->tmp, a->tmp);
203 fclose(script);
204
205 cmds = commands_new();
9b76398f
SW
206 command_add(cmds, "%sbin/sh %sextract_vars >%sextracted_vars.txt",
207 a->os_root, a->tmp, a->tmp);
337ad0df
DH
208 temp_file_add(a, "extracted_vars.txt");
209 if (!commands_execute(a, cmds)) {
210 commands_free(cmds);
211 return(0);
212 }
213 commands_free(cmds);
214
215 /*
216 * Delete the script immediately.
217 */
218 asprintf(&tmp_filename, "%sextract_vars", a->tmp);
219 (void)unlink(tmp_filename); /* not much we can do if it fails */
220 free(tmp_filename);
221
222 asprintf(&tmp_filename, "%sextracted_vars.txt", a->tmp);
223 f = fopen(tmp_filename, "r");
224 free(tmp_filename);
225 if (f == NULL)
226 return(0);
227 while (fgets(line, 1024, f) != NULL) {
228 if (strlen(line) > 0)
229 line[strlen(line) - 1] = '\0';
230 /* split line at first = */
231 for (value = line; *value != '=' && *value != '\0'; value++)
232 ;
233 if (*value == '\0')
234 break;
235 *value = '\0';
236 value++;
237 config_var_set(cvs, line, value);
238 }
239 fclose(f);
240
241 return(1);
242}