summaryrefslogtreecommitdiff
path: root/contrib/sendmail/vacation/vacation.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/vacation/vacation.c')
-rw-r--r--contrib/sendmail/vacation/vacation.c1182
1 files changed, 0 insertions, 1182 deletions
diff --git a/contrib/sendmail/vacation/vacation.c b/contrib/sendmail/vacation/vacation.c
deleted file mode 100644
index 281119392bd28..0000000000000
--- a/contrib/sendmail/vacation/vacation.c
+++ /dev/null
@@ -1,1182 +0,0 @@
-/*
- * Copyright (c) 1999-2002 Sendmail, Inc. and its suppliers.
- * All rights reserved.
- * Copyright (c) 1983, 1987, 1993
- * The Regents of the University of California. All rights reserved.
- * Copyright (c) 1983 Eric P. Allman. All rights reserved.
- *
- * By using this file, you agree to the terms and conditions set
- * forth in the LICENSE file which can be found at the top level of
- * the sendmail distribution.
- *
- */
-
-#include <sm/gen.h>
-
-SM_IDSTR(copyright,
-"@(#) Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.\n\
- All rights reserved.\n\
- Copyright (c) 1983, 1987, 1993\n\
- The Regents of the University of California. All rights reserved.\n\
- Copyright (c) 1983 Eric P. Allman. All rights reserved.\n")
-
-SM_IDSTR(id, "@(#)$Id: vacation.c,v 8.137.2.2 2002/11/01 16:48:55 ca Exp $")
-
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <syslog.h>
-#include <time.h>
-#include <unistd.h>
-#ifdef EX_OK
-# undef EX_OK /* unistd.h may have another use for this */
-#endif /* EX_OK */
-#include <sm/sysexits.h>
-
-#include <sm/cf.h>
-#include <sm/mbdb.h>
-#include "sendmail/sendmail.h"
-#include <sendmail/pathnames.h>
-#include "libsmdb/smdb.h"
-
-#define ONLY_ONCE ((time_t) 0) /* send at most one reply */
-#define INTERVAL_UNDEF ((time_t) (-1)) /* no value given */
-
-uid_t RealUid;
-gid_t RealGid;
-char *RealUserName;
-uid_t RunAsUid;
-uid_t RunAsGid;
-char *RunAsUserName;
-int Verbose = 2;
-bool DontInitGroups = false;
-uid_t TrustedUid = 0;
-BITMAP256 DontBlameSendmail;
-
-/*
-** VACATION -- return a message to the sender when on vacation.
-**
-** This program is invoked as a message receiver. It returns a
-** message specified by the user to whomever sent the mail, taking
-** care not to return a message too often to prevent "I am on
-** vacation" loops.
-*/
-
-#define VDB ".vacation" /* vacation database */
-#define VMSG ".vacation.msg" /* vacation message */
-#define SECSPERDAY (60 * 60 * 24)
-#define DAYSPERWEEK 7
-
-typedef struct alias
-{
- char *name;
- struct alias *next;
-} ALIAS;
-
-ALIAS *Names = NULL;
-
-SMDB_DATABASE *Db;
-
-char From[MAXLINE];
-
-#if defined(__hpux) || defined(__osf__)
-# ifndef SM_CONF_SYSLOG_INT
-# define SM_CONF_SYSLOG_INT 1
-# endif /* SM_CONF_SYSLOG_INT */
-#endif /* defined(__hpux) || defined(__osf__) */
-
-#if SM_CONF_SYSLOG_INT
-# define SYSLOG_RET_T int
-# define SYSLOG_RET return 0
-#else /* SM_CONF_SYSLOG_INT */
-# define SYSLOG_RET_T void
-# define SYSLOG_RET
-#endif /* SM_CONF_SYSLOG_INT */
-
-typedef SYSLOG_RET_T SYSLOG_T __P((int, const char *, ...));
-SYSLOG_T *msglog = syslog;
-static SYSLOG_RET_T debuglog __P((int, const char *, ...));
-static void eatmsg __P((void));
-static void listdb __P((void));
-
-/* exit after reading input */
-#define EXITIT(excode) \
-{ \
- eatmsg(); \
- return excode; \
-}
-
-#define EXITM(excode) \
-{ \
- if (!initdb && !list) \
- eatmsg(); \
- exit(excode); \
-}
-
-int
-main(argc, argv)
- int argc;
- char **argv;
-{
- bool alwaysrespond = false;
- bool initdb, exclude;
- bool runasuser = false;
- bool list = false;
- int mfail = 0, ufail = 0;
- int ch;
- int result;
- long sff;
- time_t interval;
- struct passwd *pw;
- ALIAS *cur;
- char *dbfilename = NULL;
- char *msgfilename = NULL;
- char *cfpath = NULL;
- char *name;
- char *returnaddr = NULL;
- SMDB_USER_INFO user_info;
- static char rnamebuf[MAXNAME];
- extern int optind, opterr;
- extern char *optarg;
- extern void usage __P((void));
- extern void setinterval __P((time_t));
- extern int readheaders __P((bool));
- extern bool recent __P((void));
- extern void setreply __P((char *, time_t));
- extern void sendmessage __P((char *, char *, char *));
- extern void xclude __P((SM_FILE_T *));
-
- /* Vars needed to link with smutil */
- clrbitmap(DontBlameSendmail);
- RunAsUid = RealUid = getuid();
- RunAsGid = RealGid = getgid();
- pw = getpwuid(RealUid);
- if (pw != NULL)
- {
- if (strlen(pw->pw_name) > MAXNAME - 1)
- pw->pw_name[MAXNAME] = '\0';
- sm_snprintf(rnamebuf, sizeof rnamebuf, "%s", pw->pw_name);
- }
- else
- sm_snprintf(rnamebuf, sizeof rnamebuf,
- "Unknown UID %d", (int) RealUid);
- RunAsUserName = RealUserName = rnamebuf;
-
-# ifdef LOG_MAIL
- openlog("vacation", LOG_PID, LOG_MAIL);
-# else /* LOG_MAIL */
- openlog("vacation", LOG_PID);
-# endif /* LOG_MAIL */
-
- opterr = 0;
- initdb = false;
- exclude = false;
- interval = INTERVAL_UNDEF;
- *From = '\0';
-
-
-#define OPTIONS "a:C:df:Iijlm:R:r:s:t:Uxz"
-
- while (mfail == 0 && ufail == 0 &&
- (ch = getopt(argc, argv, OPTIONS)) != -1)
- {
- switch((char)ch)
- {
- case 'a': /* alias */
- cur = (ALIAS *) malloc((unsigned int) sizeof(ALIAS));
- if (cur == NULL)
- {
- mfail++;
- break;
- }
- cur->name = optarg;
- cur->next = Names;
- Names = cur;
- break;
-
- case 'C':
- cfpath = optarg;
- break;
-
- case 'd': /* debug mode */
- msglog = debuglog;
- break;
-
- case 'f': /* alternate database */
- dbfilename = optarg;
- break;
-
- case 'I': /* backward compatible */
- case 'i': /* init the database */
- initdb = true;
- break;
-
-#if _FFR_RESPOND_ALL
- case 'j':
- alwaysrespond = true;
- break;
-#endif /* _FFR_RESPOND_ALL */
-
- case 'l':
- list = true; /* list the database */
- break;
-
- case 'm': /* alternate message file */
- msgfilename = optarg;
- break;
-
-#if _FFR_RETURN_ADDR
- case 'R':
- returnaddr = optarg;
- break;
-#endif /* _FFR_RETURN_ADDR */
-
- case 'r':
- if (isascii(*optarg) && isdigit(*optarg))
- {
- interval = atol(optarg) * SECSPERDAY;
- if (interval < 0)
- ufail++;
- }
- else
- interval = ONLY_ONCE;
- break;
-
- case 's': /* alternate sender name */
- (void) sm_strlcpy(From, optarg, sizeof From);
- break;
-
- case 't': /* SunOS: -t1d (default expire) */
- break;
-
- case 'U': /* run as single user mode */
- runasuser = true;
- break;
-
- case 'x':
- exclude = true;
- break;
-
- case 'z':
- returnaddr = "<>";
- break;
-
- case '?':
- default:
- 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 (!initdb && !list && !exclude)
- usage();
- if ((pw = getpwuid(getuid())) == NULL)
- {
- msglog(LOG_ERR,
- "vacation: no such user uid %u.\n", getuid());
- EXITM(EX_NOUSER);
- }
- name = pw->pw_name;
- user_info.smdbu_id = pw->pw_uid;
- user_info.smdbu_group_id = pw->pw_gid;
- (void) sm_strlcpy(user_info.smdbu_name, pw->pw_name,
- SMDB_MAX_USER_NAME_LEN);
- if (chdir(pw->pw_dir) != 0)
- {
- msglog(LOG_NOTICE,
- "vacation: no such directory %s.\n",
- pw->pw_dir);
- EXITM(EX_NOINPUT);
- }
- }
- else if (runasuser)
- {
- name = *argv;
- if (dbfilename == NULL || msgfilename == NULL)
- {
- msglog(LOG_NOTICE,
- "vacation: -U requires setting both -f and -m\n");
- EXITM(EX_NOINPUT);
- }
- user_info.smdbu_id = pw->pw_uid;
- user_info.smdbu_group_id = pw->pw_gid;
- (void) sm_strlcpy(user_info.smdbu_name, pw->pw_name,
- SMDB_MAX_USER_NAME_LEN);
- }
- else
- {
- int err;
- SM_CF_OPT_T mbdbname;
- SM_MBDB_T user;
-
- cfpath = getcfname(0, 0, SM_GET_SENDMAIL_CF, cfpath);
- mbdbname.opt_name = "MailboxDatabase";
- mbdbname.opt_val = "pw";
- (void) sm_cf_getopt(cfpath, 1, &mbdbname);
- err = sm_mbdb_initialize(mbdbname.opt_val);
- if (err != EX_OK)
- {
- msglog(LOG_ERR,
- "vacation: can't open mailbox database: %s.\n",
- sm_strexit(err));
- EXITM(err);
- }
- err = sm_mbdb_lookup(*argv, &user);
- if (err == EX_NOUSER)
- {
- msglog(LOG_ERR, "vacation: no such user %s.\n", *argv);
- EXITM(EX_NOUSER);
- }
- if (err != EX_OK)
- {
- msglog(LOG_ERR,
- "vacation: can't read mailbox database: %s.\n",
- sm_strexit(err));
- EXITM(err);
- }
- name = user.mbdb_name;
- if (chdir(user.mbdb_homedir) != 0)
- {
- msglog(LOG_NOTICE,
- "vacation: no such directory %s.\n",
- user.mbdb_homedir);
- EXITM(EX_NOINPUT);
- }
- user_info.smdbu_id = user.mbdb_uid;
- user_info.smdbu_group_id = user.mbdb_gid;
- (void) sm_strlcpy(user_info.smdbu_name, user.mbdb_name,
- SMDB_MAX_USER_NAME_LEN);
- }
-
- if (dbfilename == NULL)
- dbfilename = VDB;
- if (msgfilename == NULL)
- msgfilename = VMSG;
-
- sff = SFF_CREAT;
- if (getegid() != getgid())
- {
- /* Allow a set-group-ID vacation binary */
- RunAsGid = user_info.smdbu_group_id = getegid();
- sff |= SFF_OPENASROOT;
- }
- if (getuid() == 0)
- {
- /* Allow root to initialize user's vacation databases */
- sff |= SFF_OPENASROOT|SFF_ROOTOK;
-
- /* ... safely */
- sff |= SFF_NOSLINK|SFF_NOHLINK|SFF_REGONLY;
- }
-
-
- result = smdb_open_database(&Db, dbfilename,
- O_CREAT|O_RDWR | (initdb ? O_TRUNC : 0),
- S_IRUSR|S_IWUSR, sff,
- SMDB_TYPE_DEFAULT, &user_info, NULL);
- if (result != SMDBE_OK)
- {
- msglog(LOG_NOTICE, "vacation: %s: %s\n", dbfilename,
- sm_errstring(result));
- EXITM(EX_DATAERR);
- }
-
- if (list)
- {
- listdb();
- (void) Db->smdb_close(Db);
- exit(EX_OK);
- }
-
- if (interval != INTERVAL_UNDEF)
- setinterval(interval);
-
- if (initdb && !exclude)
- {
- (void) Db->smdb_close(Db);
- exit(EX_OK);
- }
-
- if (exclude)
- {
- xclude(smioin);
- (void) Db->smdb_close(Db);
- EXITM(EX_OK);
- }
-
- if ((cur = (ALIAS *) malloc((unsigned int) sizeof(ALIAS))) == NULL)
- {
- msglog(LOG_NOTICE,
- "vacation: can't allocate memory for username.\n");
- (void) Db->smdb_close(Db);
- EXITM(EX_OSERR);
- }
- cur->name = name;
- cur->next = Names;
- Names = cur;
-
- result = readheaders(alwaysrespond);
- if (result == EX_OK && !recent())
- {
- time_t now;
-
- (void) time(&now);
- setreply(From, now);
- (void) Db->smdb_close(Db);
- sendmessage(name, msgfilename, returnaddr);
- }
- else
- (void) Db->smdb_close(Db);
- if (result == EX_NOUSER)
- result = EX_OK;
- exit(result);
-}
-
-/*
-** EATMSG -- read stdin till EOF
-**
-** Parameters:
-** none.
-**
-** Returns:
-** nothing.
-**
-*/
-
-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:
-** alwaysrespond -- respond regardless of whether msg is to me
-**
-** Returns:
-** a exit code: NOUSER if no reply, OK if reply, * if error
-**
-** Side Effects:
-** may exit().
-**
-*/
-
-int
-readheaders(alwaysrespond)
- bool alwaysrespond;
-{
- bool tome, cont;
- register char *p;
- register ALIAS *cur;
- char buf[MAXLINE];
- extern bool junkmail __P((char *));
- extern bool nsearch __P((char *, char *));
-
- cont = false;
- tome = alwaysrespond;
- while (sm_io_fgets(smioin, SM_TIME_DEFAULT, buf, sizeof(buf)) &&
- *buf != '\n')
- {
- switch(*buf)
- {
- case 'F': /* "From " */
- cont = false;
- if (strncmp(buf, "From ", 5) == 0)
- {
- bool quoted = false;
-
- p = buf + 5;
- while (*p != '\0')
- {
- /* escaped character */
- if (*p == '\\')
- {
- p++;
- if (*p == '\0')
- {
- msglog(LOG_NOTICE,
- "vacation: badly formatted \"From \" line.\n");
- EXITIT(EX_DATAERR);
- }
- }
- else if (*p == '"')
- quoted = !quoted;
- else if (*p == '\r' || *p == '\n')
- break;
- else if (*p == ' ' && !quoted)
- break;
- p++;
- }
- if (quoted)
- {
- msglog(LOG_NOTICE,
- "vacation: badly formatted \"From \" line.\n");
- EXITIT(EX_DATAERR);
- }
- *p = '\0';
-
- /* ok since both strings have MAXLINE length */
- if (*From == '\0')
- (void) sm_strlcpy(From, buf + 5,
- sizeof From);
- if ((p = strchr(buf + 5, '\n')) != NULL)
- *p = '\0';
- if (junkmail(buf + 5))
- EXITIT(EX_NOUSER);
- }
- break;
-
- case 'P': /* "Precedence:" */
- case 'p':
- cont = false;
- if (strlen(buf) <= 10 ||
- strncasecmp(buf, "Precedence", 10) != 0 ||
- (buf[10] != ':' && buf[10] != ' ' &&
- buf[10] != '\t'))
- break;
- if ((p = strchr(buf, ':')) == NULL)
- break;
- while (*++p != '\0' && isascii(*p) && isspace(*p));
- if (*p == '\0')
- break;
- if (strncasecmp(p, "junk", 4) == 0 ||
- strncasecmp(p, "bulk", 4) == 0 ||
- strncasecmp(p, "list", 4) == 0)
- EXITIT(EX_NOUSER);
- break;
-
- case 'C': /* "Cc:" */
- case 'c':
- if (strncasecmp(buf, "Cc:", 3) != 0)
- break;
- cont = true;
- goto findme;
-
- case 'T': /* "To:" */
- case 't':
- if (strncasecmp(buf, "To:", 3) != 0)
- break;
- cont = true;
- goto findme;
-
- default:
- if (!isascii(*buf) || !isspace(*buf) || !cont || tome)
- {
- cont = false;
- break;
- }
-findme:
- for (cur = Names;
- !tome && cur != NULL;
- cur = cur->next)
- tome = nsearch(cur->name, buf);
- }
- }
- if (!tome)
- EXITIT(EX_NOUSER);
- if (*From == '\0')
- {
- msglog(LOG_NOTICE, "vacation: no initial \"From \" line.\n");
- EXITIT(EX_DATAERR);
- }
- EXITIT(EX_OK);
-}
-
-/*
-** NSEARCH --
-** do a nice, slow, search of a string for a substring.
-**
-** Parameters:
-** name -- name to search.
-** str -- string in which to search.
-**
-** Returns:
-** is name a substring of str?
-**
-*/
-
-bool
-nsearch(name, str)
- register char *name, *str;
-{
- register size_t len;
- register char *s;
-
- len = strlen(name);
-
- for (s = str; *s != '\0'; ++s)
- {
- /*
- ** Check to make sure that the string matches and
- ** the previous character is not an alphanumeric and
- ** the next character after the match is not an alphanumeric.
- **
- ** This prevents matching "eric" to "derick" while still
- ** matching "eric" to "<eric+detail>".
- */
-
- if (tolower(*s) == tolower(*name) &&
- strncasecmp(name, s, len) == 0 &&
- (s == str || !isascii(*(s - 1)) || !isalnum(*(s - 1))) &&
- (!isascii(*(s + len)) || !isalnum(*(s + len))))
- return true;
- }
- return false;
-}
-
-/*
-** JUNKMAIL --
-** read the header and return if automagic/junk/bulk/list mail
-**
-** Parameters:
-** from -- sender address.
-**
-** Returns:
-** 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;
-{
- bool quot;
- char *e;
- size_t len;
- IGNORE_T *cur;
- char sender[MAX_USER_LEN];
- static IGNORE_T ignore[] =
- {
- { "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
- */
-
- 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;
- }
- 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, e - cur->len - 1,
- cur->len) == 0)
- return true;
- }
- return false;
-}
-
-#define VIT "__VACATION__INTERVAL__TIMER__"
-
-/*
-** RECENT --
-** find out if user has gotten a vacation message recently.
-**
-** Parameters:
-** none.
-**
-** Returns:
-** true iff user has gotten a vacation message recently.
-**
-*/
-
-bool
-recent()
-{
- SMDB_DBENT key, data;
- time_t then, next;
- bool trydomain = false;
- int st;
- char *domain;
-
- memset(&key, '\0', sizeof key);
- memset(&data, '\0', sizeof data);
-
- /* get interval time */
- 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, sizeof(next));
-
- memset(&data, '\0', sizeof data);
-
- /* get record for this address */
- key.data = From;
- key.size = strlen(From);
-
- do
- {
- st = Db->smdb_get(Db, &key, &data, 0);
- if (st == SMDBE_OK)
- {
- memmove(&then, data.data, sizeof(then));
- if (next == ONLY_ONCE || then == ONLY_ONCE ||
- then + next > time(NULL))
- return true;
- }
- if ((trydomain = !trydomain) &&
- (domain = strchr(From, '@')) != NULL)
- {
- key.data = domain;
- key.size = strlen(domain);
- }
- } while (trydomain);
- return false;
-}
-
-/*
-** SETINTERVAL --
-** store the reply interval
-**
-** Parameters:
-** interval -- time interval for replies.
-**
-** Returns:
-** nothing.
-**
-** Side Effects:
-** stores the reply interval in database.
-*/
-
-void
-setinterval(interval)
- time_t interval;
-{
- SMDB_DBENT key, data;
-
- memset(&key, '\0', sizeof key);
- memset(&data, '\0', sizeof data);
-
- key.data = VIT;
- key.size = sizeof(VIT);
- data.data = (char*) &interval;
- data.size = sizeof(interval);
- (void) (Db->smdb_put)(Db, &key, &data, 0);
-}
-
-/*
-** SETREPLY --
-** store that this user knows about the vacation.
-**
-** Parameters:
-** from -- sender address.
-** when -- last reply time.
-**
-** Returns:
-** nothing.
-**
-** Side Effects:
-** stores user/time in database.
-*/
-
-void
-setreply(from, when)
- char *from;
- time_t when;
-{
- SMDB_DBENT key, data;
-
- memset(&key, '\0', sizeof key);
- memset(&data, '\0', sizeof data);
-
- key.data = from;
- key.size = strlen(from);
- data.data = (char*) &when;
- data.size = sizeof(when);
- (void) (Db->smdb_put)(Db, &key, &data, 0);
-}
-
-/*
-** XCLUDE --
-** add users to vacation db so they don't get a reply.
-**
-** Parameters:
-** f -- file pointer with list of address to exclude
-**
-** Returns:
-** nothing.
-**
-** Side Effects:
-** stores users in database.
-*/
-
-void
-xclude(f)
- SM_FILE_T *f;
-{
- char buf[MAXLINE], *p;
-
- if (f == NULL)
- return;
- while (sm_io_fgets(f, SM_TIME_DEFAULT, buf, sizeof buf))
- {
- if ((p = strchr(buf, '\n')) != NULL)
- *p = '\0';
- setreply(buf, ONLY_ONCE);
- }
-}
-
-/*
-** SENDMESSAGE --
-** exec sendmail to send the vacation file to sender
-**
-** Parameters:
-** myname -- user name.
-** msgfn -- name of file with vacation message.
-** sender -- use as sender address
-**
-** Returns:
-** nothing.
-**
-** Side Effects:
-** sends vacation reply.
-*/
-
-void
-sendmessage(myname, msgfn, sender)
- char *myname;
- char *msgfn;
- char *sender;
-{
- SM_FILE_T *mfp, *sfp;
- int i;
- int pvect[2];
- char *pv[8];
- char buf[MAXLINE];
-
- mfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, msgfn, SM_IO_RDONLY, NULL);
- if (mfp == NULL)
- {
- if (msgfn[0] == '/')
- msglog(LOG_NOTICE, "vacation: no %s file.\n", msgfn);
- else
- msglog(LOG_NOTICE, "vacation: no ~%s/%s file.\n",
- myname, msgfn);
- exit(EX_NOINPUT);
- }
- if (pipe(pvect) < 0)
- {
- msglog(LOG_ERR, "vacation: pipe: %s", sm_errstring(errno));
- exit(EX_OSERR);
- }
- pv[0] = "sendmail";
- pv[1] = "-oi";
- pv[2] = "-f";
- if (sender != NULL)
- pv[3] = sender;
- else
- pv[3] = myname;
- pv[4] = "--";
- pv[5] = From;
- pv[6] = NULL;
- i = fork();
- if (i < 0)
- {
- msglog(LOG_ERR, "vacation: fork: %s", sm_errstring(errno));
- exit(EX_OSERR);
- }
- if (i == 0)
- {
- (void) dup2(pvect[0], 0);
- (void) close(pvect[0]);
- (void) close(pvect[1]);
- (void) sm_io_close(mfp, SM_TIME_DEFAULT);
- (void) execv(_PATH_SENDMAIL, pv);
- msglog(LOG_ERR, "vacation: can't exec %s: %s",
- _PATH_SENDMAIL, sm_errstring(errno));
- exit(EX_UNAVAILABLE);
- }
- /* check return status of the following calls? XXX */
- (void) close(pvect[0]);
- if ((sfp = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT,
- (void *) &(pvect[1]),
- SM_IO_WRONLY, NULL)) != NULL)
- {
- (void) sm_io_fprintf(sfp, SM_TIME_DEFAULT, "To: %s\n", From);
- (void) sm_io_fprintf(sfp, SM_TIME_DEFAULT,
- "Auto-Submitted: auto-replied\n");
- while (sm_io_fgets(mfp, SM_TIME_DEFAULT, buf, sizeof buf))
- (void) sm_io_fputs(sfp, SM_TIME_DEFAULT, buf);
- (void) sm_io_close(mfp, SM_TIME_DEFAULT);
- (void) sm_io_close(sfp, SM_TIME_DEFAULT);
- }
- else
- {
- (void) sm_io_close(mfp, SM_TIME_DEFAULT);
- msglog(LOG_ERR, "vacation: can't open pipe to sendmail");
- exit(EX_UNAVAILABLE);
- }
-}
-
-void
-usage()
-{
- char *retusage = "";
- char *respusage = "";
-
-#if _FFR_RETURN_ADDR
- retusage = "[-R returnaddr] ";
-#endif /* _FFR_RETURN_ADDR */
-
-#if _FFR_RESPOND_ALL
- respusage = "[-j] ";
-#endif /* _FFR_RESPOND_ALL */
-
- msglog(LOG_NOTICE,
- "uid %u: usage: vacation [-a alias] [-C cfpath] [-d] [-f db] [-i] %s[-l] [-m msg] %s[-r interval] [-s sender] [-t time] [-U] [-x] [-z] login\n",
- getuid(), respusage, retusage);
- exit(EX_USAGE);
-}
-
-/*
-** 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)
- {
- sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
- "vacation: set cursor: %s\n",
- sm_errstring(result));
- return;
- }
-
- while ((result = cursor->smdbc_get(cursor, &db_key, &db_value,
- SMDB_CURSOR_GET_NEXT)) == SMDBE_OK)
- {
- char *timestamp;
-
- /* skip magic VIT entry */
- if (db_key.size == strlen(VIT) + 1 &&
- strncmp((char *)db_key.data, VIT,
- (int)db_key.size - 1) == 0)
- continue;
-
- /* skip bogus values */
- if (db_value.size != sizeof t)
- {
- sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
- "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;
-
- if (t <= 0)
- {
- /* must be an exclude */
- timestamp = "(exclusion)\n";
- }
- else
- {
- timestamp = ctime(&t);
- }
- sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%-40.*s %-10s",
- (int) db_key.size, (char *) db_key.data,
- timestamp);
-
- memset(&db_key, '\0', sizeof db_key);
- memset(&db_value, '\0', sizeof db_value);
- }
-
- if (result != SMDBE_OK && result != SMDBE_LAST_ENTRY)
- {
- sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
- "vacation: get value at cursor: %s\n",
- sm_errstring(result));
- if (cursor != NULL)
- {
- (void) cursor->smdbc_close(cursor);
- cursor = NULL;
- }
- return;
- }
- (void) cursor->smdbc_close(cursor);
- cursor = NULL;
-}
-
-/*
-** 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 SYSLOG_RET_T
-#ifdef __STDC__
-debuglog(int i, const char *fmt, ...)
-#else /* __STDC__ */
-debuglog(i, fmt, va_alist)
- int i;
- const char *fmt;
- va_dcl
-#endif /* __STDC__ */
-
-{
- SM_VA_LOCAL_DECL
-
- SM_VA_START(ap, fmt);
- sm_io_vfprintf(smioerr, SM_TIME_DEFAULT, fmt, ap);
- SM_VA_END(ap);
- SYSLOG_RET;
-}