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