commit 8b10295ec9ddde4f3bfef322b31d3601d6040c62 from: Stefan Sperling via: Thomas Adam date: Fri Mar 21 13:22:46 2025 UTC send notification configuration to the gotd session_write process This allows the session_write process to work without reading gotd.conf. Again, we gain consistent run-time behaviour since changes to the notification configuration in gotd.conf will not take effect until gotd is restarted. However, the notify proccess still needs the same fix. commit - 4fd3ab65db81313a54815adef56b05709e08fce6 commit + 8b10295ec9ddde4f3bfef322b31d3601d6040c62 blob - dfaea693e455367a6ee8fea158b8dbdfa779fed7 blob + 1210e46dd5c67d6073935d5542ac84dc5a6f6a15 --- gotd/gotd.c +++ gotd/gotd.c @@ -1146,6 +1146,14 @@ connect_repo_child(struct gotd_client *client, fatal("socketpair"); memset(&ireq, 0, sizeof(ireq)); + if (strlcpy(ireq.repo_name, repo_proc->repo_name, + sizeof(ireq.repo_name)) >= sizeof(ireq.repo_name)) { + err = got_error_msg(GOT_ERR_NO_SPACE, + "repository name too long"); + close(pipe[0]); + close(pipe[1]); + return err; + } ireq.proc_id = repo_proc->type; /* Pass repo child pipe to session child process. */ @@ -1807,8 +1815,259 @@ run_gotsys_apply(struct gotd_repo *repo) execvp(argv[0], (char * const *)argv); fatal("execvp"); +} + +static const struct got_error * +send_pathlist_elem(struct gotd_imsgev *iev, const char *refname, int imsg_type) +{ + struct gotd_imsg_pathlist_elem ielem; + struct ibuf *wbuf = NULL; + + memset(&ielem, 0, sizeof(ielem)); + ielem.path_len = strlen(refname); + + wbuf = imsg_create(&iev->ibuf, imsg_type, GOTD_PROC_GOTD, gotd.pid, + sizeof(ielem) + ielem.path_len); + if (wbuf == NULL) + return got_error_from_errno_fmt("imsg_create %d", imsg_type); + + if (imsg_add(wbuf, &ielem, sizeof(ielem)) == -1) + return got_error_from_errno_fmt("imsg_add %d", imsg_type); + if (imsg_add(wbuf, refname, ielem.path_len) == -1) + return got_error_from_errno_fmt("imsg_add %d", imsg_type); + + imsg_close(&iev->ibuf, wbuf); + return gotd_imsg_flush(&iev->ibuf); +} + +static const struct got_error * +send_request_timeout(struct gotd_imsgev *iev, struct timeval *timeout) +{ + if (gotd_imsg_compose_event(iev, GOTD_IMSG_REQUEST_TIMEOUT, + GOTD_PROC_GOTD, -1, timeout, sizeof(*timeout)) == -1) { + return got_error_from_errno("imsg compose REQUEST_TIMEOUT"); + } + + return NULL; +} + +static const struct got_error * +send_notification_target_email(struct gotd_imsgev *iev, + struct gotd_notification_target *target) +{ + struct gotd_imsg_notitfication_target_email itarget; + struct ibuf *wbuf = NULL; + + memset(&itarget, 0, sizeof(itarget)); + + if (target->conf.email.sender) + itarget.sender_len = strlen(target->conf.email.sender); + if (target->conf.email.recipient) + itarget.recipient_len = strlen(target->conf.email.recipient); + if (target->conf.email.responder) + itarget.responder_len = strlen(target->conf.email.responder); + if (target->conf.email.hostname) + itarget.hostname_len = strlen(target->conf.email.hostname); + if (target->conf.email.port) + itarget.port_len = strlen(target->conf.email.port); + + wbuf = imsg_create(&iev->ibuf, GOTD_IMSG_NOTIFICATION_TARGET_EMAIL, + 0, 0, sizeof(itarget) + itarget.sender_len + itarget.recipient_len + + itarget.responder_len + itarget.hostname_len + itarget.port_len); + if (wbuf == NULL) { + return got_error_from_errno("imsg_create " + "NOTIFICATION_TARGET_EMAIL"); + } + + if (imsg_add(wbuf, &itarget, sizeof(itarget)) == -1) { + return got_error_from_errno("imsg_add " + "NOTIFICATION_TARGET_EMAIL"); + } + if (target->conf.email.sender) { + if (imsg_add(wbuf, target->conf.email.sender, + itarget.sender_len) == -1) { + return got_error_from_errno("imsg_add " + "NOTIFICATION_TARGET_EMAIL"); + } + } + if (target->conf.email.recipient) { + if (imsg_add(wbuf, target->conf.email.recipient, + itarget.recipient_len) == -1) { + return got_error_from_errno("imsg_add " + "NOTIFICATION_TARGET_EMAIL"); + } + } + if (target->conf.email.responder) { + if (imsg_add(wbuf, target->conf.email.responder, + itarget.responder_len) == -1) { + return got_error_from_errno("imsg_add " + "NOTIFICATION_TARGET_EMAIL"); + } + } + if (target->conf.email.hostname) { + if (imsg_add(wbuf, target->conf.email.hostname, + itarget.hostname_len) == -1) { + return got_error_from_errno("imsg_add " + "NOTIFICATION_TARGET_EMAIL"); + } + } + if (target->conf.email.port) { + if (imsg_add(wbuf, target->conf.email.port, + itarget.port_len) == -1) { + return got_error_from_errno("imsg_add " + "NOTIFICATION_TARGET_EMAIL"); + } + } + + imsg_close(&iev->ibuf, wbuf); + return gotd_imsg_flush(&iev->ibuf); } +static const struct got_error * +send_notification_target_http(struct gotd_imsgev *iev, + struct gotd_notification_target *target) +{ + struct gotd_imsg_notitfication_target_http itarget; + struct ibuf *wbuf = NULL; + + memset(&itarget, 0, sizeof(itarget)); + + itarget.tls = target->conf.http.tls; + itarget.hostname_len = strlen(target->conf.http.hostname); + itarget.port_len = strlen(target->conf.http.port); + itarget.path_len = strlen(target->conf.http.path); + if (target->conf.http.auth) + itarget.auth_len = strlen(target->conf.http.auth); + if (target->conf.http.hmac) + itarget.hmac_len = strlen(target->conf.http.hmac); + + wbuf = imsg_create(&iev->ibuf, GOTD_IMSG_NOTIFICATION_TARGET_HTTP, + 0, 0, sizeof(itarget) + itarget.hostname_len + itarget.port_len + + itarget.path_len + itarget.auth_len + itarget.hmac_len); + if (wbuf == NULL) { + return got_error_from_errno("imsg_create " + "NOTIFICATION_TARGET_HTTP"); + } + + if (imsg_add(wbuf, &itarget, sizeof(itarget)) == -1) { + return got_error_from_errno("imsg_add " + "NOTIFICATION_TARGET_HTTP"); + } + if (imsg_add(wbuf, target->conf.http.hostname, + itarget.hostname_len) == -1) { + return got_error_from_errno("imsg_add " + "NOTIFICATION_TARGET_HTTP"); + } + if (imsg_add(wbuf, target->conf.http.port, + itarget.port_len) == -1) { + return got_error_from_errno("imsg_add " + "NOTIFICATION_TARGET_HTTP"); + } + if (imsg_add(wbuf, target->conf.http.path, + itarget.path_len) == -1) { + return got_error_from_errno("imsg_add " + "NOTIFICATION_TARGET_HTTP"); + } + + if (target->conf.http.auth) { + if (imsg_add(wbuf, target->conf.http.auth, + itarget.auth_len) == -1) { + return got_error_from_errno("imsg_add " + "NOTIFICATION_TARGET_HTTP"); + } + } + if (target->conf.http.hmac) { + if (imsg_add(wbuf, target->conf.http.hmac, + itarget.hmac_len) == -1) { + return got_error_from_errno("imsg_add " + "NOTIFICATION_TARGET_HTTP"); + } + } + + imsg_close(&iev->ibuf, wbuf); + return gotd_imsg_flush(&iev->ibuf); +} + +static const struct got_error * +send_notification_target(struct gotd_imsgev *iev, + struct gotd_notification_target *target) +{ + const struct got_error *err = NULL; + + switch (target->type) { + case GOTD_NOTIFICATION_VIA_EMAIL: + err = send_notification_target_email(iev, target); + break; + case GOTD_NOTIFICATION_VIA_HTTP: + err = send_notification_target_http(iev, target); + break; + default: + log_warn("unsupported notification target type %d", + target->type); + break; + } + + return err; +} + +static const struct got_error * +send_notification_config(struct gotd_imsgev *iev, char *repo_name) +{ + const struct got_error *err = NULL; + struct gotd_repo *repo; + struct got_pathlist_entry *pe; + struct gotd_imsg_pathlist ilist; + struct gotd_notification_target *target; + + memset(&ilist, 0, sizeof(ilist)); + + repo = gotd_find_repo_by_name(repo_name, &gotd.repos); + if (repo == NULL) + return got_error(GOT_ERR_NOT_GIT_REPO); + + ilist.nelem = repo->num_notification_refs; + if (ilist.nelem > 0) { + if (gotd_imsg_compose_event(iev, GOTD_IMSG_NOTIFICATION_REFS, + GOTD_PROC_GOTD, -1, &ilist, sizeof(ilist)) == -1) { + return got_error_from_errno("imsg compose " + "NOTIFICATION_REFS"); + } + + RB_FOREACH(pe, got_pathlist_head, &repo->notification_refs) { + err = send_pathlist_elem(iev, pe->path, + GOTD_IMSG_NOTIFICATION_REFS_ELEM); + if (err) + return err; + } + } + + ilist.nelem = repo->num_notification_ref_namespaces; + if (ilist.nelem > 0) { + if (gotd_imsg_compose_event(iev, + GOTD_IMSG_NOTIFICATION_REF_NAMESPACES, + GOTD_PROC_GOTD, -1, &ilist, sizeof(ilist)) == -1) { + return got_error_from_errno("imsg compose " + "NOTIFICATION_REF_NAMESPACES"); + } + + RB_FOREACH(pe, got_pathlist_head, + &repo->notification_ref_namespaces) { + err = send_pathlist_elem(iev, pe->path, + GOTD_IMSG_NOTIFICATION_REF_NAMESPACES_ELEM); + if (err) + return err; + } + } + + STAILQ_FOREACH(target, &repo->notification_targets, entry) { + err = send_notification_target(iev, target); + if (err) + return err; + } + + return NULL; +} + static void gotd_dispatch_client_session(int fd, short event, void *arg) { @@ -1871,6 +2130,16 @@ gotd_dispatch_client_session(int fd, short event, void err = got_error(GOT_ERR_PRIVSEP_MSG); break; } + if (client_is_writing(client)) { + err = send_request_timeout(iev, + &gotd.request_timeout); + if (err) + break; + err = send_notification_config(iev, + proc->repo_name); + if (err) + break; + } do_start_repo_child = 1; break; case GOTD_IMSG_RUN_GOTSYS_CHECK: @@ -2033,30 +2302,6 @@ connect_notifier_and_session(struct gotd_client *clien } return NULL; -} - -static const struct got_error * -send_protected_ref(struct gotd_imsgev *iev, const char *refname, - int imsg_type) -{ - struct gotd_imsg_pathlist_elem ielem; - struct ibuf *wbuf = NULL; - - memset(&ielem, 0, sizeof(ielem)); - ielem.path_len = strlen(refname); - - wbuf = imsg_create(&iev->ibuf, imsg_type, GOTD_PROC_GOTD, gotd.pid, - sizeof(ielem) + ielem.path_len); - if (wbuf == NULL) - return got_error_from_errno_fmt("imsg_create %d", imsg_type); - - if (imsg_add(wbuf, &ielem, sizeof(ielem)) == -1) - return got_error_from_errno_fmt("imsg_add %d", imsg_type); - if (imsg_add(wbuf, refname, ielem.path_len) == -1) - return got_error_from_errno_fmt("imsg_add %d", imsg_type); - - imsg_close(&iev->ibuf, wbuf); - return gotd_imsg_flush(&iev->ibuf); } static const struct got_error * @@ -2084,7 +2329,7 @@ send_protected_refs(struct gotd_imsgev *iev, const cha RB_FOREACH(pe, got_pathlist_head, &repo->protected_tag_namespaces) { - err = send_protected_ref(iev, pe->path, + err = send_pathlist_elem(iev, pe->path, GOTD_IMSG_PROTECTED_TAG_NAMESPACES_ELEM); if (err) return err; @@ -2102,7 +2347,7 @@ send_protected_refs(struct gotd_imsgev *iev, const cha RB_FOREACH(pe, got_pathlist_head, &repo->protected_branch_namespaces) { - err = send_protected_ref(iev, pe->path, + err = send_pathlist_elem(iev, pe->path, GOTD_IMSG_PROTECTED_BRANCH_NAMESPACES_ELEM); if (err) return err; @@ -2118,7 +2363,7 @@ send_protected_refs(struct gotd_imsgev *iev, const cha } RB_FOREACH(pe, got_pathlist_head, &repo->protected_branches) { - err = send_protected_ref(iev, pe->path, + err = send_pathlist_elem(iev, pe->path, GOTD_IMSG_PROTECTED_BRANCHES_ELEM); if (err) return err; @@ -2747,7 +2992,8 @@ main(int argc, char **argv) } if (proc_id != GOTD_PROC_LISTEN && proc_id != GOTD_PROC_AUTH && - proc_id != GOTD_PROC_REPO_WRITE) { + proc_id != GOTD_PROC_REPO_WRITE && + proc_id != GOTD_PROC_SESSION_WRITE) { if (gotd_parse_config(confpath, proc_id, secrets, &gotd) != 0) return 1; @@ -2941,11 +3187,8 @@ main(int argc, char **argv) err(1, "pledge"); #endif apply_unveil_repo_readwrite(repo_path); - repo = gotd_find_repo_by_path(repo_path, &gotd); - if (repo == NULL) - fatalx("no repository for path %s", repo_path); - session_write_main(title, repo_path, pack_fds, temp_fds, tmp_fd, - &gotd.request_timeout, repo); + session_write_main(title, repo_path, pack_fds, temp_fds, + tmp_fd); /* NOTREACHED */ break; case GOTD_PROC_REPO_READ: blob - bc67d2befa7742192232f3c52b8845a86648e643 blob + 95ebcef04adc3f9d2afc5df131874ee0f9170ed7 --- gotd/gotd.h +++ gotd/gotd.h @@ -141,7 +141,9 @@ struct gotd_repo { size_t nprotected_branches; struct got_pathlist_head notification_refs; + size_t num_notification_refs; struct got_pathlist_head notification_ref_namespaces; + size_t num_notification_ref_namespaces; struct gotd_notification_targets notification_targets; }; TAILQ_HEAD(gotd_repolist, gotd_repo); @@ -247,6 +249,7 @@ enum gotd_imsg_type { GOTD_IMSG_LISTENER_READY, GOTD_IMSG_LISTEN_SOCKET, GOTD_IMSG_CONNECTION_LIMIT, + GOTD_IMSG_REQUEST_TIMEOUT, GOTD_IMSG_DISCONNECT, GOTD_IMSG_CONNECT, @@ -270,6 +273,12 @@ enum gotd_imsg_type { GOTD_IMSG_PROTECTED_BRANCHES_ELEM, /* Notify child process. */ + GOTD_IMSG_NOTIFICATION_REFS, + GOTD_IMSG_NOTIFICATION_REFS_ELEM, + GOTD_IMSG_NOTIFICATION_REF_NAMESPACES, + GOTD_IMSG_NOTIFICATION_REF_NAMESPACES_ELEM, + GOTD_IMSG_NOTIFICATION_TARGET_EMAIL, + GOTD_IMSG_NOTIFICATION_TARGET_HTTP, GOTD_IMSG_CONNECT_NOTIFIER, GOTD_IMSG_CONNECT_SESSION, GOTD_IMSG_NOTIFY, @@ -521,6 +530,7 @@ struct gotd_imsg_connect { /* Structure for GOTD_IMSG_CONNECT_REPO_CHILD. */ struct gotd_imsg_connect_repo_child { + char repo_name[NAME_MAX]; enum gotd_procid proc_id; /* repo child imsg pipe is passed via imsg fd */ @@ -549,6 +559,8 @@ struct gotd_imsg_auth_access_rule { * GOTD_IMSG_PROTECTED_TAG_NAMESPACES * GOTD_IMSG_PROTECTED_BRANCH_NAMESPACES * GOTD_IMSG_PROTECTED_BRANCHES + * GOTD_IMSG_NOTIFY_BRANCHES + * GOTD_IMSG_NOTIFY_REF_NAMESPACES */ struct gotd_imsg_pathlist { size_t nelem; @@ -561,6 +573,8 @@ struct gotd_imsg_pathlist { * GOTD_IMSG_PROTECTED_TAG_NAMESPACES_ELEM * GOTD_IMSG_PROTECTED_BRANCH_NAMESPACES_ELEM * GOTD_IMSG_PROTECTED_BRANCHES_ELEM + * GOTD_IMSG_NOTIFY_BRANCHES_ELEM + * GOTD_IMSG_NOTIFY_REF_NAMESPACES_ELEM */ struct gotd_imsg_pathlist_elem { size_t path_len; @@ -568,8 +582,37 @@ struct gotd_imsg_pathlist_elem { /* Followed by path_len bytes. */ /* Followed by data_len bytes. */ +}; + +/* Structure for GOTD_IMSG_NOTIFICATION_TARGET_EMAIL. */ +struct gotd_imsg_notitfication_target_email { + size_t sender_len; + size_t recipient_len; + size_t responder_len; + size_t hostname_len; + size_t port_len; + + /* + * Followed by sender_len + responder_len + responder_len + + * hostname_len + port_len bytes. + */ }; +/* Structure for GOTD_IMSG_NOTIFICATION_TARGET_HTTP. */ +struct gotd_imsg_notitfication_target_http { + int tls; + size_t hostname_len; + size_t port_len; + size_t path_len; + size_t auth_len; + size_t hmac_len;; + + /* + * Followed by hostname_len + port_len + path_len + auth_len + + * hmac_len bytes. + */ +}; + /* Structures for GOTD_IMSG_NOTIFY. */ enum gotd_notification_action { GOTD_NOTIF_ACTION_CREATED, @@ -622,3 +665,6 @@ void gotd_imsg_send_ack(struct got_object_id *, struct uint32_t, pid_t); void gotd_imsg_send_nak(struct got_object_id *, struct imsgbuf *, uint32_t, pid_t); +const struct got_error *gotd_imsg_recv_pathlist(size_t *, struct imsg *); +const struct got_error *gotd_imsg_recv_pathlist_elem(struct imsg *, + struct got_pathlist_head *); blob - 476171315d6b76a7222751f268472e1275f1373b blob + e0c130803906829b51d5f392e75336ea4f953991 --- gotd/imsg.c +++ gotd/imsg.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -205,3 +206,49 @@ gotd_imsg_forward(struct gotd_imsgev *iev, struct imsg return gotd_imsg_compose_event(iev, imsg->hdr.type, imsg->hdr.peerid, fd, imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE); } + +const struct got_error * +gotd_imsg_recv_pathlist(size_t *npaths, struct imsg *imsg) +{ + struct gotd_imsg_pathlist ilist; + size_t datalen; + + datalen = imsg->hdr.len - IMSG_HEADER_SIZE; + if (datalen != sizeof(ilist)) + return got_error(GOT_ERR_PRIVSEP_LEN); + memcpy(&ilist, imsg->data, sizeof(ilist)); + + if (ilist.nelem == 0) + return got_error(GOT_ERR_PRIVSEP_LEN); + + *npaths = ilist.nelem; + return NULL; +} + +const struct got_error * +gotd_imsg_recv_pathlist_elem(struct imsg *imsg, struct got_pathlist_head *paths) +{ + const struct got_error *err = NULL; + struct gotd_imsg_pathlist_elem ielem; + size_t datalen; + char *path; + struct got_pathlist_entry *pe; + + datalen = imsg->hdr.len - IMSG_HEADER_SIZE; + if (datalen < sizeof(ielem)) + return got_error(GOT_ERR_PRIVSEP_LEN); + memcpy(&ielem, imsg->data, sizeof(ielem)); + + if (datalen != sizeof(ielem) + ielem.path_len) + return got_error(GOT_ERR_PRIVSEP_LEN); + + path = strndup(imsg->data + sizeof(ielem), ielem.path_len); + if (path == NULL) + return got_error_from_errno("strndup"); + + err = got_pathlist_insert(&pe, paths, path, NULL); + if (err || pe == NULL) + free(path); + return err; +} + blob - 4bf1400741232fd1549cacb7f3b0cd4cdd95cf25 blob + daaf2c2aa310ab499970f60fa62149dff6b06347 --- gotd/parse.y +++ gotd/parse.y @@ -328,7 +328,6 @@ notifyflags_l : notifyflags optnl notifyflags_l notifyflags : BRANCH STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_branch(new_repo, $2)) { free($2); @@ -339,7 +338,6 @@ notifyflags : BRANCH STRING { } | REFERENCE NAMESPACE STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_ref_namespace(new_repo, $3)) { free($3); @@ -350,7 +348,6 @@ notifyflags : BRANCH STRING { } | EMAIL TO STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_email(new_repo, NULL, $3, NULL, NULL, NULL)) { @@ -362,7 +359,6 @@ notifyflags : BRANCH STRING { } | EMAIL FROM STRING TO STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_email(new_repo, $3, $5, NULL, NULL, NULL)) { @@ -376,7 +372,6 @@ notifyflags : BRANCH STRING { } | EMAIL TO STRING REPLY TO STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_email(new_repo, NULL, $3, $6, NULL, NULL)) { @@ -390,7 +385,6 @@ notifyflags : BRANCH STRING { } | EMAIL FROM STRING TO STRING REPLY TO STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_email(new_repo, $3, $5, $8, NULL, NULL)) { @@ -406,7 +400,6 @@ notifyflags : BRANCH STRING { } | EMAIL TO STRING RELAY STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_email(new_repo, NULL, $3, NULL, $5, NULL)) { @@ -420,7 +413,6 @@ notifyflags : BRANCH STRING { } | EMAIL FROM STRING TO STRING RELAY STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_email(new_repo, $3, $5, NULL, $7, NULL)) { @@ -436,7 +428,6 @@ notifyflags : BRANCH STRING { } | EMAIL TO STRING REPLY TO STRING RELAY STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_email(new_repo, NULL, $3, $6, $8, NULL)) { @@ -452,7 +443,6 @@ notifyflags : BRANCH STRING { } | EMAIL FROM STRING TO STRING REPLY TO STRING RELAY STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_email(new_repo, $3, $5, $8, $10, NULL)) { @@ -470,7 +460,6 @@ notifyflags : BRANCH STRING { } | EMAIL TO STRING RELAY STRING PORT STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_email(new_repo, NULL, $3, NULL, $5, $7)) { @@ -486,7 +475,6 @@ notifyflags : BRANCH STRING { } | EMAIL FROM STRING TO STRING RELAY STRING PORT STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_email(new_repo, $3, $5, NULL, $7, $9)) { @@ -504,7 +492,6 @@ notifyflags : BRANCH STRING { } | EMAIL TO STRING REPLY TO STRING RELAY STRING PORT STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_email(new_repo, NULL, $3, $6, $8, $10)) { @@ -522,7 +509,6 @@ notifyflags : BRANCH STRING { } | EMAIL FROM STRING TO STRING REPLY TO STRING RELAY STRING PORT STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_email(new_repo, $3, $5, $8, $10, $12)) { @@ -542,7 +528,6 @@ notifyflags : BRANCH STRING { } | EMAIL TO STRING RELAY STRING PORT NUMBER { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_email(new_repo, NULL, $3, NULL, $5, port_sprintf($7))) { @@ -556,7 +541,6 @@ notifyflags : BRANCH STRING { } | EMAIL FROM STRING TO STRING RELAY STRING PORT NUMBER { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_email(new_repo, $3, $5, NULL, $7, port_sprintf($9))) { @@ -572,7 +556,6 @@ notifyflags : BRANCH STRING { } | EMAIL TO STRING REPLY TO STRING RELAY STRING PORT NUMBER { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_email(new_repo, NULL, $3, $6, $8, port_sprintf($10))) { @@ -588,7 +571,6 @@ notifyflags : BRANCH STRING { } | EMAIL FROM STRING TO STRING REPLY TO STRING RELAY STRING PORT NUMBER { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_email(new_repo, $3, $5, $8, $10, port_sprintf($12))) { @@ -606,7 +588,6 @@ notifyflags : BRANCH STRING { } | URL STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_http(new_repo, $2, NULL, NULL, 0)) { @@ -618,7 +599,6 @@ notifyflags : BRANCH STRING { } | URL STRING AUTH STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_http(new_repo, $2, $4, NULL, 0)) { @@ -632,7 +612,6 @@ notifyflags : BRANCH STRING { } | URL STRING AUTH STRING INSECURE { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_http(new_repo, $2, $4, NULL, 1)) { @@ -646,7 +625,6 @@ notifyflags : BRANCH STRING { } | URL STRING HMAC STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_http(new_repo, $2, NULL, $4, 0)) { @@ -660,7 +638,6 @@ notifyflags : BRANCH STRING { } | URL STRING AUTH STRING HMAC STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_http(new_repo, $2, $4, $6, 0)) { @@ -676,7 +653,6 @@ notifyflags : BRANCH STRING { } | URL STRING AUTH STRING INSECURE HMAC STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_NOTIFY) { if (conf_notify_http(new_repo, $2, $4, $7, 1)) { @@ -704,7 +680,6 @@ repository : REPOSITORY STRING { } if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_GITWRAPPER | gotd_proc_id == GOTD_PROC_NOTIFY) { new_repo = conf_new_repo($2); @@ -716,7 +691,6 @@ repository : REPOSITORY STRING { repoopts1 : PATH STRING { if (gotd_proc_id == GOTD_PROC_GOTD || - gotd_proc_id == GOTD_PROC_SESSION_WRITE || gotd_proc_id == GOTD_PROC_GITWRAPPER || gotd_proc_id == GOTD_PROC_NOTIFY) { if (!got_path_is_absolute($2)) { @@ -1523,6 +1497,8 @@ conf_notify_branch(struct gotd_repo *repo, char *branc } if (pe == NULL) free(refname); + else + repo->num_notification_refs++; return 0; } @@ -1552,6 +1528,8 @@ conf_notify_ref_namespace(struct gotd_repo *repo, char } if (pe == NULL) free(s); + else + repo->num_notification_ref_namespaces++; return 0; } blob - 7d8e2cf8d5bc2251c71eadad35e0d5e810910b00 blob + 219767f09e11b7fc1231a8076ebabe3276c1fb22 --- gotd/repo_write.c +++ gotd/repo_write.c @@ -2727,55 +2727,10 @@ recv_connect(struct imsg *imsg) event_set(&iev->ev, iev->ibuf.fd, EV_READ, repo_write_dispatch_session, iev); gotd_imsg_event_add(iev); - - return NULL; -} - -static const struct got_error * -recv_pathlist(size_t *npaths, struct imsg *imsg) -{ - struct gotd_imsg_pathlist ilist; - size_t datalen; - - datalen = imsg->hdr.len - IMSG_HEADER_SIZE; - if (datalen != sizeof(ilist)) - return got_error(GOT_ERR_PRIVSEP_LEN); - memcpy(&ilist, imsg->data, sizeof(ilist)); - if (ilist.nelem == 0) - return got_error(GOT_ERR_PRIVSEP_LEN); - - *npaths = ilist.nelem; return NULL; } -static const struct got_error * -recv_pathlist_elem(struct imsg *imsg, struct got_pathlist_head *paths) -{ - const struct got_error *err = NULL; - struct gotd_imsg_pathlist_elem ielem; - size_t datalen; - char *path; - struct got_pathlist_entry *pe; - - datalen = imsg->hdr.len - IMSG_HEADER_SIZE; - if (datalen < sizeof(ielem)) - return got_error(GOT_ERR_PRIVSEP_LEN); - memcpy(&ielem, imsg->data, sizeof(ielem)); - - if (datalen != sizeof(ielem) + ielem.path_len) - return got_error(GOT_ERR_PRIVSEP_LEN); - - path = strndup(imsg->data + sizeof(ielem), ielem.path_len); - if (path == NULL) - return got_error_from_errno("strndup"); - - err = got_pathlist_insert(&pe, paths, path, NULL); - if (err || pe == NULL) - free(path); - return err; -} - static void repo_write_dispatch(int fd, short event, void *arg) { @@ -2819,7 +2774,7 @@ repo_write_dispatch(int fd, short event, void *arg) err = got_error(GOT_ERR_PRIVSEP_MSG); break; } - err = recv_pathlist(&npaths, &imsg); + err = gotd_imsg_recv_pathlist(&npaths, &imsg); if (err) break; repo_write.protected_refs_cur = @@ -2833,7 +2788,7 @@ repo_write_dispatch(int fd, short event, void *arg) err = got_error(GOT_ERR_PRIVSEP_MSG); break; } - err = recv_pathlist(&npaths, &imsg); + err = gotd_imsg_recv_pathlist(&npaths, &imsg); if (err) break; repo_write.protected_refs_cur = @@ -2847,7 +2802,7 @@ repo_write_dispatch(int fd, short event, void *arg) err = got_error(GOT_ERR_PRIVSEP_MSG); break; } - err = recv_pathlist(&npaths, &imsg); + err = gotd_imsg_recv_pathlist(&npaths, &imsg); if (err) break; repo_write.protected_refs_cur = @@ -2865,7 +2820,7 @@ repo_write_dispatch(int fd, short event, void *arg) err = got_error(GOT_ERR_PRIVSEP_MSG); break; } - err = recv_pathlist_elem(&imsg, + err = gotd_imsg_recv_pathlist_elem(&imsg, repo_write.protected_refs_cur); if (err) break; blob - 013664a6ec707d98777ecf00c0180d760ca947d7 blob + d139091dacf9e073b2a167c8dca8537a36c7c461 --- gotd/session_write.c +++ gotd/session_write.c @@ -76,7 +76,7 @@ static struct gotd_session_write { pid_t pid; const char *title; struct got_repository *repo; - struct gotd_repo *repo_cfg; + char repo_name[NAME_MAX]; int *pack_fds; int *temp_fds; int content_fd; @@ -85,6 +85,12 @@ static struct gotd_session_write { struct timeval request_timeout; enum gotd_session_write_state state; struct gotd_imsgev repo_child_iev; + struct got_pathlist_head notification_refs; + struct got_pathlist_head notification_ref_namespaces; + size_t num_notification_refs_needed; + size_t num_notification_refs_received; + struct got_pathlist_head *notification_refs_cur; + struct gotd_notification_targets notification_targets; } gotd_session; static struct gotd_session_client { @@ -258,8 +264,8 @@ request_gotsys_conf(struct gotd_imsgev *iev) static int need_packfile_verification(void) { - return (strcmp(gotd_session.repo_cfg->name, "gotsys") == 0 || - strcmp(gotd_session.repo_cfg->name, "gotsys.git") == 0); + return (strcmp(gotd_session.repo_name, "gotsys") == 0 || + strcmp(gotd_session.repo_name, "gotsys.git") == 0); } static const struct got_error * @@ -556,23 +562,22 @@ queue_notification(struct got_object_id *old_id, struc struct got_repository *repo, struct got_reference *ref) { const struct got_error *err = NULL; - struct gotd_repo *repo_cfg = gotd_session.repo_cfg; struct gotd_imsgev *iev = &gotd_session.repo_child_iev; struct got_pathlist_entry *pe; struct gotd_session_notif *notif; if (iev->ibuf.fd == -1 || - STAILQ_EMPTY(&repo_cfg->notification_targets)) + STAILQ_EMPTY(&gotd_session.notification_targets)) return NULL; /* notifications unused */ - RB_FOREACH(pe, got_pathlist_head, &repo_cfg->notification_refs) { + RB_FOREACH(pe, got_pathlist_head, &gotd_session.notification_refs) { const char *refname = pe->path; if (strcmp(got_ref_get_name(ref), refname) == 0) break; } if (pe == NULL) { RB_FOREACH(pe, got_pathlist_head, - &repo_cfg->notification_ref_namespaces) { + &gotd_session.notification_ref_namespaces) { const char *namespace = pe->path; err = validate_namespace(namespace); @@ -589,8 +594,8 @@ queue_notification(struct got_object_id *old_id, struc * configuration file then only send notifications if a match * was found. */ - if (pe == NULL && (!RB_EMPTY(&repo_cfg->notification_refs) || - !RB_EMPTY(&repo_cfg->notification_ref_namespaces))) + if (pe == NULL && (!RB_EMPTY(&gotd_session.notification_refs) || + !RB_EMPTY(&gotd_session.notification_ref_namespaces))) return NULL; notif = calloc(1, sizeof(*notif)); @@ -710,11 +715,11 @@ forward_notification(struct gotd_session_client *clien goto done; } - strlcpy(inotify.repo_name, gotd_session.repo_cfg->name, + strlcpy(inotify.repo_name, gotd_session.repo_name, sizeof(inotify.repo_name)); snprintf(inotify.subject_line, sizeof(inotify.subject_line), - "%s: %s %s %s: %.12s", gotd_session.repo_cfg->name, + "%s: %s %s %s: %.12s", gotd_session.repo_name, client->username, action, notif->refname, id_str); inotify.username_len = strlen(client->username); @@ -1732,6 +1737,12 @@ recv_repo_child(struct imsg *imsg) fd = imsg_get_fd(imsg); if (fd == -1) return got_error(GOT_ERR_PRIVSEP_NO_FD); + + if (strlcpy(gotd_session.repo_name, ichild.repo_name, + sizeof(gotd_session.repo_name)) >= sizeof(gotd_session.repo_name)) { + return got_error_msg(GOT_ERR_NO_SPACE, + "repository name too long"); + } if (imsgbuf_init(&gotd_session.repo_child_iev.ibuf, fd) == -1) { close(fd); @@ -1754,6 +1765,240 @@ recv_repo_child(struct imsg *imsg) } static void +free_notification_target(struct gotd_notification_target *target) +{ + if (target == NULL) + return; + + switch (target->type) { + case GOTD_NOTIFICATION_VIA_EMAIL: + free(target->conf.email.sender); + free(target->conf.email.recipient); + free(target->conf.email.responder); + free(target->conf.email.hostname); + free(target->conf.email.port); + break; + case GOTD_NOTIFICATION_VIA_HTTP: + free(target->conf.http.hostname); + free(target->conf.http.port); + free(target->conf.http.path); + free(target->conf.http.auth); + free(target->conf.http.hmac); + break; + default: + break; + } + + free(target); +} + +static const struct got_error * +recv_notification_target_email(struct imsg *imsg) +{ + const struct got_error *err = NULL; + struct gotd_imsg_notitfication_target_email itarget; + struct gotd_notification_target *target; + size_t datalen; + + datalen = imsg->hdr.len - IMSG_HEADER_SIZE; + if (datalen < sizeof(itarget)) + return got_error(GOT_ERR_PRIVSEP_LEN); + memcpy(&itarget, imsg->data, sizeof(itarget)); + + if (datalen != sizeof(itarget) + itarget.sender_len + + itarget.recipient_len + itarget.responder_len + + itarget.hostname_len + itarget.port_len) + return got_error(GOT_ERR_PRIVSEP_LEN); + if (itarget.recipient_len == 0) + return got_error(GOT_ERR_PRIVSEP_LEN); + + target = calloc(1, sizeof(*target)); + if (target == NULL) + return got_error_from_errno("calloc"); + + target->type = GOTD_NOTIFICATION_VIA_EMAIL; + + if (itarget.sender_len) { + target->conf.email.sender = strndup(imsg->data + + sizeof(itarget), itarget.sender_len); + if (target->conf.email.sender == NULL) { + err = got_error_from_errno("strndup"); + goto done; + } + if (strlen(target->conf.email.sender) != itarget.sender_len) { + err = got_error(GOT_ERR_PRIVSEP_LEN); + goto done; + } + } + + target->conf.email.recipient = strndup(imsg->data + sizeof(itarget) + + itarget.sender_len, itarget.recipient_len); + if (target->conf.email.recipient == NULL) { + err = got_error_from_errno("strndup"); + goto done; + } + if (strlen(target->conf.email.recipient) != itarget.recipient_len) { + err = got_error(GOT_ERR_PRIVSEP_LEN); + goto done; + } + + if (itarget.responder_len) { + target->conf.email.responder = strndup(imsg->data + + sizeof(itarget) + itarget.sender_len + itarget.recipient_len, + itarget.responder_len); + if (target->conf.email.responder == NULL) { + err = got_error_from_errno("strndup"); + goto done; + } + if (strlen(target->conf.email.responder) != + itarget.responder_len) { + err = got_error(GOT_ERR_PRIVSEP_LEN); + goto done; + } + } + + if (itarget.hostname_len) { + target->conf.email.hostname = strndup(imsg->data + + sizeof(itarget) + itarget.sender_len + + itarget.recipient_len + itarget.responder_len, + itarget.hostname_len); + if (target->conf.email.hostname == NULL) { + err = got_error_from_errno("strndup"); + goto done; + } + if (strlen(target->conf.email.hostname) != + itarget.hostname_len) { + err = got_error(GOT_ERR_PRIVSEP_LEN); + goto done; + } + } + + if (itarget.port_len) { + target->conf.email.port = strndup(imsg->data + + sizeof(itarget) + itarget.sender_len + + itarget.recipient_len + itarget.responder_len + + itarget.hostname_len, itarget.port_len); + if (target->conf.email.port == NULL) { + err = got_error_from_errno("strndup"); + goto done; + } + if (strlen(target->conf.email.port) != itarget.port_len) { + err = got_error(GOT_ERR_PRIVSEP_LEN); + goto done; + } + } + + STAILQ_INSERT_TAIL(&gotd_session.notification_targets, target, entry); + target = NULL; +done: + if (err) + free_notification_target(target); + return err; +} + +static const struct got_error * +recv_notification_target_http(struct imsg *imsg) +{ + const struct got_error *err = NULL; + struct gotd_imsg_notitfication_target_http itarget; + struct gotd_notification_target *target; + size_t datalen; + + datalen = imsg->hdr.len - IMSG_HEADER_SIZE; + if (datalen < sizeof(itarget)) + return got_error(GOT_ERR_PRIVSEP_LEN); + memcpy(&itarget, imsg->data, sizeof(itarget)); + + if (datalen != sizeof(itarget) + itarget.hostname_len + + itarget.port_len + itarget.path_len + itarget.auth_len + + itarget.hmac_len) + return got_error(GOT_ERR_PRIVSEP_LEN); + + if (itarget.hostname_len == 0 || itarget.port_len == 0 || + itarget.path_len == 0) + return got_error(GOT_ERR_PRIVSEP_LEN); + + target = calloc(1, sizeof(*target)); + if (target == NULL) + return got_error_from_errno("calloc"); + + target->type = GOTD_NOTIFICATION_VIA_HTTP; + + target->conf.http.tls = itarget.tls; + + target->conf.http.hostname = strndup(imsg->data + + sizeof(itarget), itarget.hostname_len); + if (target->conf.http.hostname == NULL) { + err = got_error_from_errno("strndup"); + goto done; + } + if (strlen(target->conf.http.hostname) != itarget.hostname_len) { + err = got_error(GOT_ERR_PRIVSEP_LEN); + goto done; + } + + target->conf.http.port = strndup(imsg->data + sizeof(itarget) + + itarget.hostname_len, itarget.port_len); + if (target->conf.http.port == NULL) { + err = got_error_from_errno("strndup"); + goto done; + } + if (strlen(target->conf.http.port) != itarget.port_len) { + err = got_error(GOT_ERR_PRIVSEP_LEN); + goto done; + } + + target->conf.http.path = strndup(imsg->data + + sizeof(itarget) + itarget.hostname_len + itarget.port_len, + itarget.path_len); + if (target->conf.http.path == NULL) { + err = got_error_from_errno("strndup"); + goto done; + } + if (strlen(target->conf.http.path) != itarget.path_len) { + err = got_error(GOT_ERR_PRIVSEP_LEN); + goto done; + } + + if (itarget.auth_len) { + target->conf.http.auth = strndup(imsg->data + + sizeof(itarget) + itarget.hostname_len + + itarget.port_len + itarget.path_len, + itarget.auth_len); + if (target->conf.http.auth == NULL) { + err = got_error_from_errno("strndup"); + goto done; + } + if (strlen(target->conf.http.auth) != itarget.auth_len) { + err = got_error(GOT_ERR_PRIVSEP_LEN); + goto done; + } + } + + if (itarget.hmac_len) { + target->conf.http.hmac = strndup(imsg->data + + sizeof(itarget) + itarget.hostname_len + + itarget.port_len + itarget.path_len + + itarget.auth_len, itarget.hmac_len); + if (target->conf.http.hmac == NULL) { + err = got_error_from_errno("strndup"); + goto done; + } + if (strlen(target->conf.http.hmac) != itarget.hmac_len) { + err = got_error(GOT_ERR_PRIVSEP_LEN); + goto done; + } + } + + STAILQ_INSERT_TAIL(&gotd_session.notification_targets, target, entry); + target = NULL; +done: + if (err) + free_notification_target(target); + return err; +} + +static void session_dispatch(int fd, short event, void *arg) { const struct got_error *err = NULL; @@ -1764,6 +2009,7 @@ session_dispatch(int fd, short event, void *arg) ssize_t n; int shut = 0; struct imsg imsg; + size_t npaths; if (event & EV_READ) { if ((n = imsgbuf_read(ibuf)) == -1) @@ -1802,7 +2048,61 @@ session_dispatch(int fd, short event, void *arg) break; case GOTD_IMSG_DISCONNECT: do_disconnect = 1; + break; + case GOTD_IMSG_NOTIFICATION_REFS: + if (gotd_session.notification_refs_cur != NULL || + gotd_session.num_notification_refs_needed != 0) { + err = got_error(GOT_ERR_PRIVSEP_MSG); + break; + } + err = gotd_imsg_recv_pathlist(&npaths, &imsg); + if (err) + break; + gotd_session.notification_refs_cur = + &gotd_session.notification_refs; + gotd_session.num_notification_refs_needed = npaths; + gotd_session.num_notification_refs_received = 0; + break; + case GOTD_IMSG_NOTIFICATION_REF_NAMESPACES: + if (gotd_session.notification_refs_cur != NULL || + gotd_session.num_notification_refs_needed != 0) { + err = got_error(GOT_ERR_PRIVSEP_MSG); + break; + } + err = gotd_imsg_recv_pathlist(&npaths, &imsg); + if (err) + break; + gotd_session.notification_refs_cur = + &gotd_session.notification_ref_namespaces; + gotd_session.num_notification_refs_needed = npaths; + gotd_session.num_notification_refs_received = 0; break; + break; + case GOTD_IMSG_NOTIFICATION_REFS_ELEM: + case GOTD_IMSG_NOTIFICATION_REF_NAMESPACES_ELEM: + if (gotd_session.notification_refs_cur == NULL || + gotd_session.num_notification_refs_needed == 0 || + gotd_session.num_notification_refs_received >= + gotd_session.num_notification_refs_needed) { + err = got_error(GOT_ERR_PRIVSEP_MSG); + break; + } + err = gotd_imsg_recv_pathlist_elem(&imsg, + gotd_session.notification_refs_cur); + if (err) + break; + if (++gotd_session.num_notification_refs_received >= + gotd_session.num_notification_refs_needed) { + gotd_session.notification_refs_cur = NULL; + gotd_session.num_notification_refs_needed = 0; + } + break; + case GOTD_IMSG_NOTIFICATION_TARGET_EMAIL: + err = recv_notification_target_email(&imsg); + break; + case GOTD_IMSG_NOTIFICATION_TARGET_HTTP: + err = recv_notification_target_http(&imsg); + break; case GOTD_IMSG_CONNECT_NOTIFIER: err = recv_notifier(&imsg); break; @@ -1883,8 +2183,7 @@ done: void session_write_main(const char *title, const char *repo_path, - int *pack_fds, int *temp_fds, int content_fd, - struct timeval *request_timeout, struct gotd_repo *repo_cfg) + int *pack_fds, int *temp_fds, int content_fd) { const struct got_error *err = NULL; struct event evsigint, evsigterm, evsighup, evsigusr1; @@ -1896,9 +2195,11 @@ session_write_main(const char *title, const char *repo gotd_session.pack_fds = pack_fds; gotd_session.temp_fds = temp_fds; gotd_session.content_fd = content_fd; - memcpy(&gotd_session.request_timeout, request_timeout, - sizeof(gotd_session.request_timeout)); - gotd_session.repo_cfg = repo_cfg; + gotd_session.request_timeout.tv_sec = GOTD_DEFAULT_REQUEST_TIMEOUT; + gotd_session.request_timeout.tv_usec = 0; + RB_INIT(&gotd_session.notification_refs); + RB_INIT(&gotd_session.notification_ref_namespaces); + STAILQ_INIT(&gotd_session.notification_targets); if (imsgbuf_init(&gotd_session.notifier_iev.ibuf, -1) == -1) { err = got_error_from_errno("imsgbuf_init"); blob - ee305618aa6d63a642f30434e275cd9891eef086 blob + d49eece585f1b9c8fb4214f0727c03bceda85676 --- gotd/session_write.h +++ gotd/session_write.h @@ -14,5 +14,4 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -void session_write_main(const char *, const char *, int *, int *, int, - struct timeval *, struct gotd_repo *); +void session_write_main(const char *, const char *, int *, int *, int);