386BSD 0.1 development
[unix-history] / usr / src / bin / rmail / rmail.c
CommitLineData
537ba487
WJ
1/*
2 * Copyright (c) 1981, 1988 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35char copyright[] =
36"@(#) Copyright (c) 1981, 1988 The Regents of the University of California.\n\
37 All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41static char sccsid[] = "@(#)rmail.c 4.15 (Berkeley) 5/31/90";
42#endif /* not lint */
43
44/*
45 * RMAIL -- UUCP mail server.
46 *
47 * This program reads the >From ... remote from ... lines that
48 * UUCP is so fond of and turns them into something reasonable.
49 * It calls sendmail giving it a -f option built from these lines.
50 */
51
52#include <sysexits.h>
53#include <sys/types.h>
54#include <sys/file.h>
55#include <sys/stat.h>
56#include <stdio.h>
57#include <paths.h>
58
59typedef char bool;
60#define TRUE 1
61#define FALSE 0
62
63extern char *index();
64extern char *rindex();
65
66char *Domain = "UUCP"; /* Default "Domain" */
67
68main(argc, argv)
69 int argc;
70 char **argv;
71{
72 char lbuf[1024]; /* one line of the message */
73 char from[512]; /* accumulated path of sender */
74 char ufrom[512]; /* user on remote system */
75 char sys[512]; /* a system in path */
76 char fsys[512]; /* first system in path */
77 char junk[1024]; /* scratchpad */
78 char *args[100]; /* arguments to mailer command */
79 register char *cp;
80 register char *uf = NULL; /* ptr into ufrom */
81 int i;
82 long position;
83 struct stat sbuf;
84#ifdef DEBUG
85 bool Debug;
86
87 if (argc > 1 && strcmp(argv[1], "-T") == 0) {
88 Debug = TRUE;
89 argc--;
90 argv++;
91 }
92#endif
93
94 if (argc < 2) {
95 fprintf(stderr, "Usage: rmail user ...\n");
96 exit(EX_USAGE);
97 }
98 if (argc > 2 && strncmp(argv[1], "-D", 2) == 0) {
99 Domain = &argv[1][2];
100 argc -= 2;
101 argv += 2;
102 }
103 from[0] = '\0';
104 fsys[0] = '\0';
105 (void) strcpy(ufrom, _PATH_DEVNULL);
106
107 for (position = 0;; position = ftell(stdin)) {
108 if (fgets(lbuf, sizeof lbuf, stdin) == NULL)
109 exit(EX_DATAERR);
110 if (strncmp(lbuf, "From ", 5) != 0 &&
111 strncmp(lbuf, ">From ", 6) != 0)
112 break;
113 (void) sscanf(lbuf, "%s %s", junk, ufrom);
114 cp = lbuf;
115 uf = ufrom;
116 for (;;) {
117 cp = index(cp + 1, 'r');
118 if (cp == NULL) {
119 register char *p = rindex(uf, '!');
120
121 if (p != NULL) {
122 *p = '\0';
123 (void) strcpy(sys, uf);
124 uf = p + 1;
125 break;
126 }
127 (void) strcpy(sys, "");
128 break; /* no "remote from" found */
129 }
130#ifdef DEBUG
131 if (Debug)
132 printf("cp='%s'\n", cp);
133#endif
134 if (strncmp(cp, "remote from ", 12) == 0)
135 break;
136 }
137 if (cp != NULL)
138 (void) sscanf(cp, "remote from %s", sys);
139 if (fsys[0] == '\0')
140 (void) strcpy(fsys, sys);
141 if (sys[0]) {
142 (void) strcat(from, sys);
143 (void) strcat(from, "!");
144 }
145#ifdef DEBUG
146 if (Debug)
147 printf("ufrom='%s', sys='%s', from now '%s'\n", uf, sys, from);
148#endif
149 }
150 if (uf == NULL) { /* No From line was provided */
151 fprintf(stderr, "No From line in rmail\n");
152 exit(EX_DATAERR);
153 }
154 (void) strcat(from, uf);
155 (void) fstat(0, &sbuf);
156 (void) lseek(0, position, L_SET);
157
158 /*
159 * Now we rebuild the argument list and chain to sendmail. Note that
160 * the above lseek might fail on irregular files, but we check for
161 * that case below.
162 */
163 i = 0;
164 args[i++] = _PATH_SENDMAIL;
165 args[i++] = "-oee"; /* no errors, just status */
166 args[i++] = "-odq"; /* queue it, don't try to deliver */
167 args[i++] = "-oi"; /* ignore '.' on a line by itself */
168 if (fsys[0] != '\0') { /* set sender's host name */
169 static char junk2[512];
170
171 if (index(fsys, '.') == NULL) {
172 (void) strcat(fsys, ".");
173 (void) strcat(fsys, Domain);
174 }
175 (void) sprintf(junk2, "-oMs%s", fsys);
176 args[i++] = junk2;
177 }
178 /* set protocol used */
179 (void) sprintf(junk, "-oMr%s", Domain);
180 args[i++] = junk;
181 if (from[0] != '\0') { /* set name of ``from'' person */
182 static char junk2[512];
183
184 (void) sprintf(junk2, "-f%s", from);
185 args[i++] = junk2;
186 }
187 for (; *++argv != NULL; i++) {
188 /*
189 * don't copy arguments beginning with - as they will
190 * be passed to sendmail and could be interpreted as flags
191 * should be fixed in sendmail by using getopt(3), and
192 * just passing "--" before regular args.
193 */
194 if (**argv != '-')
195 args[i] = *argv;
196 }
197 args[i] = NULL;
198#ifdef DEBUG
199 if (Debug) {
200 printf("Command:");
201 for (i = 0; args[i]; i++)
202 printf(" %s", args[i]);
203 printf("\n");
204 }
205#endif
206 if ((sbuf.st_mode & S_IFMT) != S_IFREG) {
207 /*
208 * If we were not called with standard input on a regular
209 * file, then we have to fork another process to send the
210 * first line down the pipe.
211 */
212 int pipefd[2];
213#ifdef DEBUG
214 if (Debug)
215 printf("Not a regular file!\n");
216#endif
217 if (pipe(pipefd) < 0)
218 exit(EX_OSERR);
219 if (fork() == 0) {
220 /*
221 * Child: send the message down the pipe.
222 */
223 FILE *out;
224
225 out = fdopen(pipefd[1], "w");
226 close(pipefd[0]);
227 fputs(lbuf, out);
228 while (fgets(lbuf, sizeof lbuf, stdin))
229 fputs(lbuf, out);
230 (void) fclose(out);
231 exit(EX_OK);
232 }
233 /*
234 * Parent: call sendmail with pipe as standard input
235 */
236 close(pipefd[1]);
237 dup2(pipefd[0], 0);
238 }
239 execv(_PATH_SENDMAIL, args);
240 fprintf(stderr, "Exec of %s failed!\n", _PATH_SENDMAIL);
241 exit(EX_OSERR);
242}