converted man page
[unix-history] / usr / src / bin / rmail / rmail.c
CommitLineData
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
9char 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 15static 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 34typedef char bool;
44ae4c24
EA
35#define TRUE 1
36#define FALSE 0
37
306f949d
KB
38extern char *index();
39extern char *rindex();
0f5791a6 40
306f949d 41char *Domain = "UUCP"; /* Default "Domain" */
0f5791a6 42
9adc8f2c 43main(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}