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