diff options
Diffstat (limited to 'contrib/sendmail/vacation/vacation.c')
-rw-r--r-- | contrib/sendmail/vacation/vacation.c | 1182 |
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; -} |