18fe1b8c0SXin LI /* $OpenBSD: mailwrapper.c,v 1.15 2003/03/09 01:24:26 millert Exp $ */ 28fe1b8c0SXin LI /* $NetBSD: mailwrapper.c,v 1.7 2003/02/17 21:18:46 is Exp $ */ 33ae92913SPeter Wemm 43ae92913SPeter Wemm /* 53ae92913SPeter Wemm * Copyright (c) 1998 63ae92913SPeter Wemm * Perry E. Metzger. All rights reserved. 73ae92913SPeter Wemm * 83ae92913SPeter Wemm * Redistribution and use in source and binary forms, with or without 93ae92913SPeter Wemm * modification, are permitted provided that the following conditions 103ae92913SPeter Wemm * are met: 113ae92913SPeter Wemm * 1. Redistributions of source code must retain the above copyright 123ae92913SPeter Wemm * notice, this list of conditions and the following disclaimer. 133ae92913SPeter Wemm * 2. Redistributions in binary form must reproduce the above copyright 143ae92913SPeter Wemm * notice, this list of conditions and the following disclaimer in the 153ae92913SPeter Wemm * documentation and/or other materials provided with the distribution. 163ae92913SPeter Wemm * 3. All advertising materials mentioning features or use of this software 173ae92913SPeter Wemm * must display the following acknowledgment: 183ae92913SPeter Wemm * This product includes software developed for the NetBSD Project 193ae92913SPeter Wemm * by Perry E. Metzger. 203ae92913SPeter Wemm * 4. The name of the author may not be used to endorse or promote products 213ae92913SPeter Wemm * derived from this software without specific prior written permission. 223ae92913SPeter Wemm * 233ae92913SPeter Wemm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 243ae92913SPeter Wemm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 253ae92913SPeter Wemm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 263ae92913SPeter Wemm * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 273ae92913SPeter Wemm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 283ae92913SPeter Wemm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 293ae92913SPeter Wemm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 303ae92913SPeter Wemm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 313ae92913SPeter Wemm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 323ae92913SPeter Wemm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 333ae92913SPeter Wemm */ 343ae92913SPeter Wemm 3554ede02dSPhilippe Charnier #include <sys/cdefs.h> 3654ede02dSPhilippe Charnier __FBSDID("$FreeBSD$"); 3754ede02dSPhilippe Charnier 383ae92913SPeter Wemm #include <err.h> 393ae92913SPeter Wemm #include <stdio.h> 403ae92913SPeter Wemm #include <string.h> 413ae92913SPeter Wemm #include <unistd.h> 428fe1b8c0SXin LI #include <stdlib.h> 43521cb9d2SPeter Wemm #include <libutil.h> 448fe1b8c0SXin LI #include <sysexits.h> 45ff4d7851SWarner Losh #include <syslog.h> 463ae92913SPeter Wemm 47521cb9d2SPeter Wemm #include "pathnames.h" 483ae92913SPeter Wemm 493ae92913SPeter Wemm struct arglist { 503ae92913SPeter Wemm size_t argc, maxc; 513ae92913SPeter Wemm char **argv; 523ae92913SPeter Wemm }; 533ae92913SPeter Wemm 54d89167b4SAlfred Perlstein int main(int, char *[], char *[]); 553ae92913SPeter Wemm 56d89167b4SAlfred Perlstein static void initarg(struct arglist *); 578fe1b8c0SXin LI static void addarg(struct arglist *, const char *); 583ae92913SPeter Wemm 593ae92913SPeter Wemm static void 608fe1b8c0SXin LI initarg(struct arglist *al) 613ae92913SPeter Wemm { 623ae92913SPeter Wemm al->argc = 0; 633ae92913SPeter Wemm al->maxc = 10; 643ae92913SPeter Wemm if ((al->argv = malloc(al->maxc * sizeof(char *))) == NULL) 658fe1b8c0SXin LI err(EX_TEMPFAIL, "malloc"); 663ae92913SPeter Wemm } 673ae92913SPeter Wemm 683ae92913SPeter Wemm static void 698fe1b8c0SXin LI addarg(struct arglist *al, const char *arg) 703ae92913SPeter Wemm { 71ff4d7851SWarner Losh 723ae92913SPeter Wemm if (al->argc == al->maxc) { 733ae92913SPeter Wemm al->maxc <<= 1; 748fe1b8c0SXin LI al->argv = realloc(al->argv, al->maxc * sizeof(char *)); 758fe1b8c0SXin LI if (al->argv == NULL) 768fe1b8c0SXin LI err(EX_TEMPFAIL, "realloc"); 77ff4d7851SWarner Losh } 788fe1b8c0SXin LI if (arg == NULL) 798fe1b8c0SXin LI al->argv[al->argc++] = NULL; 808fe1b8c0SXin LI else if ((al->argv[al->argc++] = strdup(arg)) == NULL) 818fe1b8c0SXin LI err(EX_TEMPFAIL, "strdup"); 823ae92913SPeter Wemm } 833ae92913SPeter Wemm 843ae92913SPeter Wemm int 858fe1b8c0SXin LI main(int argc, char *argv[], char *envp[]) 863ae92913SPeter Wemm { 873ae92913SPeter Wemm FILE *config; 883ae92913SPeter Wemm char *line, *cp, *from, *to, *ap; 898fe1b8c0SXin LI const char *progname; 903ae92913SPeter Wemm size_t len, lineno = 0; 918fe1b8c0SXin LI int i; 923ae92913SPeter Wemm struct arglist al; 933ae92913SPeter Wemm 948fe1b8c0SXin LI /* change __progname to mailwrapper so we get sensible error messages */ 958fe1b8c0SXin LI progname = getprogname(); 968fe1b8c0SXin LI setprogname("mailwrapper"); 978fe1b8c0SXin LI 983ae92913SPeter Wemm initarg(&al); 998fe1b8c0SXin LI addarg(&al, argv[0]); 1003ae92913SPeter Wemm 101ff4d7851SWarner Losh if ((config = fopen(_PATH_MAILERCONF, "r")) == NULL) { 1028fe1b8c0SXin LI addarg(&al, NULL); 1038fe1b8c0SXin LI openlog(getprogname(), LOG_PID, LOG_MAIL); 1048fe1b8c0SXin LI syslog(LOG_INFO, "cannot open %s, using %s as default MTA", 105ff4d7851SWarner Losh _PATH_MAILERCONF, _PATH_DEFAULTMTA); 106ff4d7851SWarner Losh closelog(); 107ff4d7851SWarner Losh execve(_PATH_DEFAULTMTA, al.argv, envp); 1088fe1b8c0SXin LI err(EX_OSERR, "cannot exec %s", _PATH_DEFAULTMTA); 109ff4d7851SWarner Losh /*NOTREACHED*/ 110ff4d7851SWarner Losh } 1113ae92913SPeter Wemm 1123ae92913SPeter Wemm for (;;) { 1133ae92913SPeter Wemm if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL) { 1143ae92913SPeter Wemm if (feof(config)) 1158fe1b8c0SXin LI errx(EX_CONFIG, "no mapping in %s", _PATH_MAILERCONF); 1168fe1b8c0SXin LI err(EX_CONFIG, "cannot parse line %lu", (u_long)lineno); 1173ae92913SPeter Wemm } 1183ae92913SPeter Wemm 1193ae92913SPeter Wemm #define WS " \t\n" 1203ae92913SPeter Wemm cp = line; 1213ae92913SPeter Wemm 1223ae92913SPeter Wemm cp += strspn(cp, WS); 1233ae92913SPeter Wemm if (cp[0] == '\0') { 1243ae92913SPeter Wemm /* empty line */ 1253ae92913SPeter Wemm free(line); 1263ae92913SPeter Wemm continue; 1273ae92913SPeter Wemm } 1283ae92913SPeter Wemm 1293ae92913SPeter Wemm if ((from = strsep(&cp, WS)) == NULL) 1303ae92913SPeter Wemm goto parse_error; 1313ae92913SPeter Wemm 1323ae92913SPeter Wemm cp += strspn(cp, WS); 1333ae92913SPeter Wemm 1343ae92913SPeter Wemm if ((to = strsep(&cp, WS)) == NULL) 1353ae92913SPeter Wemm goto parse_error; 1363ae92913SPeter Wemm 1378fe1b8c0SXin LI if (strcmp(from, progname) == 0) { 1383ae92913SPeter Wemm for (ap = strsep(&cp, WS); ap != NULL; 1398fe1b8c0SXin LI ap = strsep(&cp, WS)) { 1403ae92913SPeter Wemm if (*ap) 1418fe1b8c0SXin LI addarg(&al, ap); 1428fe1b8c0SXin LI } 1433ae92913SPeter Wemm break; 1443ae92913SPeter Wemm } 1453ae92913SPeter Wemm 1463ae92913SPeter Wemm free(line); 1473ae92913SPeter Wemm } 1483ae92913SPeter Wemm 1493ae92913SPeter Wemm (void)fclose(config); 1503ae92913SPeter Wemm 1518fe1b8c0SXin LI for (i = 1; i < argc; i++) 1528fe1b8c0SXin LI addarg(&al, argv[i]); 1538fe1b8c0SXin LI 1548fe1b8c0SXin LI addarg(&al, NULL); 1553ae92913SPeter Wemm execve(to, al.argv, envp); 1568fe1b8c0SXin LI err(EX_OSERR, "cannot exec %s", to); 1573ae92913SPeter Wemm /*NOTREACHED*/ 1583ae92913SPeter Wemm parse_error: 1598fe1b8c0SXin LI errx(EX_CONFIG, "parse error in %s at line %lu", 1603ae92913SPeter Wemm _PATH_MAILERCONF, (u_long)lineno); 1613ae92913SPeter Wemm /*NOTREACHED*/ 1623ae92913SPeter Wemm } 163