-static void
-bounce(struct qitem *it, const char *reason)
-{
- struct queue bounceq;
- struct qitem *bit;
- char line[1000];
- int error;
-
- /* Don't bounce bounced mails */
- if (it->sender[0] == 0) {
- syslog(LOG_CRIT, "%s: delivery panic: can't bounce a bounce",
- it->queueid);
- exit(1);
- }
-
- syslog(LOG_ERR, "%s: delivery failed, bouncing",
- it->queueid);
-
- LIST_INIT(&bounceq.queue);
- if (add_recp(&bounceq, it->sender, "", 1) != 0)
- goto fail;
- if (gentempf(&bounceq) != 0)
- goto fail;
- if (preparespool(&bounceq, "") != 0)
- goto fail;
-
- bit = LIST_FIRST(&bounceq.queue);
- error = fprintf(bit->queuef, "\
-Received: from MAILER-DAEMON\n\
-\tid %"PRIxMAX"\n\
-\tby %s (%s)\n\
-\t%s\n\
-X-Original-To: <%s>\n\
-From: MAILER-DAEMON <>\n\
-To: %s\n\
-Subject: Mail delivery failed\n\
-Message-Id: <%"PRIxMAX"@%s>\n\
-Date: %s\n\
-\n\
-This is the %s at %s.\n\
-\n\
-There was an error delivering your mail to <%s>.\n\
-\n\
-%s\n\
-\n\
-Message headers follow.\n\
-\n\
-",
- bounceq.id,
- hostname(), VERSION,
- rfc822date(),
- it->addr,
- it->sender,
- bounceq.id, hostname(),
- rfc822date(),
- VERSION, hostname(),
- it->addr,
- reason);
- if (error < 0)
- goto fail;
- if (fflush(bit->queuef) != 0)
- goto fail;
-
- if (fseek(it->queuef, it->hdrlen, SEEK_SET) != 0)
- goto fail;
- while (!feof(it->queuef)) {
- if (fgets(line, sizeof(line), it->queuef) == NULL)
- break;
- if (line[0] == '\n')
- break;
- write(bounceq.mailfd, line, strlen(line));
- }
- if (fsync(bounceq.mailfd) != 0)
- goto fail;
- if (linkspool(&bounceq) != 0)
- goto fail;
- /* bounce is safe */
-
- unlink(it->queuefn);
- fclose(it->queuef);
-
- bit = go_background(&bounceq);
- deliver(bit);
- /* NOTREACHED */
-
-fail:
- syslog(LOG_CRIT, "%s: error creating bounce: %m", it->queueid);
- unlink(it->queuefn);
- exit(1);
-}
-
-static int
-deliver_local(struct qitem *it, const char **errmsg)
-{
- char fn[PATH_MAX+1];
- char line[1000];
- size_t linelen;
- int mbox;
- int error;
- off_t mboxlen;
- time_t now = time(NULL);
-
- error = snprintf(fn, sizeof(fn), "%s/%s", _PATH_MAILDIR, it->addr);
- if (error < 0 || (size_t)error >= sizeof(fn)) {
- syslog(LOG_ERR, "%s: local delivery deferred: %m",
- it->queueid);
- return (1);
- }
-
- /* mailx removes users mailspool file if empty, so open with O_CREAT */
- mbox = open_locked(fn, O_WRONLY | O_APPEND | O_CREAT);
- if (mbox < 0) {
- syslog(LOG_ERR, "%s: local delivery deferred: can not open `%s': %m",
- it->queueid, fn);
- return (1);
- }
- mboxlen = lseek(mbox, 0, SEEK_CUR);
-
- if (fseek(it->queuef, it->hdrlen, SEEK_SET) != 0) {
- syslog(LOG_ERR, "%s: local delivery deferred: can not seek: %m",
- it->queueid);
- return (1);
- }
-
- error = snprintf(line, sizeof(line), "From %s\t%s", it->sender, ctime(&now));
- if (error < 0 || (size_t)error >= sizeof(line)) {
- syslog(LOG_ERR, "%s: local delivery deferred: can not write header: %m",
- it->queueid);
- return (1);
- }
- if (write(mbox, line, error) != error)
- goto wrerror;
-
- while (!feof(it->queuef)) {
- if (fgets(line, sizeof(line), it->queuef) == NULL)
- break;
- linelen = strlen(line);
- if (linelen == 0 || line[linelen - 1] != '\n') {
- syslog(LOG_CRIT, "%s: local delivery failed: corrupted queue file",
- it->queueid);
- *errmsg = "corrupted queue file";
- error = -1;
- goto chop;
- }
-
- if (strncmp(line, "From ", 5) == 0) {
- const char *gt = ">";
-
- if (write(mbox, gt, 1) != 1)
- goto wrerror;
- }
- if ((size_t)write(mbox, line, linelen) != linelen)
- goto wrerror;
- }
- line[0] = '\n';
- if (write(mbox, line, 1) != 1)
- goto wrerror;
- close(mbox);
- return (0);
-
-wrerror:
- syslog(LOG_ERR, "%s: local delivery failed: write error: %m",
- it->queueid);
- error = 1;
-chop:
- if (ftruncate(mbox, mboxlen) != 0)
- syslog(LOG_WARNING, "%s: error recovering mbox `%s': %m",
- it->queueid, fn);
- close(mbox);
- return (error);
-}
-