note other reasons for pclose to return -1; wait(2) -> wait4(2)
[unix-history] / usr / src / usr.bin / lock / lock.c
index 89273d0..01fe469 100644 (file)
+/*
+ * Copyright (c) 1980, 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.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980, 1987 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
 #ifndef lint
 #ifndef lint
-static char *sccsid = "@(#)lock.c      4.3 (Berkeley) %G%";
-#endif
+static char sccsid[] = "@(#)lock.c     5.7 (Berkeley) %G%";
+#endif /* not lint */
 
 /*
 
 /*
- * Lock a terminal up until the knowledgeable Joe returns.
+ * Lock a terminal up until the given key is entered, until the root
+ * password is entered, or the given interval times out.
+ *
+ * Timeout interval is by default TIMEOUT, it can be changed with
+ * an argument of the form -time where time is in minutes
  */
  */
-#include <stdio.h>
-#include <sys/types.h>
+
+#include <sys/param.h>
 #include <sys/stat.h>
 #include <sys/stat.h>
-#include <signal.h>
+#include <sys/time.h>
+#include <sys/signal.h>
+#include <pwd.h>
 #include <sgtty.h>
 #include <sgtty.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#define        TIMEOUT 15
+
+int    quit(), bye(), hi();
 
 
-char   masterp[] =     "hasta la vista\n";
-struct sgttyb tty, ntty;
-char   s[BUFSIZ], s1[BUFSIZ];
+struct timeval timeout;
+struct timeval zerotime;
+struct sgttyb  tty, ntty;
+long   nexttime;                       /* keep the timeout time */
 
 
+/*ARGSUSED*/
 main(argc, argv)
 main(argc, argv)
+       int argc;
        char **argv;
 {
        char **argv;
 {
-       register int t;
-       struct stat statb;
-
-       signal(SIGINT, SIG_IGN);
-       signal(SIGQUIT, SIG_IGN);
-       signal(SIGTSTP, SIG_IGN);
-       if (argc > 0)
-               argv[0] = 0;
+       extern char *optarg;
+       extern int optind;
+       struct passwd *root_pwd, *my_pwd;
+       struct timeval timval;
+       struct itimerval ntimer, otimer;
+       struct tm *timp;
+       int ch, sectimeout, use_mine;
+       char *ttynam, *ap, *tzn;
+       char hostname[MAXHOSTNAMELEN], s[BUFSIZ], s1[BUFSIZ];
+       char *crypt(), *index(), *ttyname();
+
+       use_mine = 0;
+       sectimeout = TIMEOUT;
+       while ((ch = getopt(argc, argv, "pt:")) != EOF)
+               switch((char)ch) {
+               case 't':
+                       if ((sectimeout = atoi(optarg)) <= 0)
+                               exit(0);
+                       break;
+               case 'p':
+                       use_mine = 1;
+                       break;
+               case '?':
+               default:
+                       fputs("usage: lock [-p] [-t timeout]\n", stderr);
+                       exit(1);
+       }
+       timeout.tv_sec = sectimeout * 60;
+
+       /* get information for header */
        if (ioctl(0, TIOCGETP, &tty))
                exit(1);
        if (ioctl(0, TIOCGETP, &tty))
                exit(1);
-       ntty = tty; ntty.sg_flags &= ~ECHO;
-       ioctl(0, TIOCSETN, &ntty);
-       printf("Key: ");
-       fgets(s, sizeof s, stdin);
-       printf("\nAgain: ");
-       fgets(s1, sizeof s1, stdin);
-       putchar('\n');
-       if (strcmp(s1, s)) {
-               putchar(07);
-               stty(0, &tty);
+       gethostname(hostname, sizeof(hostname));
+       if (!(ttynam = ttyname(0))) {
+               puts("lock: not a terminal?");
+               exit(1);
+       }
+       if (gettimeofday(&timval, (struct timezone *)NULL)) {
+               perror("gettimeofday");
                exit(1);
        }
                exit(1);
        }
-       s[0] = 0;
+       nexttime = timval.tv_sec + (sectimeout * 60);
+       timp = localtime(&timval.tv_sec);
+       ap = asctime(timp);
+       tzn = timp->tm_zone;
+
+       (void)signal(SIGINT, quit);
+       (void)signal(SIGQUIT, quit);
+       ntty = tty; ntty.sg_flags &= ~ECHO;
+       (void)ioctl(0, TIOCSETP, &ntty);
+
+       if (!use_mine) {
+               /* get key and check again */
+               fputs("Key: ", stdout);
+               if (!gets(s, sizeof(s)))
+                       quit();
+               fputs("\nAgain: ", stdout);
+               /*
+                * Don't need EOF test here, if we get EOF, then s1 != s
+                * and the right things will happen.
+                */
+               (void)gets(s1, sizeof(s1));
+               putchar('\n');
+               if (strcmp(s1, s)) {
+                       puts("\07lock: passwords didn't match.");
+                       ioctl(0, TIOCSETP, &tty);
+                       exit(1);
+               }
+               s[0] = NULL;
+       }
+
+       /* set signal handlers */
+       (void)signal(SIGINT, hi);
+       (void)signal(SIGQUIT, hi);
+       (void)signal(SIGTSTP, hi);
+       (void)signal(SIGALRM, bye);
+
+       ntimer.it_interval = zerotime;
+       ntimer.it_value = timeout;
+       setitimer(ITIMER_REAL, &ntimer, &otimer);
+
+       /* header info */
+       printf ("lock: %s on %s. timeout in %d minutes\ntime now is %.20s%s%s",
+               ttynam, hostname, sectimeout, ap, tzn, ap + 19);
+
+       /* wait */
+       root_pwd = getpwuid(0);
+       if (use_mine)
+               my_pwd = getpwuid(getuid());
        for (;;) {
        for (;;) {
-               fgets(s, sizeof s, stdin);
-               if (strcmp(s1, s) == 0)
+               fputs("Key: ", stdout);
+               if (!gets(s, sizeof(s))) {
+                       clearerr(stdin);
+                       hi();
+                       continue;
+               }
+               if (use_mine) {
+                       if (!my_pwd || !*my_pwd->pw_passwd || !strcmp(my_pwd->pw_passwd, crypt(s, my_pwd->pw_passwd)))
+                               break;
+               }
+               else if (!strcmp(s1, s))
                        break;
                        break;
-               if (strcmp(s, masterp) == 0)
+               if (!root_pwd || !*root_pwd->pw_passwd || !strcmp(root_pwd->pw_passwd, crypt(s, root_pwd->pw_passwd)))
                        break;
                        break;
-               putchar(07);
+               puts("\07");
                if (ioctl(0, TIOCGETP, &ntty))
                        exit(1);
        }
                if (ioctl(0, TIOCGETP, &ntty))
                        exit(1);
        }
-       ioctl(0, TIOCSETN, &tty);
+       putchar('\n');
+       quit();
+}
+
+static
+hi()
+{
+       struct timeval timval;
+
+       if (!gettimeofday(&timval, (struct timezone *)NULL))
+           printf("lock: type in the unlock key. timeout in %ld:%ld minutes\n",
+           (nexttime - timval.tv_sec) / 60, (nexttime - timval.tv_sec) % 60);
+}
+
+static
+quit()
+{
+       (void)ioctl(0, TIOCSETP, &tty);
+       exit(0);
+}
+
+static
+bye()
+{
+       (void)ioctl(0, TIOCSETP, &tty);
+       puts("lock: timeout");
+       exit(1);
 }
 }