/* vi: set sw=4 ts=4: */ /* * KON2 - Kanji ON Console - * Copyright (C) 1992-1996 Takashi MANABE (manabe@papilio.tutics.tut.ac.jp) * * CCE - Console Chinese Environment - * Copyright (C) 1998-2003 Rui He (rhe@3eti.com) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include #include #include #include #include #undef DEBUG /* Rui He, we are not debugging CAP */ #define BUF_SIZE 2048 #define MAX_CAPS 30 static struct capability { char *name; /* Name of capability label */ initializer *func; /* Function to perform configuration */ int initialized; /* 1 if initialized */ char *arg; /* Command line argument for this capability. */ char *def_value; /* Default value. NULL means required entry. */ } cap[MAX_CAPS]; static struct capability *FindCap(const char *name) { int i; struct capability *cp; for (i = 0, cp = cap; i < MAX_CAPS; i++, cp++) { if ((cp->name != NULL) && (strcasecmp(name, cp->name) == 0)) return cp; } return NULL; } void DefineCap(const char *name, initializer *func, const char *def_value) { int i; struct capability *cp; if ((cp = FindCap(name)) != NULL) { #ifdef DEBUG fprintf(stderr, "cap %s redefined (default %s)\r\n", name, def_value ? def_value : "None"); #endif if (cp->name) free(cp->name); /* Added by security patch */ cp->name = strdup(name); cp->func = func; if (cp->def_value) free(cp->def_value); /* Added by security patch */ if (def_value) cp->def_value = strdup(def_value); return; } for (i = 0, cp = cap; i < MAX_CAPS; i++, cp++) { if (cp->name == NULL) { #ifdef DEBUG fprintf(stderr, "cap %s defined (default %s)\r\n", name, def_value ? def_value : "None"); #endif cp->name = strdup(name); cp->func = func; if (def_value) cp->def_value = strdup(def_value); return; } } fprintf(stderr, "Fatal: internal error - can't find room for capability `%s'\r\r\n", name); abort(); } void CapInit(void) { struct capability *cp; int i; for (i = 0, cp = cap; i < MAX_CAPS; i++, cp++) { #ifdef DEBUG if (cp->name) fprintf(stderr, "cap %s deleted\r\n", cp->name); #endif cp->initialized = 0; if (cp->name) free(cp->name); if (cp->arg) free(cp->arg); if (cp->def_value) free(cp->def_value); cp->name = cp->arg = cp->def_value = NULL; } } static const char label_delim[] = ":,; \t\n"; int ReadConfig(const char *filename) { FILE *capFp; char line[MAX_COLS], *p; char buf[BUF_SIZE]; struct capability *c; int i; int errors = 0; /* number of errors during configuration */ if ((capFp = fopen(filename, "r")) == NULL) { fprintf(stderr, "Error: can't open config file\r\r\n"); perror(filename); return FAILURE; } while(fgets(line, MAX_COLS, capFp) != NULL) { nextLabel: if ((p = strchr(line, '#')) != NULL) *p = '\0'; if (strchr(line, ':') == NULL) continue; /* not a label */ for (p = strtok(line, label_delim); p != NULL; p = strtok(NULL, label_delim)) { if ((c = FindCap(p)) != NULL) { char *l = buf; while (fgets(line, MAX_COLS, capFp) != NULL && line[0] == '\t') { char *l2 = line; while (*l2 != '\n' && *l2 != '#') { *l++ = *l2++; } *l++ = '\n'; } *l = '\0'; if (! c->initialized) { if (c->arg) { #ifdef DEBUG fprintf(stderr, "Capability %s set to arg %s\r\n", c->name, c->arg); #endif if (c->func(c->arg) < 0) errors++; } else { #ifdef DEBUG fprintf(stderr, "Capability %s set to %s", c->name, buf); #endif if (c->func(buf) < 0) errors++; } c->initialized = 1; } goto nextLabel; /* next line already read */ } } } for (i = 0, c = cap; i < MAX_CAPS; i++, c++) { if ((c->name != NULL) && !c->initialized) { if (c->arg) { #ifdef DEBUG fprintf(stderr, "Capability %s defaults to arg %s\r\n", c->name, c->arg); #endif if (c->func(c->arg) < 0) errors++; } else if (c->def_value) { #ifdef DEBUG fprintf(stderr, "Capability %s defaults to %s\r\n", c->name, c->def_value); #endif if (c->func(c->def_value) < 0) errors++; } else { fprintf(stderr, "Error: entry for capability `%s' not found\r\r\n", c->name); errors++; } } } fclose(capFp); #ifdef DEBUG fprintf(stderr, "Finished reading config file\r\n"); #endif if (errors) return FAILURE; else return SUCCESS; } int SetCapArg(const char *capName, const char *value) { struct capability *cp; if ((cp = FindCap(capName)) == NULL) { return FAILURE; } if (cp->def_value == NULL) { return FAILURE; } if (cp->arg) free(cp->arg); cp->arg = strdup(value); #ifdef DEBUG fprintf(stderr, "Setting arg for %s to %s\r\n", capName, value); #endif return SUCCESS; } bool BoolConf(const char *confstr) { char name[MAX_COLS]; sscanf(confstr, "%255s", name); if (strcasecmp(name, "On") == 0 || strcasecmp(name, "True") == 0) { return TRUE; } else if (strcasecmp(name, "Off") != 0 && strcasecmp(name, "False") != 0) { fprintf(stderr, "Warning: value `%s' unrecognized as boolean; assuming `Off'\r\r\n", name); } return FALSE; } char *skip_space(char *p) { while (*p == ' ' || *p == '\t') p++; return p; } char *to_space(char *p) { while(*p && *p != ' ' && *p != '\t' && *p != '\n' && *p != '\r' && *p != '#') p++; /* skip to the next space */ return p; }