xref: /csrg-svn/usr.bin/lock/lock.c (revision 30652)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 char copyright[] =
9 "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10  All rights reserved.\n";
11 #endif not lint
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)lock.c	5.2 (Berkeley) 03/18/87";
15 #endif not lint
16 
17 /*
18  * Lock a terminal up until the given key is entered,
19  * or until the root password is entered,
20  * or the given interval times out.
21  *
22  * Timeout interval is by default TIMEOUT, it can be changed with
23  * an argument of the form -time where time is in minutes
24  */
25 
26 #include <sys/param.h>
27 #include <sys/stat.h>
28 #include <sys/time.h>
29 #include <sys/signal.h>
30 #include <pwd.h>
31 #include <sgtty.h>
32 #include <stdio.h>
33 
34 #define	TIMEOUT 15
35 
36 int	quit(), bye(), hi();
37 
38 struct timeval	timeout;
39 struct timeval	zerotime;
40 struct sgttyb	tty, ntty;
41 long	nexttime;		/* keep the timeout time */
42 
43 main(argc,argv)
44 	int	argc;
45 	char	**argv;
46 {
47 	struct passwd	*pwd;
48 	struct timeval	timval;
49 	struct itimerval	ntimer, otimer;
50 	struct tm	*timp;
51 	int	sectimeout = TIMEOUT;
52 	char	*ttynam, *ap, *tzn,
53 		hostname[MAXHOSTNAMELEN],
54 		s[BUFSIZ], s1[BUFSIZ],
55 		*crypt(), *index(), *ttyname();
56 
57 	/* process argument */
58 
59 	if (argc > 1 && (argv[1][0] != '-' ||
60 	    (sectimeout = atoi(argv[1] + 1)) <= 0)) {
61 		puts("Usage: lock [-timeout]");
62 		exit (1);
63 	}
64 	timeout.tv_sec = sectimeout * 60;
65 
66 	/* get information for header */
67 
68 	if (ioctl(0, TIOCGETP, &tty))
69 		exit(1);
70 	gethostname(hostname, sizeof(hostname));
71 	if (!(ttynam = ttyname(0))) {
72 		puts("lock: not a terminal?");
73 		exit (1);
74 	}
75 	if (gettimeofday(&timval, (struct timezone *)NULL)) {
76 		perror("gettimeofday");
77 		exit (1);
78 	}
79 	nexttime = timval.tv_sec + (sectimeout * 60);
80 	timp = localtime(&timval.tv_sec);
81 	ap = asctime(timp);
82 	tzn = timp->tm_zone;
83 
84 	/* get key and check again */
85 
86 	(void)signal(SIGINT, quit);
87 	(void)signal(SIGQUIT, quit);
88 	ntty = tty; ntty.sg_flags &= ~ECHO;
89 	(void)ioctl(0, TIOCSETP, &ntty);
90 
91 	fputs("Key: ",stdout);
92 	if (!gets(s,sizeof(s)))
93 		quit();
94 	fputs("\nAgain: ",stdout);
95 
96 	/*
97 	 * Don't need EOF test here, if we get EOF, then s1 != s
98 	 * and the right things will happen.
99 	 */
100 	(void)gets(s1,sizeof(s1));
101 	putchar('\n');
102 	if (strcmp(s1, s)) {
103 		putchar(07);
104 		ioctl(0, TIOCSETP, &tty);
105 		exit(1);
106 	}
107 	s[0] = NULL;
108 
109 	/* Set signal handlers */
110 
111 	(void)signal(SIGINT, hi);
112 	(void)signal(SIGQUIT, hi);
113 	(void)signal(SIGTSTP, hi);
114 	(void)signal(SIGALRM, bye);
115 
116 	ntimer.it_interval = zerotime;
117 	ntimer.it_value = timeout;
118 	setitimer(ITIMER_REAL, &ntimer, &otimer);
119 
120 	/* Header info */
121 
122 	printf ("lock: %s on %s. timeout in %d minutes\ntime now is %.20s%s%s",
123 		ttynam,hostname,sectimeout,ap,tzn,ap+19);
124 
125 	/* wait */
126 
127 	for (pwd = getpwuid(0);;) {
128 		fputs("Key: ",stdout);
129 		if (!gets(s,sizeof(s))) {
130 			clearerr(stdin);
131 			hi();
132 			continue;
133 		}
134 		if (!strcmp(s1,s) || !pwd || !*pwd->pw_passwd ||
135 			!strcmp(pwd->pw_passwd,crypt(s,pwd->pw_passwd)))
136 			break;
137 		puts("\07");
138 		if (ioctl(0, TIOCGETP, &ntty))
139 			exit(1);
140 	}
141 	putchar('\n');
142 	quit();
143 }
144 
145 /*
146  *	tell the user we are waiting
147  */
148 
149 static
150 hi()
151 {
152 	struct timeval	timval;
153 
154 	if (!gettimeofday(&timval, (struct timezone *)NULL))
155 	    printf("lock: type in the unlock key. timeout in %d minutes\n",
156 	    (nexttime - timval.tv_sec) / 60);
157 }
158 
159 /*
160  *	get out of here
161  */
162 static
163 quit()
164 {
165 	(void)ioctl(0, TIOCSETP, &tty);
166 	exit (0);
167 }
168 
169 static
170 bye()
171 {
172 	(void)ioctl(0, TIOCSETP, &tty);
173 	puts("lock: timeout");
174 	exit (1);
175 }
176