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 $
47 #include "libaura/mem.h"
48 #include "libaura/dict.h"
50 #include "libdfui/dfui.h"
52 #include "functions.h"
56 /*** INSTALLER CONTEXT CONSTRUCTOR ***/
59 i_fn_args_new(const char *os_root
, const char *def_tmp_dir
, int transport
, const char *rendezvous
)
64 AURA_MALLOC(a
, i_fn_args
);
67 a
->os_root
= aura_strdup(os_root
);
79 asprintf(&filename
, "%sinstall.log", def_tmp_dir
);
80 a
->log
= fopen(filename
, "w");
87 i_log(a
, "Installer started");
88 i_log(a
, "-----------------");
90 i_log(a
, "+ Creating DFUI connection on ``%s''\n", rendezvous
);
92 if ((a
->c
= dfui_connection_new(transport
, rendezvous
)) == NULL
) {
93 i_log(a
, "! ERROR: Couldn't create connection on ``%s''\n", rendezvous
);
98 i_log(a
, "+ Connecting on ``%s''\n", rendezvous
);
100 if (!dfui_be_start(a
->c
)) {
101 i_log(a
, "! ERROR: Couldn't connect to frontend on ``%s''\n", rendezvous
);
106 if ((a
->s
= storage_new()) == NULL
) {
107 i_log(a
, "! ERROR: Couldn't create storage descriptor");
112 a
->tmp
= def_tmp_dir
; /* XXX temporarily set to this */
113 a
->temp_files
= aura_dict_new(23, AURA_DICT_HASH
);
114 a
->cmd_names
= config_vars_new();
115 if (!config_vars_read(a
, a
->cmd_names
, CONFIG_TYPE_SH
,
116 "usr/share/installer/cmdnames.conf")) {
117 i_log(a
, "! ERROR: Couldn't read cmdnames config file");
122 a
->tmp
= cmd_name(a
, "INSTALLER_TEMP");
124 i_log(a
, "+ Starting installer state machine");
130 i_fn_args_free(struct i_fn_args
*a
)
133 if (a
->temp_files
!= NULL
) {
135 aura_dict_free(a
->temp_files
);
137 if (a
->cmd_names
!= NULL
) {
138 config_vars_free(a
->cmd_names
);
146 if (a
->log
!= NULL
) {
149 AURA_FREE(a
, i_fn_args
);
153 /*** INSTALLER CONTEXT FUNCTIONS ***/
156 i_log(struct i_fn_args
*a
, const char *fmt
, ...)
161 vfprintf(stderr
, fmt
, args
);
162 fprintf(stderr
, "\n");
164 if (a
->log
!= NULL
) {
166 vfprintf(a
->log
, fmt
, args
);
167 fprintf(a
->log
, "\n");
183 assert_clean(struct dfui_connection
*c
, const char *name
, const char *field
,
184 const char *not_allowed
)
186 if (strpbrk(field
, not_allowed
) != NULL
) {
187 inform(c
, "The %s field may not contain any of the "
188 "following characters:\n\n%s",
197 * Expects a leading 0x.
200 hex_to_int(const char *hex
, int *result
)
205 if (strncmp(hex
, "0x", 2) != 0)
208 for (i
= 2; hex
[i
] != '\0'; i
++) {
213 a
= a
* 16 + (d
- '0');
214 else if (d
>= 'A' && d
<= 'F')
215 a
= a
* 16 + (d
+ 10 - 'A');
225 first_non_space_char_is(const char *line
, char x
)
229 for (i
= 0; line
[i
] != '\0'; i
++) {
230 if (isspace(line
[i
]))
241 capacity_to_string(long capacity
)
243 static char string
[256];
246 strlcpy(string
, "*", 2);
248 snprintf(string
, 255, "%ldM", capacity
);
254 string_to_capacity(const char *string
, long *capacity
)
258 unit
= string
[strlen(string
) - 1];
259 if (!strcmp(string
, "*")) {
262 } else if (unit
== 'm' || unit
== 'M') {
263 *capacity
= strtol(string
, NULL
, 10);
265 } else if (unit
== 'g' || unit
== 'G') {
266 *capacity
= strtol(string
, NULL
, 10) * 1024;
274 * Round a number up to the nearest power of two.
277 next_power_of_two(unsigned long n
)
283 while (p
< n
&& p
> op
) {
288 return(p
> op
? p
: n
);
292 * Returns file name without extension.
294 * ru.koi8-r.kbd -> ru.koi8-r
297 * Caller is responsible for freeing the string returned.
300 filename_noext(const char *filename
)
305 buffer
= aura_strdup(filename
);
307 if (strlen(filename
) == 0) {
312 p
= strrchr(filename
, '.');
315 i
= strlen(filename
) - strlen(p
);
327 temp_file_add(struct i_fn_args
*a
, const char *filename
)
329 aura_dict_store(a
->temp_files
, filename
, strlen(filename
) + 1, "", 1);
334 temp_files_clean(struct i_fn_args
*a
)
340 aura_dict_rewind(a
->temp_files
);
341 while (!aura_dict_eof(a
->temp_files
)) {
342 aura_dict_get_current_key(a
->temp_files
, &rk
, &rk_len
);
343 asprintf(&filename
, "%s%s", a
->tmp
, (char *)rk
);
344 (void)unlink(filename
); /* not much we can do if it fails */
346 aura_dict_next(a
->temp_files
);
355 cmd_name(const struct i_fn_args
*a
, const char *cmd_key
)
359 name
= config_var_get(a
->cmd_names
, cmd_key
);
360 if (strcmp(name
, "") == 0)
361 return("bin/echo"); /* XXX usr/local/sbin/error? */