// SPDX-License-Identifier: GPL-2.0-only /* Copyright (C) 2019 Daniel Borkmann */ #include #include #include #include #include #include #include #include #include "l2md.h" enum { FORK_ERROR = -1, FORK_CHILD = 0, }; static void pipe_new_mail(struct config_repo *repo, uint32_t which, const char *oid, const void *raw, size_t len) { char tmp[PATH_MAX]; int fd[2]; xpipe(fd); switch(fork()) { case FORK_ERROR: panic("Cannot fork: %s\n", strerror(errno)); case FORK_CHILD: close(fd[1]); dup2(fd[0], STDIN_FILENO); close(fd[0]); strcpy(tmp, repo->out); execl(repo->out, basename(tmp), NULL); break; default: close(fd[0]); xwrite(fd[1], raw, len); close(fd[1]); wait(NULL); break; } } static void pipe_bootstrap(struct config *cfg) { struct config_repo *repo; struct stat sb; uint32_t i; repo_for_each(cfg, repo, i) { if (stat(repo->out, &sb) != 0) panic("Cannot stat %s: %s\n", repo->out, strerror(errno)); if (!(sb.st_mode & S_IXUSR)) panic("%s is not an executable!\n", repo->out); } } static void pipe_set_defaults(struct config *cfg) { } const struct mail_ops ops_pipe = { .name = "pipe", .bootstrap = pipe_bootstrap, .new_mail = pipe_new_mail, .set_defaults = pipe_set_defaults, };