require -t flag for command line timeout value
[unix-history] / usr / src / usr.bin / lock / lock.c
CommitLineData
22e155fc 1/*
750362f3
KB
2 * Copyright (c) 1980, 1987 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
5e8b0e60
KB
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22e155fc
DF
16 */
17
18#ifndef lint
19char copyright[] =
750362f3 20"@(#) Copyright (c) 1980, 1987 Regents of the University of California.\n\
22e155fc 21 All rights reserved.\n";
750362f3 22#endif /* not lint */
22e155fc 23
4ca10280 24#ifndef lint
fcc2be53 25static char sccsid[] = "@(#)lock.c 5.7 (Berkeley) %G%";
750362f3 26#endif /* not lint */
4ca10280
SL
27
28/*
f84e1e5b
KB
29 * Lock a terminal up until the given key is entered, until the root
30 * password is entered, or the given interval times out.
d523b17b
RC
31 *
32 * Timeout interval is by default TIMEOUT, it can be changed with
33 * an argument of the form -time where time is in minutes
4ca10280 34 */
d523b17b 35
654949dc 36#include <sys/param.h>
36e4dcd1 37#include <sys/stat.h>
d523b17b 38#include <sys/time.h>
654949dc
KB
39#include <sys/signal.h>
40#include <pwd.h>
d97d0c53 41#include <sgtty.h>
654949dc 42#include <stdio.h>
2cbfd2f5 43#include <ctype.h>
d97d0c53 44
f84e1e5b 45#define TIMEOUT 15
d523b17b 46
654949dc 47int quit(), bye(), hi();
d523b17b 48
654949dc
KB
49struct timeval timeout;
50struct timeval zerotime;
d523b17b 51struct sgttyb tty, ntty;
f84e1e5b 52long nexttime; /* keep the timeout time */
d97d0c53 53
f84e1e5b
KB
54/*ARGSUSED*/
55main(argc, argv)
fcc2be53
KB
56 int argc;
57 char **argv;
d97d0c53 58{
fcc2be53
KB
59 extern char *optarg;
60 extern int optind;
61 struct passwd *root_pwd, *my_pwd;
62 struct timeval timval;
63 struct itimerval ntimer, otimer;
64 struct tm *timp;
65 int ch, sectimeout, use_mine;
66 char *ttynam, *ap, *tzn;
67 char hostname[MAXHOSTNAMELEN], s[BUFSIZ], s1[BUFSIZ];
68 char *crypt(), *index(), *ttyname();
69
70 use_mine = 0;
71 sectimeout = TIMEOUT;
72 while ((ch = getopt(argc, argv, "pt:")) != EOF)
73 switch((char)ch) {
74 case 't':
75 if ((sectimeout = atoi(optarg)) <= 0)
76 exit(0);
77 break;
78 case 'p':
79 use_mine = 1;
80 break;
81 case '?':
82 default:
83 fputs("usage: lock [-p] [-t timeout]\n", stderr);
84 exit(1);
d523b17b
RC
85 }
86 timeout.tv_sec = sectimeout * 60;
87
88 /* get information for header */
4ca10280 89 if (ioctl(0, TIOCGETP, &tty))
d97d0c53 90 exit(1);
d523b17b 91 gethostname(hostname, sizeof(hostname));
654949dc
KB
92 if (!(ttynam = ttyname(0))) {
93 puts("lock: not a terminal?");
f84e1e5b 94 exit(1);
654949dc
KB
95 }
96 if (gettimeofday(&timval, (struct timezone *)NULL)) {
97 perror("gettimeofday");
f84e1e5b 98 exit(1);
d523b17b 99 }
d523b17b
RC
100 nexttime = timval.tv_sec + (sectimeout * 60);
101 timp = localtime(&timval.tv_sec);
102 ap = asctime(timp);
654949dc 103 tzn = timp->tm_zone;
d523b17b 104
654949dc
KB
105 (void)signal(SIGINT, quit);
106 (void)signal(SIGQUIT, quit);
d97d0c53 107 ntty = tty; ntty.sg_flags &= ~ECHO;
654949dc
KB
108 (void)ioctl(0, TIOCSETP, &ntty);
109
f84e1e5b
KB
110 if (!use_mine) {
111 /* get key and check again */
112 fputs("Key: ", stdout);
113 if (!gets(s, sizeof(s)))
114 quit();
115 fputs("\nAgain: ", stdout);
116 /*
117 * Don't need EOF test here, if we get EOF, then s1 != s
118 * and the right things will happen.
119 */
120 (void)gets(s1, sizeof(s1));
121 putchar('\n');
122 if (strcmp(s1, s)) {
123 puts("\07lock: passwords didn't match.");
124 ioctl(0, TIOCSETP, &tty);
125 exit(1);
126 }
127 s[0] = NULL;
d97d0c53 128 }
d523b17b 129
f84e1e5b 130 /* set signal handlers */
654949dc
KB
131 (void)signal(SIGINT, hi);
132 (void)signal(SIGQUIT, hi);
133 (void)signal(SIGTSTP, hi);
134 (void)signal(SIGALRM, bye);
135
d523b17b
RC
136 ntimer.it_interval = zerotime;
137 ntimer.it_value = timeout;
138 setitimer(ITIMER_REAL, &ntimer, &otimer);
139
f84e1e5b 140 /* header info */
654949dc 141 printf ("lock: %s on %s. timeout in %d minutes\ntime now is %.20s%s%s",
f84e1e5b 142 ttynam, hostname, sectimeout, ap, tzn, ap + 19);
d523b17b
RC
143
144 /* wait */
f84e1e5b
KB
145 root_pwd = getpwuid(0);
146 if (use_mine)
147 my_pwd = getpwuid(getuid());
148 for (;;) {
149 fputs("Key: ", stdout);
150 if (!gets(s, sizeof(s))) {
3e58f554
RE
151 clearerr(stdin);
152 hi();
153 continue;
154 }
f84e1e5b
KB
155 if (use_mine) {
156 if (!my_pwd || !*my_pwd->pw_passwd || !strcmp(my_pwd->pw_passwd, crypt(s, my_pwd->pw_passwd)))
157 break;
158 }
159 else if (!strcmp(s1, s))
160 break;
161 if (!root_pwd || !*root_pwd->pw_passwd || !strcmp(root_pwd->pw_passwd, crypt(s, root_pwd->pw_passwd)))
d97d0c53 162 break;
654949dc 163 puts("\07");
4ca10280 164 if (ioctl(0, TIOCGETP, &ntty))
d97d0c53
BJ
165 exit(1);
166 }
d523b17b 167 putchar('\n');
654949dc 168 quit();
d523b17b
RC
169}
170
654949dc
KB
171static
172hi()
d523b17b 173{
fcc2be53 174 struct timeval timval;
d523b17b 175
654949dc 176 if (!gettimeofday(&timval, (struct timezone *)NULL))
f84e1e5b
KB
177 printf("lock: type in the unlock key. timeout in %ld:%ld minutes\n",
178 (nexttime - timval.tv_sec) / 60, (nexttime - timval.tv_sec) % 60);
d523b17b
RC
179}
180
654949dc
KB
181static
182quit()
d523b17b 183{
654949dc 184 (void)ioctl(0, TIOCSETP, &tty);
f84e1e5b 185 exit(0);
654949dc 186}
d523b17b 187
654949dc
KB
188static
189bye()
190{
191 (void)ioctl(0, TIOCSETP, &tty);
192 puts("lock: timeout");
f84e1e5b
KB
193 exit(1);
194}