diff options
author | Brian Cully <bjc@kublai.com> | 2022-03-09 21:10:26 -0500 |
---|---|---|
committer | Brian Cully <bjc@kublai.com> | 2022-03-09 21:37:48 -0500 |
commit | 720864f2a76d4ee3ed75cb99298b8e94c01f1b29 (patch) | |
tree | 7a163efe3d699725a9e9dd2c17aebaa6a6feadc7 /conf.c | |
download | ticra-720864f2a76d4ee3ed75cb99298b8e94c01f1b29.tar.gz ticra-720864f2a76d4ee3ed75cb99298b8e94c01f1b29.zip |
I used to really hate AMANDA.
Diffstat (limited to 'conf.c')
-rw-r--r-- | conf.c | 336 |
1 files changed, 336 insertions, 0 deletions
@@ -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; +} |