2007-05-30 22:05:54 +00:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
|
|
|
|
*
|
|
|
|
*/
|
2005-11-26 09:02:21 +00:00
|
|
|
|
|
|
|
#define __NO_INLINE__
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <stdio.h>
|
2005-11-27 22:31:07 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2007-05-16 20:43:41 +00:00
|
|
|
#include <libstream.h>
|
2007-08-21 22:07:05 +00:00
|
|
|
#include <libui.h>
|
2007-08-25 21:33:57 +00:00
|
|
|
#include <libconfig.h>
|
2005-11-27 22:31:07 +00:00
|
|
|
#include "config.h"
|
2005-11-26 09:02:21 +00:00
|
|
|
#if defined(USE_CLI) && defined(__LINUX__)
|
|
|
|
#include "console.h"
|
|
|
|
#endif
|
|
|
|
#include "arch.h"
|
2007-05-22 20:04:08 +00:00
|
|
|
#include "misc.h"
|
2007-05-24 17:27:35 +00:00
|
|
|
#include "bank.h"
|
2007-09-16 15:27:53 +00:00
|
|
|
#include "vga.h"
|
|
|
|
#include "serial.h"
|
2005-11-26 09:02:21 +00:00
|
|
|
|
2007-09-17 23:31:17 +00:00
|
|
|
#define MSG_STATE_0 console_set_cursor_position(win.l + win.h + 1, 1); \
|
2007-09-11 23:05:11 +00:00
|
|
|
printf(" Press 'b' or [RETURN] to boot or 'e' to edit\n");
|
|
|
|
|
2007-09-17 23:31:17 +00:00
|
|
|
#define MSG_STATE_1 console_set_cursor_position(win.l + win.h + 1, 1); \
|
2007-09-11 23:05:11 +00:00
|
|
|
printf(" Press 'b' to boot, 'e' or [RETURN] to edit \n" \
|
|
|
|
" Press 'd' to delete, 'n' to create \n" \
|
|
|
|
" Press [ESC] to go back \n");
|
|
|
|
|
2007-09-17 23:31:17 +00:00
|
|
|
#define MSG_CLEAN console_set_cursor_position(win.l + win.h + 1, 1); \
|
2007-09-11 23:05:11 +00:00
|
|
|
printf(" \n" \
|
|
|
|
" \n" \
|
|
|
|
" \n");
|
|
|
|
|
2007-08-21 22:07:05 +00:00
|
|
|
#define MAX_KERNELS 20
|
|
|
|
#define MAX_KERNEL_PARAMS 5
|
2007-05-16 20:43:41 +00:00
|
|
|
|
2007-08-22 18:59:03 +00:00
|
|
|
#define COMMAND_LINE_LENGTH 256
|
|
|
|
#define DEFAULT_TIMEOUT 5
|
2005-11-27 22:31:07 +00:00
|
|
|
|
2007-05-16 20:43:41 +00:00
|
|
|
static int8_t *open_config(emile_l2_header_t *info)
|
|
|
|
{
|
|
|
|
stream_t *stream;
|
|
|
|
struct stream_stat stat;
|
|
|
|
int8_t *configuration;
|
|
|
|
char property[COMMAND_LINE_LENGTH];
|
|
|
|
int ret;
|
|
|
|
|
2007-09-16 15:27:53 +00:00
|
|
|
configuration = (int8_t*)malloc(info->conf_size);
|
|
|
|
if (configuration == NULL)
|
|
|
|
{
|
|
|
|
printf("ERROR: cannot allocate %d bytes for "
|
2007-10-22 22:06:52 +00:00
|
|
|
"configuration\n", info->conf_size);
|
2007-09-16 15:27:53 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
memcpy(configuration, info->configuration, info->conf_size);
|
|
|
|
|
|
|
|
if (config_get_property(configuration,
|
2007-08-31 23:25:41 +00:00
|
|
|
"configuration", property) != -1)
|
2007-05-16 20:43:41 +00:00
|
|
|
{
|
|
|
|
stream = stream_open(property);
|
|
|
|
if (stream == NULL)
|
|
|
|
{
|
|
|
|
printf("ERROR: cannot open configuration file %s\n",
|
|
|
|
property);
|
2008-07-28 23:43:21 +00:00
|
|
|
configuration[0] = 0;
|
|
|
|
return configuration;
|
2007-05-16 20:43:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
stream_fstat(stream, &stat);
|
|
|
|
|
2007-09-16 15:27:53 +00:00
|
|
|
free(configuration);
|
|
|
|
|
2007-05-16 20:43:41 +00:00
|
|
|
configuration = (int8_t*)malloc(stat.st_size);
|
|
|
|
if (configuration == NULL)
|
|
|
|
{
|
|
|
|
printf("ERROR: cannot allocate %d bytes for "
|
|
|
|
"configuration file %s\n",
|
|
|
|
(int)stat.st_size, property);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = stream_read(stream, configuration, stat.st_size);
|
|
|
|
if (ret != stat.st_size)
|
|
|
|
{
|
|
|
|
printf("ERROR: cannot read %d bytes from "
|
|
|
|
"configuration file %s (%d)\n",
|
|
|
|
(int)stat.st_size, property, ret);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream_close(stream);
|
|
|
|
}
|
|
|
|
|
|
|
|
return configuration;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void close_config(int8_t *configuration)
|
|
|
|
{
|
|
|
|
free(configuration);
|
|
|
|
}
|
|
|
|
|
2005-11-28 23:20:25 +00:00
|
|
|
static char *decode_serial(char* s, int *baudrate, int *parity, int *datasize, int *stopbits)
|
2005-11-27 22:31:07 +00:00
|
|
|
{
|
|
|
|
*baudrate = strtol(s, &s, 0);
|
|
|
|
switch(*s)
|
|
|
|
{
|
|
|
|
case 'n':
|
|
|
|
case 'N':
|
|
|
|
*parity = 0;
|
|
|
|
break;
|
|
|
|
case 'o':
|
|
|
|
case 'O':
|
|
|
|
*parity = 1;
|
|
|
|
break;
|
|
|
|
case 'e':
|
|
|
|
case 'E':
|
|
|
|
*parity = 2;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
*parity = -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
s++;
|
|
|
|
*datasize = strtol(s, &s, 0);
|
2005-11-28 23:20:25 +00:00
|
|
|
if (*s != '+')
|
2007-09-16 16:22:07 +00:00
|
|
|
{
|
|
|
|
*stopbits = 0;
|
2005-11-28 23:20:25 +00:00
|
|
|
return s;
|
2007-09-16 16:22:07 +00:00
|
|
|
}
|
2005-11-28 23:20:25 +00:00
|
|
|
s++;
|
|
|
|
*stopbits = strtol(s, &s, 0);
|
2005-11-27 22:31:07 +00:00
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2008-04-16 13:43:28 +00:00
|
|
|
static char *concat_path(char *root, char *path)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
char *full;
|
|
|
|
|
|
|
|
if (root == NULL)
|
|
|
|
return strdup(path);
|
|
|
|
|
|
|
|
len = strlen(root) + strlen(path) + 1;
|
|
|
|
|
|
|
|
full = (char*)malloc(len);
|
|
|
|
if (full == NULL)
|
|
|
|
return NULL;
|
|
|
|
sprintf(full, "%s%s", root, path);
|
|
|
|
|
|
|
|
return full;
|
|
|
|
}
|
|
|
|
|
2007-10-21 01:48:34 +00:00
|
|
|
int read_config(emile_l2_header_t* info, emile_config_t *econfig)
|
2007-05-16 20:43:41 +00:00
|
|
|
{
|
2005-12-08 06:34:58 +00:00
|
|
|
char property[COMMAND_LINE_LENGTH];
|
2007-05-16 20:43:41 +00:00
|
|
|
int8_t *configuration;
|
|
|
|
int index;
|
2007-08-21 22:07:05 +00:00
|
|
|
char* title[MAX_KERNELS];
|
|
|
|
char* properties[MAX_KERNELS][MAX_KERNEL_PARAMS];
|
|
|
|
int prop_nb[MAX_KERNELS];
|
|
|
|
char *known_properties[] = {
|
2008-04-16 13:43:28 +00:00
|
|
|
"root",
|
2007-08-21 22:07:05 +00:00
|
|
|
"kernel",
|
2008-04-16 13:43:28 +00:00
|
|
|
"args",
|
2007-08-21 22:07:05 +00:00
|
|
|
"initrd",
|
2007-10-10 17:16:15 +00:00
|
|
|
"chainloader",
|
2007-08-21 22:07:05 +00:00
|
|
|
NULL
|
|
|
|
};
|
2007-08-21 22:12:27 +00:00
|
|
|
int i;
|
|
|
|
int choice;
|
2007-08-22 18:59:03 +00:00
|
|
|
int timeout;
|
2007-08-31 21:56:45 +00:00
|
|
|
int current;
|
|
|
|
int res;
|
2007-09-16 15:27:53 +00:00
|
|
|
int bitrate, parity, datasize, stopbits;
|
2008-04-16 13:43:28 +00:00
|
|
|
char *root;
|
2007-08-21 22:07:05 +00:00
|
|
|
#if defined(USE_CLI) && defined(__LINUX__)
|
2007-09-11 23:05:11 +00:00
|
|
|
int l, c;
|
|
|
|
emile_window_t win;
|
2007-08-21 22:07:05 +00:00
|
|
|
emile_list_t list;
|
|
|
|
int state;
|
2008-07-08 21:58:03 +00:00
|
|
|
char line[80];
|
|
|
|
int len;
|
2007-08-21 22:07:05 +00:00
|
|
|
#endif
|
|
|
|
|
2007-05-16 20:43:41 +00:00
|
|
|
if (!EMILE_COMPAT(EMILE_07_SIGNATURE, info->signature))
|
2005-11-26 09:02:21 +00:00
|
|
|
{
|
2007-09-16 15:27:53 +00:00
|
|
|
vga_init("default");
|
2005-11-26 09:02:21 +00:00
|
|
|
printf("Bad header signature !\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2007-05-16 20:43:41 +00:00
|
|
|
configuration = open_config(info);
|
2007-05-24 17:27:35 +00:00
|
|
|
|
2007-09-16 15:27:53 +00:00
|
|
|
if (config_get_property(configuration, "vga", property) != -1)
|
|
|
|
vga_init(property);
|
2008-07-28 23:43:21 +00:00
|
|
|
else
|
|
|
|
vga_init("default");
|
2007-09-16 15:27:53 +00:00
|
|
|
|
|
|
|
if (config_get_property(configuration, "modem", property) != -1)
|
|
|
|
{
|
|
|
|
decode_serial(property, &bitrate, &parity, &datasize, &stopbits);
|
|
|
|
serial_enable(SERIAL_MODEM_PORT, bitrate, parity, datasize, stopbits);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config_get_property(configuration, "printer", property) != -1)
|
|
|
|
{
|
|
|
|
decode_serial(property, &bitrate, &parity, &datasize, &stopbits);
|
|
|
|
serial_enable(SERIAL_PRINTER_PORT, bitrate, parity, datasize, stopbits);
|
|
|
|
}
|
|
|
|
|
2007-08-31 23:25:41 +00:00
|
|
|
if (config_get_property(configuration, "gestaltID", property) != -1)
|
2007-05-24 17:27:35 +00:00
|
|
|
{
|
|
|
|
machine_id = strtol(property, NULL, 0);
|
|
|
|
printf("User forces gestalt ID to %ld\n", machine_id);
|
|
|
|
}
|
2007-05-16 20:43:41 +00:00
|
|
|
|
2007-08-22 18:59:03 +00:00
|
|
|
choice = 0;
|
2007-08-31 23:25:41 +00:00
|
|
|
if (config_get_property(configuration, "default", property) != -1)
|
2007-08-22 18:59:03 +00:00
|
|
|
choice = strtol(property, NULL, 0);
|
|
|
|
|
|
|
|
timeout = DEFAULT_TIMEOUT;
|
2007-08-31 23:25:41 +00:00
|
|
|
if (config_get_property(configuration, "timeout", property) != -1)
|
2007-08-22 18:59:03 +00:00
|
|
|
timeout = strtol(property, NULL, 0);
|
|
|
|
|
2007-08-31 21:56:45 +00:00
|
|
|
current = 0;
|
2007-05-16 20:43:41 +00:00
|
|
|
for (index = 0; index < MAX_KERNELS; index++)
|
2005-11-26 09:02:21 +00:00
|
|
|
{
|
2007-08-21 22:07:05 +00:00
|
|
|
int prop;
|
|
|
|
|
|
|
|
title[index] = NULL;
|
2007-05-16 20:43:41 +00:00
|
|
|
|
2007-08-31 21:56:45 +00:00
|
|
|
res = config_get_property(configuration + current,
|
|
|
|
"title", property);
|
|
|
|
|
|
|
|
if (res == -1)
|
|
|
|
{
|
|
|
|
if (index)
|
|
|
|
break;
|
|
|
|
title[index] = strdup("Linux");
|
|
|
|
}
|
|
|
|
else
|
2007-05-16 20:43:41 +00:00
|
|
|
{
|
2007-08-21 22:07:05 +00:00
|
|
|
title[index] = strdup(property);
|
|
|
|
if (title[index] == NULL)
|
2007-05-16 20:43:41 +00:00
|
|
|
{
|
|
|
|
close_config(configuration);
|
|
|
|
return -1;
|
|
|
|
}
|
2007-08-31 21:56:45 +00:00
|
|
|
current += res;
|
|
|
|
current = config_get_next_property(configuration,
|
|
|
|
current,
|
|
|
|
NULL, NULL);
|
2007-05-16 20:43:41 +00:00
|
|
|
}
|
2007-08-21 22:07:05 +00:00
|
|
|
prop = 0;
|
|
|
|
for(i = 0; known_properties[i] != NULL; i++)
|
2007-05-16 20:43:41 +00:00
|
|
|
{
|
2007-08-25 21:33:57 +00:00
|
|
|
if (config_get_indexed_property(configuration,
|
2007-08-31 21:56:45 +00:00
|
|
|
(res == -1) ? NULL :"title",
|
|
|
|
title[index],
|
|
|
|
known_properties[i],
|
|
|
|
property) == -1)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
properties[index][prop] =
|
|
|
|
malloc(strlen(known_properties[i]) +
|
|
|
|
strlen(property) + 2);
|
|
|
|
if (properties[index][prop] == NULL)
|
2007-05-16 20:43:41 +00:00
|
|
|
{
|
2007-08-31 21:56:45 +00:00
|
|
|
close_config(configuration);
|
|
|
|
return -1;
|
2007-05-16 20:43:41 +00:00
|
|
|
}
|
2007-08-31 21:56:45 +00:00
|
|
|
sprintf(properties[index][prop], "%s %s",
|
|
|
|
known_properties[i], property);
|
|
|
|
prop++;
|
2007-05-16 20:43:41 +00:00
|
|
|
}
|
2007-08-21 22:07:05 +00:00
|
|
|
prop_nb[index] = prop;
|
|
|
|
}
|
2007-09-11 22:57:52 +00:00
|
|
|
if (choice > index - 1)
|
|
|
|
choice = index - 1;
|
2007-09-11 23:05:11 +00:00
|
|
|
|
|
|
|
#if defined(USE_CLI) && defined(__LINUX__)
|
2007-09-16 15:27:53 +00:00
|
|
|
timeout = console_select(timeout);
|
2007-09-11 23:05:11 +00:00
|
|
|
|
|
|
|
console_get_size(&l, &c);
|
|
|
|
console_clear();
|
2008-07-08 21:58:03 +00:00
|
|
|
sprintf(line, "EMILE v"VERSION
|
|
|
|
" (c) 2004-2008 Laurent Vivier (%ld kB)",
|
2007-09-11 23:05:11 +00:00
|
|
|
bank_mem_avail() / 1024);
|
2008-07-08 21:58:03 +00:00
|
|
|
len = strlen(line);
|
|
|
|
if (len < c)
|
|
|
|
len = (c - len) / 2 + 1;
|
|
|
|
else
|
|
|
|
len = 1;
|
|
|
|
console_set_cursor_position(1, len);
|
|
|
|
printf("%s\n", line);
|
2007-09-11 23:05:11 +00:00
|
|
|
|
2007-08-21 22:07:05 +00:00
|
|
|
state = 0;
|
|
|
|
|
2007-09-17 23:31:17 +00:00
|
|
|
win.l = 4;
|
2007-09-11 23:05:11 +00:00
|
|
|
win.c = 4;
|
|
|
|
win.h = l - 16;
|
|
|
|
win.w = c - 8;
|
2007-08-31 23:11:04 +00:00
|
|
|
|
|
|
|
MSG_STATE_0
|
2007-08-21 22:07:05 +00:00
|
|
|
while(state != -1)
|
|
|
|
{
|
|
|
|
switch(state)
|
2007-05-16 20:43:41 +00:00
|
|
|
{
|
2007-08-21 22:07:05 +00:00
|
|
|
case 0: /* select entry */
|
|
|
|
list.item = title;
|
2007-09-11 22:57:52 +00:00
|
|
|
list.nb = index;
|
2007-08-22 18:59:03 +00:00
|
|
|
list.current = choice;
|
|
|
|
res = emile_scrolllist(&win, &list, timeout);
|
2007-08-21 22:07:05 +00:00
|
|
|
choice = list.current;
|
2007-08-22 18:59:03 +00:00
|
|
|
timeout = 0;
|
2007-08-21 22:07:05 +00:00
|
|
|
switch(res)
|
2007-05-16 20:43:41 +00:00
|
|
|
{
|
2007-08-21 22:07:05 +00:00
|
|
|
case '\r':
|
|
|
|
case 'b':
|
|
|
|
case 'B':
|
|
|
|
state = -1;
|
2007-08-31 23:11:04 +00:00
|
|
|
MSG_CLEAN
|
2007-08-21 22:07:05 +00:00
|
|
|
break;
|
|
|
|
case 'e':
|
|
|
|
case 'E':
|
|
|
|
list.current = 0;
|
|
|
|
state = 1;
|
2007-08-31 23:11:04 +00:00
|
|
|
MSG_STATE_1
|
2007-08-21 22:07:05 +00:00
|
|
|
break;
|
2007-05-16 20:43:41 +00:00
|
|
|
}
|
2007-08-21 22:07:05 +00:00
|
|
|
break;
|
|
|
|
case 1: /* select parameter */
|
|
|
|
list.item = properties[choice];
|
|
|
|
list.nb = prop_nb[choice];
|
2007-08-22 18:59:03 +00:00
|
|
|
res = emile_scrolllist(&win, &list, 0);
|
2007-08-21 22:07:05 +00:00
|
|
|
switch(res)
|
2007-05-16 20:43:41 +00:00
|
|
|
{
|
2007-08-21 22:07:05 +00:00
|
|
|
case 'd':
|
|
|
|
case 'D':
|
|
|
|
free(properties[choice][list.current]);
|
|
|
|
prop_nb[choice]--;
|
|
|
|
for(i = list.current; i < prop_nb[choice]; i++)
|
|
|
|
properties[choice][i] =
|
|
|
|
properties[choice][i + 1];
|
|
|
|
if (list.current >= prop_nb[choice])
|
|
|
|
list.current--;
|
|
|
|
break;
|
|
|
|
case 'n':
|
|
|
|
case 'N':
|
|
|
|
properties[choice][prop_nb[choice]] = strdup("");
|
|
|
|
list.current = prop_nb[choice];
|
|
|
|
prop_nb[choice]++;
|
|
|
|
state = 2;
|
2007-08-31 23:11:04 +00:00
|
|
|
MSG_CLEAN
|
2007-08-21 22:07:05 +00:00
|
|
|
break;
|
|
|
|
case '\033': /* ESC */
|
|
|
|
list.current = choice;
|
|
|
|
state = 0;
|
2007-08-31 23:11:04 +00:00
|
|
|
MSG_CLEAN
|
|
|
|
MSG_STATE_0
|
2007-08-21 22:07:05 +00:00
|
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
case 'B':
|
2007-08-31 23:11:04 +00:00
|
|
|
MSG_CLEAN
|
2007-08-21 22:07:05 +00:00
|
|
|
state = -1;
|
|
|
|
break;
|
|
|
|
case '\r':
|
|
|
|
case 'e':
|
2007-08-31 23:11:04 +00:00
|
|
|
MSG_CLEAN
|
2007-08-21 22:07:05 +00:00
|
|
|
state = 2;
|
|
|
|
break;
|
2007-05-16 20:43:41 +00:00
|
|
|
}
|
2007-05-24 17:27:35 +00:00
|
|
|
break;
|
2007-08-21 22:07:05 +00:00
|
|
|
case 2: /* edit parameter */
|
|
|
|
memset(property, 0, COMMAND_LINE_LENGTH);
|
|
|
|
strncpy(property, properties[choice][list.current], COMMAND_LINE_LENGTH);
|
|
|
|
free(properties[choice][list.current]);
|
2007-09-17 23:31:17 +00:00
|
|
|
console_set_cursor_position(win.l + win.h + 1, 3);
|
2007-08-21 22:07:05 +00:00
|
|
|
console_cursor_on();
|
2007-09-17 23:31:17 +00:00
|
|
|
emile_edit(property, COMMAND_LINE_LENGTH);
|
2007-08-21 22:07:05 +00:00
|
|
|
console_cursor_off();
|
|
|
|
properties[choice][list.current] = strdup(property);
|
|
|
|
console_set_cursor_position(win.l + win.h + 2, 3);
|
|
|
|
memset(property, ' ', strlen(property));
|
|
|
|
printf("%s", property);
|
2007-09-19 20:40:40 +00:00
|
|
|
console_set_cursor_position(win.l + win.h + 1, 3);
|
|
|
|
for(i = 0; i < strlen(property); i++)
|
|
|
|
console_putchar(' ');
|
2007-08-21 22:07:05 +00:00
|
|
|
state = 1;
|
2007-08-31 23:11:04 +00:00
|
|
|
MSG_STATE_1
|
2007-08-21 22:07:05 +00:00
|
|
|
break;
|
|
|
|
}
|
2005-12-08 06:34:58 +00:00
|
|
|
}
|
2007-08-21 22:07:05 +00:00
|
|
|
#endif
|
2005-11-26 09:02:21 +00:00
|
|
|
|
2008-04-16 13:43:28 +00:00
|
|
|
root = NULL;
|
2007-10-21 01:48:34 +00:00
|
|
|
memset(econfig, 0, sizeof(*econfig));
|
2007-08-21 22:07:05 +00:00
|
|
|
for (i = 0; i < prop_nb[choice]; i++)
|
|
|
|
{
|
|
|
|
char *id, *next;
|
|
|
|
|
2007-08-25 21:33:57 +00:00
|
|
|
id = config_read_word(properties[choice][i], &next);
|
2007-08-21 22:07:05 +00:00
|
|
|
*next = 0;
|
|
|
|
next++;
|
2008-04-16 13:43:28 +00:00
|
|
|
if (strcmp("root", id) == 0)
|
|
|
|
root = next;
|
|
|
|
else if (strcmp("kernel", id) == 0)
|
2008-07-08 21:58:03 +00:00
|
|
|
econfig->kernel = concat_path(root, next);
|
2008-04-16 18:22:05 +00:00
|
|
|
else if (strcmp("args", id) == 0)
|
2007-10-21 01:48:34 +00:00
|
|
|
econfig->command_line = strdup(next);
|
2007-08-21 22:07:05 +00:00
|
|
|
else if (strcmp("initrd", id) == 0)
|
2008-04-16 13:43:28 +00:00
|
|
|
econfig->initrd = concat_path(root, next);
|
2007-10-10 17:16:15 +00:00
|
|
|
else if (strcmp("chainloader", id) == 0)
|
2008-04-16 13:43:28 +00:00
|
|
|
econfig->chainloader = concat_path(root, next);
|
2007-08-21 22:07:05 +00:00
|
|
|
}
|
2007-05-22 18:32:48 +00:00
|
|
|
|
2007-08-21 22:07:05 +00:00
|
|
|
for (index--; index >= 0; index--)
|
2005-11-26 09:02:21 +00:00
|
|
|
{
|
2007-08-21 22:07:05 +00:00
|
|
|
free(title[index]);
|
|
|
|
|
2007-10-22 22:06:52 +00:00
|
|
|
for (i = 0; i < prop_nb[index]; i++)
|
2007-08-21 22:07:05 +00:00
|
|
|
free(properties[index][i]);
|
2005-11-26 09:02:21 +00:00
|
|
|
}
|
2007-08-21 22:07:05 +00:00
|
|
|
|
2007-05-16 20:43:41 +00:00
|
|
|
close_config(configuration);
|
2005-11-26 09:02:21 +00:00
|
|
|
return 0;
|
|
|
|
}
|