#include #include #include #include #include #include #include extern const char *__progname; #include "vars.h" #include "structs.h" #include "linereader.h" #include "config.h" extern SECT_OPS sectops_repo; extern SECT_OPS sectops_listen; static SECT_OPS *sects[] = { §ops_repo, §ops_listen }; void config_err(CONFIG *cfg, const char *fmt, ...) { va_list ap; char *s; va_start(ap,fmt); asprintf(&s,fmt,ap); va_end(ap); if (! cfg->pt) abort(); (*cfg->pt->err_throw)(s); } void config_err_post(void (*post)(void), CONFIG *cfg, const char *fmt, ...) { va_list ap; char *s; va_start(ap,fmt); asprintf(&s,fmt,ap); va_end(ap); (*post)(); if (! cfg->pt) abort(); (*cfg->pt->err_throw)(s); } static void config_prep(CONFIG *cfg) { cfg->repos = 0; cfg->listens = 0; cfg->pt = malloc(sizeof(CONFIG_PARSE_TEMP)); cfg->pt->ops = 0; cfg->pt->priv = 0; cfg->pt->err_throw = 0; } static int config_process(CONFIG *cfg, const char *line) { int i; if (cfg->pt->ops) { switch ((*cfg->pt->ops->parse)(cfg->pt->priv,line)) { case SPRV_GOOD: return(0); break; case SPRV_UNKNOWN: break; case SPRV_ERROR: return(1); break; default: abort(); break; } } for (i=(sizeof(sects)/sizeof(sects[0]))-1;i>=0;i--) { void *pp; pp = (*sects[i]->start)(line,cfg); if (pp) { char *errmsg; void free_errmsg(void) { free(errmsg); } errmsg = 0; if (cfg->pt->ops) { __label__ errjmp; void err_throw(char *msg) { errmsg = msg; goto errjmp; } void (*saved_err_throw)(char *); saved_err_throw = cfg->pt->err_throw; cfg->pt->err_throw = &err_throw; (*cfg->pt->ops->done)(cfg->pt->priv); errjmp:; cfg->pt->err_throw = saved_err_throw; } cfg->pt->ops = sects[i]; cfg->pt->priv = pp; if (errmsg) config_err_post(&free_errmsg,cfg,"previous section: %s",errmsg); } } if (cfg->pt->ops) { config_err(cfg,"not valid in this section and not a valid section start line"); } else { config_err(cfg,"not a valid section start line"); } } static void config_free(CONFIG *cfg) { cfg=cfg; /* XXX XXX XXX */ } static void config_replace(CONFIG *old, CONFIG *new) { old=old; new=new; /* XXX XXX XXX */ } int reload_config(void) { __label__ errjmp; CONFIG *cfg; int fd; LINEREADER *lr; int err; int errs; void err_throw(char *msg) { fprintf(stderr,"%s: line %d: %s\n",configfile,lr_lineno(lr),msg); free(msg); goto errjmp; } fd = open(configfile,O_RDONLY,0); if (fd < 0) { fprintf(stderr,"%s: %s: open: %s\n",__progname,configfile,strerror(errno)); return(-1); } lr = lr_setup(fd); cfg = malloc(sizeof(CONFIG)); config_prep(cfg); if (fstat(fd,&cfg->confstat) < 0) { fprintf(stderr,"%s: %s: fstat %s\n",__progname,configfile,strerror(errno)); lr_done(lr); free(cfg); close(fd); return(-1); } errs = 0; while <"lines"> (1) { switch (lr_getline(lr)) { case LRGL_ERROR: errs = 1; break <"lines">; case LRGL_EOF: break <"lines">; case LRGL_LINE: break; default: abort(); break; } cfg->pt->err_throw = &err_throw; err = config_process(cfg,lr_ptr(lr)); if (0) { errjmp:; err = 1; } cfg->pt->err_throw = 0; if (err) errs = 1; if (err < 0) break; } lr_done(lr); if (errs) { config_free(cfg); return(-1); } else { config_replace(conf,cfg); conf = cfg; return(0); } }