xref: /csrg-svn/usr.bin/lock/lock.c (revision 36292)
121565Sdist /*
233161Sbostic  * Copyright (c) 1980, 1987 Regents of the University of California.
333161Sbostic  * All rights reserved.
433161Sbostic  *
533161Sbostic  * Redistribution and use in source and binary forms are permitted
634911Sbostic  * provided that the above copyright notice and this paragraph are
734911Sbostic  * duplicated in all such forms and that any documentation,
834911Sbostic  * advertising materials, and other materials related to such
934911Sbostic  * distribution and use acknowledge that the software was developed
1034911Sbostic  * by the University of California, Berkeley.  The name of the
1134911Sbostic  * University may not be used to endorse or promote products derived
1234911Sbostic  * from this software without specific prior written permission.
1334911Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1434911Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1534911Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1621565Sdist  */
1721565Sdist 
1812989Ssam #ifndef lint
1921565Sdist char copyright[] =
2033161Sbostic "@(#) Copyright (c) 1980, 1987 Regents of the University of California.\n\
2121565Sdist  All rights reserved.\n";
2233161Sbostic #endif /* not lint */
2312989Ssam 
2421565Sdist #ifndef lint
25*36292Sbostic static char sccsid[] = "@(#)lock.c	5.7 (Berkeley) 12/05/88";
2633161Sbostic #endif /* not lint */
2721565Sdist 
2812989Ssam /*
2930956Sbostic  * Lock a terminal up until the given key is entered, until the root
3030956Sbostic  * password is entered, or the given interval times out.
3116239Sralph  *
3216239Sralph  * Timeout interval is by default TIMEOUT, it can be changed with
3316239Sralph  * an argument of the form -time where time is in minutes
3412989Ssam  */
3516239Sralph 
3630652Sbostic #include <sys/param.h>
375748Sroot #include <sys/stat.h>
3816239Sralph #include <sys/time.h>
3930652Sbostic #include <sys/signal.h>
4030652Sbostic #include <pwd.h>
411041Sbill #include <sgtty.h>
4230652Sbostic #include <stdio.h>
4332615Sbostic #include <ctype.h>
441041Sbill 
4530956Sbostic #define	TIMEOUT	15
461041Sbill 
4730652Sbostic int	quit(), bye(), hi();
4816239Sralph 
4930652Sbostic struct timeval	timeout;
5030652Sbostic struct timeval	zerotime;
5116239Sralph struct sgttyb	tty, ntty;
5230956Sbostic long	nexttime;			/* keep the timeout time */
5316239Sralph 
5430956Sbostic /*ARGSUSED*/
5530956Sbostic main(argc, argv)
56*36292Sbostic 	int argc;
57*36292Sbostic 	char **argv;
581041Sbill {
59*36292Sbostic 	extern char *optarg;
60*36292Sbostic 	extern int optind;
61*36292Sbostic 	struct passwd *root_pwd, *my_pwd;
62*36292Sbostic 	struct timeval timval;
63*36292Sbostic 	struct itimerval ntimer, otimer;
64*36292Sbostic 	struct tm *timp;
65*36292Sbostic 	int ch, sectimeout, use_mine;
66*36292Sbostic 	char *ttynam, *ap, *tzn;
67*36292Sbostic 	char hostname[MAXHOSTNAMELEN], s[BUFSIZ], s1[BUFSIZ];
68*36292Sbostic 	char *crypt(), *index(), *ttyname();
691041Sbill 
70*36292Sbostic 	use_mine = 0;
71*36292Sbostic 	sectimeout = TIMEOUT;
72*36292Sbostic 	while ((ch = getopt(argc, argv, "pt:")) != EOF)
73*36292Sbostic 		switch((char)ch) {
74*36292Sbostic 		case 't':
75*36292Sbostic 			if ((sectimeout = atoi(optarg)) <= 0)
76*36292Sbostic 				exit(0);
77*36292Sbostic 			break;
78*36292Sbostic 		case 'p':
79*36292Sbostic 			use_mine = 1;
80*36292Sbostic 			break;
81*36292Sbostic 		case '?':
82*36292Sbostic 		default:
83*36292Sbostic 			fputs("usage: lock [-p] [-t timeout]\n", stderr);
84*36292Sbostic 			exit(1);
8516239Sralph 	}
8616239Sralph 	timeout.tv_sec = sectimeout * 60;
8716239Sralph 
8816239Sralph 	/* get information for header */
8912989Ssam 	if (ioctl(0, TIOCGETP, &tty))
901041Sbill 		exit(1);
9116239Sralph 	gethostname(hostname, sizeof(hostname));
9230652Sbostic 	if (!(ttynam = ttyname(0))) {
9330652Sbostic 		puts("lock: not a terminal?");
9430956Sbostic 		exit(1);
9516239Sralph 	}
9630652Sbostic 	if (gettimeofday(&timval, (struct timezone *)NULL)) {
9730652Sbostic 		perror("gettimeofday");
9830956Sbostic 		exit(1);
9930652Sbostic 	}
10016239Sralph 	nexttime = timval.tv_sec + (sectimeout * 60);
10116239Sralph 	timp = localtime(&timval.tv_sec);
10216239Sralph 	ap = asctime(timp);
10330652Sbostic 	tzn = timp->tm_zone;
10416239Sralph 
10530652Sbostic 	(void)signal(SIGINT, quit);
10630652Sbostic 	(void)signal(SIGQUIT, quit);
1071041Sbill 	ntty = tty; ntty.sg_flags &= ~ECHO;
10830652Sbostic 	(void)ioctl(0, TIOCSETP, &ntty);
10930652Sbostic 
11030956Sbostic 	if (!use_mine) {
11130956Sbostic 		/* get key and check again */
11230956Sbostic 		fputs("Key: ", stdout);
11330956Sbostic 		if (!gets(s, sizeof(s)))
11430956Sbostic 			quit();
11530956Sbostic 		fputs("\nAgain: ", stdout);
11630956Sbostic 		/*
11730956Sbostic 		 * Don't need EOF test here, if we get EOF, then s1 != s
11830956Sbostic 		 * and the right things will happen.
11930956Sbostic 		 */
12030956Sbostic 		(void)gets(s1, sizeof(s1));
12130956Sbostic 		putchar('\n');
12230956Sbostic 		if (strcmp(s1, s)) {
12330956Sbostic 			puts("\07lock: passwords didn't match.");
12430956Sbostic 			ioctl(0, TIOCSETP, &tty);
12530956Sbostic 			exit(1);
12630956Sbostic 		}
12730956Sbostic 		s[0] = NULL;
1281041Sbill 	}
12916239Sralph 
13030956Sbostic 	/* set signal handlers */
13130652Sbostic 	(void)signal(SIGINT, hi);
13230652Sbostic 	(void)signal(SIGQUIT, hi);
13330652Sbostic 	(void)signal(SIGTSTP, hi);
13430652Sbostic 	(void)signal(SIGALRM, bye);
13530652Sbostic 
13616239Sralph 	ntimer.it_interval = zerotime;
13716239Sralph 	ntimer.it_value = timeout;
13816239Sralph 	setitimer(ITIMER_REAL, &ntimer, &otimer);
13916239Sralph 
14030956Sbostic 	/* header info */
14130652Sbostic 	printf ("lock: %s on %s. timeout in %d minutes\ntime now is %.20s%s%s",
14230956Sbostic 		ttynam, hostname, sectimeout, ap, tzn, ap + 19);
14316239Sralph 
14416239Sralph 	/* wait */
14530956Sbostic 	root_pwd = getpwuid(0);
14630956Sbostic 	if (use_mine)
14730956Sbostic 		my_pwd = getpwuid(getuid());
14830956Sbostic 	for (;;) {
14930956Sbostic 		fputs("Key: ", stdout);
15030956Sbostic 		if (!gets(s, sizeof(s))) {
15116599Skre 			clearerr(stdin);
15216599Skre 			hi();
15316599Skre 			continue;
15416599Skre 		}
15530956Sbostic 		if (use_mine) {
15630956Sbostic 			if (!my_pwd || !*my_pwd->pw_passwd || !strcmp(my_pwd->pw_passwd, crypt(s, my_pwd->pw_passwd)))
15730956Sbostic 				break;
15830956Sbostic 		}
15930956Sbostic 		else if (!strcmp(s1, s))
1601041Sbill 			break;
16130956Sbostic 		if (!root_pwd || !*root_pwd->pw_passwd || !strcmp(root_pwd->pw_passwd, crypt(s, root_pwd->pw_passwd)))
16230956Sbostic 			break;
16330652Sbostic 		puts("\07");
16412989Ssam 		if (ioctl(0, TIOCGETP, &ntty))
1651041Sbill 			exit(1);
1661041Sbill 	}
16716239Sralph 	putchar('\n');
16830652Sbostic 	quit();
1691041Sbill }
17016239Sralph 
17130652Sbostic static
17230652Sbostic hi()
17330652Sbostic {
174*36292Sbostic 	struct timeval timval;
17530652Sbostic 
17630652Sbostic 	if (!gettimeofday(&timval, (struct timezone *)NULL))
17730956Sbostic 	    printf("lock: type in the unlock key. timeout in %ld:%ld minutes\n",
17830956Sbostic 	    (nexttime - timval.tv_sec) / 60, (nexttime - timval.tv_sec) % 60);
17930652Sbostic }
18030652Sbostic 
18130652Sbostic static
18216239Sralph quit()
18316239Sralph {
18430652Sbostic 	(void)ioctl(0, TIOCSETP, &tty);
18530956Sbostic 	exit(0);
18616239Sralph }
18716239Sralph 
18830652Sbostic static
18916239Sralph bye()
19016239Sralph {
19130652Sbostic 	(void)ioctl(0, TIOCSETP, &tty);
19230652Sbostic 	puts("lock: timeout");
19330956Sbostic 	exit(1);
19416239Sralph }
195