X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=secnet.git;a=blobdiff_plain;f=conffile.c;h=5cce211415921556a5c384817d1278d9eb9dc158;hp=318d608a77ca7e7befcd6f7876ac770c987f1dc3;hb=e1b81bd68228f908e7e69794386947d7f7f98451;hpb=d3fe100dfc120244d316e083ce87b1eb130fe4fd diff --git a/conffile.c b/conffile.c index 318d608..5cce211 100644 --- a/conffile.c +++ b/conffile.c @@ -1,22 +1,18 @@ -/* - * $Log$ - */ - /* conffile.c - process the configuration file */ /* #define DUMP_PARSE_TREE */ #include "secnet.h" +#include +#include #include #include #include "conffile.h" #include "conffile_internal.h" +#include "conffile.yy.h" #include "util.h" #include "ipaddr.h" -/* from modules.c */ -extern void init_builtin_modules(dict_t *dict); - static struct cloc no_loc={"none",0}; struct atomlist { @@ -39,7 +35,7 @@ struct dict { struct dict *parent; struct searchlist *search; struct entry *entries; - uint32_t size; + int32_t size; }; static struct atomlist *atoms=NULL; @@ -77,7 +73,7 @@ static void dict_iadd(dict_t *dict, atom_t key, list_t *val) { struct entry *e; if (dict_ilookup_primitive(dict, key)) { - fatal("duplicate key \"%s\" in dictionary\n",key); + fatal("duplicate key \"%s\" in dictionary",key); } e=safe_malloc(sizeof(*e),"dict_add"); e->next=dict->entries; @@ -132,25 +128,25 @@ static void ptree_mangle(struct p_node *t) ptree_mangle(t->r); switch (t->type) { case T_DICT: - /* ASSERT !t->l || t->l->type==T_ALIST */ - /* ASSERT !t->r || t->r->type==T_LISTITEM */ + ASSERT(!t->l || t->l->type==T_ALIST); + ASSERT(!t->r || t->r->type==T_LISTITEM); t->l=list_reverse(t->l); t->r=list_reverse(t->r); break; case T_ASSIGNMENT: - /* ASSERT t->l->type==T_KEY */ - /* ASSERT t->r->type==T_LISTITEM */ + ASSERT(t->l->type==T_KEY); + ASSERT(t->r->type==T_LISTITEM); t->r=list_reverse(t->r); break; case T_ABSPATH: case T_RELPATH: - /* ASSERT t->l==NULL */ - /* ASSERT t->r->type==T_PATHELEM */ + ASSERT(t->l==NULL); + ASSERT(t->r->type==T_PATHELEM); t->r=list_reverse(t->r); break; case T_EXEC: - /* ASSERT t->l */ - /* ASSERT t->r->type==T_LISTITEM */ + ASSERT(t->l); + ASSERT(t->r==NULL || t->r->type==T_LISTITEM); t->r=list_reverse(t->r); break; } @@ -177,9 +173,9 @@ static string_t ntype(uint32_t type) return "**unknown**"; } -static void ptree_indent(uint32_t amount) +static void ptree_indent(int amount) { - uint32_t i; + int i; for (i=0; itype),n->loc.file,n->loc.line); ptree_indent(d); printf(" |-"); ptree_dump(n->l, d+1); @@ -224,8 +221,8 @@ static list_t *dict_lookup_path(dict_t *context, struct p_node *p) dict_t *i; list_t *l; - /* ASSERT p->type==T_PATHELEM */ - /* ASSERT p->l->type==T_KEY */ + ASSERT(p->type==T_PATHELEM); + ASSERT(p->l->type==T_KEY); l=dict_ilookup(context, p->l->data.key); if (!l) { cfgfatal(p->loc,"conffile","can't find key %s\n", @@ -292,7 +289,7 @@ static list_t *process_item(dict_t *context, struct p_node *i) default: #ifdef DUMP_PARSE_TREE ptree_dump(i,0); - fatal("process_item: invalid node type for a list item (%s)\n", + fatal("process_item: invalid node type for a list item (%s)", ntype(i->type)); #else fatal("process_item: list item has invalid node type %d - recompile " @@ -309,7 +306,7 @@ static list_t *process_ilist(dict_t *context, struct p_node *l) struct p_node *i; list_t *r; - /* ASSERT l->type==T_LISTITEM */ + ASSERT(!l || l->type==T_LISTITEM); r=list_new(); @@ -325,9 +322,8 @@ static list_t *process_invocation(dict_t *context, struct p_node *i) item_t *cl; list_t *args; - /* ASSERT i->type==T_EXEC */ - /* ASSERT i->r->type==T_LISTITEM */ - /* XXX it might be null too */ + ASSERT(i->type==T_EXEC); + ASSERT(i->r==NULL || i->r->type==T_LISTITEM); cll=process_item(context,i->l); cl=cll->item; if (cl->type != t_closure) { @@ -348,15 +344,15 @@ static void process_alist(dict_t *context, struct p_node *c) if (!c) return; /* NULL assignment lists are valid (empty dictionary) */ - /* ASSERT c->type==T_ALIST */ + ASSERT(c->type==T_ALIST); if (c->type!=T_ALIST) { - fatal("invalid node type in assignment list\n"); + fatal("invalid node type in assignment list"); } for (i=c; i; i=i->r) { - /* ASSERT i->l && i->l->type==T_ASSIGNMENT */ - /* ASSERT i->l->l->type==T_KEY */ - /* ASSERT i->l->r->type==T_LISTITEM */ + ASSERT(i->l && i->l->type==T_ASSIGNMENT); + ASSERT(i->l->l->type==T_KEY); + ASSERT(i->l->r->type==T_LISTITEM); k=i->l->l->data.key; l=process_ilist(context, i->l->r); dict_iadd(context, k, l); @@ -448,8 +444,9 @@ static list_t *readfile(closure_t *self, struct cloc loc, r=new_item(t_string,loc); r->data.string=safe_malloc(length+1,"readfile"); if (fread(r->data.string,length,1,f)!=1) { - fatal("readfile (%s:%d): fread: could not read all of file\n", - loc.file,loc.line); + (ferror(f) ? fatal_perror : fatal) + ("readfile (%s:%d): fread: could not read all of file", + loc.file,loc.line); } r->data.string[length]=0; if (fclose(f)!=0) { @@ -470,6 +467,9 @@ static dict_t *process_config(struct p_node *c) context=root; /* Predefined keys for boolean values */ + /* "nowise" and "verily" have the advantage of being the same + length, so they line up nicely... thanks VKC and SGT (who also + point out that "mayhap" is a good "maybe" value as well) */ i=new_item(t_bool,no_loc); i->data.bool=False; false=list_append(NULL,i); @@ -482,12 +482,18 @@ static dict_t *process_config(struct p_node *c) dict_add(root,"no",false); dict_add(root,"No",false); dict_add(root,"NO",false); + dict_add(root,"nowise",false); + dict_add(root,"Nowise",false); + dict_add(root,"NOWISE",false); dict_add(root,"true",true); dict_add(root,"True",true); dict_add(root,"TRUE",true); dict_add(root,"yes",true); dict_add(root,"Yes",true); dict_add(root,"YES",true); + dict_add(root,"verily",true); + dict_add(root,"Verily",true); + dict_add(root,"VERILY",true); add_closure(root,"makelist",makelist); add_closure(root,"readfile",readfile); @@ -502,7 +508,7 @@ static dict_t *process_config(struct p_node *c) /***** Externally accessible functions */ -atom_t intern(string_t s) +atom_t intern(cstring_t s) { struct atomlist *i; @@ -520,22 +526,22 @@ atom_t intern(string_t s) return i->a; } -list_t *dict_lookup(dict_t *dict, string_t key) +list_t *dict_lookup(dict_t *dict, cstring_t key) { return dict_ilookup(dict, intern(key)); } -list_t *dict_lookup_primitive(dict_t *dict, string_t key) +list_t *dict_lookup_primitive(dict_t *dict, cstring_t key) { return dict_ilookup_primitive(dict, intern(key)); } -void dict_add(dict_t *dict, string_t key, list_t *val) +void dict_add(dict_t *dict, cstring_t key, list_t *val) { dict_iadd(dict,intern(key),val); } -string_t *dict_keys(dict_t *dict) +cstring_t *dict_keys(dict_t *dict) { atom_t *r, *j; struct entry *i; @@ -555,15 +561,15 @@ list_t *list_new(void) return NULL; } -uint32_t list_length(list_t *a) +int32_t list_length(list_t *a) { - uint32_t l=0; + int32_t l=0; list_t *i; - for (i=a; i; i=i->next) l++; + for (i=a; i; i=i->next) { assert(l < INT_MAX); l++; } return l; } -list_t *list_copy(list_t *a) +static list_t *list_copy(list_t *a) { list_t *r, *i, *b, *l; @@ -602,7 +608,7 @@ list_t *list_append(list_t *list, item_t *item) return list_append_list(list,l); } -item_t *list_elem(list_t *l, uint32_t index) +item_t *list_elem(list_t *l, int32_t index) { if (!l) return NULL; if (index==0) return l->item; @@ -618,19 +624,20 @@ list_t *new_closure(closure_t *cl) return list_append(NULL,i); } -void add_closure(dict_t *dict, string_t name, apply_fn apply) +void add_closure(dict_t *dict, cstring_t name, apply_fn apply) { closure_t *c; c=safe_malloc(sizeof(*c),"add_closure"); c->description=name; + c->type=CL_PURE; c->apply=apply; c->interface=NULL; dict_add(dict,name,new_closure(c)); } -void *find_cl_if(dict_t *dict, string_t name, uint32_t type, - bool_t fail_if_invalid, string_t desc, struct cloc loc) +void *find_cl_if(dict_t *dict, cstring_t name, uint32_t type, + bool_t fail_if_invalid, cstring_t desc, struct cloc loc) { list_t *l; item_t *i; @@ -655,8 +662,8 @@ void *find_cl_if(dict_t *dict, string_t name, uint32_t type, } /* Convenience functions for modules reading configuration dictionaries */ -item_t *dict_find_item(dict_t *dict, string_t key, bool_t required, - string_t desc, struct cloc loc) +item_t *dict_find_item(dict_t *dict, cstring_t key, bool_t required, + cstring_t desc, struct cloc loc) { list_t *l; item_t *i; @@ -670,8 +677,8 @@ item_t *dict_find_item(dict_t *dict, string_t key, bool_t required, return i; } -string_t dict_read_string(dict_t *dict, string_t key, bool_t required, - string_t desc, struct cloc loc) +string_t dict_read_string(dict_t *dict, cstring_t key, bool_t required, + cstring_t desc, struct cloc loc) { item_t *i; string_t r; @@ -681,12 +688,15 @@ string_t dict_read_string(dict_t *dict, string_t key, bool_t required, if (i->type!=t_string) { cfgfatal(loc,desc,"\"%s\" must be a string\n",key); } + if (strlen(i->data.string) > INT_MAX/10) { + cfgfatal(loc,desc,"\"%s\" is unreasonably long\n",key); + } r=i->data.string; return r; } -uint32_t dict_read_number(dict_t *dict, string_t key, bool_t required, - string_t desc, struct cloc loc, uint32_t def) +uint32_t dict_read_number(dict_t *dict, cstring_t key, bool_t required, + cstring_t desc, struct cloc loc, uint32_t def) { item_t *i; uint32_t r; @@ -696,12 +706,15 @@ uint32_t dict_read_number(dict_t *dict, string_t key, bool_t required, if (i->type!=t_number) { cfgfatal(loc,desc,"\"%s\" must be a number\n",key); } + if (i->data.number >= 0x80000000) { + cfgfatal(loc,desc,"\"%s\" must fit into a 32-bit signed integer\n",key); + } r=i->data.number; return r; } -bool_t dict_read_bool(dict_t *dict, string_t key, bool_t required, - string_t desc, struct cloc loc, bool_t def) +bool_t dict_read_bool(dict_t *dict, cstring_t key, bool_t required, + cstring_t desc, struct cloc loc, bool_t def) { item_t *i; bool_t r; @@ -715,8 +728,8 @@ bool_t dict_read_bool(dict_t *dict, string_t key, bool_t required, return r; } -uint32_t string_to_word(string_t s, struct cloc loc, - struct flagstr *f, string_t desc) +uint32_t string_to_word(cstring_t s, struct cloc loc, + struct flagstr *f, cstring_t desc) { struct flagstr *j; for (j=f; j->name; j++) @@ -726,7 +739,7 @@ uint32_t string_to_word(string_t s, struct cloc loc, return 0; } -uint32_t string_list_to_word(list_t *l, struct flagstr *f, string_t desc) +uint32_t string_list_to_word(list_t *l, struct flagstr *f, cstring_t desc) { list_t *i; uint32_t r=0; @@ -743,7 +756,7 @@ uint32_t string_list_to_word(list_t *l, struct flagstr *f, string_t desc) return r; } -dict_t *read_conffile(char *name) +dict_t *read_conffile(const char *name) { FILE *conffile; struct p_node *config;