commit - a994c1755a6f17171db0bd9a56efd28f03954949
commit + 1916c2111fb07adb0485c50211d75a35bcbac452
blob - 020795e6496b2f22da447417c67793d1b001f5f6
blob + 4ce0a0931df0eff3514a34017c6e52d0312cac1d
--- gotd/gotd.c
+++ gotd/gotd.c
err = ensure_client_is_not_writing(client);
if (err)
return err;
- repo = gotd_find_repo_by_name(ireq.repo_name, &gotd);
+ repo = gotd_find_repo_by_name(ireq.repo_name, &gotd.repos);
if (repo == NULL)
return got_error(GOT_ERR_NOT_GIT_REPO);
err = start_auth_child(client, GOTD_AUTH_READ, repo,
err = ensure_client_is_not_reading(client);
if (err)
return err;
- repo = gotd_find_repo_by_name(ireq.repo_name, &gotd);
+ repo = gotd_find_repo_by_name(ireq.repo_name, &gotd.repos);
if (repo == NULL)
return got_error(GOT_ERR_NOT_GIT_REPO);
err = start_auth_child(client,
goto done;
}
- repo = gotd_find_repo_by_name(client->auth->repo_name, &gotd);
+ repo = gotd_find_repo_by_name(client->auth->repo_name, &gotd.repos);
if (repo == NULL) {
err = got_error(GOT_ERR_NOT_GIT_REPO);
goto done;
struct gotd_repo *repo;
const char *name = client->session->repo_name;
- repo = gotd_find_repo_by_name(name, &gotd);
+ repo = gotd_find_repo_by_name(name, &gotd.repos);
if (repo != NULL) {
enum gotd_procid proc_type;
apply_unveil_repo_readonly(repo_path, 1);
else
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_main(title, repo_path, pack_fds, temp_fds,
- &gotd.request_timeout, proc_id);
+ &gotd.request_timeout,
+ &repo->notification_refs,
+ &repo->notification_ref_namespaces,
+ repo->summarize_notifications,
+ &repo->notification_targets,
+ proc_id);
/* NOTREACHED */
break;
case PROC_REPO_READ:
blob - dcc070cb7fdab140e8aa219b04f1423c773bd7b0
blob + 97b77d29898f9e0859f385d519bf8e52600928f0
--- gotd/gotd.h
+++ gotd/gotd.h
};
int parse_config(const char *, enum gotd_procid, struct gotd *);
-struct gotd_repo *gotd_find_repo_by_name(const char *, struct gotd *);
+struct gotd_repo *gotd_find_repo_by_name(const char *, struct gotd_repolist *);
struct gotd_repo *gotd_find_repo_by_path(const char *, struct gotd *);
struct gotd_uid_connection_limit *gotd_find_uid_connection_limit(
struct gotd_uid_connection_limit *limits, size_t nlimits, uid_t uid);
blob - bbb8bc71084a768db3ea5cabaf3053203b4ccfcc
blob + d8541cd4c711e5330e5a012fabb0dcc19ef71550
--- gotd/notify.c
+++ gotd/notify.c
if (imsg->fd == -1)
return got_error(GOT_ERR_PRIVSEP_NO_FD);
- TAILQ_FOREACH(repo, gotd_notify.repos, entry) {
- if (strcmp(repo->name, inotify.repo_name) == 0)
- break;
- }
+ repo = gotd_find_repo_by_name(inotify.repo_name, gotd_notify.repos);
if (repo == NULL)
return got_error(GOT_ERR_PRIVSEP_MSG);
blob - e6b74faab16c4cb5b6fd21b2629f83b08210a2ed
blob + 3b2080734f2ecae8a86ee65092221758aafc2f4a
--- gotd/parse.y
+++ gotd/parse.y
}
struct gotd_repo *
-gotd_find_repo_by_name(const char *repo_name, struct gotd *gotd)
+gotd_find_repo_by_name(const char *repo_name, struct gotd_repolist *repos)
{
struct gotd_repo *repo;
size_t namelen;
- TAILQ_FOREACH(repo, &gotd->repos, entry) {
+ TAILQ_FOREACH(repo, repos, entry) {
namelen = strlen(repo->name);
if (strncmp(repo->name, repo_name, namelen) != 0)
continue;
blob - 8e8c38fdba8ea220bb277b5edc26a7f4bffa00f2
blob + 6bad495759fd5455d3e40a25cf588583054b3baa
--- gotd/session.c
+++ gotd/session.c
struct gotd_imsgev notifier_iev;
struct timeval request_timeout;
enum gotd_procid proc_id;
+ struct got_pathlist_head *notification_refs;
+ struct got_pathlist_head *notification_ref_namespaces;
+ int summarize_notifications;
+ struct gotd_notification_targets *notification_targets;
} gotd_session;
static struct gotd_session_client {
return got_error(GOT_ERR_PRIVSEP_MSG);
client->nref_updates = istart.nref_updates;
+ return NULL;
+}
+
+static const struct got_error *
+validate_namespace(const char *namespace)
+{
+ size_t len = strlen(namespace);
+
+ if (len < 5 || strncmp("refs/", namespace, 5) != 0 ||
+ namespace[len - 1] != '/') {
+ return got_error_fmt(GOT_ERR_BAD_REF_NAME,
+ "reference namespace '%s'", namespace);
+ }
+
return NULL;
}
{
const struct got_error *err = NULL;
struct gotd_imsgev *iev = &gotd_session.notifier_iev;
+ struct got_pathlist_entry *pe;
+ int fd = -1;
if (iev->ibuf.fd == -1)
return NULL; /* notifications unused */
+ TAILQ_FOREACH(pe, gotd_session.notification_refs, entry) {
+ const char *refname = pe->path;
+ if (strcmp(got_ref_get_name(ref), refname) == 0)
+ break;
+ }
+ if (pe == NULL && !TAILQ_EMPTY(gotd_session.notification_refs))
+ return NULL;
+
+ TAILQ_FOREACH(pe, gotd_session.notification_ref_namespaces, entry) {
+ const char *namespace = pe->path;
+
+ err = validate_namespace(namespace);
+ if (err)
+ return err;
+ if (strncmp(namespace, got_ref_get_name(ref),
+ strlen(namespace)) == 0)
+ break;
+ }
+ if (pe == NULL &&
+ !TAILQ_EMPTY(gotd_session.notification_ref_namespaces))
+ return NULL;
+
+ fd = got_opentempfd();
+ if (fd == -1)
+ return got_error_from_errno("got_opentempfd");
+
if (old_id == NULL) {
+ dprintf(fd, "created %s\n", got_ref_get_name(ref));
} else if (new_id == NULL) {
+ dprintf(fd, "deleted %s\n", got_ref_get_name(ref));
} else {
+ dprintf(fd, "modified %s\n", got_ref_get_name(ref));
}
+ /* TODO: send imsg */
+
+ if (fd != -1 && close(fd) == -1 && err == NULL)
+ err = got_error_from_errno("close");
return err;
}
void
session_main(const char *title, const char *repo_path,
int *pack_fds, int *temp_fds, struct timeval *request_timeout,
+ struct got_pathlist_head *notification_refs,
+ struct got_pathlist_head *notification_ref_namespaces,
+ int summarize_notifications,
+ struct gotd_notification_targets *notification_targets,
enum gotd_procid proc_id)
{
const struct got_error *err = NULL;
memcpy(&gotd_session.request_timeout, request_timeout,
sizeof(gotd_session.request_timeout));
gotd_session.proc_id = proc_id;
+ gotd_session.notification_refs = notification_refs;
+ gotd_session.notification_ref_namespaces = notification_ref_namespaces;
+ gotd_session.summarize_notifications = summarize_notifications;
+ gotd_session.notification_targets = notification_targets;
imsg_init(&gotd_session.notifier_iev.ibuf, -1);
blob - de20117ce268c646687a1977e8e0c7086a7fb2d6
blob + f98879f84ca1815ba0e760a8995524e6205f7a7b
--- gotd/session.h
+++ gotd/session.h
*/
void session_main(const char *, const char *, int *, int *, struct timeval *,
- enum gotd_procid);
+ struct got_pathlist_head *, struct got_pathlist_head *, int,
+ struct gotd_notification_targets *, enum gotd_procid);