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