diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-03-12 13:26:54 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-03-12 13:26:54 +0200 |
commit | 293108d7806aa3c0c5e706237b3788b261779e66 (patch) | |
tree | f3ea5c3419c5de0284da68f1d1b6002933e02a73 /src/triplet.c | |
parent | 02c6a0ad553ad51f91af9d9e6c28f2529e759305 (diff) | |
download | wydawca-293108d7806aa3c0c5e706237b3788b261779e66.tar.gz wydawca-293108d7806aa3c0c5e706237b3788b261779e66.tar.bz2 |
Improve triplet API.
* src/wydawca.h (uploader_info): Rename to wy_user.
(file_triplet) <uploader_count>: Remove.
<admin_list>: New member.
(triplet_get_uploaders,triplet_get_uploader)
(triplet_get_admins): New protos.
* src/triplet.c (wy_user_create)
(wy_userlist_free): New static functions.
(hash_triplet_free): Use wy_userlist_free.
(triplet_get_uploaders,triplet_get_uploader)
(triplet_get_admins): New functions.
* src/verify.c (verify_directive_file): Rewrite using
triplet_get_uploaders.
* src/gpg.c (verify_directive_signature): Call triplet_get_uploaders
to initialize the uploaders list.
* modules/mailutils/mod_mailutils.c (get_recipient): Remove.
(get_owner_address): New function. All callers updated.
Remove useless const qualifiers.
Diffstat (limited to 'src/triplet.c')
-rw-r--r-- | src/triplet.c | 242 |
1 files changed, 233 insertions, 9 deletions
diff --git a/src/triplet.c b/src/triplet.c index 0481659..932ab86 100644 --- a/src/triplet.c +++ b/src/triplet.c @@ -110,6 +110,30 @@ triplet_list_ordered_insert(struct file_triplet *tp) } } +static struct wy_user * +wy_user_create(struct wy_user *src) +{ + struct wy_user *p = grecs_malloc(sizeof(*p)); + p->next = NULL; + p->name = src->name; + p->realname = src->realname; + p->gpg_key = src->gpg_key; + p->email = src->email; + p->fpr = NULL; + return p; +} + +static void +wy_userlist_free(struct wy_user *wp) +{ + while (wp) { + struct wy_user *next = wp->next; + free(wp->fpr); + free(wp); + wp = next; + } +} + /* Functions for operation on a symtab of triplets. */ static unsigned hash_triplet_hasher(void *data, unsigned long n_buckets) @@ -133,7 +157,6 @@ hash_triplet_free(void *data) { int i; struct file_triplet *tp = data; - struct uploader_info *up; free(tp->name); @@ -147,14 +170,10 @@ hash_triplet_free(void *data) free(tp->tmp); txtacc_free(tp->acc); - /* Free uploader list */ - for (up = tp->uploader_list; up;) { - struct uploader_info *next = up->next; - free(up->fpr); - free(up); - up = next; - } - + /* Free uploader and admin lists */ + wy_userlist_free(tp->uploader_list); + wy_userlist_free(tp->admin_list); + free(tp); } @@ -892,3 +911,208 @@ triplet_expand_param(const char *tmpl, struct file_triplet const *trp, free(mp); return p; } + +struct wy_user * +triplet_get_uploaders(struct file_triplet *trp) +{ + const struct spool *spool; + struct dictionary *dict; + void *md; + char *command; + int rc; + size_t nrows, ncols, i; + struct wy_user *head, *tail; + + if (trp->uploader_list) + return trp->uploader_list; + + ASGN_SPOOL(spool, trp, return NULL); + dict = spool->dictionary[project_uploader_dict]; + + md = dictionary_open(dict); + if (!md) + return NULL; + + command = triplet_expand_dictionary_query(dict, md, trp); + + rc = dictionary_lookup(dict, md, command); + free(command); + if (rc) { + wy_log(LOG_ERR, _("cannot get uploaders for %s"), trp->name); + dictionary_close(dict, md); + return NULL; + } + + nrows = dictionary_num_rows(dict); + if (nrows == 0) { + wy_log(LOG_ERR, _("found no uploaders for %s"), trp->name); + dictionary_close(dict, md); + return NULL; + } + + ncols = dictionary_num_cols(dict); + if (ncols < 4) { + wy_log(LOG_ERR, + _("project-uploader dictionary error: " + "too few columns (%lu)"), + (unsigned long)ncols); + dictionary_close(dict, md); + return NULL; + } + + head = tail = NULL; + for (i = 0; i < nrows; i++) { + const char *p; + struct wy_user info, *ptr; + + memset(&info, 0, sizeof(info)); + p = dictionary_result(dict, md, i, 0); + if (p) + info.name = triplet_strdup(trp, p); + p = dictionary_result(dict, md, i, 1); + if (p) + info.realname = triplet_strdup(trp, p); + p = dictionary_result(dict, md, i, 2); + if (p) + info.email = triplet_strdup(trp, p); + p = dictionary_result(dict, md, i, 3); + if (p) + info.gpg_key = triplet_strdup(trp, p); + + if (wy_debug_level > 3) { + wy_log(LOG_DEBUG, _("name: %s"), + SP(info.name)); + wy_log(LOG_DEBUG, _("realname: %s"), + SP(info.realname)); + wy_log(LOG_DEBUG, _("gpg-key: %s"), + SP(info.gpg_key)); + wy_log(LOG_DEBUG, _("email: %s"), + SP(info.email)); + } + + if (!info.name || !info.realname || !info.gpg_key || + !info.email) { + wy_log(LOG_ERR, + _("project-uploader dictionary error: " + "malformed row %lu"), + (unsigned long)i); + /* FIXME: Memory allocated for `info' will + be reclaimed only when the triplet is + freed. */ + continue; + } + + ptr = wy_user_create(&info); + if (tail) + tail->next = ptr; + else + head = ptr; + tail = ptr; + } + + dictionary_close(dict, md); + + if (!head) { + wy_log(LOG_ERR, _("no valid uploaders found for %s"), + trp->name); + return NULL; + } + + trp->uploader_list = head; + + return head; +} + +struct wy_user * +triplet_get_uploader(struct file_triplet *trp) +{ + return trp->uploader; +} + + +struct wy_user * +triplet_get_admins(struct file_triplet *trp) +{ + const struct spool *spool; + struct dictionary *dict; + void *md; + char *command; + int rc; + size_t nrows, ncols, i; + struct wy_user *head, *tail; + + if (trp->admin_list) + return trp->admin_list; + + ASGN_SPOOL(spool, trp, return NULL); + dict = spool->dictionary[project_owner_dict]; + + if (dict->type == dictionary_none) { + wy_log(LOG_ERR, + _("%s: dictionary %s not configured (spool %s)"), + trp->name, "project_owner_dict", spool->tag); + return NULL; + } + + md = dictionary_open(dict); + if (!md) { + wy_log(LOG_ERR, + _("%s: failed to open dictionary %s (spool %s)"), + trp->name, "project_owner_dict", spool->tag); + return NULL; + } + + command = triplet_expand_dictionary_query(dict, md, trp); + + rc = dictionary_lookup(dict, md, command); + free(command); + if (rc) { + wy_log(LOG_ERR, + _("%s: cannot obtain recipient emails"), + trp->name); + dictionary_close(dict, md); + return NULL; + } + + nrows = dictionary_num_rows(dict); + ncols = dictionary_num_cols(dict); + + if (nrows == 0) { + wy_log(LOG_ERR, + _("%s: cannot obtain recipient emails"), + trp->name); + return NULL; + } + + head = tail = NULL; + for (i = 0; i < nrows; i++) { + const char *p; + struct wy_user info, *ptr; + + memset(&info, 0, sizeof(info)); + p = dictionary_result(dict, md, i, 0); + if (p) + info.email = triplet_strdup(trp, p); + if (ncols > 0 && (p = dictionary_result(dict, md, i, 1))) + info.realname = triplet_strdup(trp, p); + + if (wy_debug_level > 3) { + wy_log(LOG_DEBUG, _("realname: %s"), + SP(info.realname)); + wy_log(LOG_DEBUG, _("email: %s"), + SP(info.email)); + } + + ptr = wy_user_create(&info); + if (tail) + tail->next = ptr; + else + head = ptr; + tail = ptr; + + } + dictionary_close(dict, md); + trp->admin_list = head; + + return trp->admin_list; +} |