[net.unix-wizards] Lock

gorlick (03/25/83)

     Lock(1) suffers from the following deficiencies:
     (1)  it doesn't print `LOCKED' on the terminal as the manual
          page claims;
     (2)  it doesn't ignore the stop signal thereby permitting
          any user to regain control of the terminal;
     (3)  it doesn't timeout after a short period of time;
     (4)  if killed it leaves the terminal in a state with echo
          disabled;
     (5)  it contains a master password mechanism allowing any
          knowledgeable user to unlock any `locked' terminal;

The following source corrects the problems listed above.

-Michael Gorlick, TRW-

#include <stdio.h>
#include <sys/types.h>
#include <stat.h>
#include <signal.h>
#include <sgtty.h>

#define BELL '\007'
#define TIMEOUT (15*60)
#define MINUTES (TIMEOUT/60.)

struct sgttyb Old, New;
char *Whoami;
int wakeup();	/* alarm and terminate signal handler */

main(argc, argv)
int argc;
char *argv[];
{
	register int i;
	char s[BUFSIZ], t[BUFSIZ];

	Whoami = argv[0];
	for (i = 1; i <= NSIG; i++)
		switch (i) {
		case SIGHUP: case SIGALRM: case SIGTERM:
			continue;
		default:
			signal(i, SIG_IGN);
		}

	if (gtty(0, &Old))
		exit(1);
	New = Old;
	New.sg_flags &= ~ECHO;
	stty(0, &New);

	printf("Key: ");
	gets(s, sizeof s, stdin);
	printf("\nAgain: ");
	gets(t, sizeof t, stdin);
	putchar('\n');
	if (strcmp(s, t)) {
		putchar(BELL);
		stty(0, &Old);
		exit(1);
	}
	printf("LOCKED\n");
	signal(SIGALRM, wakeup);
	signal(SIGTERM, wakeup);
	alarm(TIMEOUT);

	for (;;) {
		gets(s, sizeof s, stdin);
		if (strcmp(s, t) == 0)
			break;
		putchar(BELL);
		if (gtty(0, &New))
			exit(1);
	}
	stty(0, &Old);
	exit(0);
}

wakeup (which)
int which;
{
	if (which == SIGALRM)
		printf("%s: timed out after %.1f minutes\n", Whoami, MINUTES);
	else if (which == SIGTERM)
		printf("%s: terminated\n", Whoami);
	stty(0, &Old);
	exit(1);
}