Commit | Line | Data |
---|---|---|
9b7cb659 KB |
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 are permitted | |
6 | * provided that the above copyright notice and this paragraph are | |
7 | * duplicated in all such forms and that any documentation, | |
8 | * advertising materials, and other materials related to such | |
9 | * distribution and use acknowledge that the software was developed | |
10 | * by the University of California, Berkeley. The name of the | |
11 | * University may not be used to endorse or promote products derived | |
12 | * from this software without specific prior written permission. | |
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
14 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
15 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
16 | */ | |
17 | ||
18 | #ifndef lint | |
19 | char copyright[] = | |
20 | "@(#) Copyright (c) 1981, 1988 The Regents of the University of California.\n\ | |
21 | All rights reserved.\n"; | |
22 | #endif /* not lint */ | |
23 | ||
205a2d85 | 24 | #ifndef lint |
7abf8d65 | 25 | static char sccsid[] = "@(#)rmail.c 4.13 (Berkeley) %G%"; |
9b7cb659 | 26 | #endif /* not lint */ |
205a2d85 | 27 | |
9adc8f2c | 28 | /* |
306f949d KB |
29 | * RMAIL -- UUCP mail server. |
30 | * | |
31 | * This program reads the >From ... remote from ... lines that | |
32 | * UUCP is so fond of and turns them into something reasonable. | |
33 | * It calls sendmail giving it a -f option built from these lines. | |
34 | */ | |
9adc8f2c | 35 | |
306f949d KB |
36 | #include <sysexits.h> |
37 | #include <sys/types.h> | |
38 | #include <sys/file.h> | |
39 | #include <sys/stat.h> | |
7abf8d65 KB |
40 | #include <stdio.h> |
41 | #include <paths.h> | |
b5fd168f | 42 | # include "conf.h" |
9adc8f2c | 43 | |
306f949d | 44 | typedef char bool; |
44ae4c24 EA |
45 | #define TRUE 1 |
46 | #define FALSE 0 | |
47 | ||
306f949d KB |
48 | extern char *index(); |
49 | extern char *rindex(); | |
0f5791a6 | 50 | |
306f949d | 51 | char *Domain = "UUCP"; /* Default "Domain" */ |
0f5791a6 | 52 | |
9adc8f2c | 53 | main(argc, argv) |
306f949d | 54 | int argc; |
0f5791a6 | 55 | char **argv; |
9adc8f2c | 56 | { |
ecbd0932 JL |
57 | char lbuf[1024]; /* one line of the message */ |
58 | char from[512]; /* accumulated path of sender */ | |
59 | char ufrom[512]; /* user on remote system */ | |
60 | char sys[512]; /* a system in path */ | |
306f949d | 61 | char fsys[512]; /* first system in path */ |
ecbd0932 | 62 | char junk[1024]; /* scratchpad */ |
306f949d | 63 | char *args[100]; /* arguments to mailer command */ |
0f5791a6 | 64 | register char *cp; |
306f949d | 65 | register char *uf = NULL; /* ptr into ufrom */ |
9777ef27 | 66 | int i; |
306f949d KB |
67 | long position; |
68 | struct stat sbuf; | |
69 | #ifdef DEBUG | |
70 | bool Debug; | |
9adc8f2c | 71 | |
306f949d | 72 | if (argc > 1 && strcmp(argv[1], "-T") == 0) { |
0f5791a6 EA |
73 | Debug = TRUE; |
74 | argc--; | |
75 | argv++; | |
9adc8f2c | 76 | } |
306f949d | 77 | #endif |
9adc8f2c | 78 | |
306f949d | 79 | if (argc < 2) { |
0f5791a6 EA |
80 | fprintf(stderr, "Usage: rmail user ...\n"); |
81 | exit(EX_USAGE); | |
82 | } | |
306f949d KB |
83 | if (argc > 2 && strncmp(argv[1], "-D", 2) == 0) { |
84 | Domain = &argv[1][2]; | |
85 | argc -= 2; | |
86 | argv += 2; | |
87 | } | |
88 | from[0] = '\0'; | |
89 | fsys[0] = '\0'; | |
7abf8d65 | 90 | (void) strcpy(ufrom, _PATH_DEVNULL); |
b8b8df54 | 91 | |
306f949d | 92 | for (position = 0;; position = ftell(stdin)) { |
74c5fe7c | 93 | (void) fgets(lbuf, sizeof lbuf, stdin); |
306f949d KB |
94 | if (strncmp(lbuf, "From ", 5) != 0 && |
95 | strncmp(lbuf, ">From ", 6) != 0) | |
9adc8f2c | 96 | break; |
ed45aae1 | 97 | (void) sscanf(lbuf, "%s %s", junk, ufrom); |
9adc8f2c | 98 | cp = lbuf; |
306f949d KB |
99 | uf = ufrom; |
100 | for (;;) { | |
101 | cp = index(cp + 1, 'r'); | |
102 | if (cp == NULL) { | |
09fa495a EA |
103 | register char *p = rindex(uf, '!'); |
104 | ||
306f949d | 105 | if (p != NULL) { |
09fa495a | 106 | *p = '\0'; |
f9566d23 | 107 | (void) strcpy(sys, uf); |
09fa495a EA |
108 | uf = p + 1; |
109 | break; | |
110 | } | |
306f949d KB |
111 | (void) strcpy(sys, ""); |
112 | break; /* no "remote from" found */ | |
09fa495a | 113 | } |
9adc8f2c | 114 | #ifdef DEBUG |
0f5791a6 EA |
115 | if (Debug) |
116 | printf("cp='%s'\n", cp); | |
9adc8f2c | 117 | #endif |
306f949d | 118 | if (strncmp(cp, "remote from ", 12) == 0) |
9adc8f2c EA |
119 | break; |
120 | } | |
09fa495a EA |
121 | if (cp != NULL) |
122 | (void) sscanf(cp, "remote from %s", sys); | |
306f949d KB |
123 | if (fsys[0] == '\0') |
124 | (void) strcpy(fsys, sys); | |
125 | if (sys[0]) { | |
126 | (void) strcat(from, sys); | |
127 | (void) strcat(from, "!"); | |
128 | } | |
9adc8f2c | 129 | #ifdef DEBUG |
0f5791a6 | 130 | if (Debug) |
09fa495a | 131 | printf("ufrom='%s', sys='%s', from now '%s'\n", uf, sys, from); |
9adc8f2c EA |
132 | #endif |
133 | } | |
306f949d KB |
134 | if (uf == NULL) { /* No From line was provided */ |
135 | fprintf(stderr, "No From line in rmail\n"); | |
136 | exit(EX_DATAERR); | |
137 | } | |
f9566d23 | 138 | (void) strcat(from, uf); |
306f949d KB |
139 | (void) fstat(0, &sbuf); |
140 | (void) lseek(0, position, L_SET); | |
141 | ||
142 | /* | |
143 | * Now we rebuild the argument list and chain to sendmail. Note that | |
144 | * the above lseek might fail on irregular files, but we check for | |
145 | * that case below. | |
146 | */ | |
147 | i = 0; | |
7abf8d65 | 148 | args[i++] = _PATH_SENDMAIL; |
1b48a4b1 KB |
149 | args[i++] = "-oee"; /* no errors, just status */ |
150 | args[i++] = "-odq"; /* queue it, don't try to deliver */ | |
151 | args[i++] = "-oi"; /* ignore '.' on a line by itself */ | |
152 | if (fsys[0] != '\0') { /* set sender's host name */ | |
306f949d KB |
153 | static char junk2[512]; |
154 | ||
155 | if (index(fsys, '.') == NULL) { | |
156 | (void) strcat(fsys, "."); | |
157 | (void) strcat(fsys, Domain); | |
158 | } | |
159 | (void) sprintf(junk2, "-oMs%s", fsys); | |
160 | args[i++] = junk2; | |
161 | } | |
1b48a4b1 | 162 | /* set protocol used */ |
306f949d KB |
163 | (void) sprintf(junk, "-oMr%s", Domain); |
164 | args[i++] = junk; | |
1b48a4b1 | 165 | if (from[0] != '\0') { /* set name of ``from'' person */ |
306f949d | 166 | static char junk2[512]; |
9adc8f2c | 167 | |
306f949d KB |
168 | (void) sprintf(junk2, "-f%s", from); |
169 | args[i++] = junk2; | |
170 | } | |
171 | for (; *++argv != NULL; i++) { | |
6c59f6dd KB |
172 | /* |
173 | * don't copy arguments beginning with - as they will | |
174 | * be passed to sendmail and could be interpreted as flags | |
1b48a4b1 KB |
175 | * should be fixed in sendmail by using getopt(3), and |
176 | * just passing "--" before regular args. | |
6c59f6dd KB |
177 | */ |
178 | if (**argv != '-') | |
179 | args[i] = *argv; | |
0f5791a6 | 180 | } |
306f949d | 181 | args[i] = NULL; |
9adc8f2c | 182 | #ifdef DEBUG |
306f949d KB |
183 | if (Debug) { |
184 | printf("Command:"); | |
185 | for (i = 0; args[i]; i++) | |
186 | printf(" %s", args[i]); | |
187 | printf("\n"); | |
9777ef27 | 188 | } |
306f949d KB |
189 | #endif |
190 | if ((sbuf.st_mode & S_IFMT) != S_IFREG) { | |
191 | /* | |
192 | * If we were not called with standard input on a regular | |
193 | * file, then we have to fork another process to send the | |
194 | * first line down the pipe. | |
195 | */ | |
196 | int pipefd[2]; | |
1b48a4b1 | 197 | #ifdef DEBUG |
306f949d KB |
198 | if (Debug) |
199 | printf("Not a regular file!\n"); | |
1b48a4b1 | 200 | #endif |
306f949d KB |
201 | if (pipe(pipefd) < 0) |
202 | exit(EX_OSERR); | |
203 | if (fork() == 0) { | |
204 | /* | |
205 | * Child: send the message down the pipe. | |
206 | */ | |
207 | FILE *out; | |
9adc8f2c | 208 | |
306f949d KB |
209 | out = fdopen(pipefd[1], "w"); |
210 | close(pipefd[0]); | |
211 | fputs(lbuf, out); | |
212 | while (fgets(lbuf, sizeof lbuf, stdin)) | |
213 | fputs(lbuf, out); | |
214 | (void) fclose(out); | |
215 | exit(EX_OK); | |
216 | } | |
217 | /* | |
218 | * Parent: call sendmail with pipe as standard input | |
219 | */ | |
220 | close(pipefd[1]); | |
221 | dup2(pipefd[0], 0); | |
222 | } | |
7abf8d65 KB |
223 | execv(_PATH_SENDMAIL, args); |
224 | fprintf(stderr, "Exec of %s failed!\n", _PATH_SENDMAIL); | |
306f949d | 225 | exit(EX_OSERR); |
9adc8f2c | 226 | } |