diff options
Diffstat (limited to 'src/acl.c')
-rw-r--r-- | src/acl.c | 206 |
1 files changed, 112 insertions, 94 deletions
@@ -1,3 +1,3 @@ /* This file is part of GNU Pies - Copyright (C) 2009, 2010 Sergey Poznyakoff + Copyright (C) 2009, 2010, 2011 Sergey Poznyakoff @@ -27,3 +27,2 @@ #include <netdb.h> -#include <hash.h> @@ -42,4 +41,4 @@ struct acl_entry pies_acl_t acl; - gl_list_t groups; - gl_list_t sockaddrs; + struct grecs_list *groups; + struct grecs_list *sockaddrs; }; @@ -50,3 +49,3 @@ struct pies_acl grecs_locus_t locus; - gl_list_t list; + struct grecs_list *list; }; @@ -63,7 +62,3 @@ pies_acl_create (const char *name, grecs_locus_t *locus) acl->locus = *locus; - acl->list = gl_list_create_empty(&gl_linked_list_implementation, - NULL, - NULL, - NULL, - false); + acl->list = grecs_list_create (); return acl; @@ -71,2 +66,10 @@ pies_acl_create (const char *name, grecs_locus_t *locus) +void +pies_acl_free (pies_acl_t acl) +{ + free (acl->name); + grecs_list_free (acl->list); + free (acl); +} + static struct pies_sockaddr * @@ -191,3 +194,3 @@ _parse_sockaddr (struct acl_entry *entry, const grecs_value_t *value) } - gl_list_add_last (entry->sockaddrs, sptr); + grecs_list_append (entry->sockaddrs, sptr); return 0; @@ -196,3 +199,3 @@ _parse_sockaddr (struct acl_entry *entry, const grecs_value_t *value) static int -_parse_from (struct acl_entry *entry, size_t argc, const grecs_value_t *argv) +_parse_from (struct acl_entry *entry, size_t argc, grecs_value_t **argv) { @@ -200,3 +203,3 @@ _parse_from (struct acl_entry *entry, size_t argc, const grecs_value_t *argv) return 0; - else if (argv->type == GRECS_TYPE_LIST) + else if (argv[0]->type == GRECS_TYPE_LIST) { @@ -205,6 +208,6 @@ _parse_from (struct acl_entry *entry, size_t argc, const grecs_value_t *argv) } - else if (strcmp (argv->v.string, "from")) + else if (strcmp (argv[0]->v.string, "from")) { grecs_error (&entry->locus, 0, _("expected `from', but found `%s'"), - argv->v.string); + argv[0]->v.string); return 1; @@ -221,10 +224,6 @@ _parse_from (struct acl_entry *entry, size_t argc, const grecs_value_t *argv) - entry->sockaddrs = gl_list_create_empty(&gl_linked_list_implementation, - NULL, - NULL, - NULL, - false); - if (argv->type == GRECS_TYPE_STRING) + entry->sockaddrs = grecs_list_create (); + if (argv[0]->type == GRECS_TYPE_STRING) { - if (_parse_sockaddr (entry, argv)) + if (_parse_sockaddr (entry, argv[0])) return 1; @@ -233,8 +232,7 @@ _parse_from (struct acl_entry *entry, size_t argc, const grecs_value_t *argv) { - gl_list_iterator_t itr = gl_list_iterator (argv->v.list); - const void *p; int rc = 0; - while (gl_list_iterator_next (&itr, &p, NULL)) - rc += _parse_sockaddr (entry, (const grecs_value_t*) p); - gl_list_iterator_free (&itr); + struct grecs_list_entry *ep; + + for (ep = argv[0]->v.list->head; ep; ep = ep->next) + rc += _parse_sockaddr (entry, (const grecs_value_t*) ep->data); if (rc) @@ -252,3 +250,3 @@ _parse_from (struct acl_entry *entry, size_t argc, const grecs_value_t *argv) static int -_parse_sub_acl (struct acl_entry *entry, size_t argc, grecs_value_t *argv) +_parse_sub_acl (struct acl_entry *entry, size_t argc, grecs_value_t **argv) { @@ -256,3 +254,3 @@ _parse_sub_acl (struct acl_entry *entry, size_t argc, grecs_value_t *argv) return 0; - if (strcmp (argv->v.string, "acl") == 0) + if (strcmp (argv[0]->v.string, "acl") == 0) { @@ -267,3 +265,3 @@ _parse_sub_acl (struct acl_entry *entry, size_t argc, grecs_value_t *argv) - if (argv->type != GRECS_TYPE_STRING) + if (argv[0]->type != GRECS_TYPE_STRING) { @@ -274,3 +272,3 @@ _parse_sub_acl (struct acl_entry *entry, size_t argc, grecs_value_t *argv) - entry->acl = pies_acl_lookup (argv->v.string); + entry->acl = pies_acl_lookup (argv[0]->v.string); @@ -279,3 +277,3 @@ _parse_sub_acl (struct acl_entry *entry, size_t argc, grecs_value_t *argv) grecs_error (&entry->locus, 0, _("ACL not defined: `%s'"), - argv->v.string); + argv[0]->v.string); return 1; @@ -289,5 +287,5 @@ _parse_sub_acl (struct acl_entry *entry, size_t argc, grecs_value_t *argv) static int -_parse_group (struct acl_entry *entry, size_t argc, grecs_value_t * argv) +_parse_group (struct acl_entry *entry, size_t argc, grecs_value_t **argv) { - if (strcmp (argv->v.string, "group") == 0) + if (strcmp (argv[0]->v.string, "group") == 0) { @@ -301,13 +299,9 @@ _parse_group (struct acl_entry *entry, size_t argc, grecs_value_t * argv) } - if (argv->type == GRECS_TYPE_STRING) + if (argv[0]->type == GRECS_TYPE_STRING) { - entry->groups = gl_list_create_empty(&gl_linked_list_implementation, - NULL, - NULL, - NULL, - false); - gl_list_add_last (entry->groups, (void *) argv->v.string); + entry->groups = grecs_list_create (); + grecs_list_append (entry->groups, xstrdup (argv[0]->v.string)); } else - entry->groups = argv->v.list; + entry->groups = argv[0]->v.list; argc--; @@ -319,7 +313,7 @@ _parse_group (struct acl_entry *entry, size_t argc, grecs_value_t * argv) static int -_parse_acl (struct acl_entry *entry, size_t argc, grecs_value_t *argv) +_parse_acl (struct acl_entry *entry, size_t argc, grecs_value_t **argv) { - if (assert_grecs_value_type (&entry->locus, argv, GRECS_TYPE_STRING)) + if (assert_grecs_value_type (&entry->locus, argv[0], GRECS_TYPE_STRING)) return 1; - else if (_parse_token (entry, argv) == 0) + else if (_parse_token (entry, argv[0]) == 0) return _parse_sub_acl (entry, argc - 1, argv + 1); @@ -358,3 +352,3 @@ parse_acl_line (grecs_locus_t *locus, int allow, pies_acl_t acl, } - gl_list_add_last (acl->list, entry); + grecs_list_append (acl->list, entry); return 0; @@ -375,3 +369,2 @@ _acl_common_section_parser (enum grecs_callback_command cmd, pies_acl_t acl; - grecs_locus_t defn_loc; const char *tag = NULL; @@ -414,11 +407,4 @@ _acl_common_section_parser (enum grecs_callback_command cmd, acl = pies_acl_create (tag, locus); - if (tag && pies_acl_install (acl, &defn_loc)) - { - grecs_error (locus, 0, - _("redefinition of ACL %s"), - value->v.string); - grecs_error (&defn_loc, 0, - _("location of the previous definition")); - return 1; - } + if (tag && (acl = pies_acl_install (acl)) == NULL) + return 1; if (pacl) @@ -572,7 +558,6 @@ _acl_check (struct acl_entry *ent, struct acl_input *input) { - const void *p; - gl_list_iterator_t itr = gl_list_iterator (ent->groups); - while (result && gl_list_iterator_next (&itr, &p, NULL)) - result = match_group (input->groups, p); - gl_list_iterator_free (&itr); + struct grecs_list_entry *ep; + + for (ep = ent->groups->head; result && ep; ep = ep->next) + result = match_group (input->groups, ep->data); if (!result) @@ -587,8 +572,8 @@ _acl_check (struct acl_entry *ent, struct acl_input *input) { - const void *p; - gl_list_iterator_t itr = gl_list_iterator (ent->sockaddrs); + struct grecs_list_entry *ep; + result = 0; - while (gl_list_iterator_next (&itr, &p, NULL)) + for (ep = ent->sockaddrs->head; ep; ep = ep->next) { - result = _check_sockaddr ((struct pies_sockaddr *)p, input); + result = _check_sockaddr ((struct pies_sockaddr *)ep->data, input); if (result) @@ -596,3 +581,2 @@ _acl_check (struct acl_entry *ent, struct acl_input *input) } - gl_list_iterator_free (&itr); } @@ -606,3 +590,3 @@ _acl_check_cb (struct acl_entry *ent, struct acl_input *input, int *pres) int result = _acl_check (ent, input); - debug (1, ("%s:%d: %s", ent->locus.file, ent->locus.line, + debug (1, ("%s:%d: %s", ent->locus.beg.file, ent->locus.beg.line, /* TRANSLATORS: `MATCHES' is the verb `match' in 2nd person. @@ -624,8 +608,7 @@ pies_acl_check (pies_acl_t acl, struct acl_input *input, int result) { - const void *p; - gl_list_iterator_t itr = gl_list_iterator (acl->list); - while (gl_list_iterator_next (&itr, &p, NULL) - && !_acl_check_cb ((struct acl_entry *)p, input, &result)) - ; - gl_list_iterator_free (&itr); + struct grecs_list_entry *ep; + + for (ep = acl->list->head; ep; ep = ep->next) + if (_acl_check_cb ((struct acl_entry *)ep->data, input, &result)) + break; } @@ -637,10 +620,10 @@ pies_acl_check (pies_acl_t acl, struct acl_input *input, int result) -static Hash_table *acl_table; +static struct grecs_symtab *acl_table; /* Calculate the hash of a string. */ -static size_t -acl_hasher (void const *data, size_t n_buckets) +static unsigned +acl_hasher (void *data, unsigned long n_buckets) { const struct pies_acl *p = data; - return hash_string (p->name, n_buckets); + return grecs_hash_string (p->name, n_buckets); } @@ -648,3 +631,3 @@ acl_hasher (void const *data, size_t n_buckets) /* Compare two strings for equality. */ -static bool +static int acl_compare (void const *data1, void const *data2) @@ -653,23 +636,58 @@ acl_compare (void const *data1, void const *data2) const struct pies_acl *p2 = data2; - return strcasecmp (p1->name, p2->name) == 0; + return strcasecmp (p1->name, p2->name); } -int -pies_acl_install (pies_acl_t acl, grecs_locus_t * locus) +static int +acl_copy (void *a, void *b) +{ + const struct pies_acl *pb = b; + + memcpy (a, b, sizeof (struct pies_acl)); + memset (b, 0, sizeof (struct pies_acl)); + return 0; +} + +static void +acl_free_entry (void *p) +{ + pies_acl_free (p); +} + +pies_acl_t +pies_acl_install (pies_acl_t acl) { pies_acl_t ret; - if (!((acl_table - || (acl_table = hash_initialize (0, 0, - acl_hasher, - acl_compare, 0))) - && (ret = hash_insert (acl_table, acl)))) - xalloc_die (); - - if (ret != acl) + int install = 1; + + if (!acl_table) { - if (locus) - *locus = ret->locus; - return 1; + acl_table = grecs_symtab_create(sizeof (struct pies_acl), + acl_hasher, + acl_compare, + acl_copy, + NULL, + acl_free_entry); + if (!acl_table) + xalloc_die (); } - return 0; + + ret = grecs_symtab_lookup_or_install (acl_table, acl, &install); + + if (!ret) + { + logmsg (LOG_ERR, _("cannot install acl: %s"), strerror (errno)); + exit (1); + } + + if (!install) + { + grecs_error (&acl->locus, 0, + _("redefinition of ACL %s"), + ret->name); + grecs_error (&ret->locus, 0, + _("location of the previous definition")); + ret = NULL; + } + pies_acl_free (acl); + return ret; } @@ -683,3 +701,3 @@ pies_acl_lookup (const char *name) samp.name = (char *) name; - return hash_lookup (acl_table, &samp); + return grecs_symtab_lookup_or_install (acl_table, &samp, NULL); } |