From: Mikhail Date: Tue, 7 Apr 2015 13:21:49 +0000 (+0300) Subject: Initial version X-Git-Url: http://git.ipfire.org/?p=people%2Fms%2Fdma.git;a=commitdiff_plain;h=de196e3343319e7fe388cd3337a41e723fc51ba9 Initial version --- diff --git a/TODO b/TODO index 01de465..e70814c 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,4 @@ - unquote/handle quoted local recipients -- use proper sysexit codes - handle/use ESMTP extensions - .forward support - suggest way to run a queue flush on boot diff --git a/conf.c b/conf.c index 919ab7c..3e3c7d3 100644 --- a/conf.c +++ b/conf.c @@ -64,7 +64,7 @@ trim_line(char *line) if (line[0] == '.') { if ((linelen + 2) > 1000) { syslog(LOG_CRIT, "Cannot escape leading dot. Buffer overflow"); - exit(1); + exit(EX_DATAERR); } memmove((line + 1), line, (linelen + 1)); line[0] = '.'; @@ -101,7 +101,7 @@ parse_authfile(const char *path) a = fopen(path, "r"); if (a == NULL) { - errlog(1, "can not open auth file `%s'", path); + errlog(EX_NOINPUT, "can not open auth file `%s'", path); /* NOTREACHED */ } @@ -121,7 +121,7 @@ parse_authfile(const char *path) au = calloc(1, sizeof(*au)); if (au == NULL) - errlog(1, NULL); + errlog(EX_OSERR, NULL); data = strdup(line); au->login = strsep(&data, "|"); @@ -131,8 +131,7 @@ parse_authfile(const char *path) if (au->login == NULL || au->host == NULL || au->password == NULL) { - errlogx(1, "syntax error in authfile %s:%d", - path, lineno); + errlogx(EX_CONFIG, "syntax error in authfile %s:%d", path, lineno); /* NOTREACHED */ } @@ -160,7 +159,7 @@ parse_conf(const char *config_path) /* Don't treat a non-existing config file as error */ if (errno == ENOENT) return; - errlog(1, "can not open config `%s'", config_path); + errlog(EX_NOINPUT, "can not open config `%s'", config_path); /* NOTREACHED */ } @@ -211,7 +210,7 @@ parse_conf(const char *config_path) } else { host = data; } - if (host && *host == 0) + if (host && *host == 0) host = NULL; if (user && *user == 0) user = NULL; @@ -232,13 +231,13 @@ parse_conf(const char *config_path) else if (strcmp(word, "NULLCLIENT") == 0 && data == NULL) config.features |= NULLCLIENT; else { - errlogx(1, "syntax error in %s:%d", config_path, lineno); + errlogx(EX_CONFIG, "syntax error in %s:%d", config_path, lineno); /* NOTREACHED */ } } if ((config.features & NULLCLIENT) && config.smarthost == NULL) { - errlogx(1, "%s: NULLCLIENT requires SMARTHOST", config_path); + errlogx(EX_CONFIG, "%s: NULLCLIENT requires SMARTHOST", config_path); /* NOTREACHED */ } diff --git a/dma-mbox-create.c b/dma-mbox-create.c index 26b86d3..532a7af 100644 --- a/dma-mbox-create.c +++ b/dma-mbox-create.c @@ -54,7 +54,7 @@ static void -logfail(const char *fmt, ...) +logfail(int exitcode, const char *fmt, ...) { int oerrno = errno; va_list ap; @@ -73,7 +73,7 @@ logfail(const char *fmt, ...) else syslog(LOG_ERR, errno ? "%m" : "unknown error"); - exit(1); + exit(exitcode); } /* @@ -98,21 +98,21 @@ main(int argc, char **argv) errno = 0; gr = getgrnam(DMA_GROUP); if (!gr) - logfail("cannot find dma group `%s'", DMA_GROUP); + logfail(EX_CONFIG, "cannot find dma group `%s'", DMA_GROUP); mail_gid = gr->gr_gid; if (setgid(mail_gid) != 0) - logfail("cannot set gid to %d (%s)", mail_gid, DMA_GROUP); + logfail(EX_NOPERM, "cannot set gid to %d (%s)", mail_gid, DMA_GROUP); if (getegid() != mail_gid) - logfail("cannot set gid to %d (%s), still at %d", mail_gid, DMA_GROUP, getegid()); + 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("no arguments"); + logfail(EX_USAGE, "no arguments"); } user = argv[1]; @@ -121,7 +121,7 @@ main(int argc, char **argv) /* the username may not contain a pathname separator */ if (strchr(user, '/')) { errno = 0; - logfail("path separator in username `%s'", user); + logfail(EX_DATAERR, "path separator in username `%s'", user); exit(1); } @@ -129,7 +129,7 @@ main(int argc, char **argv) errno = 0; pw = getpwnam(user); if (!pw) - logfail("cannot find user `%s'", user); + logfail(EX_NOUSER, "cannot find user `%s'", user); user_uid = pw->pw_uid; @@ -137,20 +137,20 @@ main(int argc, char **argv) if (error < 0 || (size_t)error >= sizeof(fn)) { if (error >= 0) { errno = 0; - logfail("mbox path too long"); + logfail(EX_USAGE, "mbox path too long"); } - logfail("cannot build mbox path for `%s/%s'", _PATH_MAILDIR, user); + logfail(EX_CANTCREAT, "cannot build mbox path for `%s/%s'", _PATH_MAILDIR, user); } f = open(fn, O_RDONLY|O_CREAT, 0600); if (f < 0) - logfail("cannot open mbox `%s'", fn); + logfail(EX_NOINPUT, "cannt open mbox `%s'", fn); if (fchown(f, user_uid, mail_gid)) - logfail("cannot change owner of mbox `%s'", fn); + logfail(EX_OSERR, "cannot change owner of mbox `%s'", fn); if (fchmod(f, 0620)) - logfail("cannot change permissions of mbox `%s'", fn); + logfail(EX_OSERR, "cannot change permissions of mbox `%s'", fn); /* file should be present with the right owner and permissions */ diff --git a/dma.c b/dma.c index 80dacfc..94fc331 100644 --- a/dma.c +++ b/dma.c @@ -248,7 +248,7 @@ go_background(struct queue *queue) if (daemonize && daemon(0, 0) != 0) { syslog(LOG_ERR, "can not daemonize: %m"); - exit(1); + exit(EX_OSERR); } daemonize = 0; @@ -265,7 +265,7 @@ go_background(struct queue *queue) switch (pid) { case -1: syslog(LOG_ERR, "can not fork: %m"); - exit(1); + exit(EX_OSERR); break; case 0: @@ -287,11 +287,11 @@ retit: break; case 1: if (doqueue) - exit(0); + exit(EX_OK); syslog(LOG_WARNING, "could not lock queue file"); - exit(1); + exit(EX_SOFTWARE); default: - exit(1); + exit(EX_SOFTWARE); } dropspool(queue, it); return (it); @@ -307,7 +307,7 @@ retit: } syslog(LOG_CRIT, "reached dead code"); - exit(1); + exit(EX_SOFTWARE); } static void @@ -332,12 +332,12 @@ retry: case 0: delqueue(it); syslog(LOG_INFO, "delivery successful"); - exit(0); + exit(EX_OK); case 1: if (stat(it->queuefn, &st) != 0) { syslog(LOG_ERR, "lost queue file `%s'", it->queuefn); - exit(1); + exit(EX_SOFTWARE); } if (gettimeofday(&now, NULL) == 0 && (now.tv_sec - st.st_mtim.tv_sec > MAX_TIMEOUT)) { @@ -439,16 +439,16 @@ main(int argc, char **argv) pw = getpwnam(DMA_ROOT_USER); if (pw == NULL) { if (errno == 0) - errx(1, "user '%s' not found", DMA_ROOT_USER); + errx(EX_CONFIG, "user '%s' not found", DMA_ROOT_USER); else - err(1, "cannot drop root privileges"); + err(EX_OSERR, "cannot drop root privileges"); } if (setuid(pw->pw_uid) != 0) - err(1, "cannot drop root privileges"); + err(EX_OSERR, "cannot drop root privileges"); if (geteuid() == 0 || getuid() == 0) - errx(1, "cannot drop root privileges"); + errx(EX_OSERR, "cannot drop root privileges"); } atexit(deltmp); @@ -461,15 +461,15 @@ main(int argc, char **argv) argv++; argc--; showq = 1; if (argc != 0) - errx(1, "invalid arguments"); + errx(EX_USAGE, "invalid arguments"); goto skipopts; } else if (strcmp(argv[0], "newaliases") == 0) { logident_base = "dma"; setlogident(NULL); if (read_aliases() != 0) - errx(1, "could not parse aliases file `%s'", config.aliases); - exit(0); + errx(EX_SOFTWARE, "could not parse aliases file `%s'", config.aliases); + exit(EX_OK); } opterr = 0; @@ -548,7 +548,7 @@ main(int argc, char **argv) default: fprintf(stderr, "invalid argument: `-%c'\n", optopt); - exit(1); + exit(EX_USAGE); } } argc -= optind; @@ -556,10 +556,10 @@ main(int argc, char **argv) opterr = 1; if (argc != 0 && (showq || doqueue)) - errx(1, "sending mail and queue operations are mutually exclusive"); + errx(EX_USAGE, "sending mail and queue operations are mutually exclusive"); if (showq + doqueue > 1) - errx(1, "conflicting queue operations"); + errx(EX_USAGE, "conflicting queue operations"); skipopts: if (logident_base == NULL) @@ -579,7 +579,7 @@ skipopts: if (showq) { if (load_queue(&queue) < 0) - errlog(1, "can not load queue"); + errlog(EX_NOINPUT, "can not load queue"); show_queue(&queue); return (0); } @@ -587,38 +587,38 @@ skipopts: if (doqueue) { flushqueue_signal(); if (load_queue(&queue) < 0) - errlog(1, "can not load queue"); + errlog(EX_NOINPUT, "can not load queue"); run_queue(&queue); return (0); } if (read_aliases() != 0) - errlog(1, "could not parse aliases file `%s'", config.aliases); + errlog(EX_SOFTWARE, "could not parse aliases file `%s'", config.aliases); if ((sender = set_from(&queue, sender)) == NULL) - errlog(1, NULL); + errlog(EX_SOFTWARE, NULL); if (newspoolf(&queue) != 0) - errlog(1, "can not create temp file in `%s'", config.spooldir); + 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(1, "invalid recipient `%s'", argv[i]); + errlogx(EX_DATAERR, "invalid recipient `%s'", argv[i]); } if (LIST_EMPTY(&queue.queue) && !recp_from_header) - errlogx(1, "no recipients"); + errlogx(EX_NOINPUT, "no recipients"); if (readmail(&queue, nodot, recp_from_header) != 0) - errlog(1, "can not read mail"); + errlog(EX_NOINPUT, "can not read mail"); if (LIST_EMPTY(&queue.queue)) - errlogx(1, "no recipients"); + errlogx(EX_NOINPUT, "no recipients"); if (linkspool(&queue) != 0) - errlog(1, "can not create spools"); + errlog(EX_CANTCREAT, "can not create spools"); /* From here on the mail is safe. */ diff --git a/dma.h b/dma.h index bf0cecf..acf5e44 100644 --- a/dma.h +++ b/dma.h @@ -44,6 +44,7 @@ #include #include #include +#include #define VERSION "DragonFly Mail Agent " DMA_VERSION diff --git a/local.c b/local.c index f7b9895..e3e0152 100644 --- a/local.c +++ b/local.c @@ -82,7 +82,7 @@ create_mbox(const char *name) execl(LIBEXEC_PATH "/dma-mbox-create", "dma-mbox-create", name, NULL); syslog(LOG_ERR, "cannot execute "LIBEXEC_PATH"/dma-mbox-create: %m"); - exit(1); + exit(EX_SOFTWARE); default: /* parent */ diff --git a/mail.c b/mail.c index d0f728f..a6d11fc 100644 --- a/mail.c +++ b/mail.c @@ -52,7 +52,7 @@ bounce(struct qitem *it, const char *reason) /* Don't bounce bounced mails */ if (it->sender[0] == 0) { syslog(LOG_INFO, "can not bounce a bounce message, discarding"); - exit(1); + exit(EX_SOFTWARE); } bzero(&bounceq, sizeof(bounceq)); @@ -133,7 +133,7 @@ bounce(struct qitem *it, const char *reason) fail: syslog(LOG_CRIT, "error creating bounce: %m"); delqueue(it); - exit(1); + exit(EX_IOERR); } struct parse_state { @@ -333,10 +333,10 @@ newaddr: ps->pos = 0; addr = strdup(ps->addr); if (addr == NULL) - errlog(1, NULL); + errlog(EX_SOFTWARE, NULL); if (add_recp(queue, addr, EXPAND_WILDCARD) != 0) - errlogx(1, "invalid recipient `%s'", addr); + errlogx(EX_DATAERR, "invalid recipient `%s'", addr); goto again; } @@ -375,7 +375,7 @@ readmail(struct queue *queue, int nodot, int recp_from_header) if (fgets(line, sizeof(line) - 1, stdin) == NULL) break; if (had_last_line) - errlogx(1, "bad mail input format:" + errlogx(EX_DATAERR, "bad mail input format:" " from %s (uid %d) (envelope-from %s)", username, useruid, queue->sender); linelen = strlen(line); @@ -408,7 +408,7 @@ readmail(struct queue *queue, int nodot, int recp_from_header) if (parse_state.state != NONE) { if (parse_addrs(&parse_state, line, queue) < 0) { - errlogx(1, "invalid address in header\n"); + errlogx(EX_DATAERR, "invalid address in header\n"); /* NOTREACHED */ } } @@ -419,7 +419,7 @@ readmail(struct queue *queue, int nodot, int recp_from_header) strprefixcmp(line, "Bcc:") == 0)) { parse_state.state = START; if (parse_addrs(&parse_state, line, queue) < 0) { - errlogx(1, "invalid address in header\n"); + errlogx(EX_DATAERR, "invalid address in header\n"); /* NOTREACHED */ } } diff --git a/spool.c b/spool.c index 8f4e2ea..e9c9c43 100644 --- a/spool.c +++ b/spool.c @@ -290,7 +290,7 @@ load_queue(struct queue *queue) spooldir = opendir(config.spooldir); if (spooldir == NULL) - err(1, "reading queue"); + err(EX_NOINPUT, "reading queue"); while ((de = readdir(spooldir)) != NULL) { queuefn = NULL;