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