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 * Generic functions for installer.
37 * $Id: functions.c,v 1.22 2005/02/06 21:05:18 cpressey Exp $
48 #include "libaura/mem.h"
49 #include "libaura/dict.h"
51 #include "libdfui/dfui.h"
53 #include "functions.h"
57 /*** INSTALLER CONTEXT CONSTRUCTOR ***/
60 i_fn_args_new(const char *os_root, const char *def_tmp_dir, int transport, const char *rendezvous)
65 AURA_MALLOC(a, i_fn_args);
68 a->os_root = aura_strdup(os_root);
80 asprintf(&filename, "%sinstall.log", def_tmp_dir);
81 a->log = fopen(filename, "w");
88 i_log(a, "Installer started");
89 i_log(a, "-----------------");
91 i_log(a, "+ Creating DFUI connection on ``%s''\n", rendezvous);
93 if ((a->c = dfui_connection_new(transport, rendezvous)) == NULL) {
94 i_log(a, "! ERROR: Couldn't create connection on ``%s''\n", rendezvous);
99 i_log(a, "+ Connecting on ``%s''\n", rendezvous);
101 if (!dfui_be_start(a->c)) {
102 i_log(a, "! ERROR: Couldn't connect to frontend on ``%s''\n", rendezvous);
107 if ((a->s = storage_new()) == NULL) {
108 i_log(a, "! ERROR: Couldn't create storage descriptor");
113 a->tmp = def_tmp_dir; /* XXX temporarily set to this */
114 a->temp_files = aura_dict_new(23, AURA_DICT_HASH);
115 a->cmd_names = config_vars_new();
116 if (!config_vars_read(a, a->cmd_names, CONFIG_TYPE_SH,
117 "usr/share/installer/cmdnames.conf")) {
118 i_log(a, "! ERROR: Couldn't read cmdnames config file");
123 a->tmp = cmd_name(a, "INSTALLER_TEMP");
125 i_log(a, "+ Starting installer state machine");
131 i_fn_args_free(struct i_fn_args *a)
134 if (a->temp_files != NULL) {
136 aura_dict_free(a->temp_files);
138 if (a->cmd_names != NULL) {
139 config_vars_free(a->cmd_names);
147 if (a->log != NULL) {
150 AURA_FREE(a, i_fn_args);
154 /*** INSTALLER CONTEXT FUNCTIONS ***/
157 i_log(struct i_fn_args *a, const char *fmt, ...)
162 vfprintf(stderr, fmt, args);
163 fprintf(stderr, "\n");
165 if (a->log != NULL) {
167 vfprintf(a->log, fmt, args);
168 fprintf(a->log, "\n");
184 assert_clean(struct dfui_connection *c, const char *name, const char *field,
185 const char *not_allowed)
187 if (strpbrk(field, not_allowed) != NULL) {
188 inform(c, "The %s field may not contain any of the "
189 "following characters:\n\n%s",
198 * Expects a leading 0x.
201 hex_to_int(const char *hex, int *result)
206 if (strncmp(hex, "0x", 2) != 0)
209 for (i = 2; hex[i] != '\0'; i++) {
214 a = a * 16 + (d - '0');
215 else if (d >= 'A' && d <= 'F')
216 a = a * 16 + (d + 10 - 'A');
226 first_non_space_char_is(const char *line, char x)
230 for (i = 0; line[i] != '\0'; i++) {
231 if (isspace(line[i]))
242 capacity_to_string(long capacity)
244 static char string[6];
247 strlcpy(string, "*", 2);
249 humanize_number(string, sizeof(string),
250 (int64_t)capacity * 1024 * 1024, "",
251 HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
257 string_to_capacity(const char *string, long *capacity)
262 if (!strcmp(string, "*")) {
266 error = dehumanize_number(string, &result);
269 result /= 1024 * 1024;
277 * Round a number up to the nearest power of two.
280 next_power_of_two(unsigned long n)
286 while (p < n && p > op) {
291 return(p > op ? p : n);
295 * Returns file name without extension.
297 * ru.koi8-r.kbd -> ru.koi8-r
300 * Caller is responsible for freeing the string returned.
303 filename_noext(const char *filename)
308 buffer = aura_strdup(filename);
310 if (strlen(filename) == 0) {
315 p = strrchr(filename, '.');
318 i = strlen(filename) - strlen(p);
330 temp_file_add(struct i_fn_args *a, const char *filename)
332 aura_dict_store(a->temp_files, filename, strlen(filename) + 1, "", 1);
337 temp_files_clean(struct i_fn_args *a)
343 aura_dict_rewind(a->temp_files);
344 while (!aura_dict_eof(a->temp_files)) {
345 aura_dict_get_current_key(a->temp_files, &rk, &rk_len);
346 asprintf(&filename, "%s%s", a->tmp, (char *)rk);
347 (void)unlink(filename); /* not much we can do if it fails */
349 aura_dict_next(a->temp_files);
358 cmd_name(const struct i_fn_args *a, const char *cmd_key)
362 name = config_var_get(a->cmd_names, cmd_key);
363 if (strcmp(name, "") == 0)
364 return("bin/echo"); /* XXX usr/local/sbin/error? */