This commit is contained in:
seta75D
2021-10-11 18:37:13 -03:00
commit ff309bfe1c
14130 changed files with 3180272 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
#
# @(#)Makefile 1.1 94/10/31 SMI; from UCB 3.6 02/18/83
#
#
# Makefile for assorted programs related (perhaps distantly) to Sendmail.
#
ALL= mailstats mconnect vacation Makefile
SRCS= mailstats.c mconnect.c vacation.c
LIBS= -ldbm
DBMLIB= -ldbm
CONVTIME=../src/convtime.o
DESTDIR=
CHOWN= -echo chown
CHMOD= chmod
O= -O
COPTS=
CCONFIG=-I../include -I../src -DVMUNIX
CFLAGS= $O $(COPTS) $(CCONFIG)
AR= -ar
CC= /bin/cc
ARFLAGS=rvu
LINT= lint
XREF= ctags -x
CP= cp
MV= mv
INSTALL=install -c -s
M4= m4
TOUCH= touch
ABORT= false
GET= sccs get
DELTA= sccs delta
WHAT= sccs what
PRT= sccs prt
REL=
ROOT= root
OBJMODE=755
all: $(ALL)
mailstats: mailstats.o
$(CC) $(COPTS) -o $@ $@.o
logger: logger.o
$(CC) $(COPTS) -o $@ $@.o $(LIBS)
mconnect: mconnect.o
$(CC) $(COPTS) -o $@ $@.o
praliases: praliases.o
$(CC) $(COPTS) -o $@ $@.o
vacation: vacation.o
$(CC) $(COPTS) -o $@ $@.o $(CONVTIME) $(DBMLIB)
sources: $(SRCS)
$(SRCS):
$(GET) $(REL) SCCS/s.$@
clean:
rm -f $(ALL) core a.out make.out lint.out errs
rm -f *.o ,*
vacation.o: ../include/userdbm.h

View File

@@ -0,0 +1,65 @@
# include <sys/types.h>
# include <sys/stat.h>
# include <stdio.h>
# include "conf.h"
# include "mailstats.h"
#ifndef lint
static char sccsid[] = "@(#)mailstats.c 1.1 94/10/31 SMI"; /* From UCB 4.1 7/25/83 */
#endif
/*
** MAILSTATS -- print mail statistics.
**
** Arguments:
** file Name of statistics file.
**
** Exit Status:
** zero.
*/
main(argc, argv)
char **argv;
{
register int fd;
struct statistics st;
char *sfile = "/etc/sendmail.st";
register int i;
struct stat sbuf;
extern char *ctime();
if (argc > 1) sfile = argv[1];
fd = open(sfile, 0);
if (fd < 0)
{
perror(sfile);
exit(1);
}
fstat(fd, &sbuf);
if (read(fd, &st, sizeof st) != sizeof st ||
st.stat_size != sizeof st)
{
(void) sprintf(stderr, "File size change\n");
exit(1);
}
printf("Mail statistics from %24.24s", ctime(&st.stat_itime));
printf(" to %s\n", ctime(&sbuf.st_mtime));
printf(" Mailer msgs from bytes from msgs to bytes to\n");
for (i = 0; i < MAXMAILERS; i++)
{
if (st.stat_nf[i] == 0 && st.stat_nt[i] == 0)
continue;
printf("%2d %-10s", i, st.stat_names[i]);
if (st.stat_nf[i])
printf("%6ld %10ldK ", st.stat_nf[i], st.stat_bf[i]);
else
printf(" ");
if (st.stat_nt[i])
printf("%10ld %10ldK\n", st.stat_nt[i], st.stat_bt[i]);
else
printf("\n");
}
exit(0);
}

View File

@@ -0,0 +1,152 @@
#ifndef lint
static char sccsid[] = "@(#)mconnect.c 1.1 94/10/31 SMI"; /* From UCB 3.4 1/5/83 */
#endif
/*
* mconnect.c - A program to test out SMTP connections.
* Usage: mconnect [host]
* ... SMTP dialog
* ^C or ^D or QUIT
*/
# include <stdio.h>
# include <signal.h>
# include <ctype.h>
# include <sgtty.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <netdb.h>
struct sockaddr_in SendmailAddress;
struct sgttyb TtyBuf;
main(argc, argv)
int argc;
char **argv;
{
register int s;
char *host = NULL;
int pid;
int on = 1;
struct servent *sp;
int raw = 0;
char buf[1000];
extern char *index();
register FILE *f;
register struct hostent *hp;
u_long theaddr;
extern u_long inet_addr();
extern finis();
(void) gtty(0, &TtyBuf);
(void) signal(SIGINT, finis);
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0)
{
perror("socket");
exit(-1);
}
(void) setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof(on));
sp = getservbyname("smtp", "tcp");
if (sp != NULL)
SendmailAddress.sin_port = sp->s_port;
while (--argc > 0)
{
register char *p = *++argv;
if (*p == '-')
{
switch (*++p)
{
case 'h': /* host */
break;
case 'p': /* port */
SendmailAddress.sin_port = htons(atoi(*++argv));
argc--;
break;
case 'r': /* raw connection */
raw = 1;
TtyBuf.sg_flags &= ~CRMOD;
stty(0, &TtyBuf);
TtyBuf.sg_flags |= CRMOD;
break;
}
}
else if (host == NULL)
host = p;
}
if (host == NULL)
host = "localhost";
hp = gethostbyname(host);
if (hp == NULL)
{
/* Try for dotted pair or whatever */
theaddr = inet_addr(host);
SendmailAddress.sin_addr.s_addr = theaddr;
if (-1 == theaddr) {
fprintf(stderr, "mconnect: unknown host %s\r\n", host);
finis();
}
} else {
bcopy(hp->h_addr, &SendmailAddress.sin_addr, hp->h_length);
}
SendmailAddress.sin_family = AF_INET;
printf("connecting to host %s (%s), port %d\r\n", host,
inet_ntoa(SendmailAddress.sin_addr),
ntohs(SendmailAddress.sin_port));
if (connect(s, &SendmailAddress, sizeof SendmailAddress) < 0)
{
perror("connect");
exit(-1);
}
/* good connection, fork both sides */
printf("connection open\n");
pid = fork();
if (pid < 0)
{
perror("fork");
exit(-1);
}
if (pid == 0)
{
/* child -- standard input to sendmail */
int c;
f = fdopen(s, "w");
while ((c = fgetc(stdin)) >= 0)
{
if (!raw && c == '\n')
fputc('\r', f);
fputc(c, f);
if (c == '\n')
fflush(f);
}
shutdown(s,1);
sleep(10);
}
else
{
/* parent -- sendmail to standard output */
f = fdopen(s, "r");
while (fgets(buf, sizeof buf, f) != NULL)
{
fputs(buf, stdout);
fflush(stdout);
}
kill(pid, SIGTERM);
}
finis();
}
finis()
{
stty(0, &TtyBuf);
exit(0);
}

View File

@@ -0,0 +1,720 @@
/*
** 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.
*/
#ifndef lint
static char SccsId[] = "@(#)vacation.c 1.1 94/10/31 SMI"; /* from UCB 5.3 7/1/85 */
#endif not lint
# include <pwd.h>
# include <stdio.h>
# include <sysexits.h>
# include <ctype.h>
# include "useful.h"
# include "userdbm.h"
/*
** VACATION -- return a message to the sender when on vacation.
**
** This program could be invoked as a message receiver
** when someone is on vacation. It returns a message
** specified by the user to whoever sent the mail, taking
** care not to return a message too often to prevent
** "I am on vacation" loops.
**
** For best operation, this program should run setuid to
** root or uucp or someone else that sendmail will believe
** a -f flag from. Otherwise, the user must be careful
** to include a header on his .vacation.msg file.
**
** Positional Parameters:
** the user to collect the vacation message from.
**
** Flag Parameters:
** -I initialize the database.
** -d turn on debugging.
** -tT set the timeout to T. messages arriving more
** often than T will be ignored to avoid loops.
**
** Side Effects:
** A message is sent back to the sender.
**
** Author:
** Eric Allman
** UCB/INGRES
*/
# define MAXLINE 256 /* max size of a line */
# define ONEWEEK (60L*60L*24L*7L)
# define MsgFile "/.vacation.msg"
time_t Timeout = ONEWEEK; /* timeout between notices per user */
struct dbrec
{
long sentdate;
};
bool Debug = FALSE;
bool AnswerAll = FALSE; /* default to answer if in To:/Cc: only */
char *myname; /* name of person "on vacation" */
char *homedir; /* home directory of said person */
char *Subject = ""; /* subject in message header */
char *AliasList[MAXLINE]; /* list of aliases to allow */
int AliasCount = 0;
main(argc, argv)
char **argv;
{
char *from;
register char *p;
struct passwd *pw;
char *shortfrom;
char buf[MAXLINE];
extern struct passwd *getpwnam();
extern char *newstr();
extern char *getfrom();
extern bool knows();
extern bool junkmail();
extern time_t convtime();
if (argc == 1) {
AutoInstall();
exit (EX_OK);
}
/* process arguments */
while (--argc > 0 && (p = *++argv) != NULL && *p == '-')
{
switch (*++p)
{
case 'a': /* answer all mail, even if not in To/Cc */
AliasList[AliasCount++] = argv[1];
if (argc > 0) {
argc--; argv++;
}
break;
case 'd': /* debug */
Debug = TRUE;
break;
case 'I': /* initialize */
initialize();
exit(EX_OK);
case 'j': /* answer all mail, even if not in To/Cc */
AnswerAll = TRUE;
break;
case 't': /* set timeout */
Timeout = convtime(++p);
break;
default:
usrerr("Unknown flag -%s", p);
exit(EX_USAGE);
}
}
/* verify recipient argument */
if (argc != 1)
{
usrerr("Usage: vacation [-j] [-a alias] [-tN] username (or) vacation -I");
exit(EX_USAGE);
}
myname = p;
/* find user's home directory */
pw = getpwnam(myname);
if (pw == NULL)
{
usrerr("Unknown user %s", myname);
exit(EX_NOUSER);
}
homedir = newstr(pw->pw_dir);
(void) strcpy(buf, homedir);
(void) strcat(buf, "/.vacation");
dbminit(buf);
/* read message from standard input (just from line) */
from = getfrom(&shortfrom);
/* check if junk mail or this person is already informed */
if (!junkmail(shortfrom) && !knows(shortfrom))
{
/* mark this person as knowing */
setknows(shortfrom);
/* send the message back */
(void) strcpy(buf, homedir);
(void) strcat(buf, MsgFile);
if (Debug)
printf("Sending %s to %s\n", buf, from);
else
{
sendmessage(buf, from, myname);
/*NOTREACHED*/
}
}
exit (EX_OK);
}
/*
** GETFROM -- read message from standard input and return sender
**
** Parameters:
** none.
**
** Returns:
** pointer to the sender address.
**
** Side Effects:
** Reads first line from standard input.
*/
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 = index(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 = index(start, '@')) == NULL) /* leftmost '@' */
at = p; /* if none, use end of addr */
saveat = *at;
*at = '\0';
if ((bang = rindex(start, '!')) != NULL) { /* rightmost '!' */
char *bang2;
*bang = '\0';
if ((bang2 = rindex(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 start;
}
/*
** JUNKMAIL -- read the header and tell us if this is junk/bulk mail.
**
** Parameters:
** from -- the Return-Path of the sender. We assume that
** anything from "*-REQUEST@*" is bulk mail.
**
** Returns:
** TRUE -- if this is junk or bulk mail (that is, if the
** sender shouldn't receive a response).
** FALSE -- if the sender deserves a response.
**
** Side Effects:
** May read the header from standard input. When this
** returns the position on stdin is undefined.
*/
bool
junkmail(from)
char *from;
{
register char *p;
char buf[MAXLINE+1];
extern char *index();
extern char *rindex();
extern char *strtok();
extern bool sameword();
bool inside, foundto, onlist;
/* test for inhuman sender */
p = rindex(from, '@');
if (p != NULL)
{
*p = '\0';
if (sameword(&p[-8], "-REQUEST") ||
sameword(&p[-10], "Postmaster") ||
sameword(&p[-13], "MAILER-DAEMON"))
{
*p = '@';
return (TRUE);
}
*p = '@';
}
# define Delims " \t\n,:;()<>@!"
/* read the header looking for "interesting" lines */
inside = FALSE;
onlist = FALSE;
foundto = FALSE;
while (fgets(buf, MAXLINE, stdin) != NULL && buf[0] != '\n')
{
if (buf[0]!=' ' && buf[0] != '\t' && index(buf,':') == NULL)
return(FALSE); /* no header found */
p = strtok(buf, Delims);
if (p==NULL)
continue;
if (sameword(p, "To") || sameword(p, "Cc"))
{
inside = TRUE;
p = strtok(NULL, Delims);
if (p==NULL)
continue;
}
else /* continuation line? */
if (inside)
inside = (buf[0]==' ' || buf[0]=='\t');
if (inside) {
int i;
do {
if (sameword(p,myname))
onlist = TRUE; /* I am on the list */
for (i=0;i<AliasCount;i++)
if (sameword(p,AliasList[i]))
onlist = TRUE; /* alias on list */
} while (p = strtok(NULL, Delims));
foundto = TRUE;
continue;
}
if (sameword(p, "Precedence"))
{
/* find the value of this field */
p = strtok(NULL, Delims);
if (p == NULL)
continue;
/* see if it is "junk" or "bulk" */
p[4] = '\0';
if (sameword(p, "junk") || sameword(p, "bulk"))
return (TRUE);
}
if (sameword(p, "Subject"))
{
Subject = newstr(buf+9);
if (p = rindex(Subject,'\n'))
*p = '\0';
if (Debug)
printf("Subject=%s\n", Subject);
}
}
if (AnswerAll)
return (FALSE);
else
return (foundto && !onlist);
}
/*
** KNOWS -- predicate telling if user has already been informed.
**
** Parameters:
** user -- the user who sent this message.
**
** Returns:
** TRUE if 'user' has already been informed that the
** recipient is on vacation.
** FALSE otherwise.
**
** Side Effects:
** none.
*/
bool
knows(user)
char *user;
{
DATUM k, d;
long now;
auto long then;
time(&now);
k.dptr = user;
k.dsize = strlen(user) + 1;
d = fetch(k);
if (d.dptr == NULL)
return (FALSE);
/* be careful on 68k's and others with alignment restrictions */
bcopy((char *) &((struct dbrec *) d.dptr)->sentdate, (char *) &then, sizeof then);
if (then + Timeout < now)
return (FALSE);
if (Debug)
printf("User %s already knows\n");
return (TRUE);
}
/*
** SETKNOWS -- set that this user knows about the vacation.
**
** Parameters:
** user -- the user who should be marked.
**
** Returns:
** none.
**
** Side Effects:
** The dbm file is updated as appropriate.
*/
setknows(user)
char *user;
{
DATUM k, d;
struct dbrec xrec;
k.dptr = user;
k.dsize = strlen(user) + 1;
time(&xrec.sentdate);
d.dptr = (char *) &xrec;
d.dsize = sizeof xrec;
store(k, d);
}
/*
** SENDMESSAGE -- send a message to a particular user.
**
** Parameters:
** msgf -- filename containing the message.
** user -- user who should receive it.
**
** Returns:
** none.
**
** Side Effects:
** sends mail to 'user' using /usr/lib/sendmail.
*/
sendmessage(msgf, user, myname)
char *msgf;
char *user;
char *myname;
{
FILE *f, *pipe;
char line[MAXLINE];
char *p;
/* find the message to send */
f = fopen(msgf, "r");
if (f == NULL)
{
f = fopen("/usr/lib/vacation.def", "r");
if (f == NULL)
syserr("No message to send");
}
(void) sprintf(line, "/usr/lib/sendmail -eq -f %s %s", myname, user);
pipe = popen(line, "w");
if (pipe == NULL)
syserr("Cannot exec /usr/lib/sendmail");
while (fgets(line, MAXLINE, f)) {
p = index(line,'$');
if (p && strncmp(p,"$SUBJECT",8)==0) {
*p = '\0';
fputs(line, pipe);
fputs(Subject, pipe);
fputs(p+8, pipe);
continue;
}
fputs(line, pipe);
}
pclose(pipe);
fclose(f);
}
/*
** INITIALIZE -- initialize the database before leaving for vacation
**
** Parameters:
** none.
**
** Returns:
** none.
**
** Side Effects:
** Initializes the files .vacation.{pag,dir} in the
** caller's home directory.
*/
initialize()
{
char *homedir;
char buf[MAXLINE];
extern char *getenv();
setgid(getgid());
setuid(getuid());
homedir = getenv("HOME");
if (homedir == NULL)
syserr("No home!");
(void) strcpy(buf, homedir);
(void) strcat(buf, "/.vacation.dir");
if (close(creat(buf, 0644)) < 0)
syserr("Cannot create %s", buf);
(void) strcpy(buf, homedir);
(void) strcat(buf, "/.vacation.pag");
if (close(creat(buf, 0644)) < 0)
syserr("Cannot create %s", buf);
}
/*
** USRERR -- print user error
**
** Parameters:
** f -- format.
** p -- first parameter.
**
** Returns:
** none.
**
** Side Effects:
** none.
*/
usrerr(f, p)
char *f;
char *p;
{
fprintf(stderr, "vacation: ");
_doprnt(f, &p, stderr);
fprintf(stderr, "\n");
}
/*
** SYSERR -- print system error
**
** Parameters:
** f -- format.
** p -- first parameter.
**
** Returns:
** none.
**
** Side Effects:
** none.
*/
syserr(f, p)
char *f;
char *p;
{
fprintf(stderr, "vacation: ");
_doprnt(f, &p, stderr);
fprintf(stderr, "\n");
exit(EX_USAGE);
}
/*
** 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;
extern char *malloc();
p = malloc((unsigned)strlen(s) + 1);
if (p == NULL)
{
syserr("newstr: cannot alloc memory");
exit(EX_OSERR);
}
strcpy(p, s);
return (p);
}
/*
** SAMEWORD -- return TRUE if the words are the same
**
** Ignores case.
**
** Parameters:
** a, b -- the words to compare.
**
** Returns:
** TRUE if a & b match exactly (modulo case)
** FALSE otherwise.
**
** Side Effects:
** none.
*/
bool
sameword(a, b)
register char *a, *b;
{
char ca, cb;
do
{
ca = *a++;
cb = *b++;
if (isascii(ca) && isupper(ca))
ca = ca - 'A' + 'a';
if (isascii(cb) && isupper(cb))
cb = cb - 'A' + 'a';
} while (ca != '\0' && ca == cb);
return (ca == cb);
}
/*
* When invoked with no arguments, we fall into an automatic installation
* mode, stepping the user through a default installation.
*/
AutoInstall()
{
char file[MAXLINE];
char forward[MAXLINE];
char cmd[MAXLINE];
char line[MAXLINE];
char *editor;
FILE *f;
myname = getenv("USER");
homedir = getenv("HOME");
if (homedir == NULL)
syserr("Home directory unknown");
printf("This program can be used to answer your mail automatically\n");
printf("when you go away on vacation.\n");
(void) strcpy(file, homedir);
(void) strcat(file, MsgFile);
do {
f = fopen(file,"r");
if (f) {
printf("You have a message file in %s.\n", file);
if (ask("Would you like to see it")) {
sprintf(cmd, "/usr/ucb/more %s", file);
system(cmd);
}
if (ask("Would you like to edit it"))
f = NULL;
}
else {
printf("You need to create a message file in %s first.\n", file);
f = fopen(file,"w");
if (myname)
fprintf(f,"From: %s (via the vacation program)\n", myname);
fprintf(f,"Subject: away from my mail\n");
fprintf(f,"\nI will not be reading my mail for a while.\n");
fprintf(f,"Your mail regarding \"$SUBJECT\" will be read when I return.\n");
fclose(f);
f = NULL;
}
if (f == NULL) {
editor = getenv("VISUAL");
if (editor == NULL)
editor = getenv("EDITOR");
if (editor == NULL)
editor = "/usr/ucb/vi";
sprintf(cmd, "%s %s", editor, file);
printf("Please use your editor (%s) to edit this file.\n", editor);
system(cmd);
}
} while (f == NULL);
fclose(f);
(void) strcpy(forward, homedir);
(void) strcat(forward, "/.forward");
f = fopen(forward,"r");
if (f) {
printf("You have a .forward file in your home directory containing:\n");
while (fgets(line, MAXLINE, f))
printf(" %s", line);
fclose(f);
if (!ask("Would you like to remove it and disable the vacation 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 vacation feature a \".forward\" file is created.\n");
if (!ask("Would you like to enable the vacation feature")) {
printf("OK, vacation feature NOT enabled.\n");
exit(0);
}
f = fopen(forward,"w");
if (f==NULL) {
perror("Error opening .forward file");
exit(EX_USAGE);
}
fprintf(f,"\\%s, \"|/usr/ucb/vacation %s\"\n", myname, myname);
fclose(f);
printf("Vacation feature ENABLED. Please remember to turn it off when\n");
printf("you get back from vacation. Bon voyage.\n");
initialize();
}
/*
* Ask the user a question until we get a reasonable answer
*/
ask(prompt)
char *prompt;
{
char line[MAXLINE];
while (1) {
printf("%s? ", prompt);
fflush(stdout);
gets(line);
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");
}
}