223 lines
4.7 KiB
C
223 lines
4.7 KiB
C
#ifndef lint
|
|
static char sccsid[] = "@(#)rmail.c 1.1 94/10/31 SMI"; /* from UCB 4.8 5/15/86 */
|
|
#endif
|
|
|
|
|
|
/*
|
|
** RMAIL -- UUCP mail server.
|
|
**
|
|
** This program reads the >From ... remote from ... lines that
|
|
** UUCP is so fond of and turns them into something reasonable.
|
|
** It calls sendmail giving it a -f option built from these
|
|
** lines.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <sysexits.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
|
|
typedef char bool;
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
|
|
extern FILE *popen();
|
|
extern char *index();
|
|
extern char *rindex();
|
|
|
|
bool Debug;
|
|
char *Domain = "UUCP"; /* Default "Domain" */
|
|
|
|
# define MAILER "/usr/lib/sendmail"
|
|
|
|
# define A_BUFSIZE 512
|
|
# define LBUFSIZE (2*A_BUFSIZE)
|
|
|
|
main(argc, argv)
|
|
char **argv;
|
|
{
|
|
FILE *out; /* output to sendmail */
|
|
char lbuf[LBUFSIZE]; /* one line of the message */
|
|
char from[A_BUFSIZE]; /* accumulated path of sender */
|
|
char ufrom[A_BUFSIZE]; /* user on remote system */
|
|
char sys[A_BUFSIZE]; /* a system in path */
|
|
char fsys[A_BUFSIZE]; /* first system in path */
|
|
char junk[LBUFSIZE]; /* scratchpad */
|
|
char *args[100]; /* arguments to mailer command */
|
|
register char *cp;
|
|
register char *uf; /* ptr into ufrom */
|
|
int i;
|
|
long position;
|
|
struct stat sbuf;
|
|
|
|
|
|
# ifdef DEBUG
|
|
if (argc > 1 && strcmp(argv[1], "-T") == 0)
|
|
{
|
|
Debug = TRUE;
|
|
argc--;
|
|
argv++;
|
|
}
|
|
# endif DEBUG
|
|
|
|
if (argc < 2)
|
|
{
|
|
fprintf(stderr, "Usage: rmail user ...\n");
|
|
exit(EX_USAGE);
|
|
}
|
|
|
|
while (argc > 1 && *argv[1] == '-') {
|
|
switch (argv[1][1]) {
|
|
case 'D':
|
|
Domain = &argv[1][2];
|
|
argc -= 2;
|
|
argv += 2;
|
|
break;
|
|
case 't': /* drop the flag */
|
|
argc -= 1;
|
|
argv += 1;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
(void) strcpy(from, "");
|
|
(void) strcpy(fsys, "");
|
|
(void) strcpy(ufrom, "/dev/null");
|
|
uf = NULL;
|
|
|
|
for (position=0;;position=ftell(stdin))
|
|
{
|
|
if (!fgets(lbuf, sizeof lbuf, stdin)) /* fix for bug id 1051832 */
|
|
break;
|
|
if (strncmp(lbuf, "From ", 5) != 0 && strncmp(lbuf, ">From ", 6) != 0)
|
|
break;
|
|
|
|
(void) sscanf(lbuf, "%s %s", junk, ufrom);
|
|
cp = lbuf;
|
|
uf = ufrom;
|
|
for (;;)
|
|
{
|
|
cp = index(cp+1, 'r');
|
|
if (cp == NULL)
|
|
{
|
|
register char *p = rindex(uf, '!');
|
|
|
|
if (p != NULL)
|
|
{
|
|
*p = '\0';
|
|
(void) strncpy(sys, uf, A_BUFSIZE);
|
|
uf = p + 1;
|
|
break;
|
|
}
|
|
(void) strncpy(sys, "", A_BUFSIZE);
|
|
break; /* no "remote from" found */
|
|
}
|
|
#ifdef DEBUG
|
|
if (Debug)
|
|
printf("cp='%s'\n", cp);
|
|
#endif
|
|
if (strncmp(cp, "remote from ", 12)==0)
|
|
break;
|
|
}
|
|
if (cp != NULL)
|
|
(void) sscanf(cp, "remote from %s", sys);
|
|
if (fsys[0] == '\0')
|
|
(void) strncpy(fsys, sys, A_BUFSIZE);
|
|
if (sys[0])
|
|
{
|
|
(void) strncat(from, sys, A_BUFSIZE - strlen(from));
|
|
(void) strncat(from, "!", A_BUFSIZE - strlen(from));
|
|
}
|
|
#ifdef DEBUG
|
|
if (Debug)
|
|
printf("ufrom='%s', sys='%s', from now '%s'\n", uf, sys, from);
|
|
#endif
|
|
}
|
|
if (uf)
|
|
(void) strncat(from, uf, A_BUFSIZE - strlen(from));
|
|
(void) fstat(0,&sbuf);
|
|
(void) lseek(0,position,0);
|
|
|
|
/*
|
|
* Now we rebuild the argument list and chain to sendmail.
|
|
* Note that the above lseek might fail on irregular files,
|
|
* but we check for that case below.
|
|
*/
|
|
i = 0;
|
|
args[i++] = MAILER;
|
|
args[i++] = "-ee";
|
|
if (fsys[0] != '\0') {
|
|
static char junk2[512];
|
|
|
|
if (index(fsys,'.') == NULL) {
|
|
(void) strncat(fsys, ".", A_BUFSIZE - strlen(fsys));
|
|
(void) strncat(fsys, Domain, A_BUFSIZE - strlen(fsys));
|
|
}
|
|
(void) sprintf(junk2, "-oMs%s", fsys);
|
|
args[i++] = junk2;
|
|
}
|
|
(void) sprintf(junk, "-oMr%s", Domain);
|
|
args[i++] = junk;
|
|
if (from[0] != '\0' && uf != NULL) {
|
|
static char junk2[512];
|
|
|
|
(void) sprintf(junk2, "-f%s", from);
|
|
args[i++] = junk2;
|
|
}
|
|
|
|
for (;*++argv != NULL;i++)
|
|
{
|
|
args[i] = *argv;
|
|
}
|
|
args[i] = NULL;
|
|
#ifdef DEBUG
|
|
if (Debug)
|
|
{
|
|
printf("Command:");
|
|
for (i=0;args[i];i++)
|
|
printf(" %s",args[i]);
|
|
printf("\n");
|
|
}
|
|
#endif
|
|
if ( (sbuf.st_mode & S_IFMT) != S_IFREG)
|
|
{
|
|
/*
|
|
* If we were not called with standard input on a regular
|
|
* file, then we have to fork another process to send the
|
|
* first line down the pipe.
|
|
*/
|
|
int pipefd[2];
|
|
# ifdef DEBUG
|
|
if (Debug) printf("Not a regular file!\n");
|
|
# endif DEBUG
|
|
if (pipe(pipefd) < 0) exit(EX_OSERR);
|
|
if (fork()==0)
|
|
{
|
|
/*
|
|
* Child: send the message down the pipe.
|
|
*/
|
|
FILE *out;
|
|
|
|
out = fdopen(pipefd[1],"w");
|
|
close(pipefd[0]);
|
|
fputs(lbuf, out);
|
|
while (fgets(lbuf, sizeof lbuf, stdin))
|
|
fputs(lbuf, out);
|
|
fclose(out);
|
|
exit(EX_OK);
|
|
}
|
|
/*
|
|
* Parent: call sendmail with pipe as standard input
|
|
*/
|
|
close(pipefd[1]);
|
|
dup2(pipefd[0],0);
|
|
}
|
|
execv(MAILER,args);
|
|
printf("Exec of %s failed!\n", MAILER);
|
|
exit(EX_OSERR);
|
|
/* NOTREACHED */
|
|
}
|
|
|