diff options
-rw-r--r-- | modules/mailutils/mod_mailutils.c | 95 | ||||
-rw-r--r-- | src/gpg.c | 4 | ||||
-rw-r--r-- | src/triplet.c | 242 | ||||
-rw-r--r-- | src/verify.c | 121 | ||||
-rw-r--r-- | src/wydawca.h | 18 |
5 files changed, 280 insertions, 200 deletions
diff --git a/modules/mailutils/mod_mailutils.c b/modules/mailutils/mod_mailutils.c index 1df460a..9a8d061 100644 --- a/modules/mailutils/mod_mailutils.c +++ b/modules/mailutils/mod_mailutils.c @@ -626,9 +626,9 @@ mod_mailutils_LTX_flush() } static mu_address_t -get_uploader_email(struct file_triplet const *trp, const char **errp) +get_uploader_email(struct file_triplet *trp, const char **errp) { - struct uploader_info const *info = trp->uploader; + struct wy_user const *info = triplet_get_uploader(trp); mu_address_t addr; mu_address_t rcpt = NULL; int rc; @@ -652,58 +652,21 @@ get_uploader_email(struct file_triplet const *trp, const char **errp) } static mu_address_t -get_recipient(struct dictionary *dict, struct file_triplet const *trp, - const char **errp) +get_owner_address(struct file_triplet *trp) { - unsigned nrows, ncols, i; + struct wy_user *wp; mu_address_t rcpt = NULL; - char *text; - int rc; - void *md; - - if (dict->type == dictionary_none) { - *errp = N_("dictionary is not configured"); - return NULL; - } - - md = dictionary_open(dict); - if (!md) { - *errp = N_("failed to open dictionary"); - return NULL; - } - - text = triplet_expand_dictionary_query(dict, md, trp); - rc = dictionary_lookup(dict, md, text); - free(text); - if (rc) { - *errp = N_("cannot obtain recipient emails"); - dictionary_close(dict, md); - return NULL; - } - - nrows = dictionary_num_rows(dict); - ncols = dictionary_num_cols(dict); - - if (nrows == 0) { - *errp = N_("cannot obtain recipient emails"); - return NULL; - } - - for (i = 0; i < nrows; i++) { + for (wp = triplet_get_admins(trp); wp; wp = wp->next) { mu_address_t addr; - const char *str = dictionary_result(dict, md, i, 0); - if (mu_address_create(&addr, str)) + if (mu_address_create(&addr, wp->email)) continue; - if (ncols > 0) { - str = dictionary_result(dict, md, i, 1); - if (str) - mu_address_set_personal(addr, 1, str); - } + if (wp->realname) + mu_address_set_personal(addr, 1, wp->realname); + mu_address_union(&rcpt, addr); mu_address_destroy(&addr); } - dictionary_close(dict, md); return rcpt; } @@ -723,13 +686,11 @@ expand_email_owner(struct metadef *def, void *data) { struct file_triplet *trp = data; mu_address_t addr; - const char *errp; - addr = get_recipient(trp->spool->dictionary[project_owner_dict], - trp, &errp); + addr = get_owner_address(trp); if (!addr) { - wy_log(LOG_ERR, _("cannot get email of the %s's owner: %s"), - trp->project, gettext(errp)); + wy_log(LOG_ERR, _("cannot get email of the %s's owner"), + trp->project); def->value = ""; } else { if (mu_address_aget_printable(addr, &def->storage) == 0) @@ -742,7 +703,7 @@ expand_email_owner(struct metadef *def, void *data) } static void -t_notify(struct mailevt *evt, int ev, struct file_triplet const *trp) +t_notify(struct mailevt *evt, int ev, struct file_triplet *trp) { mu_address_t rcpt = NULL; const char *errp; @@ -765,20 +726,25 @@ t_notify(struct mailevt *evt, int ev, struct file_triplet const *trp) case notify_user: rcpt = get_uploader_email(trp, &errp); + if (!rcpt) { + wy_log(LOG_ERR, + _("not notifying %s (project %s) about %s: %s"), + ntfrcpt_str(evt->rcpt), + trp->project, notification_event_str(ev), + gettext(errp)); + return; + } break; case notify_owner: - rcpt = get_recipient(trp->spool->dictionary[project_owner_dict], - trp, &errp); - } - - if (!rcpt && evt->rcpt != notify_read) { - wy_log(LOG_ERR, - _("not notifying %s (project %s) about %s: %s"), - ntfrcpt_str(evt->rcpt), - trp->project, notification_event_str(ev), - gettext(errp)); - return; + rcpt = get_owner_address(trp); + if (!rcpt) { + wy_log(LOG_ERR, + _("not notifying %s (project %s) about %s"), + ntfrcpt_str(evt->rcpt), + trp->project, notification_event_str(ev)); + return; + } } if (wy_debug_level) { @@ -861,7 +827,7 @@ mail_stats(struct mailevt *evt) } void -mod_mailutils_LTX_notify(void *data, int ev, struct file_triplet const *trp) +mod_mailutils_LTX_notify(void *data, int ev, struct file_triplet *trp) { struct mailevt *evt = data; @@ -870,4 +836,3 @@ mod_mailutils_LTX_notify(void *data, int ev, struct file_triplet const *trp) else if (ev == ev_statistics) mail_stats(evt); } - @@ -214,12 +214,12 @@ verify_directive_signature(struct file_triplet *trp) gpgme_data_t key_data, directive_data, plain = NULL; gpgme_error_t ec; int rc; - struct uploader_info *uptr; + struct wy_user *uptr; create_gpg_homedir(); fail_if_err(gpgme_new(&ctx)); - for (uptr = trp->uploader_list; uptr; uptr = uptr->next) { + for (uptr = triplet_get_uploaders(trp); uptr; uptr = uptr->next) { gpgme_import_result_t res; gpgme_import_status_t pstat; 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; +} diff --git a/src/verify.c b/src/verify.c index af450c8..464a2b3 100644 --- a/src/verify.c +++ b/src/verify.c @@ -168,21 +168,8 @@ fill_project_name(struct file_triplet *trp) return 0; } -struct uploader_info * -new_uploader_info(struct uploader_info *src) -{ - struct uploader_info *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; -} - -struct uploader_info * -uploader_find_frp(struct uploader_info *list, const char *fpr) +struct wy_user * +uploader_find_frp(struct wy_user *list, const char *fpr) { for (; list; list = list->next) if (list->fpr && strcmp(list->fpr, fpr) == 0) @@ -193,17 +180,6 @@ uploader_find_frp(struct uploader_info *list, const char *fpr) int verify_directive_file(struct file_triplet *trp, int noath) { - char *command; - int rc; - void *md; - size_t nrows, ncols, i; - struct uploader_info *head, *tail; - const struct spool *spool; - struct dictionary *dict; - - ASGN_SPOOL(spool, trp, return 1); - dict = spool->dictionary[project_uploader_dict]; - if (!trp->file[file_directive].name) return 1; @@ -211,99 +187,8 @@ verify_directive_file(struct file_triplet *trp, int noath) return 1; if (!noath) { - md = dictionary_open(dict); - if (!md) - return 1; - - 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 1; - } - - nrows = dictionary_num_rows(dict); - if (nrows == 0) { - wy_log(LOG_ERR, _("found no uploaders for %s"), - trp->name); - dictionary_close(dict, md); + if (!triplet_get_uploaders(trp)) return 1; - } - - 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 1; - } - - head = tail = NULL; - for (i = 0; i < nrows; i++) { - const char *p; - struct uploader_info 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 = new_uploader_info(&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 1; - } - - trp->uploader_list = head; - trp->uploader = NULL; if (verify_directive_signature(trp)) { /*FIXME: Update stats */ diff --git a/src/wydawca.h b/src/wydawca.h index 1948e75..bec8666 100644 --- a/src/wydawca.h +++ b/src/wydawca.h @@ -152,8 +152,8 @@ struct file_info { struct stat sb; }; -struct uploader_info { - struct uploader_info *next; +struct wy_user { + struct wy_user *next; char *name; char *realname; char *email; @@ -189,9 +189,10 @@ struct file_triplet { job and jq_prev, jq_next are NULL. */ struct job *job; /* User data */ - size_t uploader_count; - struct uploader_info *uploader_list; - struct uploader_info *uploader; + struct wy_user *uploader_list; + struct wy_user *uploader; + /* Admin data */ + struct wy_user *admin_list; /* Special data for template formatting */ char *project; /* Triplet project name (if known) */ int check_result; /* Result of external check */ @@ -460,6 +461,11 @@ void spool_commit_triplets(struct spool *, struct file_triplet *); struct file_triplet *link_processable_triplets(void); size_t count_collected_triplets(void); +struct wy_user *triplet_get_uploaders(struct file_triplet *trp); +struct wy_user *triplet_get_admins(struct file_triplet *trp); + +struct wy_user *triplet_get_uploader(struct file_triplet *trp); + char *triplet_expand_param(const char *tmpl, struct file_triplet const *trp, struct metadef *xmeta); char *triplet_expand_dictionary_query(struct dictionary *dict, void *handle, @@ -493,7 +499,7 @@ int verify_directive_file(struct file_triplet *trp, int noath); int verify_directive_signature(struct file_triplet *trp); int verify_detached_signature(struct file_triplet *trp); int fill_project_name(struct file_triplet *trp); -struct uploader_info *uploader_find_frp(struct uploader_info *list, +struct wy_user *uploader_find_frp(struct wy_user *list, const char *frp); /* Directive file support */ |