Author: bapt
Date: Sat Aug 20 16:29:08 2016
New Revision: 304534
URL: https://svnweb.freebsd.org/changeset/base/304534

Log:
  tag import of Dragonfly Mail Agent 20160806

Added:
  vendor/dma/20160806/
     - copied from r304532, vendor/dma/dist/
Replaced:
  vendor/dma/20160806/VERSION
     - copied unchanged from r304533, vendor/dma/dist/VERSION
  vendor/dma/20160806/dma-mbox-create.c
     - copied unchanged from r304533, vendor/dma/dist/dma-mbox-create.c
  vendor/dma/20160806/dma.c
     - copied unchanged from r304533, vendor/dma/dist/dma.c
  vendor/dma/20160806/dma.h
     - copied unchanged from r304533, vendor/dma/dist/dma.h
  vendor/dma/20160806/dns.c
     - copied unchanged from r304533, vendor/dma/dist/dns.c
  vendor/dma/20160806/local.c
     - copied unchanged from r304533, vendor/dma/dist/local.c
  vendor/dma/20160806/net.c
     - copied unchanged from r304533, vendor/dma/dist/net.c

Copied: vendor/dma/20160806/VERSION (from r304533, vendor/dma/dist/VERSION)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ vendor/dma/20160806/VERSION Sat Aug 20 16:29:08 2016        (r304534, copy 
of r304533, vendor/dma/dist/VERSION)
@@ -0,0 +1 @@
+v0.11

Copied: vendor/dma/20160806/dma-mbox-create.c (from r304533, 
vendor/dma/dist/dma-mbox-create.c)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ vendor/dma/20160806/dma-mbox-create.c       Sat Aug 20 16:29:08 2016        
(r304534, copy of r304533, vendor/dma/dist/dma-mbox-create.c)
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2010-2014, Simon Schubert <2...@0x2c.org>.
+ * Copyright (c) 2008 The DragonFly Project.  All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Simon Schubert <2...@0x2c.org>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific, prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This binary is setuid root.  Use extreme caution when touching
+ * user-supplied information.  Keep the root window as small as possible.
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <paths.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include "dma.h"
+
+
+static void
+logfail(int exitcode, const char *fmt, ...)
+{
+       int oerrno = errno;
+       va_list ap;
+       char outs[1024];
+
+       outs[0] = 0;
+       if (fmt != NULL) {
+               va_start(ap, fmt);
+               vsnprintf(outs, sizeof(outs), fmt, ap);
+               va_end(ap);
+       }
+
+       errno = oerrno;
+       if (*outs != 0)
+               syslog(LOG_ERR, errno ? "%s: %m" : "%s", outs);
+       else
+               syslog(LOG_ERR, errno ? "%m" : "unknown error");
+
+       exit(exitcode);
+}
+
+/*
+ * Create a mbox in /var/mail for a given user, or make sure
+ * the permissions are correct for dma.
+ */
+
+int
+main(int argc, char **argv)
+{
+       const char *user;
+       struct passwd *pw;
+       struct group *gr;
+       uid_t user_uid;
+       gid_t mail_gid;
+       int error;
+       char fn[PATH_MAX+1];
+       int f;
+
+       openlog("dma-mbox-create", 0, LOG_MAIL);
+
+       errno = 0;
+       gr = getgrnam(DMA_GROUP);
+       if (!gr)
+               logfail(EX_CONFIG, "cannot find dma group `%s'", DMA_GROUP);
+
+       mail_gid = gr->gr_gid;
+
+       if (setgid(mail_gid) != 0)
+               logfail(EX_NOPERM, "cannot set gid to %d (%s)", mail_gid, 
DMA_GROUP);
+       if (getegid() != mail_gid)
+               logfail(EX_NOPERM, "cannot set gid to %d (%s), still at %d", 
mail_gid, DMA_GROUP, getegid());
+
+       /*
+        * We take exactly one argument: the username.
+        */
+       if (argc != 2) {
+               errno = 0;
+               logfail(EX_USAGE, "no arguments");
+       }
+       user = argv[1];
+
+       syslog(LOG_NOTICE, "creating mbox for `%s'", user);
+
+       /* the username may not contain a pathname separator */
+       if (strchr(user, '/')) {
+               errno = 0;
+               logfail(EX_DATAERR, "path separator in username `%s'", user);
+               exit(1);
+       }
+
+       /* verify the user exists */
+       errno = 0;
+       pw = getpwnam(user);
+       if (!pw)
+               logfail(EX_NOUSER, "cannot find user `%s'", user);
+
+       user_uid = pw->pw_uid;
+
+       error = snprintf(fn, sizeof(fn), "%s/%s", _PATH_MAILDIR, user);
+       if (error < 0 || (size_t)error >= sizeof(fn)) {
+               if (error >= 0) {
+                       errno = 0;
+                       logfail(EX_USAGE, "mbox path too long");
+               }
+               logfail(EX_CANTCREAT, "cannot build mbox path for `%s/%s'", 
_PATH_MAILDIR, user);
+       }
+
+       f = open(fn, O_RDONLY|O_CREAT|O_NOFOLLOW, 0600);
+       if (f < 0)
+               logfail(EX_NOINPUT, "cannt open mbox `%s'", fn);
+
+       if (fchown(f, user_uid, mail_gid))
+               logfail(EX_OSERR, "cannot change owner of mbox `%s'", fn);
+
+       if (fchmod(f, 0620))
+               logfail(EX_OSERR, "cannot change permissions of mbox `%s'", fn);
+
+       /* file should be present with the right owner and permissions */
+
+       syslog(LOG_NOTICE, "successfully created mbox for `%s'", user);
+
+       return (0);
+}

Copied: vendor/dma/20160806/dma.c (from r304533, vendor/dma/dist/dma.c)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ vendor/dma/20160806/dma.c   Sat Aug 20 16:29:08 2016        (r304534, copy 
of r304533, vendor/dma/dist/dma.c)
@@ -0,0 +1,632 @@
+/*
+ * Copyright (c) 2008-2014, Simon Schubert <2...@0x2c.org>.
+ * Copyright (c) 2008 The DragonFly Project.  All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Simon Schubert <2...@0x2c.org>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific, prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "dfcompat.h"
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+
+#include <dirent.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <paths.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include "dma.h"
+
+
+static void deliver(struct qitem *);
+
+struct aliases aliases = LIST_HEAD_INITIALIZER(aliases);
+struct strlist tmpfs = SLIST_HEAD_INITIALIZER(tmpfs);
+struct authusers authusers = LIST_HEAD_INITIALIZER(authusers);
+char username[USERNAME_SIZE];
+uid_t useruid;
+const char *logident_base;
+char errmsg[ERRMSG_SIZE];
+
+static int daemonize = 1;
+static int doqueue = 0;
+
+struct config config = {
+       .smarthost      = NULL,
+       .port           = 25,
+       .aliases        = "/etc/aliases",
+       .spooldir       = "/var/spool/dma",
+       .authpath       = NULL,
+       .certfile       = NULL,
+       .features       = 0,
+       .mailname       = NULL,
+       .masquerade_host = NULL,
+       .masquerade_user = NULL,
+};
+
+
+static void
+sighup_handler(int signo)
+{
+       (void)signo;    /* so that gcc doesn't complain */
+}
+
+static char *
+set_from(struct queue *queue, const char *osender)
+{
+       const char *addr;
+       char *sender;
+
+       if (osender) {
+               addr = osender;
+       } else if (getenv("EMAIL") != NULL) {
+               addr = getenv("EMAIL");
+       } else {
+               if (config.masquerade_user)
+                       addr = config.masquerade_user;
+               else
+                       addr = username;
+       }
+
+       if (!strchr(addr, '@')) {
+               const char *from_host = hostname();
+
+               if (config.masquerade_host)
+                       from_host = config.masquerade_host;
+
+               if (asprintf(&sender, "%s@%s", addr, from_host) <= 0)
+                       return (NULL);
+       } else {
+               sender = strdup(addr);
+               if (sender == NULL)
+                       return (NULL);
+       }
+
+       if (strchr(sender, '\n') != NULL) {
+               errno = EINVAL;
+               return (NULL);
+       }
+
+       queue->sender = sender;
+       return (sender);
+}
+
+static int
+read_aliases(void)
+{
+       yyin = fopen(config.aliases, "r");
+       if (yyin == NULL) {
+               /*
+                * Non-existing aliases file is not a fatal error
+                */
+               if (errno == ENOENT)
+                       return (0);
+               /* Other problems are. */
+               return (-1);
+       }
+       if (yyparse())
+               return (-1);    /* fatal error, probably malloc() */
+       fclose(yyin);
+       return (0);
+}
+
+static int
+do_alias(struct queue *queue, const char *addr)
+{
+       struct alias *al;
+        struct stritem *sit;
+       int aliased = 0;
+
+        LIST_FOREACH(al, &aliases, next) {
+                if (strcmp(al->alias, addr) != 0)
+                        continue;
+               SLIST_FOREACH(sit, &al->dests, next) {
+                       if (add_recp(queue, sit->str, EXPAND_ADDR) != 0)
+                               return (-1);
+               }
+               aliased = 1;
+        }
+
+        return (aliased);
+}
+
+int
+add_recp(struct queue *queue, const char *str, int expand)
+{
+       struct qitem *it, *tit;
+       struct passwd *pw;
+       char *host;
+       int aliased = 0;
+
+       it = calloc(1, sizeof(*it));
+       if (it == NULL)
+               return (-1);
+       it->addr = strdup(str);
+       if (it->addr == NULL)
+               return (-1);
+
+       it->sender = queue->sender;
+       host = strrchr(it->addr, '@');
+       if (host != NULL &&
+           (strcmp(host + 1, hostname()) == 0 ||
+            strcmp(host + 1, "localhost") == 0)) {
+               *host = 0;
+       }
+       LIST_FOREACH(tit, &queue->queue, next) {
+               /* weed out duplicate dests */
+               if (strcmp(tit->addr, it->addr) == 0) {
+                       free(it->addr);
+                       free(it);
+                       return (0);
+               }
+       }
+       LIST_INSERT_HEAD(&queue->queue, it, next);
+
+       /**
+        * Do local delivery if there is no @.
+        * Do not do local delivery when NULLCLIENT is set.
+        */
+       if (strrchr(it->addr, '@') == NULL && (config.features & NULLCLIENT) == 
0) {
+               it->remote = 0;
+               if (expand) {
+                       aliased = do_alias(queue, it->addr);
+                       if (!aliased && expand == EXPAND_WILDCARD)
+                               aliased = do_alias(queue, "*");
+                       if (aliased < 0)
+                               return (-1);
+                       if (aliased) {
+                               LIST_REMOVE(it, next);
+                       } else {
+                               /* Local destination, check */
+                               pw = getpwnam(it->addr);
+                               if (pw == NULL)
+                                       goto out;
+                               /* XXX read .forward */
+                               endpwent();
+                       }
+               }
+       } else {
+               it->remote = 1;
+       }
+
+       return (0);
+
+out:
+       free(it->addr);
+       free(it);
+       return (-1);
+}
+
+static struct qitem *
+go_background(struct queue *queue)
+{
+       struct sigaction sa;
+       struct qitem *it;
+       pid_t pid;
+
+       if (daemonize && daemon(0, 0) != 0) {
+               syslog(LOG_ERR, "can not daemonize: %m");
+               exit(EX_OSERR);
+       }
+       daemonize = 0;
+
+       bzero(&sa, sizeof(sa));
+       sa.sa_handler = SIG_IGN;
+       sigaction(SIGCHLD, &sa, NULL);
+
+       LIST_FOREACH(it, &queue->queue, next) {
+               /* No need to fork for the last dest */
+               if (LIST_NEXT(it, next) == NULL)
+                       goto retit;
+
+               pid = fork();
+               switch (pid) {
+               case -1:
+                       syslog(LOG_ERR, "can not fork: %m");
+                       exit(EX_OSERR);
+                       break;
+
+               case 0:
+                       /*
+                        * Child:
+                        *
+                        * return and deliver mail
+                        */
+retit:
+                       /*
+                        * If necessary, acquire the queue and * mail files.
+                        * If this fails, we probably were raced by another
+                        * process.  It is okay to be raced if we're supposed
+                        * to flush the queue.
+                        */
+                       setlogident("%s", it->queueid);
+                       switch (acquirespool(it)) {
+                       case 0:
+                               break;
+                       case 1:
+                               if (doqueue)
+                                       exit(EX_OK);
+                               syslog(LOG_WARNING, "could not lock queue 
file");
+                               exit(EX_SOFTWARE);
+                       default:
+                               exit(EX_SOFTWARE);
+                       }
+                       dropspool(queue, it);
+                       return (it);
+
+               default:
+                       /*
+                        * Parent:
+                        *
+                        * fork next child
+                        */
+                       break;
+               }
+       }
+
+       syslog(LOG_CRIT, "reached dead code");
+       exit(EX_SOFTWARE);
+}
+
+static void
+deliver(struct qitem *it)
+{
+       int error;
+       unsigned int backoff = MIN_RETRY, slept;
+       struct timeval now;
+       struct stat st;
+
+       snprintf(errmsg, sizeof(errmsg), "unknown bounce reason");
+
+retry:
+       syslog(LOG_INFO, "<%s> trying delivery", it->addr);
+
+       if (it->remote)
+               error = deliver_remote(it);
+       else
+               error = deliver_local(it);
+
+       switch (error) {
+       case 0:
+               delqueue(it);
+               syslog(LOG_INFO, "<%s> delivery successful", it->addr);
+               exit(EX_OK);
+
+       case 1:
+               if (stat(it->queuefn, &st) != 0) {
+                       syslog(LOG_ERR, "lost queue file `%s'", it->queuefn);
+                       exit(EX_SOFTWARE);
+               }
+               if (gettimeofday(&now, NULL) == 0 &&
+                   (now.tv_sec - st.st_mtim.tv_sec > MAX_TIMEOUT)) {
+                       snprintf(errmsg, sizeof(errmsg),
+                                "Could not deliver for the last %d seconds. 
Giving up.",
+                                MAX_TIMEOUT);
+                       goto bounce;
+               }
+               for (slept = 0; slept < backoff;) {
+                       slept += SLEEP_TIMEOUT - sleep(SLEEP_TIMEOUT);
+                       if (flushqueue_since(slept)) {
+                               backoff = MIN_RETRY;
+                               goto retry;
+                       }
+               }
+               if (slept >= backoff) {
+                       /* pick the next backoff between [1.5, 2.5) times 
backoff */
+                       backoff = backoff + backoff / 2 + random() % backoff;
+                       if (backoff > MAX_RETRY)
+                               backoff = MAX_RETRY;
+               }
+               goto retry;
+
+       case -1:
+       default:
+               break;
+       }
+
+bounce:
+       bounce(it, errmsg);
+       /* NOTREACHED */
+}
+
+void
+run_queue(struct queue *queue)
+{
+       struct qitem *it;
+
+       if (LIST_EMPTY(&queue->queue))
+               return;
+
+       it = go_background(queue);
+       deliver(it);
+       /* NOTREACHED */
+}
+
+static void
+show_queue(struct queue *queue)
+{
+       struct qitem *it;
+       int locked = 0; /* XXX */
+
+       if (LIST_EMPTY(&queue->queue)) {
+               printf("Mail queue is empty\n");
+               return;
+       }
+
+       LIST_FOREACH(it, &queue->queue, next) {
+               printf("ID\t: %s%s\n"
+                      "From\t: %s\n"
+                      "To\t: %s\n",
+                      it->queueid,
+                      locked ? "*" : "",
+                      it->sender, it->addr);
+
+               if (LIST_NEXT(it, next) != NULL)
+                       printf("--\n");
+       }
+}
+
+/*
+ * TODO:
+ *
+ * - alias processing
+ * - use group permissions
+ * - proper sysexit codes
+ */
+
+int
+main(int argc, char **argv)
+{
+       struct sigaction act;
+       char *sender = NULL;
+       struct queue queue;
+       int i, ch;
+       int nodot = 0, showq = 0, queue_only = 0;
+       int recp_from_header = 0;
+
+       set_username();
+
+       /*
+        * We never run as root.  If called by root, drop permissions
+        * to the mail user.
+        */
+       if (geteuid() == 0 || getuid() == 0) {
+               struct passwd *pw;
+
+               errno = 0;
+               pw = getpwnam(DMA_ROOT_USER);
+               if (pw == NULL) {
+                       if (errno == 0)
+                               errx(EX_CONFIG, "user '%s' not found", 
DMA_ROOT_USER);
+                       else
+                               err(EX_OSERR, "cannot drop root privileges");
+               }
+
+               if (setuid(pw->pw_uid) != 0)
+                       err(EX_OSERR, "cannot drop root privileges");
+
+               if (geteuid() == 0 || getuid() == 0)
+                       errx(EX_OSERR, "cannot drop root privileges");
+       }
+
+       atexit(deltmp);
+       init_random();
+
+       bzero(&queue, sizeof(queue));
+       LIST_INIT(&queue.queue);
+
+       if (strcmp(argv[0], "mailq") == 0) {
+               argv++; argc--;
+               showq = 1;
+               if (argc != 0)
+                       errx(EX_USAGE, "invalid arguments");
+               goto skipopts;
+       } else if (strcmp(argv[0], "newaliases") == 0) {
+               logident_base = "dma";
+               setlogident(NULL);
+
+               if (read_aliases() != 0)
+                       errx(EX_SOFTWARE, "could not parse aliases file `%s'", 
config.aliases);
+               exit(EX_OK);
+       }
+
+       opterr = 0;
+       while ((ch = getopt(argc, argv, 
":A:b:B:C:d:Df:F:h:iL:N:no:O:q:r:R:tUV:vX:")) != -1) {
+               switch (ch) {
+               case 'A':
+                       /* -AX is being ignored, except for -A{c,m} */
+                       if (optarg[0] == 'c' || optarg[0] == 'm') {
+                               break;
+                       }
+                       /* else FALLTRHOUGH */
+               case 'b':
+                       /* -bX is being ignored, except for -bp */
+                       if (optarg[0] == 'p') {
+                               showq = 1;
+                               break;
+                       } else if (optarg[0] == 'q') {
+                               queue_only = 1;
+                               break;
+                       }
+                       /* else FALLTRHOUGH */
+               case 'D':
+                       daemonize = 0;
+                       break;
+               case 'L':
+                       logident_base = optarg;
+                       break;
+               case 'f':
+               case 'r':
+                       sender = optarg;
+                       break;
+
+               case 't':
+                       recp_from_header = 1;
+                       break;
+
+               case 'o':
+                       /* -oX is being ignored, except for -oi */
+                       if (optarg[0] != 'i')
+                               break;
+                       /* else FALLTRHOUGH */
+               case 'O':
+                       break;
+               case 'i':
+                       nodot = 1;
+                       break;
+
+               case 'q':
+                       /* Don't let getopt slup up other arguments */
+                       if (optarg && *optarg == '-')
+                               optind--;
+                       doqueue = 1;
+                       break;
+
+               /* Ignored options */
+               case 'B':
+               case 'C':
+               case 'd':
+               case 'F':
+               case 'h':
+               case 'N':
+               case 'n':
+               case 'R':
+               case 'U':
+               case 'V':
+               case 'v':
+               case 'X':
+                       break;
+
+               case ':':
+                       if (optopt == 'q') {
+                               doqueue = 1;
+                               break;
+                       }
+                       /* FALLTHROUGH */
+
+               default:
+                       fprintf(stderr, "invalid argument: `-%c'\n", optopt);
+                       exit(EX_USAGE);
+               }
+       }
+       argc -= optind;
+       argv += optind;
+       opterr = 1;
+
+       if (argc != 0 && (showq || doqueue))
+               errx(EX_USAGE, "sending mail and queue operations are mutually 
exclusive");
+
+       if (showq + doqueue > 1)
+               errx(EX_USAGE, "conflicting queue operations");
+
+skipopts:
+       if (logident_base == NULL)
+               logident_base = "dma";
+       setlogident(NULL);
+
+       act.sa_handler = sighup_handler;
+       act.sa_flags = 0;
+       sigemptyset(&act.sa_mask);
+       if (sigaction(SIGHUP, &act, NULL) != 0)
+               syslog(LOG_WARNING, "can not set signal handler: %m");
+
+       parse_conf(CONF_PATH "/dma.conf");
+
+       if (config.authpath != NULL)
+               parse_authfile(config.authpath);
+
+       if (showq) {
+               if (load_queue(&queue) < 0)
+                       errlog(EX_NOINPUT, "can not load queue");
+               show_queue(&queue);
+               return (0);
+       }
+
+       if (doqueue) {
+               flushqueue_signal();
+               if (load_queue(&queue) < 0)
+                       errlog(EX_NOINPUT, "can not load queue");
+               run_queue(&queue);
+               return (0);
+       }
+
+       if (read_aliases() != 0)
+               errlog(EX_SOFTWARE, "could not parse aliases file `%s'", 
config.aliases);
+
+       if ((sender = set_from(&queue, sender)) == NULL)
+               errlog(EX_SOFTWARE, NULL);
+
+       if (newspoolf(&queue) != 0)
+               errlog(EX_CANTCREAT, "can not create temp file in `%s'", 
config.spooldir);
+
+       setlogident("%s", queue.id);
+
+       for (i = 0; i < argc; i++) {
+               if (add_recp(&queue, argv[i], EXPAND_WILDCARD) != 0)
+                       errlogx(EX_DATAERR, "invalid recipient `%s'", argv[i]);
+       }
+
+       if (LIST_EMPTY(&queue.queue) && !recp_from_header)
+               errlogx(EX_NOINPUT, "no recipients");
+
+       if (readmail(&queue, nodot, recp_from_header) != 0)
+               errlog(EX_NOINPUT, "can not read mail");
+
+       if (LIST_EMPTY(&queue.queue))
+               errlogx(EX_NOINPUT, "no recipients");
+
+       if (linkspool(&queue) != 0)
+               errlog(EX_CANTCREAT, "can not create spools");
+
+       /* From here on the mail is safe. */
+
+       if (config.features & DEFER || queue_only)
+               return (0);
+
+       run_queue(&queue);
+
+       /* NOTREACHED */
+       return (0);
+}

Copied: vendor/dma/20160806/dma.h (from r304533, vendor/dma/dist/dma.h)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ vendor/dma/20160806/dma.h   Sat Aug 20 16:29:08 2016        (r304534, copy 
of r304533, vendor/dma/dist/dma.h)
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2008-2014, Simon Schubert <2...@0x2c.org>.
+ * Copyright (c) 2008 The DragonFly Project.  All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Simon Schubert <2...@0x2c.org> and
+ * Matthias Schmidt <matth...@dragonflybsd.org>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific, prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef DMA_H
+#define DMA_H
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#include <openssl/ssl.h>
+#include <netdb.h>
+#include <sysexits.h>
+
+#define VERSION        "DragonFly Mail Agent " DMA_VERSION
+
+#define BUF_SIZE       2048
+#define ERRMSG_SIZE    1024
+#define USERNAME_SIZE  50
+#define MIN_RETRY      300             /* 5 minutes */
+#define MAX_RETRY      (3*60*60)       /* retry at least every 3 hours */
+#define MAX_TIMEOUT    (5*24*60*60)    /* give up after 5 days */
+#define SLEEP_TIMEOUT  30              /* check for queue flush every 30 
seconds */
+#ifndef PATH_MAX
+#define PATH_MAX       1024            /* Max path len */
+#endif
+#define        SMTP_PORT       25              /* Default SMTP port */
+#define CON_TIMEOUT    (5*60)          /* Connection timeout per RFC5321 */
+
+#define STARTTLS       0x002           /* StartTLS support */
+#define SECURETRANS    0x004           /* SSL/TLS in general */
+#define NOSSL          0x008           /* Do not use SSL */
+#define DEFER          0x010           /* Defer mails */
+#define INSECURE       0x020           /* Allow plain login w/o encryption */
+#define FULLBOUNCE     0x040           /* Bounce the full message */
+#define TLS_OPP                0x080           /* Opportunistic STARTTLS */
+#define NULLCLIENT     0x100           /* Nullclient support */
+
+#ifndef CONF_PATH
+#error Please define CONF_PATH
+#endif
+
+#ifndef LIBEXEC_PATH
+#error Please define LIBEXEC_PATH
+#endif
+
+#define SPOOL_FLUSHFILE        "flush"
+
+#ifndef DMA_ROOT_USER
+#define DMA_ROOT_USER  "mail"
+#endif
+#ifndef DMA_GROUP
+#define DMA_GROUP      "mail"
+#endif
+
+#ifndef MBOX_STRICT
+#define MBOX_STRICT    0
+#endif
+
+
+struct stritem {
+       SLIST_ENTRY(stritem) next;
+       char *str;
+};
+SLIST_HEAD(strlist, stritem);
+
+struct alias {
+       LIST_ENTRY(alias) next;
+       char *alias;
+       struct strlist dests;
+};
+LIST_HEAD(aliases, alias);
+
+struct qitem {
+       LIST_ENTRY(qitem) next;
+       const char *sender;
+       char *addr;
+       char *queuefn;
+       char *mailfn;
+       char *queueid;
+       FILE *queuef;
+       FILE *mailf;
+       int remote;
+};
+LIST_HEAD(queueh, qitem);
+
+struct queue {
+       struct queueh queue;
+       char *id;
+       FILE *mailf;
+       char *tmpf;
+       const char *sender;
+};
+
+struct config {
+       const char *smarthost;
+       int port;
+       const char *aliases;
+       const char *spooldir;
+       const char *authpath;
+       const char *certfile;
+       int features;
+       const char *mailname;
+       const char *masquerade_host;
+       const char *masquerade_user;
+
+       /* XXX does not belong into config */
+       SSL *ssl;
+};
+
+
+struct authuser {
+       SLIST_ENTRY(authuser) next;
+       char *login;
+       char *password;
+       char *host;
+};
+SLIST_HEAD(authusers, authuser);
+
+
+struct mx_hostentry {
+       char            host[MAXDNAME];
+       char            addr[INET6_ADDRSTRLEN];
+       int             pref;
+       struct addrinfo ai;
+       struct sockaddr_storage sa;
+};
+
+
+/* global variables */
+extern struct aliases aliases;
+extern struct config config;
+extern struct strlist tmpfs;
+extern struct authusers authusers;
+extern char username[USERNAME_SIZE];
+extern uid_t useruid;
+extern const char *logident_base;
+
+extern char neterr[ERRMSG_SIZE];
+extern char errmsg[ERRMSG_SIZE];
+
+/* aliases_parse.y */
+int yyparse(void);
+int yywrap(void);
+int yylex(void);
+extern FILE *yyin;
+
+/* conf.c */
+void trim_line(char *);
+void parse_conf(const char *);
+void parse_authfile(const char *);
+
+/* crypto.c */
+void hmac_md5(unsigned char *, int, unsigned char *, int, unsigned char *);
+int smtp_auth_md5(int, char *, char *);
+int smtp_init_crypto(int, int);
+
+/* dns.c */
+int dns_get_mx_list(const char *, int, struct mx_hostentry **, int);
+
+/* net.c */

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to