1ff4d7851SWarner Losh /* $OpenBSD: mailwrapper.c,v 1.6 1999/12/17 05:06:28 mickey Exp $ */ 23ae92913SPeter Wemm /* $NetBSD: mailwrapper.c,v 1.3 1999/05/29 18:18:15 christos Exp $ */ 3521cb9d2SPeter Wemm /* $FreeBSD$ */ 43ae92913SPeter Wemm 53ae92913SPeter Wemm /* 63ae92913SPeter Wemm * Copyright (c) 1998 73ae92913SPeter Wemm * Perry E. Metzger. All rights reserved. 83ae92913SPeter Wemm * 93ae92913SPeter Wemm * Redistribution and use in source and binary forms, with or without 103ae92913SPeter Wemm * modification, are permitted provided that the following conditions 113ae92913SPeter Wemm * are met: 123ae92913SPeter Wemm * 1. Redistributions of source code must retain the above copyright 133ae92913SPeter Wemm * notice, this list of conditions and the following disclaimer. 143ae92913SPeter Wemm * 2. Redistributions in binary form must reproduce the above copyright 153ae92913SPeter Wemm * notice, this list of conditions and the following disclaimer in the 163ae92913SPeter Wemm * documentation and/or other materials provided with the distribution. 173ae92913SPeter Wemm * 3. All advertising materials mentioning features or use of this software 183ae92913SPeter Wemm * must display the following acknowledgment: 193ae92913SPeter Wemm * This product includes software developed for the NetBSD Project 203ae92913SPeter Wemm * by Perry E. Metzger. 213ae92913SPeter Wemm * 4. The name of the author may not be used to endorse or promote products 223ae92913SPeter Wemm * derived from this software without specific prior written permission. 233ae92913SPeter Wemm * 243ae92913SPeter Wemm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 253ae92913SPeter Wemm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 263ae92913SPeter Wemm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 273ae92913SPeter Wemm * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 283ae92913SPeter Wemm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 293ae92913SPeter Wemm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 303ae92913SPeter Wemm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 313ae92913SPeter Wemm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 323ae92913SPeter Wemm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 333ae92913SPeter Wemm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 343ae92913SPeter Wemm */ 353ae92913SPeter Wemm 363ae92913SPeter Wemm #include <err.h> 373ae92913SPeter Wemm #include <stdio.h> 383ae92913SPeter Wemm #include <string.h> 393ae92913SPeter Wemm #include <stdlib.h> 403ae92913SPeter Wemm #include <unistd.h> 41521cb9d2SPeter Wemm #include <libutil.h> 42ff4d7851SWarner Losh #include <syslog.h> 43ff4d7851SWarner Losh #include <stdarg.h> 443ae92913SPeter Wemm 45521cb9d2SPeter Wemm #include "pathnames.h" 463ae92913SPeter Wemm 473ae92913SPeter Wemm struct arglist { 483ae92913SPeter Wemm size_t argc, maxc; 493ae92913SPeter Wemm char **argv; 503ae92913SPeter Wemm }; 513ae92913SPeter Wemm 52d89167b4SAlfred Perlstein int main(int, char *[], char *[]); 533ae92913SPeter Wemm 54d89167b4SAlfred Perlstein static void initarg(struct arglist *); 55d89167b4SAlfred Perlstein static void addarg(struct arglist *, const char *, int); 56d89167b4SAlfred Perlstein static void freearg(struct arglist *, int); 573ae92913SPeter Wemm 583ae92913SPeter Wemm extern const char *__progname; /* from crt0.o */ 593ae92913SPeter Wemm 603ae92913SPeter Wemm static void 613ae92913SPeter Wemm initarg(al) 623ae92913SPeter Wemm struct arglist *al; 633ae92913SPeter Wemm { 643ae92913SPeter Wemm al->argc = 0; 653ae92913SPeter Wemm al->maxc = 10; 663ae92913SPeter Wemm if ((al->argv = malloc(al->maxc * sizeof(char *))) == NULL) 6739e80db3SPhilippe Charnier err(1, NULL); 683ae92913SPeter Wemm } 693ae92913SPeter Wemm 703ae92913SPeter Wemm static void 713ae92913SPeter Wemm addarg(al, arg, copy) 723ae92913SPeter Wemm struct arglist *al; 733ae92913SPeter Wemm const char *arg; 743ae92913SPeter Wemm int copy; 753ae92913SPeter Wemm { 76ff4d7851SWarner Losh char **argv2; 77ff4d7851SWarner Losh 783ae92913SPeter Wemm if (al->argc == al->maxc) { 793ae92913SPeter Wemm al->maxc <<= 1; 80ff4d7851SWarner Losh 81ff4d7851SWarner Losh if ((argv2 = realloc(al->argv, 82ff4d7851SWarner Losh al->maxc * sizeof(char *))) == NULL) { 83ff4d7851SWarner Losh if (al->argv) 84ff4d7851SWarner Losh free(al->argv); 85ff4d7851SWarner Losh al->argv = NULL; 8639e80db3SPhilippe Charnier err(1, NULL); 87ff4d7851SWarner Losh } else { 88ff4d7851SWarner Losh al->argv = argv2; 89ff4d7851SWarner Losh } 903ae92913SPeter Wemm } 913ae92913SPeter Wemm if (copy) { 923ae92913SPeter Wemm if ((al->argv[al->argc++] = strdup(arg)) == NULL) 9339e80db3SPhilippe Charnier err(1, NULL); 943ae92913SPeter Wemm } else 953ae92913SPeter Wemm al->argv[al->argc++] = (char *)arg; 963ae92913SPeter Wemm } 973ae92913SPeter Wemm 983ae92913SPeter Wemm static void 993ae92913SPeter Wemm freearg(al, copy) 1003ae92913SPeter Wemm struct arglist *al; 1013ae92913SPeter Wemm int copy; 1023ae92913SPeter Wemm { 1033ae92913SPeter Wemm size_t i; 1043ae92913SPeter Wemm if (copy) 1053ae92913SPeter Wemm for (i = 0; i < al->argc; i++) 1063ae92913SPeter Wemm free(al->argv[i]); 1073ae92913SPeter Wemm free(al->argv); 1083ae92913SPeter Wemm } 1093ae92913SPeter Wemm 1103ae92913SPeter Wemm int 1113ae92913SPeter Wemm main(argc, argv, envp) 1123ae92913SPeter Wemm int argc; 1133ae92913SPeter Wemm char *argv[]; 1143ae92913SPeter Wemm char *envp[]; 1153ae92913SPeter Wemm { 1163ae92913SPeter Wemm FILE *config; 1173ae92913SPeter Wemm char *line, *cp, *from, *to, *ap; 1183ae92913SPeter Wemm size_t len, lineno = 0; 1193ae92913SPeter Wemm struct arglist al; 1203ae92913SPeter Wemm 1213ae92913SPeter Wemm initarg(&al); 1223ae92913SPeter Wemm for (len = 0; len < argc; len++) 1233ae92913SPeter Wemm addarg(&al, argv[len], 0); 1243ae92913SPeter Wemm 125ff4d7851SWarner Losh if ((config = fopen(_PATH_MAILERCONF, "r")) == NULL) { 126ff4d7851SWarner Losh addarg(&al, NULL, 0); 127ff4d7851SWarner Losh openlog("mailwrapper", LOG_PID, LOG_MAIL); 128ff4d7851SWarner Losh syslog(LOG_INFO, "can't open %s, using %s as default MTA", 129ff4d7851SWarner Losh _PATH_MAILERCONF, _PATH_DEFAULTMTA); 130ff4d7851SWarner Losh closelog(); 131ff4d7851SWarner Losh execve(_PATH_DEFAULTMTA, al.argv, envp); 132ff4d7851SWarner Losh freearg(&al, 0); 13339e80db3SPhilippe Charnier err(1, "execing %s", _PATH_DEFAULTMTA); 134ff4d7851SWarner Losh /*NOTREACHED*/ 135ff4d7851SWarner Losh } 1363ae92913SPeter Wemm 1373ae92913SPeter Wemm for (;;) { 1383ae92913SPeter Wemm if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL) { 1393ae92913SPeter Wemm if (feof(config)) 14039e80db3SPhilippe Charnier errx(1, "no mapping in %s", _PATH_MAILERCONF); 14139e80db3SPhilippe Charnier err(1, "can't parse line %lu", (u_long)lineno); 1423ae92913SPeter Wemm } 1433ae92913SPeter Wemm 1443ae92913SPeter Wemm #define WS " \t\n" 1453ae92913SPeter Wemm cp = line; 1463ae92913SPeter Wemm 1473ae92913SPeter Wemm cp += strspn(cp, WS); 1483ae92913SPeter Wemm if (cp[0] == '\0') { 1493ae92913SPeter Wemm /* empty line */ 1503ae92913SPeter Wemm free(line); 1513ae92913SPeter Wemm continue; 1523ae92913SPeter Wemm } 1533ae92913SPeter Wemm 1543ae92913SPeter Wemm if ((from = strsep(&cp, WS)) == NULL) 1553ae92913SPeter Wemm goto parse_error; 1563ae92913SPeter Wemm 1573ae92913SPeter Wemm cp += strspn(cp, WS); 1583ae92913SPeter Wemm 1593ae92913SPeter Wemm if ((to = strsep(&cp, WS)) == NULL) 1603ae92913SPeter Wemm goto parse_error; 1613ae92913SPeter Wemm 1623ae92913SPeter Wemm if (strcmp(from, __progname) == 0) { 1633ae92913SPeter Wemm for (ap = strsep(&cp, WS); ap != NULL; 1643ae92913SPeter Wemm ap = strsep(&cp, WS)) 1653ae92913SPeter Wemm if (*ap) 1663ae92913SPeter Wemm addarg(&al, ap, 0); 1673ae92913SPeter Wemm break; 1683ae92913SPeter Wemm } 1693ae92913SPeter Wemm 1703ae92913SPeter Wemm free(line); 1713ae92913SPeter Wemm } 1723ae92913SPeter Wemm 1733ae92913SPeter Wemm (void)fclose(config); 1743ae92913SPeter Wemm 175ff4d7851SWarner Losh addarg(&al, NULL, 0); 1763ae92913SPeter Wemm execve(to, al.argv, envp); 1773ae92913SPeter Wemm freearg(&al, 0); 17857b6c4a5SPaul Richards warn("execing %s", to); 1793ae92913SPeter Wemm free(line); 18057b6c4a5SPaul Richards exit(1); 1813ae92913SPeter Wemm /*NOTREACHED*/ 1823ae92913SPeter Wemm parse_error: 1833ae92913SPeter Wemm freearg(&al, 0); 1843ae92913SPeter Wemm free(line); 18539e80db3SPhilippe Charnier errx(1, "parse error in %s at line %lu", 1863ae92913SPeter Wemm _PATH_MAILERCONF, (u_long)lineno); 1873ae92913SPeter Wemm /*NOTREACHED*/ 1883ae92913SPeter Wemm } 189