aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--Makefile.am2
-rw-r--r--TODO4
-rw-r--r--configure.in1
-rw-r--r--etc/Makefile.am1
-rw-r--r--etc/mpio/mpioshrc5
-rw-r--r--mpiosh/Makefile.am19
-rw-r--r--mpiosh/callback.c17
-rw-r--r--mpiosh/cfgio.c654
-rw-r--r--mpiosh/cfgio.h453
-rw-r--r--mpiosh/command.c6
-rw-r--r--mpiosh/command.h4
-rw-r--r--mpiosh/config.c162
-rw-r--r--mpiosh/config.h48
-rw-r--r--mpiosh/global.c21
-rw-r--r--mpiosh/global.h36
-rw-r--r--mpiosh/mpiosh.c38
-rw-r--r--mpiosh/readline.c23
18 files changed, 1448 insertions, 60 deletions
diff --git a/ChangeLog b/ChangeLog
index e316eb2..b0f7f08 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2002-10-29 Andreas Buesching <crunchy@tzi.de>
+
+ * mpiosh/mpiosh.c (mpiosh_init): uses the new configuration file
+ support to initialise the shell
+
+ * etc/mpio/mpioshrc: add a sample configuration file will be
+ install as a global configuration file in
+ @sysconfdir@/mpio/mpioshrc
+
+ * mpiosh/cfgio.c, mpiosh/cfgio.c, mpiosh/config.c,
+ mpiosh/config.h: added these new files to support global and user
+ configuration files.
+
+
2002-10-27 Markus Germeier <mager@tzi.de>
* libmpio/mpio.{c,h}: split mpio_file_{get,put} into several
diff --git a/Makefile.am b/Makefile.am
index 8bf1d26..3b1ac82 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS=kernel libmpio mpiosh
+SUBDIRS=kernel libmpio mpiosh etc
sbin_SCRIPTS=mkmpiodev
EXTRA_DIST=mpio.spec mkmpiodev \ No newline at end of file
diff --git a/TODO b/TODO
index 68ce235..c09d77e 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-$Id: TODO,v 1.16 2002/10/13 17:14:51 germeier Exp $
+$Id: TODO,v 1.17 2002/10/29 20:03:34 crunchy Exp $
* Kernel Module
- the MPIO can no multitasking, so:
@@ -39,4 +39,6 @@ $Id: TODO,v 1.16 2002/10/13 17:14:51 germeier Exp $
- using stdin for reading command sequences [DONE]
- fill: uses current local directory to fill the current memory card
+ options: random, best(?)
+ - configuration files [almost DONE]
+ - save command history
diff --git a/configure.in b/configure.in
index 3af68e4..4fd895a 100644
--- a/configure.in
+++ b/configure.in
@@ -72,6 +72,7 @@ AC_OUTPUT(
kernel/Makefile
libmpio/Makefile
mpiosh/Makefile
+ etc/Makefile
mpio.spec
)
diff --git a/etc/Makefile.am b/etc/Makefile.am
new file mode 100644
index 0000000..02f1137
--- /dev/null
+++ b/etc/Makefile.am
@@ -0,0 +1 @@
+sysconf_DATA = mpio/mpioshrc \ No newline at end of file
diff --git a/etc/mpio/mpioshrc b/etc/mpio/mpioshrc
new file mode 100644
index 0000000..516b7d0
--- /dev/null
+++ b/etc/mpio/mpioshrc
@@ -0,0 +1,5 @@
+[mpiosh]
+default_mem=internal
+prompt_int=mpio <i>
+prompt_ext=mpio <e>
+
diff --git a/mpiosh/Makefile.am b/mpiosh/Makefile.am
index d6586a8..ed5843e 100644
--- a/mpiosh/Makefile.am
+++ b/mpiosh/Makefile.am
@@ -2,7 +2,22 @@ INCLUDES=-I..
bin_PROGRAMS=mpiosh
-mpiosh_SOURCES=mpiosh.c callback.c readline.c command.c global.c
+mpiosh_SOURCES = mpiosh.c \
+ callback.c \
+ readline.c \
+ command.c \
+ global.c \
+ cfgio.c \
+ config.c
+
+AM_CFLAGS=-DSYSCONFDIR=\"@sysconfdir@\"
+
mpiosh_LDADD=../libmpio/libmpio.la -lreadline -lncurses
-noinst_HEADERS=mpiosh.h callback.h readline.h command.h global.h \ No newline at end of file
+noinst_HEADERS = mpiosh.h \
+ callback.h \
+ readline.h \
+ command.h \
+ global.h \
+ cfgio.h \
+ config.h \ No newline at end of file
diff --git a/mpiosh/callback.c b/mpiosh/callback.c
index 24cb402..dfd8474 100644
--- a/mpiosh/callback.c
+++ b/mpiosh/callback.c
@@ -2,7 +2,7 @@
*
* Author: Andreas Büsching <crunchy@tzi.de>
*
- * $Id: callback.c,v 1.29 2002/10/27 17:37:27 germeier Exp $
+ * $Id: callback.c,v 1.30 2002/10/29 20:03:34 crunchy Exp $
*
* Copyright (C) 2001 Andreas Büsching <crunchy@tzi.de>
*
@@ -76,8 +76,8 @@ mpiosh_cmd_version(char *args[])
void
mpiosh_cmd_help(char *args[])
{
- mpiosh_cmd_t *cmd = commands;
- int ignore;
+ struct mpiosh_cmd_t *cmd = commands;
+ int ignore;
while (cmd->cmd) {
if (args[0] != NULL) {
@@ -418,17 +418,17 @@ mpiosh_cmd_mput(char *args[])
FTYPE_MUSIC, mpiosh_callback_put) == -1) {
mpio_perror("error");
/* an existing file is no reason for a complete abort!! */
- if (mpio_errno()==MPIO_ERR_FILE_EXISTS)
+ if (mpio_errno() == MPIO_ERR_FILE_EXISTS)
continue;
break;
}
- written=1; /* we did write something, so do mpio_sync afterwards */
+ written = 1; /* we did write something, so do mpio_sync afterwards */
printf("\n");
} else {
regerror(error, &regex, errortext, 100);
- debugn (2, "file does not match: %s (%s)\n",
- (*run)->d_name, errortext);
+ debugn(2, "file does not match: %s (%s)\n",
+ (*run)->d_name, errortext);
}
free(*run);
}
@@ -646,7 +646,7 @@ mpiosh_cmd_dump_mem(char *args[])
void
mpiosh_cmd_config(char *args[])
{
- BYTE *config_data, *p;
+ BYTE *config_data;
int size;
MPIOSH_CHECK_CONNECTION_CLOSED;
@@ -715,7 +715,6 @@ mpiosh_cmd_config(char *args[])
fprintf(stderr, "error: no arguments given\n");
printf("config [read|write|show] <\n");
}
-
}
void
diff --git a/mpiosh/cfgio.c b/mpiosh/cfgio.c
new file mode 100644
index 0000000..b8a1829
--- /dev/null
+++ b/mpiosh/cfgio.c
@@ -0,0 +1,654 @@
+#include "cfgio.h"
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+/***************************************************
+ * help!!! functions
+ ***************************************************/
+
+char *
+cfg_resolve_path(const char *filename)
+{
+ char *fn = NULL;
+
+ if (filename[0] != '~') return strdup(filename);
+
+ if (filename[1] == '/' ) {
+ /* own home directory */
+ char *home;
+ if ((home = getenv ("HOME")) == NULL) {
+ fn = strdup(filename);
+ } else {
+ fn = (char *)malloc(strlen(home) + strlen(filename+1) + 1);
+ sprintf(fn, "%s%s", home,filename+1);
+ }
+ } else {
+ /* other home directory */
+ struct passwd *pw;
+ char *dir = strchr(filename, '/');
+ size_t len = (size_t)(dir - filename-1);
+ char user[len];
+ strncpy(user, filename+1, len);
+ user[len] = '\0';
+
+ if (!(pw = getpwnam(user))) {
+ fn = strdup(filename);
+ } else {
+ fn = (char *) malloc(strlen(pw->pw_dir) + strlen(dir) + 1);
+ sprintf (fn, "%s%s",pw->pw_dir, dir);
+ }
+ }
+
+ return fn;
+}
+
+/***************************************************
+ * open functions
+ ***************************************************/
+int cfg_save(CfgHandle *h, int cl){
+ if (h && h->file) {
+ FILE *f = h->file;
+ CfgGroup *group;
+ group = h->first;
+
+ while (group) {
+ CfgKey *key;
+ fprintf(f, "[%s]\n", group->name);
+ key = group->first;
+ while (key) {
+ fprintf(f, "%s=%s\n", key->name, key->value ? key->value : "");
+ key = key->next;
+ }
+ fprintf(f, "\n");
+ group = group->next;
+ }
+ if (cl) return cfg_close(h);
+ return 0;
+ }
+ return -1;
+}
+
+int cfg_save_as(CfgHandle *h, const char* filename, int err, int cl){
+ if (h && filename) {
+ int res;
+ res = cfg_handle_change_filename(h, filename);
+ if (res) return res;
+ res = cfg_open(h, err, "w+");
+ if (res) return res;
+ return cfg_save(h,cl);
+ }
+ return -1;
+}
+
+
+int cfg_read(CfgHandle *h, int cl){
+ if (h && h->file){
+ char *gname = NULL;
+ FILE* file = h->file;
+ int offset;
+ char *line = (char*)malloc(_CFG_MAX_LINE_SIZE);
+ while ((line = fgets(line, _CFG_MAX_LINE_SIZE, file)) != NULL) {
+ for (offset = strlen(line); offset > 0 && isspace(line[offset-1]); line[--offset] = '\0');
+ for (offset = 0;isspace(line[offset]); offset++);
+ switch (line[offset]) {
+ case '#':
+ case '\0': break;
+ case '[':
+ free (gname);
+ gname = strdup(line+offset+1);
+ gname[strlen(gname)-1] = '\0';
+ cfg_group_new(h, gname);
+ break;
+ default: {
+ char *k, *v, *vo, *p;
+ size_t len;
+ int i;
+ p = strchr(line+offset, '=');
+ if (p) {
+ len = (size_t)(p - (line+offset) + 1);
+ k = (char*)malloc(len);
+ k = strncpy(k, line+offset, len);
+ k[len-1] = '\0';
+ for (i = strlen(k); i > 0 && isspace(k[i-1]); k[--i] = '\0');
+ v = (char*)malloc(strlen(p+1)+1);
+ /* v = (char*)malloc(strlen(p+1)); */
+ v = strcpy(v, p+1);
+ for (vo = v; isspace(vo[0]); vo++);
+ /* for (vo = v+1; isspace(vo[0]); vo++); */
+ cfg_key_new_with_value(h, gname, k, vo);
+ free (v);
+ } else {
+ len = (size_t)(strlen(line) - offset + 1);
+ k = (char*)malloc(len);
+ k = strncpy(k, line+offset, len);
+ k[len-1] = '\0';
+ vo = NULL;
+ cfg_key_new_with_value(h, gname, k, vo);
+ }
+
+ free (k);
+ }
+ }
+ }
+ free (line);
+ free (gname);
+ if (cl) return cfg_close(h);
+ return 0;
+ }
+ return -1;
+}
+
+
+int cfg_open_file(CfgHandle* h, const char* filename, int reportErrors, const char* mode){
+ if ((h->file = fopen (filename, mode)) != NULL) {
+ return 0;
+ } else {
+ if (reportErrors) {
+ fprintf (stderr, "Can't open configuration file \"%s\": %s\n",
+ filename, strerror (errno));
+ }
+ return -1;
+ }
+}
+
+char *
+cfg_find_file(char **files, char **pathes)
+{
+ /* e.g.:
+ char *files[] = { ".blarc", "blarc", "bla", NULL };
+ char *pathes[] = { "/", "/usr/etc/", "/etc/", NULL }; */
+ char **file, **path = pathes;
+ char *options_file = NULL, *help = NULL;
+ struct stat s;
+
+ while (*path) {
+ file = files;
+ while(*file) {
+ free(options_file);
+ options_file = (char *)malloc(sizeof(char) * (
+ strlen(*path) +
+ strlen(*file) + 1));
+ sprintf(options_file, "%s%s", *path, *file);
+ help = cfg_resolve_path(options_file);
+ if (!stat(help, &s)) {
+ free(options_file);
+ return help;
+ }
+ free(help);
+ file++;
+ }
+ path++;
+ }
+ free(options_file);
+
+ return NULL;
+}
+
+int
+cfg_open_user_file(CfgHandle *h, const char* filename,
+ int reportErrors, const char* mode)
+{
+ char *fn = cfg_resolve_path(filename);
+ int ret = cfg_open_file(h, fn, reportErrors, mode);
+
+ free(fn);
+
+ return ret;
+}
+
+int cfg_open(CfgHandle* h, int reportErrors, const char* mode){
+ int res;
+ const char *filename;
+ if (!h || !h->filename || !mode) return -1;
+ filename = h->filename;
+ if (filename[0] == '~') {
+ /* Absolute Path of a Users HomeDir */
+ res = cfg_open_user_file (h, filename, reportErrors, mode);
+ } else if (filename[0] == '/') {
+ /* Absolute pathname: try it - there are no alternatives */
+ res = cfg_open_file (h, filename, reportErrors, mode);
+ } else {
+ /* Relative pathname: try current directory first */
+ res = cfg_open_file (h, filename, 0, mode);
+ }
+ return res;
+}
+
+int cfg_open_read (CfgHandle *handle, const char* filename, int err, int cl){
+ if (handle && filename) {
+ int res;
+ res = cfg_handle_change_filename(handle, filename);
+ if (res) return res;
+ res = cfg_open(handle, err, "r");
+ if (res) return res;
+ return cfg_read(handle,cl);
+ }
+ else return -1;
+}
+
+int cfg_close (CfgHandle* h){
+ if (!h || !h->file) return -1;
+ fclose (h->file);
+ h->file = NULL;
+ return 0;
+}
+
+
+/***************************************************
+ * commons
+ ***************************************************/
+
+CfgGroup* cfg_find_group(CfgHandle* h, const char* g){
+ CfgGroup *tmp;
+ if (h == NULL || g == NULL) return NULL;
+ tmp = h->first;
+ while (tmp && strcmp(tmp->name, g) != 0) tmp = tmp->next;
+ return tmp;
+}
+
+CfgKey* cfg_find_key(CfgGroup* g, const char* key){
+ CfgKey* tmp;
+ if (g == NULL || key == NULL) return NULL;
+ tmp = g->first;
+ while (tmp && strcmp(tmp->name, key) != 0) tmp = tmp->next;
+ return tmp;
+}
+
+/***************************************************
+ * cfg_handle_...
+ ***************************************************/
+
+CfgHandle* cfg_handle_new_with_filename (const char* filename, int read){
+ CfgHandle* h;
+ h = (CfgHandle*)malloc(sizeof(CfgHandle));
+ if (!h) return NULL;
+
+ h->filename = filename ? strdup(filename) : NULL;
+ h->file = NULL;
+ h->first = h->last = NULL;
+
+ if (read) {
+ int r = cfg_open_read(h, filename, 0, 1);
+ if (r != 0) {
+ cfg_handle_free(h);
+ return NULL;
+ }
+ }
+
+ return h;
+}
+
+CfgHandle* cfg_handle_new (){
+ return cfg_handle_new_with_filename(NULL,0);
+}
+
+
+int cfg_handle_change_filename(CfgHandle *h, const char* filename){
+ if (h && filename) {
+ if (h->file) return -2;
+ free (h->filename);
+ h->filename = strdup(filename);
+ return 0;
+ }
+ else return -1;
+}
+
+
+int cfg_handle_add_group(CfgHandle* h, CfgGroup* g){
+ if (h && g) {
+ CfgGroup* last = h->last;
+ if (last) {
+ last->next = g;
+ g->prev = last;
+ } else {
+ h->first = g;
+ }
+ h->last = g;
+ g->pp = h;
+ return 0;
+ }
+ else
+ return -1;
+}
+
+void cfg_handle_free (CfgHandle* h){
+ CfgGroup *ga, *gb;
+ CfgKey *ka, *kb;
+ if (!h) return;
+ ga = h->first;
+ if (h->file) fclose (h->file);
+ while (ga){
+ gb = ga->next;
+ ka = ga->first;
+ while (ka) {
+ kb = ka->next;
+ free (ka->name);
+ free (ka->value);
+ free (ka);
+ ka = kb;
+ }
+ free (ga->name);
+ free (ga);
+ ga = gb;
+ }
+ free (h);
+}
+
+
+/***************************************************
+ * cfg_group_...
+ ***************************************************/
+
+int cfg_group_exist(CfgHandle* h, const char* name){
+ if (h == NULL || name == NULL)
+ return -1;
+ else {
+ CfgGroup* tmp = h->first;
+ while (tmp && strcmp(tmp->name,name) != 0 )
+ tmp = tmp->next;
+ if (tmp != NULL) return -1;
+ }
+ return 0;
+}
+
+int cfg_group_new (CfgHandle* handle, const char* name){
+ if (cfg_find_group(handle, name) == NULL) {
+ CfgGroup* g = (CfgGroup*)malloc(sizeof(CfgGroup));
+ if (!g) return -1;
+ g->name = strdup(name);
+ g->prev = NULL;
+ g->next = NULL;
+ g->first = NULL;
+ g->last = NULL;
+ g->pp = NULL;
+ return cfg_handle_add_group(handle, g);
+ } else
+ return -1;
+}
+
+int cfg_group_add_key(CfgGroup* g, CfgKey* k){
+ if (g && k) {
+ CfgKey* last = g->last;
+ if (last) {
+ last->next = k;
+ k->prev = last;
+ } else {
+ g->first = k;
+ }
+
+ g->last = k;
+ k->pp = g;
+ return 0;
+ } else
+ return -1;
+}
+
+void cfg_group_free(CfgHandle* h, const char* name){
+ if (h && name) {
+ CfgGroup *tmp, *prev, *next;
+ CfgKey *a, *b;
+ tmp = cfg_find_group(h, name);
+ if (!tmp) return;
+
+ a = tmp->first;
+ while (a) {
+ b = a->next;
+ free (a->name);
+ free (a->value);
+ free (a);
+ a = b;
+ }
+
+ prev = tmp->prev;
+ next = tmp->next;
+
+ free (tmp->name);
+ if (prev) {
+ prev->next = next;
+ } else {
+ tmp->pp->first= next;
+ }
+
+ if (next) {
+ next->prev = prev;
+ } else {
+ tmp->pp->last = prev;
+ }
+
+ free(tmp);
+ }
+}
+
+/***************************************************
+ * cfg_key_...
+ ***************************************************/
+
+int
+cfg_key_new (CfgHandle* h, const char* g, const char* key)
+{
+ CfgGroup *group;
+ if ((group = cfg_find_group(h, g)) == NULL) return -1;
+ // if (cfg_find_key(group, key) != NULL) return -1;
+ if (h && g && key) {
+ CfgKey* k = (CfgKey*)malloc(sizeof(CfgKey));
+ if (!k) return -1;
+ k->name = strdup(key);
+ k->value = NULL;
+ k->prev = NULL;
+ k->next = NULL;
+ k->pp = NULL;
+ return cfg_group_add_key(group, k);
+ } else
+ return -1;
+}
+
+int
+cfg_key_new_with_value(CfgHandle* h, const char* g, const char* key,
+ const char* value)
+{
+ if (cfg_key_new (h, g, key) == 0) {
+ CfgKey* tmp = cfg_find_group(h, g)->last;
+ if (!tmp) return -1;
+ tmp->value = ((value == NULL) ? NULL : strdup(value));
+ return 0;
+ } else
+ return -1;
+}
+
+int
+cfg_key_set_value(CfgHandle* h, const char* g, const char* key,
+ const char* value)
+{
+ if (h && g && key && value) {
+ CfgKey* tmp = cfg_find_key(cfg_find_group(h,g), key);
+ if (!tmp) return -1;
+ free (tmp->value);
+ tmp->value = ((value == NULL) ? NULL : strdup(value));
+ return 0;
+ } else return -1;
+}
+
+int
+cfg_key_set_uint_value (CfgHandle *h, const char* g, const char* key,
+ unsigned int value)
+{
+ char dest[30];
+ sprintf(dest,"%ud", value);
+ return cfg_key_set_value(h, g, key, dest);
+}
+
+int
+cfg_key_set_int_value (CfgHandle *h, const char* g, const char* key,
+ int value)
+{
+ char dest[30];
+ sprintf(dest,"%d", value);
+ return cfg_key_set_value(h, g, key, dest);
+}
+
+int
+cfg_key_set_double_value (CfgHandle *h, const char* g, const char* key,
+ double value)
+{
+ char dest[30];
+ sprintf(dest,"%e",value);
+ return cfg_key_set_value(h, g, key, dest);
+}
+
+int
+cfg_key_set_float_value (CfgHandle *h, const char* g, const char* key,
+ float value)
+{
+ char dest[30];
+ sprintf(dest,"%f",value);
+ return cfg_key_set_value(h, g, key, dest);
+}
+
+int
+cfg_key_set_bool_value (CfgHandle *h, const char* g, const char* key,
+ bool value)
+{
+ char dest[2];
+ sprintf(dest, "%1d", value);
+ return cfg_key_set_value(h, g, key, dest);
+}
+
+int
+cfg_key_set_char_value (CfgHandle *h, const char* g, const char* key,
+ char value)
+{
+ char dest[2];
+ sprintf(dest, "%c",value);
+ return cfg_key_set_value(h, g, key, dest);
+}
+
+const char*
+cfg_key_get_value(CfgHandle* h, const char* g, const char* key)
+{
+ if (h && g && key) {
+ CfgKey* tmp = cfg_find_key(cfg_find_group(h,g), key);
+ if (!tmp) return NULL;
+ return tmp->value;
+ } else
+ return NULL;
+}
+
+int
+cfg_key_get_value_as_bool(CfgHandle* h, const char* g, const char* key,
+ bool* res){
+ char *endptr;
+ const char *nptr = cfg_key_get_value(h, g, key);
+ if (!nptr) return -1;
+ if (!strcasecmp(nptr, "yes") || !strcasecmp(nptr, "true"))
+ *res = TRUE;
+ else
+ *res = FALSE;
+
+ return (int)*endptr;
+}
+
+int
+cfg_key_get_value_as_uint(CfgHandle* h, const char* g, const char* key,
+ unsigned int* res){
+ char *endptr;
+ const char *nptr = cfg_key_get_value(h, g, key);
+ if (!nptr) return -1;
+ *res = (unsigned int)strtoul(nptr, &endptr, 10);
+ return (int)*endptr;
+}
+
+int
+cfg_key_get_value_as_int(CfgHandle* h, const char* g, const char* key,
+ int* res)
+{
+ char *endptr;
+ const char *nptr = cfg_key_get_value(h, g, key);
+ if (!nptr) return -1;
+ *res = (int)strtol(nptr, &endptr, 10);
+ return (int)*endptr;
+}
+
+int
+cfg_key_get_value_as_ushort(CfgHandle* h, const char* g, const char* key,
+ unsigned short* res)
+{
+ char *endptr;
+ const char *nptr = cfg_key_get_value(h, g, key);
+ if (!nptr) return -1;
+ *res = (unsigned short)strtoul(nptr, &endptr, 10);
+ return (int)*endptr;
+}
+
+int
+cfg_key_get_value_as_short(CfgHandle* h, const char* g, const char* key,
+ short* res)
+{
+ char *endptr;
+ const char *nptr = cfg_key_get_value(h, g, key);
+ if (!nptr) return -1;
+ *res = (short)strtol(nptr, &endptr, 10);
+ return (int)*endptr;
+}
+
+int
+cfg_key_get_value_as_double(CfgHandle* h, const char* g, const char* key,
+ double* res)
+{
+ char *endptr;
+ const char *nptr = cfg_key_get_value(h, g, key);
+ if (!nptr) return -1;
+ *res = (double)strtod(nptr, &endptr);
+ return (int)*endptr;
+}
+
+int
+cfg_key_get_value_as_float(CfgHandle* h, const char* g, const char* key,
+ float* res)
+{
+ char *endptr;
+ const char *nptr = cfg_key_get_value(h, g, key);
+ if (!nptr) return -1;
+ *res = (float)strtod(nptr, &endptr);
+ return (int)*endptr;
+}
+
+void
+cfg_key_free (CfgHandle* h, const char* g, const char* key)
+{
+ if (h && g && key) {
+ CfgKey *tmp, *prev, *next;
+ tmp = cfg_find_key(cfg_find_group(h,g), key);
+ if (!tmp) return;
+ prev = tmp->prev;
+ next = tmp->next;
+
+ free (tmp->name);
+ free (tmp->value);
+
+ if (prev) {
+ prev->next = next;
+ } else {
+ tmp->pp->first = next;
+ }
+
+ if (next) {
+ next->prev = prev;
+ } else {
+ tmp->pp->last = prev;
+ }
+
+ free (tmp);
+ }
+}
+
+void
+cfg_key_for_each (CfgHandle* h, const char* grp, cfg_key_func func)
+{
+ CfgGroup *tmp = cfg_find_group(h,grp);
+
+ if (tmp && func) {
+ CfgKey *k = tmp->first;
+ while(k) func(k), k = k->next;
+ }
+}
diff --git a/mpiosh/cfgio.h b/mpiosh/cfgio.h
new file mode 100644
index 0000000..d58cd3f
--- /dev/null
+++ b/mpiosh/cfgio.h
@@ -0,0 +1,453 @@
+/* configreader and -writer
+ *
+ * Source in ANSI C, except function strdup
+ * needs _BSD_SOURCE or _SVID_SOURCE defined, if compiled ANSI
+ * Thomas Buntrock (bunti@tzi.de)
+ *
+ * Comments in configfile are allowed, but ONLY at the BEGINNING of a line
+ * When reading a config then writing the same, all comments will be removed
+ *
+ * The groupname MUST be put exactly between two square braces, e.g. [Name].
+ * Any Spaces in between are interpreted as part of the name.
+ *
+ * Keys and their value are separated by "=". Leading and following spaces
+ * are removed.
+ * Spaces right before and after the "=" are removed. Spaces in the value
+ * will remain.
+ * Keys without value are accepted, BUT the "=" is MANDATORY.
+ *
+ * A config line MUST NOT be longer than _CFG_MAX_LINE_SIZE (default: 256)
+ *
+ */
+
+#ifndef _CFG_IO_H
+#define _CFG_IO_H
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include <sys/types.h>
+#include <ctype.h>
+
+#define _CFG_MAX_LINE_SIZE 256
+
+/* define bool */
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+typedef unsigned char bool;
+
+struct _CFG_Key {
+ char *name;
+ char *value;
+ struct _CFG_Key* prev;
+ struct _CFG_Key* next;
+ struct _CFG_Group* pp;
+};
+
+struct _CFG_Group {
+ char *name;
+ struct _CFG_Group* prev;
+ struct _CFG_Group* next;
+ struct _CFG_Key* first;
+ struct _CFG_Key* last;
+ struct _CFG_Handle* pp;
+};
+
+struct _CFG_Handle {
+ FILE *file;
+ char *filename;
+ struct _CFG_Group *first;
+ struct _CFG_Group *last;
+};
+
+
+typedef struct _CFG_Key CfgKey;
+typedef struct _CFG_Group CfgGroup;
+typedef struct _CFG_Handle CfgHandle;
+typedef int (*cfg_key_func)(CfgKey *key);
+
+char *cfg_resolve_path(const char *filename);
+
+/*
+ * files: a list of files
+ * e.g. char *files[] = { ".blarc", ".bla", "blarc", NULL };
+ *
+ * paths: a list of paths
+ * e.g. char *paths[] = { "~/", "/etc/" "etc/", NULL};
+ *
+ * select the first path and iterates through the files,
+ * then select the next path...
+ *
+ * returns the first match of: path/file
+ */
+char *cfg_find_file (char **files, char **paths);
+
+/*
+ * Save the config
+ *
+ * close: close the file after saving
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_save (CfgHandle *handle, int close);
+
+/*
+ * Save the config with another filename
+ *
+ * handle : the config handle
+ * filename : the new filename
+ * reportErrors: 0 does not report errors the stderr
+ * close : close the file after saving
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_save_as (CfgHandle *handle, const char* filename,
+ int reportErrors, int close);
+/*
+ * Read config file
+ * requires the Handle to be associated to a file and being opened
+ *
+ * handle: the config handle
+ * close : close the file after reading
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_read (CfgHandle *handle, int close);
+
+/*
+ * Open a file to read or save
+ *
+ * handle : the config handle
+ * reportErrors: write errors to stderr
+ * mode : the mode the file should be opened with (man 3 fopen)
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_open (CfgHandle *handle, int reportErrors,
+ const char* mode);
+/*
+ * Open a file in read mode
+ *
+ * handle : the config handle
+ * filename : the filename of the config file
+ * reportErrors: write errors to stderr
+ * close : close the file after reading
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_open_read (CfgHandle *handle, const char* filename,
+ int reportErrors, int close);
+/*
+ * Close the file
+ *
+ * h: the config handle
+ *
+ * returns 0 on success or -1 if the handle was NULL or the was already closed
+ */
+int cfg_close (CfgHandle *h);
+
+/*
+ * Create a new empty file handle
+ *
+ * returns the pointer to the new handle
+ */
+CfgHandle* cfg_handle_new ();
+
+/*
+ * Create a new filehandle
+ *
+ * filename: the filename of the configfile
+ * read : read the config file
+ *
+ * returns the pointer to the new handle
+ */
+CfgHandle* cfg_handle_new_with_filename (const char* filename, int read);
+
+/*
+ * Change the filename of the config file
+ * only the internal filename ist changed, to apply on disk you need to call
+ * cfg_save
+ *
+ * filename: new filename
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_handle_change_filename (CfgHandle *h, const char* filename);
+
+/*
+ * Delete the handle
+ * An opened file will be closed
+ *
+ * h: the config handle
+ */
+void cfg_handle_free (CfgHandle* h);
+
+/*
+ * Create a new group within the config
+ *
+ * handle: the config handle
+ * name : name of the group
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_group_new (CfgHandle* handle, const char* name);
+
+/*
+ * Delete a group within the config
+ * All keys within this group will be delete as well
+ *
+ * handle: the config handle
+ * name : the name of the group
+ */
+void cfg_group_free (CfgHandle* handle, const char* name);
+
+/*
+ * returns a handle to the group g if found.
+ *
+ * handle: the config handle
+ * name : the name of the group to search for
+ */
+CfgGroup* cfg_find_group(CfgHandle* h, const char* g);
+
+/*
+ * Create a new key within a group within the config
+ *
+ * h : the config handle
+ * g : name of the group
+ * key: name of the key
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_key_new (CfgHandle* h, const char* g, const char* key);
+
+/*
+ * Create a new key within the group within the config and set its value
+ *
+ * h : the config handle
+ * g : name of the group
+ * key : name of the key
+ * value: value for the key
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_key_new_with_value (CfgHandle* h, const char* g, const char* key,
+ const char* value);
+
+/*
+ * Set the value for a specific key within a group of the config
+ *
+ * h : the config handle
+ * g : name of the group
+ * key : name of the key
+ * value: value for the key
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_key_set_value (CfgHandle* h, const char* g, const char* key,
+ const char* value);
+
+/*
+ * Set the value for a specific key within a group of the config
+ *
+ * h : the config handle
+ * g : name of the group
+ * key : name of the key
+ * value: value for the key
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_key_set_uint_value (CfgHandle *h, const char* g, const char* key,
+ unsigned int value);
+
+/*
+ * Set the value for a specific key within a group of the config
+ *
+ * h : the config handle
+ * g : name of the group
+ * key : name of the key
+ * value: value for the key
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_key_set_int_value (CfgHandle *h, const char* g, const char* key,
+ int value);
+
+/*
+ * Set the value for a specific key within a group of the config
+ *
+ * h : the config handle
+ * g : name of the group
+ * key : name of the key
+ * value: value for the key
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_key_set_double_value (CfgHandle *h, const char* g, const char* key,
+ double value);
+
+/*
+ * Set the value for a specific key within a group of the config
+ *
+ * h : the config handle
+ * g : name of the group
+ * key : name of the key
+ * value: value for the key
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_key_set_float_value (CfgHandle *h, const char* g, const char* key,
+ float value);
+
+/*
+ * Set the value for a specific key within a group of the config
+ *
+ * h : the config handle
+ * g : name of the group
+ * key : name of the key
+ * value: value for the key
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_key_set_bool_value (CfgHandle *h, const char* g, const char* key,
+ bool value);
+
+/*
+ * Set the value for a specific key within a group of the config
+ *
+ * h : the config handle
+ * g : name of the group
+ * key : name of the key
+ * value: value for the key
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_key_set_char_value (CfgHandle *h, const char* g, const char* key,
+ char value);
+
+/*
+ * Delete a key of a group within the config
+ *
+ * h : the config handle
+ * g : name of the group
+ * key : name of the key
+ */
+void cfg_key_free (CfgHandle* h, const char* g, const char* key);
+
+/*
+ * Get the value of a key within a group of the config
+ *
+ * h : the config handle
+ * g : name of the group
+ * key: name of the key
+ * res: the result will be stored in this variable
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_key_get_value_as_bool (CfgHandle* h, const char* g, const char* key,
+ bool *res);
+
+/*
+ * Get the value of a key within a group of the config
+ *
+ * h : the config handle
+ * g : name of the group
+ * key: name of the key
+ * res: the result will be stored in this variable
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_key_get_value_as_uint (CfgHandle* h, const char* g, const char* key,
+ unsigned int *res);
+
+/*
+ * Get the value of a key within a group of the config
+ *
+ * h : the config handle
+ * g : name of the group
+ * key: name of the key
+ * res: the result will be stored in this variable
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_key_get_value_as_int (CfgHandle* h, const char* g, const char* key,
+ int *res);
+
+/*
+ * Get the value of a key within a group of the config
+ *
+ * h : the config handle
+ * g : name of the group
+ * key: name of the key
+ * res: the result will be stored in this variable
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_key_get_value_as_ushort (CfgHandle* h, const char* g, const char* key,
+ unsigned short *res);
+
+/*
+ * Get the value of a key within a group of the config
+ *
+ * h : the config handle
+ * g : name of the group
+ * key: name of the key
+ * res: the result will be stored in this variable
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_key_get_value_as_short (CfgHandle* h, const char* g, const char* key,
+ short *res);
+
+/*
+ * Get the value of a key within a group of the config
+ *
+ * h : the config handle
+ * g : name of the group
+ * key: name of the key
+ * res: the result will be stored in this variable
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_key_get_value_as_double (CfgHandle* h, const char* g, const char* key,
+ double *res);
+
+/*
+ * Get the value of a key within a group of the config
+ *
+ * h : the config handle
+ * g : name of the group
+ * key: name of the key
+ * res: the result will be stored in this variable
+ *
+ * returns 0 on success or -1 on failure
+ */
+int cfg_key_get_value_as_float (CfgHandle* h, const char* g, const char* key,
+ float *res);
+
+/*
+ * Get the value of a key within a group of the config
+ *
+ * h : the config handle
+ * g : name of the group
+ * key: name of the key
+ *
+ * returns the value of the key or NULL if empty
+ */
+const char* cfg_key_get_value (CfgHandle* h, const char* g, const char* key);
+
+/*
+ * iterators through key value pairs of a group
+ *
+ * h : the config handle
+ * grp : name of the group
+ * func: pointer to the function to call with each element
+ *
+ * returns the value of the key or NULL if empty
+ */
+void cfg_key_for_each (CfgHandle* h, const char* grp, cfg_key_func func);
+#endif /* _CFG_IO_H */
diff --git a/mpiosh/command.c b/mpiosh/command.c
index 338ee8d..9c42a8c 100644
--- a/mpiosh/command.c
+++ b/mpiosh/command.c
@@ -2,7 +2,7 @@
*
* Author: Andreas Buesching <crunchy@tzi.de>
*
- * $Id: command.c,v 1.2 2002/10/12 20:06:22 crunchy Exp $
+ * $Id: command.c,v 1.3 2002/10/29 20:03:35 crunchy Exp $
*
* Copyright (C) 2001 Andreas Büsching <crunchy@tzi.de>
*
@@ -64,10 +64,10 @@ mpiosh_command_split_line(char *line)
return cmds;
}
-mpiosh_cmd_t *
+struct mpiosh_cmd_t *
mpiosh_command_find(char *line)
{
- mpiosh_cmd_t *cmd = commands;
+ struct mpiosh_cmd_t *cmd = commands;
while (cmd->cmd) {
if (strstr(line, cmd->cmd) == line) {
diff --git a/mpiosh/command.h b/mpiosh/command.h
index 1374385..34dbc9b 100644
--- a/mpiosh/command.h
+++ b/mpiosh/command.h
@@ -2,7 +2,7 @@
*
* Author: Andreas Buesching <crunchy@tzi.de>
*
- * $Id: command.h,v 1.1 2002/10/12 18:31:45 crunchy Exp $
+ * $Id: command.h,v 1.2 2002/10/29 20:03:35 crunchy Exp $
*
* Copyright (C) 2001 Andreas Büsching <crunchy@tzi.de>
*
@@ -27,7 +27,7 @@
#include "mpiosh.h"
/* command(-line) functions */
-mpiosh_cmd_t *mpiosh_command_find(char *line);
+struct mpiosh_cmd_t *mpiosh_command_find(char *line);
char **mpiosh_command_split_line(char *line);
char **mpiosh_command_get_args(char *line);
void mpiosh_command_regex_fix(char *argv[]);
diff --git a/mpiosh/config.c b/mpiosh/config.c
new file mode 100644
index 0000000..330bfea
--- /dev/null
+++ b/mpiosh/config.c
@@ -0,0 +1,162 @@
+/* config.c
+ *
+ * Author: Andreas Buesching <crunchy@tzi.de>
+ *
+ * $Id: config.c,v 1.1 2002/10/29 20:03:35 crunchy Exp $
+ *
+ * Copyright (C) 2001 Andreas Büsching <crunchy@tzi.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "global.h"
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+struct mpiosh_config_t *
+mpiosh_config_new(void)
+{
+ struct mpiosh_config_t * cfg = malloc(sizeof(struct mpiosh_config_t));
+ char *filename;
+ char *tmp;
+ struct stat st;
+
+ cfg->prompt_int = cfg->prompt_ext = NULL;
+ cfg->default_mem = MPIO_INTERNAL_MEM;
+
+ filename = malloc(strlen(CONFIG_GLOBAL) + strlen(CONFIG_FILE) + 1);
+ filename[0] = '\0';
+ strcat(filename, CONFIG_GLOBAL);
+ strcat(filename, CONFIG_FILE);
+ tmp = cfg_resolve_path(filename);
+
+ if (stat(tmp, &st) != -1)
+ cfg->handle_global =
+ cfg_handle_new_with_filename(tmp, 1);
+
+ free(tmp), free(filename);
+ filename = malloc(strlen(CONFIG_USER) + strlen(CONFIG_FILE) + 1);
+ filename[0] = '\0';
+ strcat(filename, CONFIG_USER);
+ strcat(filename, CONFIG_FILE);
+ tmp = cfg_resolve_path(filename);
+
+ if (stat(tmp, &st) != -1)
+ cfg->handle_user =
+ cfg_handle_new_with_filename(tmp, 1);
+ else
+ cfg->handle_user =
+ cfg_handle_new_with_filename(tmp, 0);
+
+ free(tmp), free(filename);
+
+ return cfg;
+}
+
+const char *
+mpiosh_config_read_key(struct mpiosh_config_t *config, const char *group,
+ const char *key)
+{
+ char *value = NULL;
+
+ if (config->handle_user)
+ value = (char *)cfg_key_get_value(config->handle_user,
+ group, key);
+ else if (config->handle_global)
+ value = (char *)cfg_key_get_value(config->handle_global,
+ group, key);
+
+ return value;
+}
+
+void
+mpiosh_config_free(struct mpiosh_config_t *config)
+{
+ cfg_close(config->handle_global);
+ cfg_close(config->handle_user);
+ free(config->prompt_int);
+ free(config->prompt_ext);
+ free(config);
+}
+
+int
+mpiosh_config_read(struct mpiosh_config_t *config)
+{
+ if (config) {
+ const char *value;
+
+ value = mpiosh_config_read_key(config, "mpiosh", "prompt_int");
+ if (value) {
+ config->prompt_int = strdup(value);
+ } else {
+ config->prompt_int = strdup(PROMPT_INT);
+ }
+
+ value = mpiosh_config_read_key(config, "mpiosh", "prompt_ext");
+ if (value) {
+ config->prompt_ext = strdup(value);
+ } else {
+ config->prompt_ext = strdup(PROMPT_EXT);
+ }
+
+ value = mpiosh_config_read_key(config, "mpiosh", "default_mem");
+ if (value) {
+ if (!strcmp("internal", value)) {
+ config->default_mem = MPIO_INTERNAL_MEM;
+ } else if (!strcmp("external", value)) {
+ config->default_mem = MPIO_EXTERNAL_MEM;
+ }
+ }
+ }
+
+ return 1;
+}
+
+int
+mpiosh_config_write(struct mpiosh_config_t *config)
+{
+ DIR *dir;
+ char *path = cfg_resolve_path(CONFIG_USER);
+
+ if ((dir = opendir(path)) == NULL)
+ mkdir(path, 0777);
+ else
+ closedir(dir);
+
+ free(path);
+
+ if (config->handle_user) {
+ cfg_key_set_value(config->handle_user,
+ "mpiosh", "prompt_int", config->prompt_int);
+ cfg_key_set_value(config->handle_user,
+ "mpiosh", "prompt_ext", config->prompt_ext);
+ if (config->default_mem == MPIO_EXTERNAL_MEM)
+ cfg_key_set_value(config->handle_user,
+ "mpiosh", "default_mem", "external");
+ else
+ cfg_key_set_value(config->handle_user,
+ "mpiosh", "default_mem", "internal");
+
+ cfg_save(config->handle_user, 0);
+ }
+
+ return 1;
+}
+
+
+/* end of config.c */
diff --git a/mpiosh/config.h b/mpiosh/config.h
new file mode 100644
index 0000000..24ca437
--- /dev/null
+++ b/mpiosh/config.h
@@ -0,0 +1,48 @@
+/* config.h
+ *
+ * Author: Andreas Buesching <crunchy@tzi.de>
+ *
+ * $Id: config.h,v 1.1 2002/10/29 20:03:35 crunchy Exp $
+ *
+ * Copyright (C) 2001 Andreas Büsching <crunchy@tzi.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef MPIOSH_CONFIG_HH
+#define MPIOSH_CONFIG_HH
+
+#include "cfgio.h"
+
+struct mpiosh_config_t {
+ CfgHandle *handle_global;
+ CfgHandle *handle_user;
+
+ char *prompt_int;
+ char *prompt_ext;
+ unsigned default_mem;
+};
+
+struct mpiosh_config_t *mpiosh_config_new(void);
+void mpiosh_config_free(struct mpiosh_config_t *config);
+
+const char *mpiosh_config_read_key(struct mpiosh_config_t *config,
+ const char *group, const char *key);
+int mpiosh_config_read(struct mpiosh_config_t *config);
+int mpiosh_config_write(struct mpiosh_config_t *config);
+
+#endif
+
+/* end of config.h */
diff --git a/mpiosh/global.c b/mpiosh/global.c
index d300f62..554652e 100644
--- a/mpiosh/global.c
+++ b/mpiosh/global.c
@@ -2,7 +2,7 @@
*
* Author: Andreas Buesching <crunchy@tzi.de>
*
- * $Id: global.c,v 1.4 2002/10/27 02:45:28 germeier Exp $
+ * $Id: global.c,v 1.5 2002/10/29 20:03:35 crunchy Exp $
*
* Copyright (C) 2001 Andreas Büsching <crunchy@tzi.de>
*
@@ -26,17 +26,24 @@
#include "readline.h"
/* structure containing current state */
-mpiosh_t mpiosh;
+struct mpiosh_t mpiosh;
+struct mpiosh_config_t config;
/* flag indicating a user-interrupt of the current command */
-int mpiosh_cancel = 0;
-int mpiosh_cancel_ack = 0;
+int mpiosh_cancel = 0;
+int mpiosh_cancel_ack = 0;
+
+/* configuration filenames */
+const char *CONFIG_GLOBAL = SYSCONFDIR "/mpio/";
+const char *CONFIG_USER = "~/.mpio/";
+const char *CONFIG_FILE = "mpioshrc";
+const char *CONFIG_HISTORY = "~/.mpio/mpiosh_history";
/* prompt strings */
-const char *PROMPT_INT = "\033[;1mmpio <i>\033[m ";
-const char *PROMPT_EXT = "\033[;1mmpio <e>\033[m ";
+const char *PROMPT_INT = "\033[;1mmpio <i>\033[m ";
+const char *PROMPT_EXT = "\033[;1mmpio <e>\033[m ";
-mpiosh_cmd_t commands[] = {
+struct mpiosh_cmd_t commands[] = {
{ "debug", NULL , "[level|file|on|off] <value>",
" modify debugging options",
mpiosh_cmd_debug, NULL },
diff --git a/mpiosh/global.h b/mpiosh/global.h
index 4800d68..a807c4a 100644
--- a/mpiosh/global.h
+++ b/mpiosh/global.h
@@ -2,7 +2,7 @@
*
* Author: Andreas Buesching <crunchy@tzi.de>
*
- * $Id: global.h,v 1.1 2002/10/12 20:06:22 crunchy Exp $
+ * $Id: global.h,v 1.2 2002/10/29 20:03:35 crunchy Exp $
*
* Copyright (C) 2001 Andreas Büsching <crunchy@tzi.de>
*
@@ -26,31 +26,39 @@
#include "libmpio/mpio.h"
+#include "config.h"
+
/* type definitions */
typedef void(*mpiosh_cmd_callback_t)(char *args[]);
typedef char *(*mpiosh_comp_callback_t)(const char *text, int state);
-typedef struct {
- mpio_t * dev;
- mpio_mem_t card;
- const char * prompt;
-} mpiosh_t;
+struct mpiosh_t {
+ mpio_t * dev;
+ mpio_mem_t card;
+ const char * prompt;
+ struct mpiosh_config_t *config;
+};
-typedef struct {
- char * cmd;
- char ** aliases;
- char * args;
- char * info;
+struct mpiosh_cmd_t {
+ char *cmd;
+ char **aliases;
+ char *args;
+ char *info;
mpiosh_cmd_callback_t cmd_func;
mpiosh_comp_callback_t comp_func;
-} mpiosh_cmd_t;
+};
/* global structures */
-extern mpiosh_t mpiosh;
-extern mpiosh_cmd_t commands[];
+extern struct mpiosh_t mpiosh;
+extern struct mpiosh_cmd_t commands[];
extern int mpiosh_cancel;
extern int mpiosh_cancel_ack;
+extern const char *CONFIG_GLOBAL;
+extern const char *CONFIG_USER;
+extern const char *CONFIG_FILE;
+extern const char *CONFIG_HISTORY;
+
extern const char *PROMPT_INT;
extern const char *PROMPT_EXT;
diff --git a/mpiosh/mpiosh.c b/mpiosh/mpiosh.c
index f5896a5..5ed1faa 100644
--- a/mpiosh/mpiosh.c
+++ b/mpiosh/mpiosh.c
@@ -2,7 +2,7 @@
/*
*
- * $Id: mpiosh.c,v 1.20 2002/10/12 20:06:22 crunchy Exp $
+ * $Id: mpiosh.c,v 1.21 2002/10/29 20:03:35 crunchy Exp $
*
* Author: Andreas Büsching <crunchy@tzi.de>
*
@@ -26,6 +26,7 @@
* */
#include <signal.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
@@ -34,6 +35,7 @@
#include "callback.h"
#include "command.h"
+#include "config.h"
#include "readline.h"
#include "mpiosh.h"
@@ -41,9 +43,26 @@
void
mpiosh_init(void)
{
+ /* set state */
mpiosh.dev = NULL;
- mpiosh.card = MPIO_INTERNAL_MEM;
- mpiosh.prompt = PROMPT_INT;
+ mpiosh.config = NULL;
+ mpiosh.prompt = NULL;
+
+ /* read configuration */
+ mpiosh.config = mpiosh_config_new();
+ if (mpiosh.config)
+ mpiosh_config_read(mpiosh.config);
+
+ mpiosh.card = mpiosh.config->default_mem;
+ if (mpiosh.config->default_mem == MPIO_EXTERNAL_MEM)
+ mpiosh.prompt = mpiosh.config->prompt_ext;
+ else
+ mpiosh.prompt = mpiosh.config->prompt_int;
+
+ /* inital mpio library */
+ mpiosh.dev = mpio_init(mpiosh_callback_init);
+
+ printf("\n");
}
void
@@ -55,9 +74,9 @@ mpiosh_signal_handler(int signal)
int
main(int argc, char *argv[]) {
- char * line;
- char ** cmds, **walk;
- mpiosh_cmd_t * cmd;
+ char *line;
+ char **cmds, **walk;
+ struct mpiosh_cmd_t *cmd;
struct sigaction sigc;
int interactive = 1;
@@ -80,13 +99,6 @@ main(int argc, char *argv[]) {
debug_init();
mpiosh_init();
- mpiosh.dev = mpio_init(mpiosh_callback_init);
- printf("\n");
-
- if (mpiosh.card == MPIO_INTERNAL_MEM)
- mpiosh.prompt = PROMPT_INT;
- else
- mpiosh.prompt = PROMPT_EXT;
if (!isatty(fileno(stdin))) {
interactive = 0;
diff --git a/mpiosh/readline.c b/mpiosh/readline.c
index cd72591..8b97219 100644
--- a/mpiosh/readline.c
+++ b/mpiosh/readline.c
@@ -2,7 +2,7 @@
*
* Author: Andreas Büsching <crunchy@tzi.de>
*
- * $Id: readline.c,v 1.4 2002/10/18 08:39:23 crunchy Exp $
+ * $Id: readline.c,v 1.5 2002/10/29 20:03:35 crunchy Exp $
*
* Copyright (C) 2001 Andreas Büsching <crunchy@tzi.de>
*
@@ -41,10 +41,9 @@ mpiosh_readline_init(void)
char *
mpiosh_readline_comp_cmd(const char *text, int state)
{
- static mpiosh_cmd_t * cmd = NULL;
- static char ** alias = NULL;
-
- char *cmd_text = NULL;
+ static struct mpiosh_cmd_t *cmd = NULL;
+ static char **alias = NULL;
+ char *cmd_text = NULL;
if (state == 0) {
cmd = commands;
@@ -123,9 +122,17 @@ mpiosh_readline_comp_mpio_file(const char *text, int state)
char *
mpiosh_readline_comp_config(const char *text, int state)
{
- char *arg = NULL;
+ static char *args[] = { "put", "write", "show", NULL };
+ static char **arg = NULL;
+ char *res = NULL;
+
+ if (state == 0) arg = args;
+ if (*arg && (strstr(*arg, text) == *arg)) {
+ res = strdup(*arg);
+ arg++;
+ }
- return arg;
+ return res;
}
@@ -139,7 +146,7 @@ mpiosh_readline_completion(const char *text, int start, int end)
if (start == 0) /* command completion */
matches = rl_completion_matches(text, mpiosh_readline_comp_cmd);
else {
- mpiosh_cmd_t *scmd;
+ struct mpiosh_cmd_t *scmd;
char *cmd, *help= rl_line_buffer;
while (*help != ' ') help++;