home *** CD-ROM | disk | FTP | other *** search
- /*
- ** fakemail - a SysV /bin/mail preprocessor for sendmail
- **
- ** Standard AT&T /bin/mail adds it's own From_ line specifying the
- ** identity of the sender (commenting out any previously existing
- ** From_ lines in the process). While this behavior might be
- ** consistent with RFC-976, it only serves to confuse mailers such
- ** as mailx which use the From_ line to determine reply addresses.
- **
- ** To determine the sender identity (placed in the generated From_
- ** line), /bin/mail uses $LOGNAME of the user/program invoking it.
- ** For local mail this is moderately acceptable (the user could fake
- ** the sender by changing $LOGNAME), but for use with sendmail this
- ** behavior is unreasonable since the invocation of /bin/mail is
- ** done by root. As a result, mailx reports all external mail as
- ** "From root", and the actual identity of the sender is obscured.
- **
- ** `fakemail' is designed as a replacement for the sendmail local
- ** delivery program. It preprocesses mail messages (read from
- ** stdin) and changes $LOGNAME before calling the regular /bin/mail.
- ** The new $LOGNAME is derived from the address portion of the From_
- ** line, which is found in the first line of the header.
- **
- ** From user@site Fri Jun 15 13:18:09 1990
- **
- ** If no From_ line is found, $LOGNAME defaults to the user of the
- ** program, as with normal /bin/mail.
- **
- ** Technically, `fakemail' could be considered a slightly better
- ** mechanism than direct /bin/mail since you cannot spoof the
- ** program by changing $LOGNAME. An argument against this, however,
- ** is the fact that you *can* trick `fakemail' by supplying a bogus
- ** From_ line as the first line of the header.
- **
- ** To use:
- **
- ** 1) Compile and install this program
- ** make fakemail
- ** cpset fakemail /usr/bin
- **
- ** 2) Edit /usr/lib/sendmail.cf
- ** change the 'Mlocal' mailer to use /usr/bin/fakemail
- **
- ** 3) Restart sendmail
- ** ps -eaf; kill -9 <sendmail_pid>
- ** /usr/lib/sendmail -bd -q30m
- **
- ** NOTE: This is simply a hack for sendmail+mailx. Use of another
- ** MTA (ie, smail) or MUA (ie, Elm) would eliminate any need for this
- ** program.
- **
- ** --
- ** Bill Houle bhoule@se-sd.SanDiego.NCR.COM
- ** NCR SE-San Diego (619) 693-5593
- */
-
- #include <stdio.h>
- #include <string.h>
-
- /*#define DEBUG "/bin/cat" /* comment this out for installation */
- #define BINMAIL "/bin/mail"
- #define TRUE 1
- #define FALSE 0
-
- char line[255], env[255];
- void exit(), perror();
-
- void syserr(str)
- char *str;
- {
- perror(str);
- exit(1);
- }
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int fd[2], from_found=TRUE;
-
- if (gets(line) != NULL) { /* read first line *
- /
- strcpy(env, "LOGNAME=");
- if (strncmp(line, "From ", 5) == 0) { /* From_ line? *
- /
- (void) strtok(line, " \t\n\r"); /* get address token *
- /
- strcat(env, strtok(NULL, " \t\n\r"));
- }
- else {
- from_found=FALSE; /* no From_ line *
- /
- strcat(env, cuserid(NULL)); /* default to user-id *
- /
- }
- (void) putenv(env); /* change $LOGNAME *
- /
- }
-
- if (pipe(fd) < 0) syserr("pipe"); /* prepare pipe *
- /
- switch (fork()) { /* fork to /bin/mail *
- /
- case -1:
- syserr("fork to /bin/mail");
- case 0:
- if (close(0) < 0) /* close stdin *
- /
- syserr("close child stdin");
- if (dup(fd[0]) != 0) /* stdin from pipe *
- /
- syserr("dup pipe to stdin");
- if (close(fd[0]) < 0 || close(fd[1]) < 0)
- syserr("close child pipe");
- #ifdef DEBUG
- (void) fprintf(stderr, "[set %s and exec %s]\n", env, BINMAIL);
- (void) fprintf(stderr, "Debugging through %s.\n", DEBUG);
- (void) execl(DEBUG, DEBUG, 0);
- (void) fprintf(stderr, "Cannot exec %s from %s.\n",
- DEBUG, argv[0]);
- exit(0);
- #else
- (void) execv(BINMAIL, argv);
- (void) fprintf(stderr, "Cannot exec %s from %s.\n",
- BINMAIL, argv[0]);
- exit(1);
- #endif
- }
-
- if (close(1) < 0) /* close stdout *
- /
- syserr("close parent stdout");
- if (dup(fd[1]) != 1) /* stdout to pipe *
- /
- syserr("dup pipe to stdout");
- if (close(fd[0]) < 0 || close(fd[1]) < 0)
- syserr("close parent pipe");
-
- if (!from_found) (void) puts(line); /* 1st line not From_ *
- /
- while (gets(line) != NULL) /* send rest of msg *
- /
- (void) puts(line);
- exit(0);
- return(0); /* make lint happy *
- /
- }
-