BSD 4_3_Net_2 release
[unix-history] / usr / src / usr.bin / vacation / vacation.c
index 54167f8..5a1b950 100644 (file)
@@ -2,17 +2,33 @@
  * Copyright (c) 1983, 1987 Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1983, 1987 Regents of the University of California.
  * All rights reserved.
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
@@ -22,7 +38,7 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)vacation.c 5.16 (Berkeley) %G%";
+static char sccsid[] = "@(#)vacation.c 5.19 (Berkeley) 3/23/91";
 #endif /* not lint */
 
 /*
 #endif /* not lint */
 
 /*
@@ -32,13 +48,19 @@ static char sccsid[] = "@(#)vacation.c      5.16 (Berkeley) %G%";
 */
 
 #include <sys/param.h>
 */
 
 #include <sys/param.h>
-#include <sys/file.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 #include <pwd.h>
 #include <pwd.h>
-#include <ndbm.h>
+#include <db.h>
+#include <time.h>
 #include <syslog.h>
 #include <tzfile.h>
 #include <syslog.h>
 #include <tzfile.h>
+#include <errno.h>
+#include <unistd.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <stdio.h>
 #include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
 #include <paths.h>
 
 /*
 #include <paths.h>
 
 /*
@@ -50,11 +72,9 @@ static char sccsid[] = "@(#)vacation.c       5.16 (Berkeley) %G%";
  *     vacation" loops.
  */
 
  *     vacation" loops.
  */
 
-#define        MAXLINE 500                     /* max line from mail header */
+#define        MAXLINE 1024                    /* max line from mail header */
+#define        VDB     ".vacation.db"          /* dbm's database */
 #define        VMSG    ".vacation.msg"         /* vacation message */
 #define        VMSG    ".vacation.msg"         /* vacation message */
-#define        VACAT   ".vacation"             /* dbm's database prefix */
-#define        VDIR    ".vacation.dir"         /* dbm's DB prefix, part 1 */
-#define        VPAG    ".vacation.pag"         /* dbm's DB prefix, part 2 */
 
 typedef struct alias {
        struct alias *next;
 
 typedef struct alias {
        struct alias *next;
@@ -62,12 +82,9 @@ typedef struct alias {
 } ALIAS;
 ALIAS *names;
 
 } ALIAS;
 ALIAS *names;
 
-static DBM *db;
-
-extern int errno;
+DB *db;
 
 
-static char *VIT = "__VACATION__INTERVAL__TIMER__";
-static char from[MAXLINE];
+char from[MAXLINE];
 
 main(argc, argv)
        int argc;
 
 main(argc, argv)
        int argc;
@@ -79,9 +96,6 @@ main(argc, argv)
        ALIAS *cur;
        time_t interval;
        int ch, iflag;
        ALIAS *cur;
        time_t interval;
        int ch, iflag;
-       char *malloc();
-       uid_t getuid();
-       long atol();
 
        opterr = iflag = 0;
        interval = -1;
 
        opterr = iflag = 0;
        interval = -1;
@@ -102,63 +116,66 @@ main(argc, argv)
                        if (isdigit(*optarg)) {
                                interval = atol(optarg) * SECSPERDAY;
                                if (interval < 0)
                        if (isdigit(*optarg)) {
                                interval = atol(optarg) * SECSPERDAY;
                                if (interval < 0)
-                                       goto usage;
+                                       usage();
                        }
                        else
                                interval = LONG_MAX;
                        break;
                case '?':
                default:
                        }
                        else
                                interval = LONG_MAX;
                        break;
                case '?':
                default:
-                       goto usage;
+                       usage();
                }
        argc -= optind;
        argv += optind;
 
        if (argc != 1) {
                }
        argc -= optind;
        argv += optind;
 
        if (argc != 1) {
-               if (!iflag) {
-usage:                 syslog(LOG_NOTICE, "uid %u: usage: vacation [-i] [-a alias] login\n", getuid());
-                       myexit(1);
-               }
+               if (!iflag)
+                       usage();
                if (!(pw = getpwuid(getuid()))) {
                if (!(pw = getpwuid(getuid()))) {
-                       syslog(LOG_ERR, "vacation: no such user uid %u.\n", getuid());
-                       myexit(1);
+                       syslog(LOG_ERR,
+                           "vacation: no such user uid %u.\n", getuid());
+                       exit(1);
                }
        }
        else if (!(pw = getpwnam(*argv))) {
                syslog(LOG_ERR, "vacation: no such user %s.\n", *argv);
                }
        }
        else if (!(pw = getpwnam(*argv))) {
                syslog(LOG_ERR, "vacation: no such user %s.\n", *argv);
-               myexit(1);
+               exit(1);
        }
        if (chdir(pw->pw_dir)) {
        }
        if (chdir(pw->pw_dir)) {
-               syslog(LOG_NOTICE, "vacation: no such directory %s.\n", pw->pw_dir);
-               myexit(1);
+               syslog(LOG_NOTICE,
+                   "vacation: no such directory %s.\n", pw->pw_dir);
+               exit(1);
        }
 
        }
 
-       if (iflag || access(VDIR, F_OK))
-               initialize();
-       if (!(db = dbm_open(VACAT, O_RDWR, 0))) {
-               syslog(LOG_NOTICE, "vacation: %s: %s\n", VACAT,
-                   strerror(errno));
-               myexit(1);
+       db = hash_open(VDB, O_CREAT|O_RDWR | (iflag ? O_TRUNC : 0),
+           S_IRUSR|S_IWUSR, (HASHINFO *)NULL);
+       if (!db) {
+               syslog(LOG_NOTICE, "vacation: %s: %s\n", VDB, strerror(errno));
+               exit(1);
        }
 
        if (interval != -1)
                setinterval(interval);
        }
 
        if (interval != -1)
                setinterval(interval);
-       if (iflag)
-               myexit(0);
 
 
-       if (!(cur = (ALIAS *)malloc((u_int)sizeof(ALIAS))))
-               myexit(1);
+       if (iflag) {
+               (void)(db->close)(db);
+               exit(0);
+       }
+
+       if (!(cur = malloc((u_int)sizeof(ALIAS))))
+               exit(1);
        cur->name = pw->pw_name;
        cur->next = names;
        names = cur;
 
        readheaders();
        cur->name = pw->pw_name;
        cur->next = names;
        names = cur;
 
        readheaders();
-
        if (!recent()) {
                setreply();
        if (!recent()) {
                setreply();
+               (void)(db->close)(db);
                sendmessage(pw->pw_name);
        }
                sendmessage(pw->pw_name);
        }
-       myexit(0);
+       (void)(db->close)(db);
+       exit(0);
        /* NOTREACHED */
 }
 
        /* NOTREACHED */
 }
 
@@ -166,13 +183,12 @@ usage:                    syslog(LOG_NOTICE, "uid %u: usage: vacation [-i] [-a alias] login\n", g
  * readheaders --
  *     read mail headers
  */
  * readheaders --
  *     read mail headers
  */
-getfrom(shortp)
-char **shortp;
+readheaders()
 {
        register ALIAS *cur;
        register char *p;
        int tome, cont;
 {
        register ALIAS *cur;
        register char *p;
        int tome, cont;
-       char buf[MAXLINE], *strcpy(), *index();
+       char buf[MAXLINE];
 
        cont = tome = 0;
        while (fgets(buf, sizeof(buf), stdin) && *buf != '\n')
 
        cont = tome = 0;
        while (fgets(buf, sizeof(buf), stdin) && *buf != '\n')
@@ -186,20 +202,22 @@ char **shortp;
                                if (p = index(from, '\n'))
                                        *p = '\0';
                                if (junkmail())
                                if (p = index(from, '\n'))
                                        *p = '\0';
                                if (junkmail())
-                                       myexit(0);
+                                       exit(0);
                        }
                        break;
                case 'P':               /* "Precedence:" */
                        cont = 0;
                        }
                        break;
                case 'P':               /* "Precedence:" */
                        cont = 0;
-                       if (strncasecmp(buf, "Precedence", 10) || buf[10] != ':' && buf[10] != ' ' && buf[10] != '\t')
+                       if (strncasecmp(buf, "Precedence", 10) ||
+                           buf[10] != ':' && buf[10] != ' ' && buf[10] != '\t')
                                break;
                        if (!(p = index(buf, ':')))
                                break;
                        while (*++p && isspace(*p));
                        if (!*p)
                                break;
                                break;
                        if (!(p = index(buf, ':')))
                                break;
                        while (*++p && isspace(*p));
                        if (!*p)
                                break;
-                       if (!strncasecmp(p, "junk", 4) || !strncasecmp(p, "bulk", 4))
-                               myexit(0);
+                       if (!strncasecmp(p, "junk", 4) ||
+                           !strncasecmp(p, "bulk", 4))
+                               exit(0);
                        break;
                case 'C':               /* "Cc:" */
                        if (strncmp(buf, "Cc:", 3))
                        break;
                case 'C':               /* "Cc:" */
                        if (strncmp(buf, "Cc:", 3))
@@ -220,14 +238,26 @@ findme:                   for (cur = names; !tome && cur; cur = cur->next)
                                tome += nsearch(cur->name, buf);
                }
        if (!tome)
                                tome += nsearch(cur->name, buf);
                }
        if (!tome)
-               myexit(0);
+               exit(0);
        if (!*from) {
                syslog(LOG_NOTICE, "vacation: no initial \"From\" line.\n");
        if (!*from) {
                syslog(LOG_NOTICE, "vacation: no initial \"From\" line.\n");
-               myexit(1);
+               exit(1);
        }
 }
 
        }
 }
 
-       return start;
+/*
+ * nsearch --
+ *     do a nice, slow, search of a string for a substring.
+ */
+nsearch(name, str)
+       register char *name, *str;
+{
+       register int len;
+
+       for (len = strlen(name); *str; ++str)
+               if (*str == *name && !strncasecmp(name, str, len))
+                       return(1);
+       return(0);
 }
 
 /*
 }
 
 /*
@@ -247,7 +277,6 @@ junkmail()
        register struct ignore *cur;
        register int len;
        register char *p;
        register struct ignore *cur;
        register int len;
        register char *p;
-       char *index(), *rindex();
 
        /*
         * This is mildly amusing, and I'm not positive it's right; trying
 
        /*
         * This is mildly amusing, and I'm not positive it's right; trying
@@ -266,36 +295,42 @@ junkmail()
                }
        len = p - from;
        for (cur = ignore; cur->name; ++cur)
                }
        len = p - from;
        for (cur = ignore; cur->name; ++cur)
-               if (len >= cur->len && !strncasecmp(cur->name, p - cur->len, cur->len))
+               if (len >= cur->len &&
+                   !strncasecmp(cur->name, p - cur->len, cur->len))
                        return(1);
        return(0);
 }
 
                        return(1);
        return(0);
 }
 
+#define        VIT     "__VACATION__INTERVAL__TIMER__"
+
 /*
  * recent --
  *     find out if user has gotten a vacation message recently.
  *     use bcopy for machines with alignment restrictions
  */
 /*
  * recent --
  *     find out if user has gotten a vacation message recently.
  *     use bcopy for machines with alignment restrictions
  */
-char *user;
+recent()
 {
 {
-       datum key, data;
-       time_t then, next, time();
-
-       if (d.dptr == NULL)
-               return FALSE;
-       bcopy(d.dptr, (char *)&ldbrec, sizeof ldbrec);  /* realign data */
-       return ldbrec.sentdate + Timeout >= time((time_t *)0);
-}
-
-#ifndef VMUNIX
-bcopy(from, to, size)
-register char *to, *from;
-register unsigned size;
-{
-       while (size-- > 0)
-               *to++ = *from++;
+       DBT key, data;
+       time_t then, next;
+
+       /* get interval time */
+       key.data = VIT;
+       key.size = sizeof(VIT);
+       if ((db->get)(db, &key, &data, 0))
+               next = SECSPERDAY * DAYSPERWEEK;
+       else
+               bcopy(data.data, &next, sizeof(next));
+
+       /* get record for this address */
+       key.data = from;
+       key.size = strlen(from);
+       if (!(db->get)(db, &key, &data, 0)) {
+               bcopy(data.data, &then, sizeof(then));
+               if (next == LONG_MAX || then + next > time(NULL))
+                       return(1);
+       }
+       return(0);
 }
 }
-#endif
 
 /*
  * setinterval --
 
 /*
  * setinterval --
@@ -304,13 +339,13 @@ register unsigned size;
 setinterval(interval)
        time_t interval;
 {
 setinterval(interval)
        time_t interval;
 {
-       datum key, data;
+       DBT key, data;
 
 
-       key.dptr = VIT;
-       key.dsize = sizeof(VIT) - 1;
-       data.dptr = (char *)&interval;
-       data.dsize = sizeof(interval);
-       dbm_store(db, key, data, DBM_REPLACE);
+       key.data = VIT;
+       key.size = sizeof(VIT);
+       data.data = &interval;
+       data.size = sizeof(interval);
+       (void)(db->put)(db, &key, &data, R_PUT);
 }
 
 /*
 }
 
 /*
@@ -319,15 +354,15 @@ setinterval(interval)
  */
 setreply()
 {
  */
 setreply()
 {
-       datum key, data;
-       time_t now, time();
+       DBT key, data;
+       time_t now;
 
 
-       key.dptr = from;
-       key.dsize = strlen(from);
+       key.data = from;
+       key.size = strlen(from);
        (void)time(&now);
        (void)time(&now);
-       data.dptr = (char *)&now;
-       data.dsize = sizeof(now);
-       dbm_store(db, key, data, DBM_REPLACE);
+       data.data = &now;
+       data.size = sizeof(now);
+       (void)(db->put)(db, &key, &data, R_PUT);
 }
 
 /*
 }
 
 /*
@@ -339,41 +374,16 @@ sendmessage(myname)
 {
        if (!freopen(VMSG, "r", stdin)) {
                syslog(LOG_NOTICE, "vacation: no ~%s/%s file.\n", myname, VMSG);
 {
        if (!freopen(VMSG, "r", stdin)) {
                syslog(LOG_NOTICE, "vacation: no ~%s/%s file.\n", myname, VMSG);
-               myexit(1);
+               exit(1);
        }
        execl(_PATH_SENDMAIL, "sendmail", "-f", myname, from, NULL);
        syslog(LOG_ERR, "vacation: can't exec %s.\n", _PATH_SENDMAIL);
        }
        execl(_PATH_SENDMAIL, "sendmail", "-f", myname, from, NULL);
        syslog(LOG_ERR, "vacation: can't exec %s.\n", _PATH_SENDMAIL);
-       myexit(1);
+       exit(1);
 }
 
 }
 
-/*
- * initialize --
- *     initialize the dbm database
- */
-initialize()
-{
-       int fd;
-
-       if ((fd = open(VDIR, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) {
-               syslog(LOG_NOTICE, "vacation: %s: %s\n", VDIR, strerror(errno));
-               exit(1);
-       }
-       (void)close(fd);
-       if ((fd = open(VPAG, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) {
-               syslog(LOG_NOTICE, "vacation: %s: %s\n", VPAG, strerror(errno));
-               exit(1);
-       }
-       (void)close(fd);
-}
-
-/*
- * myexit --
- *     we're outta here...
- */
-myexit(eval)
-       int eval;
+usage()
 {
 {
-       if (db)
-               dbm_close(db);
-       exit(eval);
+       syslog(LOG_NOTICE, "uid %u: usage: vacation [-i] [-a alias] login\n",
+           getuid());
+       exit(1);
 }
 }