#include <sys/stat.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "libaura/mem.h"
#include "libaura/dict.h"
#include "libdfui/system.h"
#include "confed.h"
#include "commands.h"
#include "functions.h"
struct config_vars *
config_vars_new(void)
{
struct config_vars *cvs;
AURA_MALLOC(cvs, config_vars);
cvs->d = aura_dict_new(1, AURA_DICT_SORTED_LIST);
return(cvs);
}
void
config_vars_free(struct config_vars *cvs)
{
if (cvs == NULL)
return;
aura_dict_free(cvs->d);
AURA_FREE(cvs, config_vars);
}
const char *
config_var_get(const struct config_vars *cvs, const char *name)
{
void *rv;
size_t rv_len;
aura_dict_fetch(cvs->d, name, strlen(name) + 1, &rv, &rv_len);
if (rv == NULL)
return("");
else
return(rv);
}
int
config_var_set(struct config_vars *cvs, const char *name, const char *value)
{
aura_dict_store(cvs->d,
name, strlen(name) + 1,
value, strlen(value) + 1);
return(1);
}
int
config_vars_write(const struct config_vars *cvs, int config_type,
const char *fmt, ...)
{
FILE *f;
va_list args;
char *filename;
void *rk, *rv;
size_t rk_len, rv_len;
va_start(args, fmt);
vasprintf(&filename, fmt, args);
va_end(args);
if ((f = fopen(filename, "a")) == NULL)
return(0);
switch (config_type) {
case CONFIG_TYPE_SH:
aura_dict_rewind(cvs->d);
while (!aura_dict_eof(cvs->d)) {
aura_dict_get_current_key(cvs->d, &rk, &rk_len),
aura_dict_fetch(cvs->d, rk, rk_len, &rv, &rv_len);
fprintf(f, "%s=\"%s\"\t# via installer configuration\n",
(char *)rk, (char *)rv);
aura_dict_next(cvs->d);
}
break;
case CONFIG_TYPE_RESOLV:
aura_dict_rewind(cvs->d);
while (!aura_dict_eof(cvs->d)) {
aura_dict_get_current_key(cvs->d, &rk, &rk_len),
aura_dict_fetch(cvs->d, rk, rk_len, &rv, &rv_len);
fprintf(f, "%s\t\t%s\n", (char *)rk, (char *)rv);
aura_dict_next(cvs->d);
}
break;
default:
fclose(f);
return(0);
}
fclose(f);
return(1);
}
static int
config_vars_read_sh(struct i_fn_args *a, struct config_vars *cvs,
const char *filename)
{
struct commands *cmds;
char *tmp_filename, line[1024], *value;
FILE *f, *script;
asprintf(&tmp_filename, "%sextract_vars", a->tmp);
script = fopen(tmp_filename, "w");
free(tmp_filename);
if (script == NULL)
return(0);
fprintf(script, "set | %susr/bin/sort >%senv.before\n", a->os_root, a->tmp);
fprintf(script, ". %s%s\n", a->os_root, filename);
fprintf(script, "set | %susr/bin/sort >%senv.after\n", a->os_root, a->tmp);
fprintf(script, "%susr/bin/comm -1 -3 %senv.before %senv.after | \\\n",
a->os_root, a->tmp, a->tmp);
fprintf(script, " %susr/bin/awk -F= '{ print $1 }' | \\\n", a->os_root);
fprintf(script, " while read __VARNAME; do\n");
fprintf(script, " echo -n ${__VARNAME}=\n");
fprintf(script, " eval echo ' $'${__VARNAME}\n");
fprintf(script, " done\n");
fprintf(script, "%sbin/rm -f %senv.before %senv.after\n",
a->os_root, a->tmp, a->tmp);
fclose(script);
cmds = commands_new();
command_add(cmds, "%sbin/sh %sextract_vars >%sextracted_vars.txt",
a->os_root, a->tmp, a->tmp);
temp_file_add(a, "extracted_vars.txt");
if (!commands_execute(a, cmds)) {
commands_free(cmds);
return(0);
}
commands_free(cmds);
asprintf(&tmp_filename, "%sextract_vars", a->tmp);
(void)unlink(tmp_filename);
free(tmp_filename);
asprintf(&tmp_filename, "%sextracted_vars.txt", a->tmp);
f = fopen(tmp_filename, "r");
free(tmp_filename);
if (f == NULL)
return(0);
while (fgets(line, sizeof(line), f) != NULL) {
line[strcspn(line, "\n")] = '\0';
for (value = line; *value != '=' && *value != '\0'; value++)
;
if (*value == '\0')
continue;
*value++ = '\0';
config_var_set(cvs, line, value);
}
fclose(f);
return(1);
}
static int
config_vars_read_resolv(struct i_fn_args *a, struct config_vars *cvs,
const char *filename)
{
FILE *f;
char *fullpath, *key, *value, *end;
char line[1024];
asprintf(&fullpath, "%s%s", a->os_root, filename);
f = fopen(fullpath, "r");
free(fullpath);
if (f == NULL)
return(0);
while (fgets(line, sizeof(line), f) != NULL) {
end = line + strlen(line);
while (end > line && isspace((unsigned char)*(end - 1)))
end--;
*end = '\0';
key = line;
while (isspace((unsigned char)*key))
key++;
if (*key == '\0' || *key == '#')
continue;
value = key;
while (*value != '\0' &&
!isspace((unsigned char)*value))
value++;
if (*value == '\0')
continue;
*value++ = '\0';
while (isspace((unsigned char)*value))
value++;
if (*value == '\0')
continue;
config_var_set(cvs, key, value);
}
fclose(f);
return(1);
}
int
config_vars_read(struct i_fn_args *a, struct config_vars *cvs,
int config_type, const char *fmt, ...)
{
char *filename;
va_list args;
int rv;
va_start(args, fmt);
vasprintf(&filename, fmt, args);
va_end(args);
switch (config_type) {
case CONFIG_TYPE_SH:
rv = config_vars_read_sh(a, cvs, filename);
break;
case CONFIG_TYPE_RESOLV:
rv = config_vars_read_resolv(a, cvs, filename);
break;
default:
rv = 0;
break;
}
free(filename);
return(rv);
}