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