xref: /csrg-svn/usr.bin/lock/lock.c (revision 32615)
121565Sdist /*
221565Sdist  * Copyright (c) 1980 Regents of the University of California.
321565Sdist  * All rights reserved.  The Berkeley software License Agreement
421565Sdist  * specifies the terms and conditions for redistribution.
521565Sdist  */
621565Sdist 
712989Ssam #ifndef lint
821565Sdist char copyright[] =
921565Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
1021565Sdist  All rights reserved.\n";
11*32615Sbostic #endif /* !lint */
1212989Ssam 
1321565Sdist #ifndef lint
14*32615Sbostic static char sccsid[] = "@(#)lock.c	5.4 (Berkeley) 11/14/87";
15*32615Sbostic #endif /* !lint */
1621565Sdist 
1712989Ssam /*
1830956Sbostic  * Lock a terminal up until the given key is entered, until the root
1930956Sbostic  * password is entered, or the given interval times out.
2016239Sralph  *
2116239Sralph  * Timeout interval is by default TIMEOUT, it can be changed with
2216239Sralph  * an argument of the form -time where time is in minutes
2312989Ssam  */
2416239Sralph 
2530652Sbostic #include <sys/param.h>
265748Sroot #include <sys/stat.h>
2716239Sralph #include <sys/time.h>
2830652Sbostic #include <sys/signal.h>
2930652Sbostic #include <pwd.h>
301041Sbill #include <sgtty.h>
3130652Sbostic #include <stdio.h>
32*32615Sbostic #include <ctype.h>
331041Sbill 
3430956Sbostic #define	TIMEOUT	15
3530956Sbostic #define	YES	1
3630956Sbostic #define	NO	0
371041Sbill 
3830652Sbostic int	quit(), bye(), hi();
3916239Sralph 
4030652Sbostic struct timeval	timeout;
4130652Sbostic struct timeval	zerotime;
4216239Sralph struct sgttyb	tty, ntty;
4330956Sbostic long	nexttime;			/* keep the timeout time */
4416239Sralph 
4530956Sbostic /*ARGSUSED*/
4630956Sbostic main(argc, argv)
4730652Sbostic 	int	argc;
4830652Sbostic 	char	**argv;
491041Sbill {
5030956Sbostic 	struct passwd	*root_pwd, *my_pwd;
5116239Sralph 	struct timeval	timval;
5216239Sralph 	struct itimerval	ntimer, otimer;
5316239Sralph 	struct tm	*timp;
5430956Sbostic 	int	sectimeout = TIMEOUT,
5530956Sbostic 		use_mine;
5630652Sbostic 	char	*ttynam, *ap, *tzn,
5730956Sbostic 		hostname[MAXHOSTNAMELEN], s[BUFSIZ], s1[BUFSIZ],
5830652Sbostic 		*crypt(), *index(), *ttyname();
591041Sbill 
6030956Sbostic 	use_mine = NO;
6130956Sbostic 	for (++argv; *argv; ++argv) {
6230956Sbostic 		if (argv[0][0] != '-')
6330956Sbostic 			usage();
6430956Sbostic 		if (argv[0][1] == 'p')
6530956Sbostic 			use_mine = YES;
66*32615Sbostic 		else if (!isdigit(argv[0][1])) {
67*32615Sbostic 			fprintf(stderr, "lock: illegal option -- %c\n", argv[0][1]);
68*32615Sbostic 			usage();
69*32615Sbostic 		}
7030956Sbostic 		else if ((sectimeout = atoi(*argv + 1)) <= 0)
7130956Sbostic 			usage();
7216239Sralph 	}
7316239Sralph 	timeout.tv_sec = sectimeout * 60;
7416239Sralph 
7516239Sralph 	/* get information for header */
7612989Ssam 	if (ioctl(0, TIOCGETP, &tty))
771041Sbill 		exit(1);
7816239Sralph 	gethostname(hostname, sizeof(hostname));
7930652Sbostic 	if (!(ttynam = ttyname(0))) {
8030652Sbostic 		puts("lock: not a terminal?");
8130956Sbostic 		exit(1);
8216239Sralph 	}
8330652Sbostic 	if (gettimeofday(&timval, (struct timezone *)NULL)) {
8430652Sbostic 		perror("gettimeofday");
8530956Sbostic 		exit(1);
8630652Sbostic 	}
8716239Sralph 	nexttime = timval.tv_sec + (sectimeout * 60);
8816239Sralph 	timp = localtime(&timval.tv_sec);
8916239Sralph 	ap = asctime(timp);
9030652Sbostic 	tzn = timp->tm_zone;
9116239Sralph 
9230652Sbostic 	(void)signal(SIGINT, quit);
9330652Sbostic 	(void)signal(SIGQUIT, quit);
941041Sbill 	ntty = tty; ntty.sg_flags &= ~ECHO;
9530652Sbostic 	(void)ioctl(0, TIOCSETP, &ntty);
9630652Sbostic 
9730956Sbostic 	if (!use_mine) {
9830956Sbostic 		/* get key and check again */
9930956Sbostic 		fputs("Key: ", stdout);
10030956Sbostic 		if (!gets(s, sizeof(s)))
10130956Sbostic 			quit();
10230956Sbostic 		fputs("\nAgain: ", stdout);
10330956Sbostic 		/*
10430956Sbostic 		 * Don't need EOF test here, if we get EOF, then s1 != s
10530956Sbostic 		 * and the right things will happen.
10630956Sbostic 		 */
10730956Sbostic 		(void)gets(s1, sizeof(s1));
10830956Sbostic 		putchar('\n');
10930956Sbostic 		if (strcmp(s1, s)) {
11030956Sbostic 			puts("\07lock: passwords didn't match.");
11130956Sbostic 			ioctl(0, TIOCSETP, &tty);
11230956Sbostic 			exit(1);
11330956Sbostic 		}
11430956Sbostic 		s[0] = NULL;
1151041Sbill 	}
11616239Sralph 
11730956Sbostic 	/* set signal handlers */
11830652Sbostic 	(void)signal(SIGINT, hi);
11930652Sbostic 	(void)signal(SIGQUIT, hi);
12030652Sbostic 	(void)signal(SIGTSTP, hi);
12130652Sbostic 	(void)signal(SIGALRM, bye);
12230652Sbostic 
12316239Sralph 	ntimer.it_interval = zerotime;
12416239Sralph 	ntimer.it_value = timeout;
12516239Sralph 	setitimer(ITIMER_REAL, &ntimer, &otimer);
12616239Sralph 
12730956Sbostic 	/* header info */
12830652Sbostic 	printf ("lock: %s on %s. timeout in %d minutes\ntime now is %.20s%s%s",
12930956Sbostic 		ttynam, hostname, sectimeout, ap, tzn, ap + 19);
13016239Sralph 
13116239Sralph 	/* wait */
13230956Sbostic 	root_pwd = getpwuid(0);
13330956Sbostic 	if (use_mine)
13430956Sbostic 		my_pwd = getpwuid(getuid());
13530956Sbostic 	for (;;) {
13630956Sbostic 		fputs("Key: ", stdout);
13730956Sbostic 		if (!gets(s, sizeof(s))) {
13816599Skre 			clearerr(stdin);
13916599Skre 			hi();
14016599Skre 			continue;
14116599Skre 		}
14230956Sbostic 		if (use_mine) {
14330956Sbostic 			if (!my_pwd || !*my_pwd->pw_passwd || !strcmp(my_pwd->pw_passwd, crypt(s, my_pwd->pw_passwd)))
14430956Sbostic 				break;
14530956Sbostic 		}
14630956Sbostic 		else if (!strcmp(s1, s))
1471041Sbill 			break;
14830956Sbostic 		if (!root_pwd || !*root_pwd->pw_passwd || !strcmp(root_pwd->pw_passwd, crypt(s, root_pwd->pw_passwd)))
14930956Sbostic 			break;
15030652Sbostic 		puts("\07");
15112989Ssam 		if (ioctl(0, TIOCGETP, &ntty))
1521041Sbill 			exit(1);
1531041Sbill 	}
15416239Sralph 	putchar('\n');
15530652Sbostic 	quit();
1561041Sbill }
15716239Sralph 
15830652Sbostic static
15930652Sbostic hi()
16030652Sbostic {
16130652Sbostic 	struct timeval	timval;
16230652Sbostic 
16330652Sbostic 	if (!gettimeofday(&timval, (struct timezone *)NULL))
16430956Sbostic 	    printf("lock: type in the unlock key. timeout in %ld:%ld minutes\n",
16530956Sbostic 	    (nexttime - timval.tv_sec) / 60, (nexttime - timval.tv_sec) % 60);
16630652Sbostic }
16730652Sbostic 
16830652Sbostic static
16916239Sralph quit()
17016239Sralph {
17130652Sbostic 	(void)ioctl(0, TIOCSETP, &tty);
17230956Sbostic 	exit(0);
17316239Sralph }
17416239Sralph 
17530652Sbostic static
17616239Sralph bye()
17716239Sralph {
17830652Sbostic 	(void)ioctl(0, TIOCSETP, &tty);
17930652Sbostic 	puts("lock: timeout");
18030956Sbostic 	exit(1);
18116239Sralph }
18230956Sbostic 
18330956Sbostic static
18430956Sbostic usage()
18530956Sbostic {
186*32615Sbostic 	fputs("usage: lock [-p] [-timeout]\n", stderr);
18730956Sbostic 	exit(1);
18830956Sbostic }
189