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 |
762d9edd | 25 | static char sccsid[] = "@(#)rmail.c 4.14 (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)) { |
762d9edd RA |
93 | if (fgets(lbuf, sizeof lbuf, stdin) == NULL) |
94 | exit(EX_DATAERR); | |
306f949d KB |
95 | if (strncmp(lbuf, "From ", 5) != 0 && |
96 | strncmp(lbuf, ">From ", 6) != 0) | |
9adc8f2c | 97 | break; |
ed45aae1 | 98 | (void) sscanf(lbuf, "%s %s", junk, ufrom); |
9adc8f2c | 99 | cp = lbuf; |
306f949d KB |
100 | uf = ufrom; |
101 | for (;;) { | |
102 | cp = index(cp + 1, 'r'); | |
103 | if (cp == NULL) { | |
09fa495a EA |
104 | register char *p = rindex(uf, '!'); |
105 | ||
306f949d | 106 | if (p != NULL) { |
09fa495a | 107 | *p = '\0'; |
f9566d23 | 108 | (void) strcpy(sys, uf); |
09fa495a EA |
109 | uf = p + 1; |
110 | break; | |
111 | } | |
306f949d KB |
112 | (void) strcpy(sys, ""); |
113 | break; /* no "remote from" found */ | |
09fa495a | 114 | } |
9adc8f2c | 115 | #ifdef DEBUG |
0f5791a6 EA |
116 | if (Debug) |
117 | printf("cp='%s'\n", cp); | |
9adc8f2c | 118 | #endif |
306f949d | 119 | if (strncmp(cp, "remote from ", 12) == 0) |
9adc8f2c EA |
120 | break; |
121 | } | |
09fa495a EA |
122 | if (cp != NULL) |
123 | (void) sscanf(cp, "remote from %s", sys); | |
306f949d KB |
124 | if (fsys[0] == '\0') |
125 | (void) strcpy(fsys, sys); | |
126 | if (sys[0]) { | |
127 | (void) strcat(from, sys); | |
128 | (void) strcat(from, "!"); | |
129 | } | |
9adc8f2c | 130 | #ifdef DEBUG |
0f5791a6 | 131 | if (Debug) |
09fa495a | 132 | printf("ufrom='%s', sys='%s', from now '%s'\n", uf, sys, from); |
9adc8f2c EA |
133 | #endif |
134 | } | |
306f949d KB |
135 | if (uf == NULL) { /* No From line was provided */ |
136 | fprintf(stderr, "No From line in rmail\n"); | |
137 | exit(EX_DATAERR); | |
138 | } | |
f9566d23 | 139 | (void) strcat(from, uf); |
306f949d KB |
140 | (void) fstat(0, &sbuf); |
141 | (void) lseek(0, position, L_SET); | |
142 | ||
143 | /* | |
144 | * Now we rebuild the argument list and chain to sendmail. Note that | |
145 | * the above lseek might fail on irregular files, but we check for | |
146 | * that case below. | |
147 | */ | |
148 | i = 0; | |
7abf8d65 | 149 | args[i++] = _PATH_SENDMAIL; |
1b48a4b1 KB |
150 | args[i++] = "-oee"; /* no errors, just status */ |
151 | args[i++] = "-odq"; /* queue it, don't try to deliver */ | |
152 | args[i++] = "-oi"; /* ignore '.' on a line by itself */ | |
153 | if (fsys[0] != '\0') { /* set sender's host name */ | |
306f949d KB |
154 | static char junk2[512]; |
155 | ||
156 | if (index(fsys, '.') == NULL) { | |
157 | (void) strcat(fsys, "."); | |
158 | (void) strcat(fsys, Domain); | |
159 | } | |
160 | (void) sprintf(junk2, "-oMs%s", fsys); | |
161 | args[i++] = junk2; | |
162 | } | |
1b48a4b1 | 163 | /* set protocol used */ |
306f949d KB |
164 | (void) sprintf(junk, "-oMr%s", Domain); |
165 | args[i++] = junk; | |
1b48a4b1 | 166 | if (from[0] != '\0') { /* set name of ``from'' person */ |
306f949d | 167 | static char junk2[512]; |
9adc8f2c | 168 | |
306f949d KB |
169 | (void) sprintf(junk2, "-f%s", from); |
170 | args[i++] = junk2; | |
171 | } | |
172 | for (; *++argv != NULL; i++) { | |
6c59f6dd KB |
173 | /* |
174 | * don't copy arguments beginning with - as they will | |
175 | * be passed to sendmail and could be interpreted as flags | |
1b48a4b1 KB |
176 | * should be fixed in sendmail by using getopt(3), and |
177 | * just passing "--" before regular args. | |
6c59f6dd KB |
178 | */ |
179 | if (**argv != '-') | |
180 | args[i] = *argv; | |
0f5791a6 | 181 | } |
306f949d | 182 | args[i] = NULL; |
9adc8f2c | 183 | #ifdef DEBUG |
306f949d KB |
184 | if (Debug) { |
185 | printf("Command:"); | |
186 | for (i = 0; args[i]; i++) | |
187 | printf(" %s", args[i]); | |
188 | printf("\n"); | |
9777ef27 | 189 | } |
306f949d KB |
190 | #endif |
191 | if ((sbuf.st_mode & S_IFMT) != S_IFREG) { | |
192 | /* | |
193 | * If we were not called with standard input on a regular | |
194 | * file, then we have to fork another process to send the | |
195 | * first line down the pipe. | |
196 | */ | |
197 | int pipefd[2]; | |
1b48a4b1 | 198 | #ifdef DEBUG |
306f949d KB |
199 | if (Debug) |
200 | printf("Not a regular file!\n"); | |
1b48a4b1 | 201 | #endif |
306f949d KB |
202 | if (pipe(pipefd) < 0) |
203 | exit(EX_OSERR); | |
204 | if (fork() == 0) { | |
205 | /* | |
206 | * Child: send the message down the pipe. | |
207 | */ | |
208 | FILE *out; | |
9adc8f2c | 209 | |
306f949d KB |
210 | out = fdopen(pipefd[1], "w"); |
211 | close(pipefd[0]); | |
212 | fputs(lbuf, out); | |
213 | while (fgets(lbuf, sizeof lbuf, stdin)) | |
214 | fputs(lbuf, out); | |
215 | (void) fclose(out); | |
216 | exit(EX_OK); | |
217 | } | |
218 | /* | |
219 | * Parent: call sendmail with pipe as standard input | |
220 | */ | |
221 | close(pipefd[1]); | |
222 | dup2(pipefd[0], 0); | |
223 | } | |
7abf8d65 KB |
224 | execv(_PATH_SENDMAIL, args); |
225 | fprintf(stderr, "Exec of %s failed!\n", _PATH_SENDMAIL); | |
306f949d | 226 | exit(EX_OSERR); |
9adc8f2c | 227 | } |