date and time created 83/02/11 15:44:43 by rrh
[unix-history] / usr / src / usr.bin / vacation / vacation.c
index cc495d6..534c11e 100644 (file)
@@ -1,10 +1,11 @@
 # include <pwd.h>
 # include <stdio.h>
 # include <sysexits.h>
 # include <pwd.h>
 # include <stdio.h>
 # include <sysexits.h>
+# include <ctype.h>
 # include "useful.h"
 # include "userdbm.h"
 
 # include "useful.h"
 # include "userdbm.h"
 
-static char    SccsId[] =      "@(#)vacation.c 3.2     %G%";
+SCCSID(@(#)vacation.c  3.9             %G%);
 
 /*
 **  VACATION -- return a message to the sender when on vacation.
 
 /*
 **  VACATION -- return a message to the sender when on vacation.
@@ -15,11 +16,18 @@ static char SccsId[] =      "@(#)vacation.c 3.2     %G%";
 **     care not to return a message too often to prevent
 **     "I am on vacation" loops.
 **
 **     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:
 **     Positional Parameters:
-**             the user to send to.
+**             the user to collect the vacation message from.
 **
 **     Flag Parameters:
 **             -I      initialize the database.
 **
 **     Flag Parameters:
 **             -I      initialize the database.
+**             -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.
 **
 **     Side Effects:
 **             A message is sent back to the sender.
@@ -32,6 +40,10 @@ static char  SccsId[] =      "@(#)vacation.c 3.2     %G%";
 # define MAXLINE       256     /* max size of a line */
 # define MAXNAME       128     /* max size of one name */
 
 # define MAXLINE       256     /* max size of a line */
 # define MAXNAME       128     /* max size of one name */
 
+# define ONEWEEK       (60L*60L*24L*7L)
+
+time_t Timeout = ONEWEEK;      /* timeout between notices per user */
+
 struct dbrec
 {
        long    sentdate;
 struct dbrec
 {
        long    sentdate;
@@ -43,12 +55,14 @@ main(argc, argv)
        char *from;
        register char *p;
        struct passwd *pw;
        char *from;
        register char *p;
        struct passwd *pw;
-       register char *homedir;
+       char *homedir;
+       char *myname;
        char buf[MAXLINE];
        extern struct passwd *getpwnam();
        extern char *newstr();
        extern char *getfrom();
        extern bool knows();
        char buf[MAXLINE];
        extern struct passwd *getpwnam();
        extern char *newstr();
        extern char *getfrom();
        extern bool knows();
+       extern time_t convtime();
 
        /* process arguments */
        while (--argc > 0 && (p = *++argv) != NULL && *p == '-')
 
        /* process arguments */
        while (--argc > 0 && (p = *++argv) != NULL && *p == '-')
@@ -56,19 +70,13 @@ main(argc, argv)
                switch (*++p)
                {
                  case 'I':     /* initialize */
                switch (*++p)
                {
                  case 'I':     /* initialize */
-                       homedir = getenv("HOME");
-                       if (homedir == NULL)
-                               syserr("No home!");
-                       strcpy(buf, homedir);
-                       strcat(buf, "/.vacation.dir");
-                       if (close(creat(buf, 0644)) < 0)
-                               syserr("Cannot create %s", buf);
-                       strcpy(buf, homedir);
-                       strcat(buf, "/.vacation.pag");
-                       if (close(creat(buf, 0644)) < 0)
-                               syserr("Cannot create %s", buf);
+                       initialize();
                        exit(EX_OK);
 
                        exit(EX_OK);
 
+                 case 't':     /* set timeout */
+                       Timeout = convtime(++p);
+                       break;
+
                  default:
                        usrerr("Unknown flag -%s", p);
                        exit(EX_USAGE);
                  default:
                        usrerr("Unknown flag -%s", p);
                        exit(EX_USAGE);
@@ -82,16 +90,18 @@ main(argc, argv)
                exit(EX_USAGE);
        }
 
                exit(EX_USAGE);
        }
 
+       myname = p;
+
        /* find user's home directory */
        /* find user's home directory */
-       pw = getpwnam(p);
+       pw = getpwnam(myname);
        if (pw == NULL)
        {
        if (pw == NULL)
        {
-               usrerr("Unknown user %s", p);
+               usrerr("Unknown user %s", myname);
                exit(EX_NOUSER);
        }
        homedir = newstr(pw->pw_dir);
                exit(EX_NOUSER);
        }
        homedir = newstr(pw->pw_dir);
-       strcpy(buf, homedir);
-       strcat(buf, "/.vacation");
+       (void) strcpy(buf, homedir);
+       (void) strcat(buf, "/.vacation");
        dbminit(buf);
 
        /* read message from standard input (just from line) */
        dbminit(buf);
 
        /* read message from standard input (just from line) */
@@ -101,11 +111,12 @@ main(argc, argv)
        if (!knows(from))
        {
                /* mark this person as knowing */
        if (!knows(from))
        {
                /* mark this person as knowing */
-               setknows(from, buf);
+               setknows(from);
 
                /* send the message back */
 
                /* send the message back */
-               strcat(buf, ".msg");
-               sendmessage(buf, from);
+               (void) strcpy(buf, homedir);
+               (void) strcat(buf, "/.vacation.msg");
+               sendmessage(buf, from, myname);
                /* never returns */
        }
        exit (EX_OK);
                /* never returns */
        }
        exit (EX_OK);
@@ -164,8 +175,6 @@ getfrom()
 **             none.
 */
 
 **             none.
 */
 
-# define ONEWEEK       (60L*60L*24L*7L)
-
 bool
 knows(user)
        char *user;
 bool
 knows(user)
        char *user;
@@ -177,7 +186,7 @@ knows(user)
        k.dptr = user;
        k.dsize = strlen(user) + 1;
        d = fetch(k);
        k.dptr = user;
        k.dsize = strlen(user) + 1;
        d = fetch(k);
-       if (d.dptr == NULL || ((struct dbrec *) d.dptr)->sentdate + ONEWEEK < now)
+       if (d.dptr == NULL || ((struct dbrec *) d.dptr)->sentdate + Timeout < now)
                return (FALSE);
        return (TRUE);
 }
                return (FALSE);
        return (TRUE);
 }
@@ -197,7 +206,6 @@ knows(user)
 setknows(user)
        char *user;
 {
 setknows(user)
        char *user;
 {
-       register int i;
        DATUM k, d;
        struct dbrec xrec;
 
        DATUM k, d;
        struct dbrec xrec;
 
@@ -222,9 +230,10 @@ setknows(user)
 **             sends mail to 'user' using /usr/lib/sendmail.
 */
 
 **             sends mail to 'user' using /usr/lib/sendmail.
 */
 
-sendmessage(msgf, user)
+sendmessage(msgf, user, myname)
        char *msgf;
        char *user;
        char *msgf;
        char *user;
+       char *myname;
 {
        FILE *f;
 
 {
        FILE *f;
 
@@ -237,10 +246,43 @@ sendmessage(msgf, user)
                        syserr("No message to send");
        }
 
                        syserr("No message to send");
        }
 
-       execl("/usr/lib/sendmail", "sendmail", "-n", user, NULL);
+       execl("/usr/lib/sendmail", "sendmail", "-f", myname, user, NULL);
        syserr("Cannot exec /usr/lib/sendmail");
 }
 \f/*
        syserr("Cannot exec /usr/lib/sendmail");
 }
 \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];
+
+       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);
+}
+\f/*
 **  USRERR -- print user error
 **
 **     Parameters:
 **  USRERR -- print user error
 **
 **     Parameters:
@@ -285,3 +327,31 @@ syserr(f, p)
        fprintf(stderr, "\n");
        exit(EX_USAGE);
 }
        fprintf(stderr, "\n");
        exit(EX_USAGE);
 }
+\f/*
+**  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;
+
+       p = malloc(strlen(s) + 1);
+       if (p == NULL)
+       {
+               syserr("newstr: cannot alloc memory");
+               exit(EX_OSERR);
+       }
+       strcpy(p, s);
+       return (p);
+}