aboutsummaryrefslogtreecommitdiffstats
path: root/conf.c
diff options
context:
space:
mode:
Diffstat (limited to 'conf.c')
-rw-r--r--conf.c336
1 files changed, 336 insertions, 0 deletions
diff --git a/conf.c b/conf.c
new file mode 100644
index 0000000..1e1fb03
--- /dev/null
+++ b/conf.c
@@ -0,0 +1,336 @@
+#include "config.h"
+#include "conf.h"
+#include "err.h"
+#include "strutil.h"
+
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+RCSID("$Id: conf.c,v 1.2 2000/02/22 22:50:33 shmit Exp $");
+
+/* Granularity to use when dynamically allocating storage. */
+const int MALLOC_GRANULARITY = 4;
+
+/* TODO: GC configuration and disklist. */
+
+config_t configuration[] = {
+ { MANAGER, STROPT, 0, -1 },
+ { LOGDIR, STROPT, 0, -1 },
+ { INFOLOG, STROPT, 0, -1 },
+ { ERRORLOG, STROPT, 0, -1 },
+ { HOSTLIST, STROPT, 0, -1 },
+ { TIMEOUT, NUMOPT, 0, -1 },
+ { RETRIES, NUMOPT, 0, -1 },
+ { SPOOLDIR, STROPT, 0, -1 },
+ { SPOOLSIZE, NUMOPT, 0, -1 },
+ { TAPEDEV, STROPT, 0, -1 },
+ { TAPESIZE, NUMOPT, 0, -1 },
+ { LABELSTR, STROPT, 0, -1 },
+ { PORTOPT, NUMOPT, 0, -1 },
+ { 0, 0, 0, 0 }
+};
+
+dump_t *dumptypes = NULL;
+int numtypes = 0;
+
+static config_t *
+find_option(const char *name)
+{
+ config_t *p = configuration;
+
+ while (p->name) {
+ if (!strcmp(name, p->name))
+ break;
+ p++;
+ }
+
+ if (!p->name)
+ return NULL;
+
+ return p;
+}
+
+/*
+ * I really hate this sort of code, but I really hate what I'd have
+ * to do without it.
+ */
+const config_t *
+findopt(const char *name)
+{
+ config_t *p;
+
+ p = find_option(name);
+ if (!p || p->numvalue == -1)
+ return NULL;
+
+ return p;
+}
+
+int
+read_config(const char *config_filen)
+{
+ FILE *config_file;
+ char buffer[MAXLINE];
+ int lineno = 0;
+
+ config_file = fopen(config_filen, "r");
+ if (!config_file) {
+ perror("Error: Couldn't open config file");
+ return -1;
+ }
+
+ while (fgets(buffer, sizeof(buffer), config_file)) {
+ config_t *optptr;
+ char *index;
+ char option[MAXLINE], optarg[MAXLINE];
+
+ lineno++;
+ index = getword(buffer, option);
+ if (!index)
+ continue;
+
+ index = getword(index, optarg);
+ if (!index) {
+ fprintf(stderr,
+ "Error: option `%s' has no argument"
+ " on line %d.\n",
+ option, lineno);
+ return -1;
+ }
+
+ optptr = find_option(option);
+ if (!optptr) {
+ fprintf(stderr,
+ "Error: option `%s' on line %d"
+ " doesn't exist.\n",
+ option, lineno);
+ return -1;
+ }
+
+ switch (optptr->type) {
+ case STROPT:
+ index = malloc(sizeof(char)*strlen(optarg));
+ if (!index) {
+ perror("Error: couldn't malloc");
+ return -1;
+ }
+
+ strcpy(index, optarg);
+ optptr->strvalue = index;
+ optptr->numvalue = 0;
+ break;
+ case NUMOPT:
+ optptr->numvalue = strtol(optarg, &index, 10);
+ if (*index) {
+ fprintf(stderr,
+ "Error: value `%s' on line %d is not"
+ " a number.\n",
+ optarg, lineno);
+ return -1;
+ }
+ break;
+ }
+ }
+
+ fclose(config_file);
+ return 0;
+}
+
+/*
+ * Find a dumptype with a given name.
+ */
+const dump_t *
+find_dumptype(const char *name)
+{
+ int i;
+
+ for (i = 0; i < numtypes; i++) {
+ if (!strncmp(dumptypes[i].d_name, name,
+ sizeof(dumptypes[i].d_name)))
+ return &dumptypes[i];
+ }
+ return NULL;
+}
+
+/*
+ * Read the dumptypes out of the configuration file.
+ */
+int
+read_dumptypes(const char *filen)
+{
+ FILE *list;
+ char buffer[MAXLINE];
+
+ list = fopen(filen, "r");
+ if (!list) {
+ err("Couldn't open dumptypes `%s': %s.\n",
+ filen, strerror(errno));
+ return -1;
+ }
+
+ dumptypes = malloc(sizeof(dump_t) * MALLOC_GRANULARITY);
+ if (!dumptypes) {
+ err("Couldn't allocate enough space for dumptypes table: %s.\n",
+ strerror(errno));
+ return -1;
+ }
+
+ while (fgets(buffer, sizeof(buffer), list)) {
+ char *index;
+
+ index = getword(buffer, dumptypes[numtypes].d_name);
+ if (!index)
+ continue;
+
+ index = getword(index, dumptypes[numtypes].d_cmdline);
+ if (!index) {
+ err("Dumptype `%s' has no command line.",
+ dumptypes[numtypes].d_name);
+ free(dumptypes);
+ return -1;
+ }
+
+ index = getword(index, dumptypes[numtypes].d_estline);
+ if (!index) {
+ dumptypes[numtypes].d_estline[0] = '\0';
+ dumptypes[numtypes].d_regexp[0] = '\0';
+ } else {
+ index = getword(buffer, dumptypes[numtypes].d_regexp);
+ if (!index) {
+ err("Dumptype `%s' has an estimate line,"
+ " but not a corresponding regexp.",
+ dumptypes[numtypes].d_name);
+ free(dumptypes);
+ return -1;
+ }
+ }
+
+ /* Allocate more buffer space, if it's needed. */
+ if ((++numtypes % MALLOC_GRANULARITY) == 0) {
+ dumptypes = realloc(dumptypes,
+ sizeof(dump_t) *
+ (numtypes + MALLOC_GRANULARITY));
+ if (!dumptypes) {
+ err("Couldn't allocate enough space for"
+ " dumptypes table: %s.\n", strerror(errno));
+ free(dumptypes);
+ return -1;
+ }
+ }
+ }
+ fclose(list);
+
+ /* Free up unused memory. */
+ /*
+ * TODO: find out if this should actually barf the entire process.
+ * it really shouldn't fail, so I think it's a non-issue, but it
+ * should be thought about anyway.
+ */
+ dumptypes = realloc(dumptypes, sizeof(dump_t) * numtypes);
+ if (!dumptypes) {
+ err("Couldn't free unused space in dumptypes table: %s.\n",
+ strerror(errno));
+ free(dumptypes);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * TODO: decide if non-fatal errors (like invalid dump types) should
+ * barf everything.
+ */
+disklist_t *
+read_disklist(const char *filen)
+{
+ FILE *list;
+ disklist_t *dl = NULL;
+ char buffer[MAXLINE];
+
+ list = fopen(filen, "r");
+ if (!list) {
+ err("Couldn't open disklist `%s': %s.\n",
+ filen, strerror(errno));
+ return NULL;
+ }
+
+ while (fgets(buffer, sizeof(buffer), list)) {
+ char vol[MAXLINE], type[MAXLINE], comp[MAXLINE], auth[MAXLINE];
+ char *index;
+ disklist_t *p;
+
+ index = getword(buffer, vol);
+ if (!index)
+ continue;
+
+ index = getword(index, type);
+ if (!index) {
+ err("Volume `%s' has no dump type.\n", vol);
+ return NULL;
+ }
+
+ index = getword(index, comp);
+ if (!index) {
+ strcpy(comp, DC_UNCOMP);
+ strcpy(auth, DA_NONE);
+ } else {
+ index = getword(index, auth);
+ if (!index)
+ strcpy(auth, DA_NONE);
+ }
+
+ p = malloc(sizeof(disklist_t));
+ if (!p) {
+ err("Couldn't malloc space for disklist node: %s.\n",
+ strerror(errno));
+ return NULL;
+ }
+ p->next = dl;
+
+ strncpy(p->disk.vol, vol, sizeof(p->disk.vol));
+
+ p->disk.type = find_dumptype(type);
+ if (!p->disk.type) {
+ err("Dump type `%s' isn't defined in dumptypes.\n",
+ type);
+ free(p);
+ return NULL;
+ }
+
+ /* Extract the compression options. */
+ if (!strcmp(comp, DC_UNCOMP))
+ p->disk.comp = UNCOMP;
+ else if (!strcmp(comp, DC_COMP))
+ p->disk.comp = COMP;
+ else if (!strcmp(comp, DC_COMP9))
+ p->disk.comp = COMP9;
+ else if (!strcmp(comp, DC_COMPFAST))
+ p->disk.comp = COMPFAST;
+ else {
+ err("Error: compression type %s isn't supported.\n",
+ comp);
+ free(p);
+ return NULL;
+ }
+
+ /* Extract method of authentication. */
+ if (!strcmp(auth, DA_NONE))
+ p->disk.auth = NOAUTH;
+ else if (!strcmp(auth, DA_RSH))
+ p->disk.auth = RSH;
+ else {
+ err("Error: auth type %s isn't supported.\n", auth);
+ free(p);
+ return NULL;
+ }
+
+ dl = p;
+ }
+
+ fclose(list);
+ return dl;
+}