int parent_fetch(struct child *child, struct msg *msg, struct msgbuf *msgbuf) { struct child_fetch_data *data = child->data; struct children *children = data->children; struct deliver_ctx *dctx; struct mail_ctx *mctx; struct mail *m; switch (msg->type) { case MSG_ACTION: if (msgbuf->buf == NULL || msgbuf->len == 0) fatalx("bad tags"); m = xcalloc(1, sizeof *m); if (mail_receive(m, msg, 0) != 0) { log_warn("parent: can't receive mail"); parent_fetch_error(child, msg); break; } m->tags = msgbuf->buf; dctx = xcalloc(1, sizeof *dctx); dctx->account = msg->data.account; dctx->mail = m; parent_fetch_action(child, children, dctx, msg); break; case MSG_COMMAND: if (msgbuf->buf == NULL || msgbuf->len == 0) fatalx("bad tags"); m = xcalloc(1, sizeof *m); if (mail_receive(m, msg, 0) != 0) { log_warn("parent: can't receive mail"); parent_fetch_error(child, msg); break; } m->tags = msgbuf->buf; mctx = xcalloc(1, sizeof *mctx); mctx->account = msg->data.account; mctx->mail = m; parent_fetch_cmd(child, children, mctx, msg); break; case MSG_DONE: fatalx("unexpected message"); case MSG_EXIT: return (-1); } return (0); }
void child_deliver_action_hook(pid_t pid, struct account *a, struct msg *msg, struct child_deliver_data *data, int *result) { struct actitem *ti = data->actitem; struct deliver_ctx *dctx = data->dctx; struct mail *m = data->mail; struct mail *md = &dctx->wr_mail; /* Check if this is the parent. */ if (pid != 0) { /* Use new mail if necessary. */ if (ti->deliver->type != DELIVER_WRBACK) { xfree(dctx); return; } if (*result != DELIVER_SUCCESS) mail_destroy(md); else { mail_close(md); if (mail_receive(m, msg, 0) != 0) { log_warn("parent_deliver: can't receive mail"); *result = DELIVER_FAILURE; } } xfree(dctx); return; } dctx->udata = xmalloc(sizeof *dctx->udata); dctx->udata->uid = data->uid; dctx->udata->gid = data->gid; dctx->udata->name = xstrdup(find_tag(m->tags, "user")); dctx->udata->home = xstrdup(find_tag(m->tags, "home")); log_debug2("%s: deliver user is: %s (%lu/%lu), home is: %s", a->name, dctx->udata->name, (u_long) dctx->udata->uid, (u_long) dctx->udata->gid, dctx->udata->home); /* This is the child. do the delivery. */ *result = ti->deliver->deliver(dctx, ti); if (ti->deliver->type != DELIVER_WRBACK || *result != DELIVER_SUCCESS) { user_free(dctx->udata); return; } user_free(dctx->udata); mail_send(md, msg); log_debug2("%s: using new mail, size %zu", a->name, md->size); }