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