1205938Sdelphij/* $OpenBSD: mailwrapper.c,v 1.18 2007/11/06 14:39:19 otto Exp $ */ 2161038Sdelphij/* $NetBSD: mailwrapper.c,v 1.9 2003/03/09 08:10:43 mjl Exp $ */ 354816Speter 454816Speter/* 554816Speter * Copyright (c) 1998 654816Speter * Perry E. Metzger. All rights reserved. 754816Speter * 854816Speter * Redistribution and use in source and binary forms, with or without 954816Speter * modification, are permitted provided that the following conditions 1054816Speter * are met: 1154816Speter * 1. Redistributions of source code must retain the above copyright 1254816Speter * notice, this list of conditions and the following disclaimer. 1354816Speter * 2. Redistributions in binary form must reproduce the above copyright 1454816Speter * notice, this list of conditions and the following disclaimer in the 1554816Speter * documentation and/or other materials provided with the distribution. 1654816Speter * 3. All advertising materials mentioning features or use of this software 1754816Speter * must display the following acknowledgment: 1854816Speter * This product includes software developed for the NetBSD Project 1954816Speter * by Perry E. Metzger. 2054816Speter * 4. The name of the author may not be used to endorse or promote products 2154816Speter * derived from this software without specific prior written permission. 2254816Speter * 2354816Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2454816Speter * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2554816Speter * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2654816Speter * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2754816Speter * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2854816Speter * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2954816Speter * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3054816Speter * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3154816Speter * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3254816Speter * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3354816Speter */ 3454816Speter 35117280Scharnier#include <sys/cdefs.h> 36117280Scharnier__FBSDID("$FreeBSD$"); 37117280Scharnier 3854816Speter#include <err.h> 3954816Speter#include <stdio.h> 4054816Speter#include <string.h> 41159326Sdelphij#include <unistd.h> 4254816Speter#include <stdlib.h> 4355228Speter#include <libutil.h> 44159326Sdelphij#include <sysexits.h> 4555705Simp#include <syslog.h> 4654816Speter 4755228Speter#include "pathnames.h" 4854816Speter 4954816Speterstruct arglist { 5054816Speter size_t argc, maxc; 5154816Speter char **argv; 5254816Speter}; 5354816Speter 5499800Salfredint main(int, char *[], char *[]); 5554816Speter 5699800Salfredstatic void initarg(struct arglist *); 57159326Sdelphijstatic void addarg(struct arglist *, const char *); 5854816Speter 5954816Speterstatic void 60159326Sdelphijinitarg(struct arglist *al) 6154816Speter{ 6254816Speter al->argc = 0; 6354816Speter al->maxc = 10; 64205938Sdelphij if ((al->argv = calloc(al->maxc, sizeof(char *))) == NULL) 65205938Sdelphij err(EX_TEMPFAIL, "calloc"); 6654816Speter} 6754816Speter 6854816Speterstatic void 69159326Sdelphijaddarg(struct arglist *al, const char *arg) 7054816Speter{ 7155705Simp 7254816Speter if (al->argc == al->maxc) { 7355705Simp al->maxc <<= 1; 74159326Sdelphij al->argv = realloc(al->argv, al->maxc * sizeof(char *)); 75159326Sdelphij if (al->argv == NULL) 76159326Sdelphij err(EX_TEMPFAIL, "realloc"); 7754816Speter } 78159326Sdelphij if (arg == NULL) 79159326Sdelphij al->argv[al->argc++] = NULL; 80159326Sdelphij else if ((al->argv[al->argc++] = strdup(arg)) == NULL) 81159326Sdelphij err(EX_TEMPFAIL, "strdup"); 8254816Speter} 8354816Speter 8454816Speterint 85159326Sdelphijmain(int argc, char *argv[], char *envp[]) 8654816Speter{ 8754816Speter FILE *config; 8854816Speter char *line, *cp, *from, *to, *ap; 89159326Sdelphij const char *progname; 9054816Speter size_t len, lineno = 0; 91159326Sdelphij int i; 9254816Speter struct arglist al; 9354816Speter 94159326Sdelphij /* change __progname to mailwrapper so we get sensible error messages */ 95159326Sdelphij progname = getprogname(); 96159326Sdelphij setprogname("mailwrapper"); 97159326Sdelphij 9854816Speter initarg(&al); 99159326Sdelphij addarg(&al, argv[0]); 10054816Speter 10155705Simp if ((config = fopen(_PATH_MAILERCONF, "r")) == NULL) { 102159326Sdelphij addarg(&al, NULL); 103159326Sdelphij openlog(getprogname(), LOG_PID, LOG_MAIL); 104159326Sdelphij syslog(LOG_INFO, "cannot open %s, using %s as default MTA", 10555705Simp _PATH_MAILERCONF, _PATH_DEFAULTMTA); 10655705Simp closelog(); 10755705Simp execve(_PATH_DEFAULTMTA, al.argv, envp); 108159326Sdelphij err(EX_OSERR, "cannot exec %s", _PATH_DEFAULTMTA); 10955705Simp /*NOTREACHED*/ 11055705Simp } 11154816Speter 11254816Speter for (;;) { 11354816Speter if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL) { 11454816Speter if (feof(config)) 115159326Sdelphij errx(EX_CONFIG, "no mapping in %s", _PATH_MAILERCONF); 116159326Sdelphij err(EX_CONFIG, "cannot parse line %lu", (u_long)lineno); 11754816Speter } 11854816Speter 11954816Speter#define WS " \t\n" 12054816Speter cp = line; 12154816Speter 12254816Speter cp += strspn(cp, WS); 12354816Speter if (cp[0] == '\0') { 12454816Speter /* empty line */ 12554816Speter free(line); 12654816Speter continue; 12754816Speter } 12854816Speter 129205938Sdelphij if ((from = strsep(&cp, WS)) == NULL || cp == NULL) 13054816Speter goto parse_error; 13154816Speter 13254816Speter cp += strspn(cp, WS); 13354816Speter 13454816Speter if ((to = strsep(&cp, WS)) == NULL) 13554816Speter goto parse_error; 13654816Speter 137159326Sdelphij if (strcmp(from, progname) == 0) { 138159326Sdelphij for (ap = strsep(&cp, WS); ap != NULL; 139159326Sdelphij ap = strsep(&cp, WS)) { 140159326Sdelphij if (*ap) 141159326Sdelphij addarg(&al, ap); 142159326Sdelphij } 14354816Speter break; 14454816Speter } 14554816Speter 14654816Speter free(line); 14754816Speter } 14854816Speter 14954816Speter (void)fclose(config); 15054816Speter 151159326Sdelphij for (i = 1; i < argc; i++) 152159326Sdelphij addarg(&al, argv[i]); 153159326Sdelphij 154159326Sdelphij addarg(&al, NULL); 15554816Speter execve(to, al.argv, envp); 156159326Sdelphij err(EX_OSERR, "cannot exec %s", to); 15754816Speter /*NOTREACHED*/ 15854816Speterparse_error: 159159326Sdelphij errx(EX_CONFIG, "parse error in %s at line %lu", 16054816Speter _PATH_MAILERCONF, (u_long)lineno); 16154816Speter /*NOTREACHED*/ 16254816Speter} 163