diff options
Diffstat (limited to 'usr/src/cmd/sendmail/aux/mailcompat.c')
-rw-r--r-- | usr/src/cmd/sendmail/aux/mailcompat.c | 340 |
1 files changed, 340 insertions, 0 deletions
diff --git a/usr/src/cmd/sendmail/aux/mailcompat.c b/usr/src/cmd/sendmail/aux/mailcompat.c new file mode 100644 index 0000000000..8b244b455a --- /dev/null +++ b/usr/src/cmd/sendmail/aux/mailcompat.c @@ -0,0 +1,340 @@ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * Copyright (c) 1983, 1984, 1986, 1986, 1987, 1988, 1989 AT&T + * All Rights Reserved + */ + +/* + * Vacation + * Copyright (c) 1983 Eric P. Allman + * Berkeley, California + * + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <pwd.h> +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <unistd.h> +#include <sysexits.h> +#include <string.h> +#include <ctype.h> +#include "conf.h" + +/* + * MAILCOMPAT -- Deliver mail to a user's mailbox with the "From's" stuffed. + */ + +typedef int bool; + +#define FALSE 0 +#define TRUE 1 + +bool Debug = FALSE; +char *myname; /* person who is to have their mail filtered */ +char *homedir; /* home directory of said person */ +char *AliasList[MAXLINE]; /* list of aliases to allow */ +char *fromp; +char *fromuser; +int AliasCount = 0; + +static char *newstr(); + +int ask(char *); +int sendmessage(char *); +void AutoInstall(void); +void usrerr(const char *, ...); + +int +main(argc, argv) + int argc; + char **argv; +{ + register char *p; + struct passwd *pw; + extern char *getfrom(); + + /* process arguments */ + while (--argc > 0 && (p = *++argv) != NULL && *p == '-') + { + switch (*++p) + { + case 'd': /* debug */ + Debug = TRUE; + break; + default: + usrerr("Unknown flag -%s", p); + exit(EX_USAGE); + } + } + + /* verify recipient argument */ + if (argc != 1) + { + if (argc == 0) + AutoInstall(); + else + usrerr("Usage: mailcompat username (or) mailcompat -r"); + exit(EX_USAGE); + } + + myname = p; + /* find user's home directory */ + pw = getpwnam(myname); + if (pw == NULL) + { + usrerr("user: %s look up failed, name services outage ?", myname); + exit(EX_TEMPFAIL); + } + homedir = newstr(pw->pw_dir); + + /* read message from standard input (just from line) */ + fromuser = getfrom(&fromp); + return (sendmessage(fromuser)); +} + +/* +** sendmessage -- read message from standard input do the from stuffing +** and forward to /bin/mail, Being sure to delete any +** content-length headers (/bin/mail recalculates them). +** +** +** Parameters: +** none. +** +** +** Side Effects: +** Reads first line from standard input. +*/ + +#define L_HEADER "Content-Length:" +#define LL_HEADER 15 + +int +sendmessage(from) +char *from; +{ + static char line[MAXLINE]; + static char command[MAXLINE]; + bool in_body = FALSE; + FILE *mail_fp; + static char user_name[L_cuserid]; + + if (from == NULL) + from = cuserid(user_name); + + snprintf(command, sizeof (command), "/bin/mail -f %s -d %s", from, + myname); + mail_fp = popen(command, "w"); + + /* read the line */ + while (fgets(line, sizeof line, stdin) != NULL) + { + if (line[0] == (char)'\n') /* end of mail headers */ + in_body = TRUE; + if (in_body && (strncmp(line, "From ", 5) == 0)) + fprintf(mail_fp, ">"); + if (in_body || (strncasecmp(line, L_HEADER, LL_HEADER) != 0)) + fputs(line, mail_fp); + } + return (pclose(mail_fp)); +} + +char * +getfrom(shortp) +char **shortp; +{ + static char line[MAXLINE]; + register char *p, *start, *at, *bang; + char saveat; + + /* read the from line */ + if (fgets(line, sizeof line, stdin) == NULL || + strncmp(line, "From ", 5) != NULL) + { + usrerr("No initial From line"); + exit(EX_USAGE); + } + + /* find the end of the sender address and terminate it */ + start = &line[5]; + p = strchr(start, ' '); + if (p == NULL) + { + usrerr("Funny From line '%s'", line); + exit(EX_USAGE); + } + *p = '\0'; + + /* + * Strip all but the rightmost UUCP host + * to prevent loops due to forwarding. + * Start searching leftward from the leftmost '@'. + * a!b!c!d yields a short name of c!d + * a!b!c!d@e yields a short name of c!d@e + * e@a!b!c yields the same short name + */ +#ifdef VDEBUG +printf("start='%s'\n", start); +#endif /* VDEBUG */ + *shortp = start; /* assume whole addr */ + if ((at = strchr(start, '@')) == NULL) /* leftmost '@' */ + at = p; /* if none, use end of addr */ + saveat = *at; + *at = '\0'; + if ((bang = strrchr(start, '!')) != NULL) { /* rightmost '!' */ + char *bang2; + *bang = '\0'; + if ((bang2 = strrchr(start, '!')) != NULL) /* 2nd rightmost '!' */ + *shortp = bang2 + 1; /* move past ! */ + *bang = '!'; + } + *at = saveat; +#ifdef VDEBUG +printf("place='%s'\n", *shortp); +#endif /* VDEBUG */ + + /* return the sender address */ + return newstr(start); +} + +/* +** USRERR -- print user error +** +** Parameters: +** f -- format. +** +** Returns: +** none. +** +** Side Effects: +** none. +*/ + +void +usrerr(const char *f, ...) +{ + va_list alist; + + va_start(alist, f); + (void) fprintf(stderr, "mailcompat: "); + (void) vfprintf(stderr, f, alist); + (void) fprintf(stderr, "\n"); + va_end(alist); +} + +/* +** NEWSTR -- copy a string +** +** Parameters: +** s -- the string to copy. +** +** Returns: +** A copy of the string. +** +** Side Effects: +** none. +*/ + +char * +newstr(s) + char *s; +{ + char *p; + size_t psize = strlen(s) + 1; + + p = malloc(psize); + if (p == NULL) + { + usrerr("newstr: cannot alloc memory"); + exit(EX_OSERR); + } + strlcpy(p, s, psize); + return (p); +} + +/* + * When invoked with no arguments, we fall into an automatic installation + * mode, stepping the user through a default installation. + */ +void +AutoInstall() +{ + char forward[MAXLINE]; + char line[MAXLINE]; + static char user_name[L_cuserid]; + FILE *f; + + myname = cuserid(user_name); + homedir = getenv("HOME"); + if (homedir == NULL) { + usrerr("Home directory unknown"); + exit(EX_CONFIG); + } + + printf("This program can be used to store your mail in a format\n"); + printf("that you can read with SunOS 4.X based mail readers\n"); + (void) strlcpy(forward, homedir, sizeof (forward)); + (void) strlcat(forward, "/.forward", sizeof (forward)); + f = fopen(forward, "r"); + if (f) { + printf("You have a .forward file in your home directory"); + printf(" containing:\n"); + while (fgets(line, MAXLINE, f)) + printf(" %s", line); + fclose(f); + if (!ask("Would you like to remove it and disable the mailcompat feature")) + exit(0); + if (unlink(forward)) + perror("Error removing .forward file:"); + else + printf("Back to normal reception of mail.\n"); + exit(0); + } + + printf("To enable the mailcompat feature a \".forward\" "); + printf("file is created.\n"); + if (!ask("Would you like to enable the mailcompat feature")) { + printf("OK, mailcompat feature NOT enabled.\n"); + exit(0); + } + f = fopen(forward, "w"); + if (f == NULL) { + perror("Error opening .forward file"); + exit(EX_USAGE); + } + fprintf(f, "\"|/usr/bin/mailcompat %s\"\n", myname); + fclose(f); + printf("Mailcompat feature ENABLED."); + printf("Run mailcompat with no arguments to remove it\n"); +} + + +/* + * Ask the user a question until we get a reasonable answer + */ +int +ask(prompt) + char *prompt; +{ + char line[MAXLINE]; + + for (;;) { + printf("%s? ", prompt); + fflush(stdout); + fgets(line, sizeof (line), stdin); + if (line[0] == 'y' || line[0] == 'Y') + return (TRUE); + if (line[0] == 'n' || line[0] == 'N') + return (FALSE); + printf("Please reply \"yes\" or \"no\" (\'y\' or \'n\')\n"); + } + /* NOTREACHED */ +} |