1ded78408SXin LI /* $OpenBSD: mailwrapper.c,v 1.18 2007/11/06 14:39:19 otto Exp $ */ 249fe7301SXin LI /* $NetBSD: mailwrapper.c,v 1.9 2003/03/09 08:10:43 mjl Exp $ */ 33ae92913SPeter Wemm 41de7b4b8SPedro F. Giffuni /*- 51de7b4b8SPedro F. Giffuni * SPDX-License-Identifier: BSD-4-Clause 61de7b4b8SPedro F. Giffuni * 73ae92913SPeter Wemm * Copyright (c) 1998 83ae92913SPeter Wemm * Perry E. Metzger. All rights reserved. 93ae92913SPeter Wemm * 103ae92913SPeter Wemm * Redistribution and use in source and binary forms, with or without 113ae92913SPeter Wemm * modification, are permitted provided that the following conditions 123ae92913SPeter Wemm * are met: 133ae92913SPeter Wemm * 1. Redistributions of source code must retain the above copyright 143ae92913SPeter Wemm * notice, this list of conditions and the following disclaimer. 153ae92913SPeter Wemm * 2. Redistributions in binary form must reproduce the above copyright 163ae92913SPeter Wemm * notice, this list of conditions and the following disclaimer in the 173ae92913SPeter Wemm * documentation and/or other materials provided with the distribution. 183ae92913SPeter Wemm * 3. All advertising materials mentioning features or use of this software 193ae92913SPeter Wemm * must display the following acknowledgment: 203ae92913SPeter Wemm * This product includes software developed for the NetBSD Project 213ae92913SPeter Wemm * by Perry E. Metzger. 223ae92913SPeter Wemm * 4. The name of the author may not be used to endorse or promote products 233ae92913SPeter Wemm * derived from this software without specific prior written permission. 243ae92913SPeter Wemm * 253ae92913SPeter Wemm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 263ae92913SPeter Wemm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 273ae92913SPeter Wemm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 283ae92913SPeter Wemm * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 293ae92913SPeter Wemm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 303ae92913SPeter Wemm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 313ae92913SPeter Wemm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 323ae92913SPeter Wemm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 333ae92913SPeter Wemm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 343ae92913SPeter Wemm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 353ae92913SPeter Wemm */ 363ae92913SPeter Wemm 3724ed0a57SBaptiste Daroussin #include <sys/param.h> 3824ed0a57SBaptiste Daroussin 393ae92913SPeter Wemm #include <err.h> 401f474190SStefan Eßer #include <paths.h> 413ae92913SPeter Wemm #include <stdio.h> 423ae92913SPeter Wemm #include <string.h> 433ae92913SPeter Wemm #include <unistd.h> 448fe1b8c0SXin LI #include <stdlib.h> 45*961bcbeeSLexi Winter #include <errno.h> 468b081eaaSBaptiste Daroussin #include <libutil.h> 478fe1b8c0SXin LI #include <sysexits.h> 48ff4d7851SWarner Losh #include <syslog.h> 493ae92913SPeter Wemm 50521cb9d2SPeter Wemm #include "pathnames.h" 513ae92913SPeter Wemm 523ae92913SPeter Wemm struct arglist { 533ae92913SPeter Wemm size_t argc, maxc; 543ae92913SPeter Wemm char **argv; 553ae92913SPeter Wemm }; 563ae92913SPeter Wemm 57d89167b4SAlfred Perlstein int main(int, char *[], char *[]); 583ae92913SPeter Wemm 59d89167b4SAlfred Perlstein static void initarg(struct arglist *); 608fe1b8c0SXin LI static void addarg(struct arglist *, const char *); 613ae92913SPeter Wemm 623ae92913SPeter Wemm static void 638fe1b8c0SXin LI initarg(struct arglist *al) 643ae92913SPeter Wemm { 653ae92913SPeter Wemm al->argc = 0; 663ae92913SPeter Wemm al->maxc = 10; 67ded78408SXin LI if ((al->argv = calloc(al->maxc, sizeof(char *))) == NULL) 68ded78408SXin LI err(EX_TEMPFAIL, "calloc"); 693ae92913SPeter Wemm } 703ae92913SPeter Wemm 713ae92913SPeter Wemm static void 728fe1b8c0SXin LI addarg(struct arglist *al, const char *arg) 733ae92913SPeter Wemm { 74ff4d7851SWarner Losh 753ae92913SPeter Wemm if (al->argc == al->maxc) { 763ae92913SPeter Wemm al->maxc <<= 1; 778fe1b8c0SXin LI al->argv = realloc(al->argv, al->maxc * sizeof(char *)); 788fe1b8c0SXin LI if (al->argv == NULL) 798fe1b8c0SXin LI err(EX_TEMPFAIL, "realloc"); 80ff4d7851SWarner Losh } 818fe1b8c0SXin LI if (arg == NULL) 828fe1b8c0SXin LI al->argv[al->argc++] = NULL; 838fe1b8c0SXin LI else if ((al->argv[al->argc++] = strdup(arg)) == NULL) 848fe1b8c0SXin LI err(EX_TEMPFAIL, "strdup"); 853ae92913SPeter Wemm } 863ae92913SPeter Wemm 873ae92913SPeter Wemm int 888fe1b8c0SXin LI main(int argc, char *argv[], char *envp[]) 893ae92913SPeter Wemm { 903ae92913SPeter Wemm FILE *config; 918b081eaaSBaptiste Daroussin char *line, *cp, *from, *to, *ap; 928fe1b8c0SXin LI const char *progname; 9324ed0a57SBaptiste Daroussin char localmailerconf[MAXPATHLEN]; 9424ed0a57SBaptiste Daroussin const char *mailerconf; 958b081eaaSBaptiste Daroussin size_t len, lineno = 0; 968fe1b8c0SXin LI int i; 973ae92913SPeter Wemm struct arglist al; 983ae92913SPeter Wemm 998fe1b8c0SXin LI /* change __progname to mailwrapper so we get sensible error messages */ 1008fe1b8c0SXin LI progname = getprogname(); 1018fe1b8c0SXin LI setprogname("mailwrapper"); 1028fe1b8c0SXin LI 1033ae92913SPeter Wemm initarg(&al); 1048fe1b8c0SXin LI addarg(&al, argv[0]); 1053ae92913SPeter Wemm 1068e103108SScott Long snprintf(localmailerconf, MAXPATHLEN, "%s/etc/mail/mailer.conf", 10756d11d4aSStefan Eßer getlocalbase()); 10824ed0a57SBaptiste Daroussin 10924ed0a57SBaptiste Daroussin mailerconf = localmailerconf; 11024ed0a57SBaptiste Daroussin if ((config = fopen(localmailerconf, "r")) == NULL) 11124ed0a57SBaptiste Daroussin mailerconf = _PATH_MAILERCONF; 11224ed0a57SBaptiste Daroussin 11324ed0a57SBaptiste Daroussin if (config == NULL && ((config = fopen(mailerconf, "r")) == NULL)) { 114*961bcbeeSLexi Winter int serrno = errno; 1158fe1b8c0SXin LI openlog(getprogname(), LOG_PID, LOG_MAIL); 116*961bcbeeSLexi Winter 117*961bcbeeSLexi Winter if (serrno == ENOENT) { 118*961bcbeeSLexi Winter addarg(&al, NULL); 119*961bcbeeSLexi Winter syslog(LOG_INFO, "%s does not exist, using %s as default MTA", 12024ed0a57SBaptiste Daroussin mailerconf, _PATH_DEFAULTMTA); 121ff4d7851SWarner Losh closelog(); 122ff4d7851SWarner Losh execve(_PATH_DEFAULTMTA, al.argv, envp); 1238fe1b8c0SXin LI err(EX_OSERR, "cannot exec %s", _PATH_DEFAULTMTA); 124*961bcbeeSLexi Winter } else { 125*961bcbeeSLexi Winter syslog(LOG_INFO, "cannot open %s: %s", 126*961bcbeeSLexi Winter mailerconf, strerror(serrno)); 127*961bcbeeSLexi Winter closelog(); 128*961bcbeeSLexi Winter errno = serrno; 129*961bcbeeSLexi Winter err(EX_OSERR, "cannot open %s", mailerconf); 130*961bcbeeSLexi Winter } 131ff4d7851SWarner Losh /*NOTREACHED*/ 132ff4d7851SWarner Losh } 1333ae92913SPeter Wemm 1343ae92913SPeter Wemm for (;;) { 1358b081eaaSBaptiste Daroussin if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL) { 1368b081eaaSBaptiste Daroussin if (feof(config)) 13724ed0a57SBaptiste Daroussin errx(EX_CONFIG, "no mapping in %s", mailerconf); 1388fe1b8c0SXin LI err(EX_CONFIG, "cannot parse line %lu", (u_long)lineno); 1393ae92913SPeter Wemm } 1408b081eaaSBaptiste Daroussin 1413ae92913SPeter Wemm #define WS " \t\n" 1423ae92913SPeter Wemm cp = line; 1433ae92913SPeter Wemm 1443ae92913SPeter Wemm cp += strspn(cp, WS); 1453ae92913SPeter Wemm if (cp[0] == '\0') { 1463ae92913SPeter Wemm /* empty line */ 1473ae92913SPeter Wemm free(line); 1483ae92913SPeter Wemm continue; 1493ae92913SPeter Wemm } 1503ae92913SPeter Wemm 151ded78408SXin LI if ((from = strsep(&cp, WS)) == NULL || cp == NULL) 1523ae92913SPeter Wemm goto parse_error; 1533ae92913SPeter Wemm 1543ae92913SPeter Wemm cp += strspn(cp, WS); 1553ae92913SPeter Wemm 1563ae92913SPeter Wemm if ((to = strsep(&cp, WS)) == NULL) 1573ae92913SPeter Wemm goto parse_error; 1583ae92913SPeter Wemm 1598fe1b8c0SXin LI if (strcmp(from, progname) == 0) { 1603ae92913SPeter Wemm for (ap = strsep(&cp, WS); ap != NULL; 1618fe1b8c0SXin LI ap = strsep(&cp, WS)) { 1623ae92913SPeter Wemm if (*ap) 1638fe1b8c0SXin LI addarg(&al, ap); 1648fe1b8c0SXin LI } 1653ae92913SPeter Wemm break; 1663ae92913SPeter Wemm } 1673ae92913SPeter Wemm 1683ae92913SPeter Wemm free(line); 1693ae92913SPeter Wemm } 1703ae92913SPeter Wemm 1713ae92913SPeter Wemm (void)fclose(config); 1723ae92913SPeter Wemm 1738fe1b8c0SXin LI for (i = 1; i < argc; i++) 1748fe1b8c0SXin LI addarg(&al, argv[i]); 1758fe1b8c0SXin LI 1768fe1b8c0SXin LI addarg(&al, NULL); 1773ae92913SPeter Wemm execve(to, al.argv, envp); 1788fe1b8c0SXin LI err(EX_OSERR, "cannot exec %s", to); 1793ae92913SPeter Wemm /*NOTREACHED*/ 1803ae92913SPeter Wemm parse_error: 1818fe1b8c0SXin LI errx(EX_CONFIG, "parse error in %s at line %lu", 18224ed0a57SBaptiste Daroussin mailerconf, (u_long)lineno); 1833ae92913SPeter Wemm /*NOTREACHED*/ 1843ae92913SPeter Wemm } 185