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