X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;ds=sidebyside;f=conffile.c;h=3c629e4eeb6b361bfa2ae9e60f494391bfc86ec5;hb=794f2398b8fe84bf398bb10d6eeca6fe6737f65f;hp=5bd735c75a77c051e4fb679f265f52c2bec30208;hpb=3454dce4c6909648b711a59b57c5a527036b2a8e;p=secnet.git diff --git a/conffile.c b/conffile.c index 5bd735c..3c629e4 100644 --- a/conffile.c +++ b/conffile.c @@ -12,7 +12,10 @@ #include "conffile.h" #include "conffile_internal.h" #include "util.h" -#include "modules.h" +#include "ipaddr.h" + +/* from modules.c */ +extern void init_builtin_modules(dict_t *dict); static struct cloc no_loc={"none",0}; @@ -332,6 +335,9 @@ static list_t *process_invocation(dict_t *context, struct p_node *i) if (cl->type != t_closure) { cfgfatal(i->l->loc,"conffile","only closures can be invoked\n"); } + if (!cl->data.closure->apply) { + cfgfatal(i->l->loc,"conffile","this closure cannot be invoked\n"); + } args=process_ilist(context, i->r); return cl->data.closure->apply(cl->data.closure, i->loc, context, args); } @@ -551,6 +557,14 @@ list_t *list_new(void) return NULL; } +uint32_t list_length(list_t *a) +{ + uint32_t l=0; + list_t *i; + for (i=a; i; i=i->next) l++; + return l; +} + list_t *list_copy(list_t *a) { list_t *r, *i, *b, *l; @@ -703,92 +717,15 @@ bool_t dict_read_bool(dict_t *dict, string_t key, bool_t required, return r; } -static struct subnet string_to_subnet(item_t *i, string_t desc) -{ - struct subnet s; - uint32_t a, b, c, d, n; - uint32_t match; - - /* i is not guaranteed to be a string */ - if (i->type!=t_string) { - cfgfatal(i->loc,desc,"expecting a string (subnet specification)\n"); - } - - /* We expect strings of the form "a.b.c.d[/n]", i.e. the dots are - NOT optional. The subnet mask is optional; if missing it is assumed - to be /32. */ - match=sscanf(i->data.string,"%u.%u.%u.%u/%u", &a, &b, &c, &d, &n); - if (match<4) { - cfgfatal(i->loc,desc,"\"%s\" is not a valid " - "subnet specification\n",i->data.string); - } - if (match<5) { - n=32; - } - if (a>255 || b>255 || c>255 || d>255 || n>32) { - cfgfatal(i->loc,desc,"\"%s\": range error\n",i->data.string); - } - s.prefix=(a<<24)|(b<<16)|(c<<8)|(d); - s.mask=(~0UL << (32-n)); - s.len=n; - if (s.prefix & ~s.mask) { - cfgfatal(i->loc,desc,"\"%s\": prefix not fully contained " - "in mask\n",i->data.string); - } - return s; -} - -uint32_t string_to_ipaddr(item_t *i, string_t desc) +uint32_t string_to_word(string_t s, struct cloc loc, + struct flagstr *f, string_t desc) { - uint32_t a, b, c, d; - uint32_t match; - - /* i is not guaranteed to be a string */ - if (i->type!=t_string) { - cfgfatal(i->loc,desc,"expecting a string (IP address)\n"); - } - - match=sscanf(i->data.string,"%u.%u.%u.%u", &a, &b, &c, &d); - if (match<4) { - cfgfatal(i->loc,desc,"\"%s\" is not a valid " - "IP address\n",i->data.string); - } - if (a>255 || b>255 || c>255 || d>255) { - cfgfatal(i->loc,desc,"\"%s\": range error\n",i->data.string); - } - return (a<<24)|(b<<16)|(c<<8)|(d); -} - -void dict_read_subnet_list(dict_t *dict, string_t key, bool_t required, - string_t desc, struct cloc loc, - struct subnet_list *sl) -{ - list_t *l, *li; - item_t *i; - uint32_t e=0; - - sl->entries=0; - sl->list=NULL; - l=dict_lookup(dict, key); - if (!l) { - if (!required) return; - cfgfatal(loc,desc,"required parameter \"%s\" not found\n",key); - } - /* Count the items in the list */ - for (li=l; li; li=li->next) e++; - if (e==0) return; - sl->entries=e; - sl->list=safe_malloc(sizeof(struct subnet)*e, "dict_read_subnet_list"); - e=0; - /* Fill in the list */ - for (li=l; li; li=li->next) { - i=li->item; - if (i->type!=t_string) { - cfgfatal(loc,desc,"parameter \"%s\": all elements must " - "be strings\n",key); - } - sl->list[e++]=string_to_subnet(i,desc); - } + struct flagstr *j; + for (j=f; j->name; j++) + if (strcmp(s,j->name)==0) + return j->value; + cfgfatal(loc,desc,"option \"%s\" not known\n",s); + return 0; } uint32_t string_list_to_word(list_t *l, struct flagstr *f, string_t desc) @@ -803,8 +740,7 @@ uint32_t string_list_to_word(list_t *l, struct flagstr *f, string_t desc) "strings\n"); } for (j=f; j->name; j++) - if (strcmp(i->item->data.string,j->name)==0) - r|=j->value; + r|=string_to_word(i->item->data.string,i->item->loc,f,desc); } return r; }