xref: /csrg-svn/usr.bin/lock/lock.c (revision 21565)
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.1 (Berkeley) 05/31/85";
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 <pwd.h>
27 #include <stdio.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <sys/time.h>
31 #include <signal.h>
32 #include <sgtty.h>
33 
34 #define TIMEOUT 15
35 
36 struct	passwd *pwd;
37 char	*crypt();
38 char	*getpass();
39 char	*index();
40 char	*ttyname();
41 char	*timezone();
42 char	*asctime();
43 struct	tm *localtime();
44 
45 int	quit();
46 int	bye();
47 int	hi();
48 
49 struct timeval	timeout	= {0, 0};
50 struct timeval	zerotime = {0, 0};
51 struct sgttyb	tty, ntty;
52 long	nexttime;		/* keep the timeout time */
53 
54 main(argc, argv)
55 	int argc;
56 	char **argv;
57 {
58 	register int t;
59 	char	*ttynam;
60 	char	*ap;
61 	int	sectimeout = TIMEOUT;
62 	char	s[BUFSIZ], s1[BUFSIZ];
63 	char	hostname[32];
64 	char	*tzn;
65 	struct timeval	timval;
66 	struct itimerval	ntimer, otimer;
67 	struct timezone	timzone;
68 	struct tm	*timp;
69 	struct stat	statb;
70 
71 	/* process arguments */
72 
73 	if (argc > 1){
74 		if (argv[1][0] != '-')
75 			goto usage;
76 		if (sscanf(&(argv[1][1]), "%d", &sectimeout) != 1)
77 			goto usage;
78 	}
79 	timeout.tv_sec = sectimeout * 60;
80 
81 	/* get information for header */
82 
83 	if (ioctl(0, TIOCGETP, &tty))
84 		exit(1);
85 	pwd = getpwuid(0);
86 	gethostname(hostname, sizeof(hostname));
87 	if (!(ttynam = ttyname(0))){
88 		printf("lock: not a terminal?");
89 		exit (1);
90 	}
91 	gettimeofday(&timval, &timzone);
92 	nexttime = timval.tv_sec + (sectimeout * 60);
93 	timp = localtime(&timval.tv_sec);
94 	ap = asctime(timp);
95 	tzn = timezone(timzone.tz_minuteswest, timp->tm_isdst);
96 
97 	/* get key and check again */
98 
99 	signal(SIGINT, quit);
100 	signal(SIGQUIT, quit);
101 	ntty = tty; ntty.sg_flags &= ~ECHO;
102 	ioctl(0, TIOCSETN, &ntty);
103 	printf("Key: ");
104 	if (fgets(s, sizeof s, stdin) == NULL) {
105 		putchar('\n');
106 		quit();
107 	}
108 	printf("\nAgain: ");
109 	/*
110 	 * Don't need EOF test here, if we get EOF, then s1 != s
111 	 * and the right things will happen.
112 	 */
113 	(void) fgets(s1, sizeof s1, stdin);
114 	putchar('\n');
115 	if (strcmp(s1, s)) {
116 		putchar(07);
117 		stty(0, &tty);
118 		exit(1);
119 	}
120 	s[0] = 0;
121 
122 	/* Set signal handlers */
123 
124 	signal(SIGINT, hi);
125 	signal(SIGQUIT, hi);
126 	signal(SIGTSTP, hi);
127 	signal(SIGALRM, bye);
128 	ntimer.it_interval = zerotime;
129 	ntimer.it_value = timeout;
130 	setitimer(ITIMER_REAL, &ntimer, &otimer);
131 
132 	/* Header info */
133 
134 	printf ("lock: %s on %s. timeout in %d minutes\n",
135 		ttynam, hostname, sectimeout);
136 	printf("time now is %.20s", ap);
137 	if (tzn)
138 		printf("%s", tzn);
139 	printf("%s", ap+19);
140 
141 	/* wait */
142 
143 	for (;;) {
144 		printf("Key: ");
145 		if (fgets(s, sizeof s, stdin) == NULL) {
146 			clearerr(stdin);
147 			hi();
148 			continue;
149 		}
150 		if (strcmp(s1, s) == 0)
151 			break;
152 		if (pwd == (struct passwd *) 0 || pwd->pw_passwd[0] == '\0')
153 			break;
154 		ap = index(s, '\n');
155 		if (ap != NULL)
156 			*ap = '\0';
157 		if (strcmp(pwd->pw_passwd, crypt(s, pwd->pw_passwd)) == 0)
158 			break;
159 		printf("\07\n");
160 		if (ioctl(0, TIOCGETP, &ntty))
161 			exit(1);
162 	}
163 	ioctl(0, TIOCSETN, &tty);
164 	putchar('\n');
165 	exit (0);
166 usage:
167 	printf("Usage: lock [-timeout]\n");
168 	exit (1);
169 }
170 
171 /*
172  *	get out of here
173  */
174 
175 quit()
176 {
177 	ioctl(0, TIOCSETN, &tty);
178 	exit (0);
179 }
180 
181 bye()
182 {
183 	ioctl(0, TIOCSETN, &tty);
184 	printf("lock: timeout\n");
185 	exit (1);
186 }
187 
188 /*
189  *	tell the user we are waiting
190  */
191 
192 hi()
193 {
194 	long	curtime;
195 	struct timeval	timval;
196 	struct timezone	timzone;
197 
198 	gettimeofday(&timval, &timzone);
199 	curtime = timval.tv_sec;
200 	printf("lock: type in the unlock key. timeout in %d minutes\n",
201 		(nexttime-curtime)/60);
202 }
203