1*421949a3Ssevan /* $NetBSD: mailwrapper.c,v 1.11 2018/01/23 21:06:25 sevan Exp $ */
2180c29c3Sperry
3180c29c3Sperry /*
4180c29c3Sperry * Copyright (c) 1998
5180c29c3Sperry * Perry E. Metzger. All rights reserved.
6180c29c3Sperry *
7180c29c3Sperry * Redistribution and use in source and binary forms, with or without
8180c29c3Sperry * modification, are permitted provided that the following conditions
9180c29c3Sperry * are met:
10180c29c3Sperry * 1. Redistributions of source code must retain the above copyright
11180c29c3Sperry * notice, this list of conditions and the following disclaimer.
12180c29c3Sperry * 2. Redistributions in binary form must reproduce the above copyright
13180c29c3Sperry * notice, this list of conditions and the following disclaimer in the
14180c29c3Sperry * documentation and/or other materials provided with the distribution.
15180c29c3Sperry * 3. All advertising materials mentioning features or use of this software
16180c29c3Sperry * must display the following acknowledgment:
17180c29c3Sperry * This product includes software developed for the NetBSD Project
18180c29c3Sperry * by Perry E. Metzger.
19180c29c3Sperry * 4. The name of the author may not be used to endorse or promote products
20180c29c3Sperry * derived from this software without specific prior written permission.
21180c29c3Sperry *
22180c29c3Sperry * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23180c29c3Sperry * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24180c29c3Sperry * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25180c29c3Sperry * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26180c29c3Sperry * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27180c29c3Sperry * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28180c29c3Sperry * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29180c29c3Sperry * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30180c29c3Sperry * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31180c29c3Sperry * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32180c29c3Sperry */
33180c29c3Sperry
34180c29c3Sperry #include <err.h>
35180c29c3Sperry #include <stdio.h>
36180c29c3Sperry #include <string.h>
370d7a8dcbSthorpej #include <stdlib.h>
38180c29c3Sperry #include <unistd.h>
39180c29c3Sperry
40180c29c3Sperry #define _PATH_MAILERCONF "/etc/mailer.conf"
41180c29c3Sperry
42854002abSchristos struct arglist {
43854002abSchristos size_t argc, maxc;
4443e54b3aSlukem const char **argv;
45854002abSchristos };
46854002abSchristos
47*421949a3Ssevan static void initarg(struct arglist *);
48*421949a3Ssevan static void addarg(struct arglist *, const char *, int);
49854002abSchristos
50854002abSchristos static void
initarg(struct arglist * al)51*421949a3Ssevan initarg(struct arglist *al)
52854002abSchristos {
53854002abSchristos al->argc = 0;
54854002abSchristos al->maxc = 10;
55854002abSchristos if ((al->argv = malloc(al->maxc * sizeof(char *))) == NULL)
56b0d37030Smjl /*
57b0d37030Smjl * This (using err("mailwrapper")) is intentional.
58b0d37030Smjl * Mailwrapper plays ugly games with argv[0] and thus it
59b0d37030Smjl * is often difficult for people to know that the error
60b0d37030Smjl * isn't from "mailq" or "sendmail" but from mailwrapper
61b0d37030Smjl * -- having mailwrapper add an indication that it was really
62b0d37030Smjl * mailwrapper running was a requested feature.
63b0d37030Smjl */
64b0d37030Smjl err(1, "mailwrapper");
65854002abSchristos }
66854002abSchristos
67854002abSchristos static void
addarg(struct arglist * al,const char * arg,int copy)68*421949a3Ssevan addarg(struct arglist *al, const char *arg, int copy)
69854002abSchristos {
70854002abSchristos if (al->argc == al->maxc) {
71854002abSchristos al->maxc <<= 1;
72854002abSchristos if ((al->argv = realloc(al->argv,
73854002abSchristos al->maxc * sizeof(char *))) == NULL)
74b0d37030Smjl err(1, "mailwrapper");
75854002abSchristos }
76854002abSchristos if (copy) {
77854002abSchristos if ((al->argv[al->argc++] = strdup(arg)) == NULL)
78b0d37030Smjl err(1, "mailwrapper:");
79854002abSchristos } else
8043e54b3aSlukem al->argv[al->argc++] = arg;
81854002abSchristos }
82854002abSchristos
83180c29c3Sperry int
main(int argc,char * argv[],char * envp[])84*421949a3Ssevan main(int argc, char *argv[], char *envp[])
85180c29c3Sperry {
86180c29c3Sperry FILE *config;
87854002abSchristos char *line, *cp, *from, *to, *ap;
880d7a8dcbSthorpej size_t len, lineno = 0;
89ca86df3fSis int i;
90854002abSchristos struct arglist al;
91854002abSchristos
92854002abSchristos initarg(&al);
93ca86df3fSis addarg(&al, argv[0], 0);
94180c29c3Sperry
95180c29c3Sperry if ((config = fopen(_PATH_MAILERCONF, "r")) == NULL)
96b0d37030Smjl err(1, "mailwrapper: can't open %s", _PATH_MAILERCONF);
97180c29c3Sperry
980d7a8dcbSthorpej for (;;) {
990d7a8dcbSthorpej if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL) {
1000d7a8dcbSthorpej if (feof(config))
101b0d37030Smjl errx(1, "mailwrapper: no mapping in %s",
102b0d37030Smjl _PATH_MAILERCONF);
103b0d37030Smjl err(1, "mailwrapper");
1040d7a8dcbSthorpej }
105180c29c3Sperry
106854002abSchristos #define WS " \t\n"
1070d7a8dcbSthorpej cp = line;
108180c29c3Sperry
109854002abSchristos cp += strspn(cp, WS);
1100d7a8dcbSthorpej if (cp[0] == '\0') {
1110d7a8dcbSthorpej /* empty line */
1120d7a8dcbSthorpej free(line);
113180c29c3Sperry continue;
1140d7a8dcbSthorpej }
115180c29c3Sperry
116854002abSchristos if ((from = strsep(&cp, WS)) == NULL)
117854002abSchristos goto parse_error;
118180c29c3Sperry
119854002abSchristos cp += strspn(cp, WS);
1200d7a8dcbSthorpej
121854002abSchristos if ((to = strsep(&cp, WS)) == NULL)
122854002abSchristos goto parse_error;
1230d7a8dcbSthorpej
12425bdbb66Scgd if (strcmp(from, getprogname()) == 0) {
125854002abSchristos for (ap = strsep(&cp, WS); ap != NULL;
126854002abSchristos ap = strsep(&cp, WS))
127854002abSchristos if (*ap)
128854002abSchristos addarg(&al, ap, 0);
129180c29c3Sperry break;
130854002abSchristos }
1310d7a8dcbSthorpej
1320d7a8dcbSthorpej free(line);
133180c29c3Sperry }
134180c29c3Sperry
135854002abSchristos (void)fclose(config);
136180c29c3Sperry
137ca86df3fSis for (i = 1; i < argc; i++)
138ca86df3fSis addarg(&al, argv[i], 0);
139ca86df3fSis
140c1fd8f00Smsaitoh addarg(&al, NULL, 0);
14143e54b3aSlukem execve(to, __UNCONST(al.argv), envp);
142b0d37030Smjl err(1, "mailwrapper: execing %s", to);
143854002abSchristos /*NOTREACHED*/
144854002abSchristos parse_error:
145b0d37030Smjl errx(1, "mailwrapper: parse error in %s at line %lu",
146854002abSchristos _PATH_MAILERCONF, (u_long)lineno);
147854002abSchristos /*NOTREACHED*/
148180c29c3Sperry }
149