summaryrefslogtreecommitdiff
path: root/gnu/usr.sbin/sendmail/vacation
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2001-01-15 21:09:13 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2001-01-15 21:09:13 +0000
commit5062bcecfa81a7e0dd07894d6e93655a97239964 (patch)
treefd0e0dd2a71271dbe81c195cd9fbdd57fb7c20fb /gnu/usr.sbin/sendmail/vacation
parent91deaea81040227b9ba537ff047f1f863f75fc31 (diff)
sendmail 8.11.2 with BSD Makefiles
Diffstat (limited to 'gnu/usr.sbin/sendmail/vacation')
-rw-r--r--gnu/usr.sbin/sendmail/vacation/vacation.126
-rw-r--r--gnu/usr.sbin/sendmail/vacation/vacation.c538
2 files changed, 450 insertions, 114 deletions
diff --git a/gnu/usr.sbin/sendmail/vacation/vacation.1 b/gnu/usr.sbin/sendmail/vacation/vacation.1
index 711d907de79..15566af8338 100644
--- a/gnu/usr.sbin/sendmail/vacation/vacation.1
+++ b/gnu/usr.sbin/sendmail/vacation/vacation.1
@@ -9,19 +9,19 @@
.\" the sendmail distribution.
.\"
.\"
-.\" $Sendmail: vacation.1,v 8.9 1999/10/27 03:42:07 ca Exp $
+.\" $Sendmail: vacation.1,v 8.11.4.6 2000/12/29 18:12:23 gshapiro Exp $
.\"
-.TH VACATION 1 "$Date: 2000/04/07 19:20:47 $"
+.TH VACATION 1 "$Date: 2001/01/15 21:09:12 $"
.SH NAME
-.B vacation
+vacation
\- return ``I am not here'' indication
.SH SYNOPSIS
.B vacation
-.B \-i
+.RB [ \-i ]
+.RB [ \-I ]
.RB [ \-r
.IR interval ]
.RB [ \-x ]
-.B vacation
.RB [ \-a
.IR alias ]
.RB [ \-f
@@ -74,6 +74,11 @@ before you modify your
.I .forward
file.
.TP
+.B \-I
+Same as
+.B \-i
+(for backwards compatibility).
+.TP
.BI \-m " filename"
Use
.I filename
@@ -95,9 +100,9 @@ one reply.
.BI \-s " address"
Use
.I address
-instead of the sender address in the
+instead of the incoming message sender address on the
.I From
-line to determine the reply address.
+line as the recipient for the vacation message.
.TP
.BI \-t " time"
Ignored, available only for compatibility with Sun's
@@ -132,6 +137,9 @@ or
headers of the mail.
No messages from
``???-REQUEST'',
+``???-RELAY'',
+``???-OWNER'',
+``OWNER-???'',
``Postmaster'',
``UUCP'',
``MAILER'',
@@ -186,10 +194,10 @@ syslog(8).
.SH FILES
.TP 1.8i
~/.vacation.db
-database file
+default database file
.TP
~/.vacation.msg
-message to send
+default message to send
.SH SEE ALSO
sendmail(8),
syslog(8)
diff --git a/gnu/usr.sbin/sendmail/vacation/vacation.c b/gnu/usr.sbin/sendmail/vacation/vacation.c
index fc218b1b58d..cdd64fb50ca 100644
--- a/gnu/usr.sbin/sendmail/vacation/vacation.c
+++ b/gnu/usr.sbin/sendmail/vacation/vacation.c
@@ -21,7 +21,7 @@ static char copyright[] =
#endif /* ! lint */
#ifndef lint
-static char id[] = "@(#)$Sendmail: vacation.c,v 8.68 2000/03/17 07:32:51 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: vacation.c,v 8.68.4.15 2000/11/27 22:17:27 ca Exp $";
#endif /* ! lint */
#include <ctype.h>
@@ -48,6 +48,11 @@ static char id[] = "@(#)$Sendmail: vacation.c,v 8.68 2000/03/17 07:32:51 gshapir
#define ONLY_ONCE ((time_t) 0) /* send at most one reply */
#define INTERVAL_UNDEF ((time_t) (-1)) /* no value given */
+#ifndef TRUE
+# define TRUE 1
+# define FALSE 0
+#endif /* ! TRUE */
+
uid_t RealUid;
gid_t RealGid;
char *RealUserName;
@@ -73,11 +78,6 @@ BITMAP256 DontBlameSendmail;
#define SECSPERDAY (60 * 60 * 24)
#define DAYSPERWEEK 7
-#ifndef TRUE
-# define TRUE 1
-# define FALSE 0
-#endif /* ! TRUE */
-
#ifndef __P
# ifdef __STDC__
# define __P(protos) protos
@@ -99,14 +99,33 @@ SMDB_DATABASE *Db;
char From[MAXLINE];
+#if _FFR_DEBUG
+void (*msglog)(int, const char *, ...) = &syslog;
+static void debuglog __P((int, const char *, ...));
+#else /* _FFR_DEBUG */
+# define msglog syslog
+#endif /* _FFR_DEBUG */
+
+static void eatmsg __P((void));
+
+/* exit after reading input */
+#define EXITIT(excode) { \
+ eatmsg(); \
+ return excode; \
+ }
int
main(argc, argv)
int argc;
char **argv;
{
bool iflag, emptysender, exclude;
+#if _FFR_LISTDB
+ bool lflag = FALSE;
+#endif /* _FFR_LISTDB */
+ int mfail = 0, ufail = 0;
int ch;
int result;
+ long sff;
time_t interval;
struct passwd *pw;
ALIAS *cur;
@@ -119,11 +138,24 @@ main(argc, argv)
extern char *optarg;
extern void usage __P((void));
extern void setinterval __P((time_t));
- extern void readheaders __P((void));
+ extern int readheaders __P((void));
extern bool recent __P((void));
extern void setreply __P((char *, time_t));
extern void sendmessage __P((char *, char *, bool));
extern void xclude __P((FILE *));
+#if _FFR_LISTDB
+#define EXITM(excode) { \
+ if (!iflag && !lflag) \
+ eatmsg(); \
+ exit(excode); \
+ }
+#else /* _FFR_LISTDB */
+#define EXITM(excode) { \
+ if (!iflag) \
+ eatmsg(); \
+ exit(excode); \
+ }
+#endif /* _FFR_LISTDB */
/* Vars needed to link with smutil */
clrbitmap(DontBlameSendmail);
@@ -153,7 +185,23 @@ main(argc, argv)
exclude = FALSE;
interval = INTERVAL_UNDEF;
*From = '\0';
- while ((ch = getopt(argc, argv, "a:f:Iim:r:s:t:xz")) != -1)
+
+#if _FFR_DEBUG && _FFR_LISTDB
+# define OPTIONS "a:df:Iilm:r:s:t:xz"
+#else /* _FFR_DEBUG && _FFR_LISTDB */
+# if _FFR_DEBUG
+# define OPTIONS "a:df:Iim:r:s:t:xz"
+# else /* _FFR_DEBUG */
+# if _FFR_LISTDB
+# define OPTIONS "a:f:Iilm:r:s:t:xz"
+# else /* _FFR_LISTDB */
+# define OPTIONS "a:f:Iim:r:s:t:xz"
+# endif /* _FFR_LISTDB */
+# endif /* _FFR_DEBUG */
+#endif /* _FFR_DEBUG && _FFR_LISTDB */
+
+ while (mfail == 0 && ufail == 0 &&
+ (ch = getopt(argc, argv, OPTIONS)) != -1)
{
switch((char)ch)
{
@@ -161,9 +209,7 @@ main(argc, argv)
cur = (ALIAS *)malloc((u_int)sizeof(ALIAS));
if (cur == NULL)
{
- syslog(LOG_NOTICE,
- "vacation: can't allocate memory for alias %s.\n",
- optarg);
+ mfail++;
break;
}
cur->name = optarg;
@@ -171,6 +217,13 @@ main(argc, argv)
Names = cur;
break;
+#if _FFR_DEBUG
+ case 'd': /* debug mode */
+ msglog = &debuglog;
+ break;
+#endif /* _FFR_DEBUG */
+
+
case 'f': /* alternate database */
dbfilename = optarg;
break;
@@ -180,6 +233,12 @@ main(argc, argv)
iflag = TRUE;
break;
+#if _FFR_LISTDB
+ case 'l':
+ lflag = TRUE; /* list the database */
+ break;
+#endif /* _FFR_LISTDB */
+
case 'm': /* alternate message file */
msgfilename = optarg;
break;
@@ -189,7 +248,7 @@ main(argc, argv)
{
interval = atol(optarg) * SECSPERDAY;
if (interval < 0)
- usage();
+ ufail++;
}
else
interval = ONLY_ONCE;
@@ -212,22 +271,35 @@ main(argc, argv)
case '?':
default:
- usage();
+ ufail++;
break;
}
}
argc -= optind;
argv += optind;
+ if (mfail != 0)
+ {
+ msglog(LOG_NOTICE,
+ "vacation: can't allocate memory for alias.\n");
+ EXITM(EX_TEMPFAIL);
+ }
+ if (ufail != 0)
+ usage();
+
if (argc != 1)
{
- if (!iflag && !exclude)
+ if (!iflag &&
+#if _FFR_LISTDB
+ !lflag &&
+#endif /* _FFR_LISTDB */
+ !exclude)
usage();
if ((pw = getpwuid(getuid())) == NULL)
{
- syslog(LOG_ERR,
+ msglog(LOG_ERR,
"vacation: no such user uid %u.\n", getuid());
- exit(EX_NOUSER);
+ EXITM(EX_NOUSER);
}
}
#if _FFR_BLACKBOX
@@ -235,15 +307,15 @@ main(argc, argv)
#else /* _FFR_BLACKBOX */
else if ((pw = getpwnam(*argv)) == NULL)
{
- syslog(LOG_ERR, "vacation: no such user %s.\n", *argv);
- exit(EX_NOUSER);
+ msglog(LOG_ERR, "vacation: no such user %s.\n", *argv);
+ EXITM(EX_NOUSER);
}
name = pw->pw_name;
if (chdir(pw->pw_dir) != 0)
{
- syslog(LOG_NOTICE,
+ msglog(LOG_NOTICE,
"vacation: no such directory %s.\n", pw->pw_dir);
- exit(EX_NOINPUT);
+ EXITM(EX_NOINPUT);
}
#endif /* _FFR_BLACKBOX */
user_info.smdbu_id = pw->pw_uid;
@@ -251,63 +323,82 @@ main(argc, argv)
(void) strlcpy(user_info.smdbu_name, pw->pw_name,
SMDB_MAX_USER_NAME_LEN);
+ sff = SFF_CREAT;
+#if _FFR_BLACKBOX
+ if (getegid() != getgid())
+ RunAsGid = user_info.smdbu_group_id = getegid();
+
+ sff |= SFF_NOPATHCHECK|SFF_OPENASROOT;
+#endif /* _FFR_BLACKBOX */
+
result = smdb_open_database(&Db, dbfilename,
O_CREAT|O_RDWR | (iflag ? O_TRUNC : 0),
- S_IRUSR|S_IWUSR, SFF_CREAT,
+ S_IRUSR|S_IWUSR, sff,
SMDB_TYPE_DEFAULT, &user_info, NULL);
if (result != SMDBE_OK)
{
- syslog(LOG_NOTICE, "vacation: %s: %s\n", dbfilename,
+ msglog(LOG_NOTICE, "vacation: %s: %s\n", dbfilename,
errstring(result));
- exit(EX_DATAERR);
+ EXITM(EX_DATAERR);
+ }
+
+#if _FFR_LISTDB
+ if (lflag)
+ {
+ static void listdb __P((void));
+
+ listdb();
+ (void) Db->smdb_close(Db);
+ exit(EX_OK);
}
+#endif /* _FFR_LISTDB */
if (interval != INTERVAL_UNDEF)
setinterval(interval);
- if (iflag)
+ if (iflag && !exclude)
{
- result = Db->smdb_close(Db);
- if (!exclude)
- exit(EX_OK);
+ (void) Db->smdb_close(Db);
+ exit(EX_OK);
}
if (exclude)
{
xclude(stdin);
- result = Db->smdb_close(Db);
- exit(EX_OK);
+ (void) Db->smdb_close(Db);
+ EXITM(EX_OK);
}
if ((cur = (ALIAS *)malloc((u_int)sizeof(ALIAS))) == NULL)
{
- syslog(LOG_NOTICE,
+ msglog(LOG_NOTICE,
"vacation: can't allocate memory for username.\n");
- exit(EX_OSERR);
+ (void) Db->smdb_close(Db);
+ EXITM(EX_OSERR);
}
cur->name = name;
cur->next = Names;
Names = cur;
- readheaders();
- if (!recent())
+ result = readheaders();
+ if (result == EX_OK && !recent())
{
time_t now;
(void) time(&now);
setreply(From, now);
- result = Db->smdb_close(Db);
+ (void) Db->smdb_close(Db);
sendmessage(name, msgfilename, emptysender);
}
else
- result = Db->smdb_close(Db);
- exit(EX_OK);
- /* NOTREACHED */
- return EX_OK;
+ (void) Db->smdb_close(Db);
+ if (result == EX_NOUSER)
+ result = EX_OK;
+ exit(result);
}
/*
-** READHEADERS -- read mail headers
+** EATMSG -- read stdin till EOF
**
** Parameters:
** none.
@@ -316,7 +407,32 @@ main(argc, argv)
** nothing.
**
*/
-void
+static void
+eatmsg()
+{
+ /*
+ ** read the rest of the e-mail and ignore it to avoid problems
+ ** with EPIPE in sendmail
+ */
+ while (getc(stdin) != EOF)
+ continue;
+}
+
+/*
+** READHEADERS -- read mail headers
+**
+** Parameters:
+** none.
+**
+** Returns:
+** a exit code: NOUSER if no reply, OK if reply, * if error
+**
+** Side Effects:
+** may exit().
+**
+*/
+
+int
readheaders()
{
bool tome, cont;
@@ -327,7 +443,7 @@ readheaders()
extern bool nsearch __P((char *, char *));
cont = tome = FALSE;
- while (!tome && fgets(buf, sizeof(buf), stdin) && *buf != '\n')
+ while (fgets(buf, sizeof(buf), stdin) && *buf != '\n')
{
switch(*buf)
{
@@ -346,9 +462,9 @@ readheaders()
p++;
if (*p == '\0')
{
- syslog(LOG_NOTICE,
+ msglog(LOG_NOTICE,
"vacation: badly formatted \"From \" line.\n");
- exit(EX_DATAERR);
+ EXITIT(EX_DATAERR);
}
}
else if (*p == '"')
@@ -361,20 +477,20 @@ readheaders()
}
if (quoted)
{
- syslog(LOG_NOTICE,
+ msglog(LOG_NOTICE,
"vacation: badly formatted \"From \" line.\n");
- exit(EX_DATAERR);
+ EXITIT(EX_DATAERR);
}
*p = '\0';
/* ok since both strings have MAXLINE length */
if (*From == '\0')
- (void)strlcpy(From, buf + 5,
- sizeof From);
+ (void) strlcpy(From, buf + 5,
+ sizeof From);
if ((p = strchr(buf + 5, '\n')) != NULL)
*p = '\0';
if (junkmail(buf + 5))
- exit(EX_OK);
+ EXITIT(EX_NOUSER);
}
break;
@@ -394,7 +510,7 @@ readheaders()
if (strncasecmp(p, "junk", 4) == 0 ||
strncasecmp(p, "bulk", 4) == 0 ||
strncasecmp(p, "list", 4) == 0)
- exit(EX_OK);
+ EXITIT(EX_NOUSER);
break;
case 'C': /* "Cc:" */
@@ -425,12 +541,13 @@ findme:
}
}
if (!tome)
- exit(EX_OK);
+ EXITIT(EX_NOUSER);
if (*From == '\0')
{
- syslog(LOG_NOTICE, "vacation: no initial \"From \" line.\n");
- exit(EX_DATAERR);
+ msglog(LOG_NOTICE, "vacation: no initial \"From \" line.\n");
+ EXITIT(EX_DATAERR);
}
+ EXITIT(EX_OK);
}
/*
@@ -485,52 +602,142 @@ nsearch(name, str)
** is this some automated/junk/bulk/list mail?
**
*/
+
+struct ignore
+{
+ char *name;
+ size_t len;
+};
+
+typedef struct ignore IGNORE_T;
+
+#define MAX_USER_LEN 256 /* maximum length of local part (sender) */
+
+/* delimiters for the local part of an address */
+#define isdelim(c) ((c) == '%' || (c) == '@' || (c) == '+')
+
bool
junkmail(from)
char *from;
{
- register size_t len;
- register char *p;
- register struct ignore *cur;
- static struct ignore
+ bool quot;
+ char *e;
+ size_t len;
+ IGNORE_T *cur;
+ char sender[MAX_USER_LEN];
+ static IGNORE_T ignore[] =
{
- char *name;
- size_t len;
- } ignore[] =
- {
- { "-request", 8 },
{ "postmaster", 10 },
{ "uucp", 4 },
{ "mailer-daemon", 13 },
{ "mailer", 6 },
+ { NULL, 0 }
+ };
+
+ static IGNORE_T ignorepost[] =
+ {
+ { "-request", 8 },
{ "-relay", 6 },
+ { "-owner", 6 },
+ { NULL, 0 }
+ };
+
+ static IGNORE_T ignorepre[] =
+ {
+ { "owner-", 6 },
{ NULL, 0 }
};
/*
- * This is mildly amusing, and I'm not positive it's right; trying
- * to find the "real" name of the sender, assuming that addresses
- * will be some variant of:
- *
- * From site!site!SENDER%site.domain%site.domain@site.domain
- */
- if ((p = strchr(from, '%')) == NULL &&
- (p = strchr(from, '@')) == NULL)
- {
- if ((p = strrchr(from, '!')) != NULL)
- ++p;
- else
- p = from;
- for (; *p; ++p)
+ ** This is mildly amusing, and I'm not positive it's right; trying
+ ** to find the "real" name of the sender, assuming that addresses
+ ** will be some variant of:
+ **
+ ** From site!site!SENDER%site.domain%site.domain@site.domain
+ */
+
+ quot = FALSE;
+ e = from;
+ len = 0;
+ while (*e != '\0' && (quot || !isdelim(*e)))
+ {
+ if (*e == '"')
+ {
+ quot = !quot;
+ ++e;
+ continue;
+ }
+ if (*e == '\\')
+ {
+ if (*(++e) == '\0')
+ {
+ /* '\\' at end of string? */
+ break;
+ }
+ if (len < MAX_USER_LEN)
+ sender[len++] = *e;
+ ++e;
continue;
+ }
+ if (*e == '!' && !quot)
+ {
+ len = 0;
+ sender[len] = '\0';
+ }
+ else
+ if (len < MAX_USER_LEN)
+ sender[len++] = *e;
+ ++e;
}
- len = p - from;
+ if (len < MAX_USER_LEN)
+ sender[len] = '\0';
+ else
+ sender[MAX_USER_LEN - 1] = '\0';
+
+ if (len <= 0)
+ return FALSE;
+#if 0
+ if (quot)
+ return FALSE; /* syntax error... */
+#endif /* 0 */
+
+ /* test prefixes */
+ for (cur = ignorepre; cur->name != NULL; ++cur)
+ {
+ if (len >= cur->len &&
+ strncasecmp(cur->name, sender, cur->len) == 0)
+ return TRUE;
+ }
+
+ /*
+ ** If the name is truncated, don't test the rest.
+ ** We could extract the "tail" of the sender address and
+ ** compare it it ignorepost, however, it seems not worth
+ ** the effort.
+ ** The address surely can't match any entry in ignore[]
+ ** (as long as all of them are shorter than MAX_USER_LEN).
+ */
+
+ if (len > MAX_USER_LEN)
+ return FALSE;
+
+ /* test full local parts */
for (cur = ignore; cur->name != NULL; ++cur)
{
+ if (len == cur->len &&
+ strncasecmp(cur->name, sender, cur->len) == 0)
+ return TRUE;
+ }
+
+ /* test postfixes */
+ for (cur = ignorepost; cur->name != NULL; ++cur)
+ {
if (len >= cur->len &&
- strncasecmp(cur->name, p - cur->len, cur->len) == 0)
+ strncasecmp(cur->name, e - cur->len - 1,
+ cur->len) == 0)
return TRUE;
}
+
return FALSE;
}
@@ -560,27 +767,27 @@ recent()
memset(&data, '\0', sizeof data);
/* get interval time */
- key.data.data = VIT;
- key.data.size = sizeof(VIT);
+ key.data = VIT;
+ key.size = sizeof(VIT);
st = Db->smdb_get(Db, &key, &data, 0);
if (st != SMDBE_OK)
next = SECSPERDAY * DAYSPERWEEK;
else
- memmove(&next, data.data.data, sizeof(next));
+ memmove(&next, data.data, sizeof(next));
memset(&data, '\0', sizeof data);
/* get record for this address */
- key.data.data = From;
- key.data.size = strlen(From);
+ key.data = From;
+ key.size = strlen(From);
do
{
st = Db->smdb_get(Db, &key, &data, 0);
if (st == SMDBE_OK)
{
- memmove(&then, data.data.data, sizeof(then));
+ memmove(&then, data.data, sizeof(then));
if (next == ONLY_ONCE || then == ONLY_ONCE ||
then + next > time(NULL))
return TRUE;
@@ -588,8 +795,8 @@ recent()
if ((trydomain = !trydomain) &&
(domain = strchr(From, '@')) != NULL)
{
- key.data.data = domain;
- key.data.size = strlen(domain);
+ key.data = domain;
+ key.size = strlen(domain);
}
} while (trydomain);
return FALSE;
@@ -617,11 +824,11 @@ setinterval(interval)
memset(&key, '\0', sizeof key);
memset(&data, '\0', sizeof data);
- key.data.data = VIT;
- key.data.size = sizeof(VIT);
- data.data.data = (char*) &interval;
- data.data.size = sizeof(interval);
- (void)(Db->smdb_put)(Db, &key, &data, 0);
+ key.data = VIT;
+ key.size = sizeof(VIT);
+ data.data = (char*) &interval;
+ data.size = sizeof(interval);
+ (void) (Db->smdb_put)(Db, &key, &data, 0);
}
/*
@@ -648,11 +855,11 @@ setreply(from, when)
memset(&key, '\0', sizeof key);
memset(&data, '\0', sizeof data);
- key.data.data = from;
- key.data.size = strlen(from);
- data.data.data = (char*) &when;
- data.data.size = sizeof(when);
- (void)(Db->smdb_put)(Db, &key, &data, 0);
+ key.data = from;
+ key.size = strlen(from);
+ data.data = (char*) &when;
+ data.size = sizeof(when);
+ (void) (Db->smdb_put)(Db, &key, &data, 0);
}
/*
@@ -714,21 +921,21 @@ sendmessage(myname, msgfn, emptysender)
if (mfp == NULL)
{
if (msgfn[0] == '/')
- syslog(LOG_NOTICE, "vacation: no %s file.\n", msgfn);
+ msglog(LOG_NOTICE, "vacation: no %s file.\n", msgfn);
else
- syslog(LOG_NOTICE, "vacation: no ~%s/%s file.\n",
+ msglog(LOG_NOTICE, "vacation: no ~%s/%s file.\n",
myname, msgfn);
exit(EX_NOINPUT);
}
if (pipe(pvect) < 0)
{
- syslog(LOG_ERR, "vacation: pipe: %s", errstring(errno));
+ msglog(LOG_ERR, "vacation: pipe: %s", errstring(errno));
exit(EX_OSERR);
}
i = fork();
if (i < 0)
{
- syslog(LOG_ERR, "vacation: fork: %s", errstring(errno));
+ msglog(LOG_ERR, "vacation: fork: %s", errstring(errno));
exit(EX_OSERR);
}
if (i == 0)
@@ -739,9 +946,9 @@ sendmessage(myname, msgfn, emptysender)
(void) fclose(mfp);
if (emptysender)
myname = "<>";
- (void) execl(_PATH_SENDMAIL, "sendmail", "-f", myname, "--",
- From, NULL);
- syslog(LOG_ERR, "vacation: can't exec %s: %s",
+ (void) execl(_PATH_SENDMAIL, "sendmail", "-oi",
+ "-f", myname, "--", From, NULL);
+ msglog(LOG_ERR, "vacation: can't exec %s: %s",
_PATH_SENDMAIL, errstring(errno));
exit(EX_UNAVAILABLE);
}
@@ -759,7 +966,7 @@ sendmessage(myname, msgfn, emptysender)
else
{
(void) fclose(mfp);
- syslog(LOG_ERR, "vacation: can't open pipe to sendmail");
+ msglog(LOG_ERR, "vacation: can't open pipe to sendmail");
exit(EX_UNAVAILABLE);
}
}
@@ -767,11 +974,132 @@ sendmessage(myname, msgfn, emptysender)
void
usage()
{
- syslog(LOG_NOTICE, "uid %u: usage: vacation [-i] [-a alias] [-f db] [-m msg] [-r interval] [-s sender] [-t time] [-x] [-z] login\n",
- getuid());
+ msglog(LOG_NOTICE, "uid %u: usage: vacation [-i] [-a alias]%s [-f db]%s [-m msg] [-r interval] [-s sender] [-t time] [-x] [-z] login\n",
+ getuid(),
+#if _FFR_DEBUG
+ " [-d]",
+#else /* _FFR_DEBUG */
+ "",
+#endif /* _FFR_DEBUG */
+#if _FFR_LISTDB
+ " [-l]"
+#else /* _FFR_LISTDB */
+ ""
+#endif /* _FFR_LISTDB */
+ );
exit(EX_USAGE);
}
+#if _FFR_LISTDB
+/*
+** LISTDB -- list the contents of the vacation database
+**
+** Parameters:
+** none.
+**
+** Returns:
+** nothing.
+*/
+
+static void
+listdb()
+{
+ int result;
+ time_t t;
+ SMDB_CURSOR *cursor = NULL;
+ SMDB_DBENT db_key, db_value;
+
+ memset(&db_key, '\0', sizeof db_key);
+ memset(&db_value, '\0', sizeof db_value);
+
+ result = Db->smdb_cursor(Db, &cursor, 0);
+ if (result != SMDBE_OK)
+ {
+ fprintf(stderr, "vacation: set cursor: %s\n",
+ errstring(result));
+ return;
+ }
+
+ while ((result = cursor->smdbc_get(cursor, &db_key, &db_value,
+ SMDB_CURSOR_GET_NEXT)) == SMDBE_OK)
+ {
+ /* skip magic VIT entry */
+ if ((int)db_key.size -1 == strlen(VIT) &&
+ strncmp((char *)db_key.data, VIT,
+ (int)db_key.size - 1) == 0)
+ continue;
+
+ /* skip bogus values */
+ if (db_value.size != sizeof t)
+ {
+ fprintf(stderr, "vacation: %.*s invalid time stamp\n",
+ (int) db_key.size, (char *) db_key.data);
+ continue;
+ }
+
+ memcpy(&t, db_value.data, sizeof t);
+
+ if (db_key.size > 40)
+ db_key.size = 40;
+
+ printf("%-40.*s %-10s",
+ (int) db_key.size, (char *) db_key.data, ctime(&t));
+
+ memset(&db_key, '\0', sizeof db_key);
+ memset(&db_value, '\0', sizeof db_value);
+ }
+
+ if (result != SMDBE_OK && result != SMDBE_LAST_ENTRY)
+ {
+ fprintf(stderr, "vacation: get value at cursor: %s\n",
+ errstring(result));
+ if (cursor != NULL)
+ {
+ (void) cursor->smdbc_close(cursor);
+ cursor = NULL;
+ }
+ return;
+ }
+ (void) cursor->smdbc_close(cursor);
+ cursor = NULL;
+}
+#endif /* _FFR_LISTDB */
+
+#if _FFR_DEBUG
+/*
+** DEBUGLOG -- write message to standard error
+**
+** Append a message to the standard error for the convenience of
+** end-users debugging without access to the syslog messages.
+**
+** Parameters:
+** i -- syslog log level
+** fmt -- string format
+**
+** Returns:
+** nothing.
+*/
+
+/*VARARGS2*/
+static void
+#ifdef __STDC__
+debuglog(int i, const char *fmt, ...)
+#else /* __STDC__ */
+debuglog(i, fmt, va_alist)
+ int i;
+ const char *fmt;
+ va_dcl
+#endif /* __STDC__ */
+
+{
+ VA_LOCAL_DECL
+
+ VA_START(fmt);
+ vfprintf(stderr, fmt, ap);
+ VA_END;
+}
+#endif /* _FFR_DEBUG */
+
/*VARARGS1*/
void
#ifdef __STDC__