[net.sources] another gone.c

oscar@utcsrgv.UUCP (Oscar M. Nierstrasz) (02/23/84)

echo README
sed 's/^ //' > README << 'Rosebud'
 
 Here is another version of gone.c that will work on both Bezerkley UNIX
 and vanilla UNIX (I hope!).  Compile it with either
 
 	cc -DBSD gone.c -ljobs -o gone
 or
 	cc -DVANILLA gone.c -o gone
 
 An added feature is that gone will try to log you off if you do not
 return in 10 minutes (reasonable?).  For this to work you must set
 the environment variable $shellpid to $$ in your .login or .profile.
 
 This program was published here previously in a slightly different
 version as lk.c.
 
 Please send lots of mail to ...
 
 	Oscar Nierstrasz @ { allegra, ihnp4 ... }!utcsrgv!oscar
Rosebud
chmod 0644 README
echo gone.1
sed 's/^ //' > gone.1 << 'Rosebud'
 .TH GONE 1
 .UC
 .SH NAME
 gone \- lock a terminal
 .SH SYNOPSIS
 .B gone 
 [timeout]
 .SH DESCRIPTION
 .I Gone
 locks your terminal until you type in your login password.
 The default timeout period is 10 minutes.
 This can be increased to a maximum of 15 minutes.
 .PP
 A short description can be given as an argument to
 .I gone.
 For example:
 .IP
 gone to sunnier climes
 .PP
 or
 .IP
 gone but not forgotten
 .PP
 .I Gone
 uses your real password instead of an improvised one thus
 saving time and reducing embarrassment if it is forgotten.
 There is no "trap-door" password.
 The ^Z signal available in csh(1) is also caught by
 .I gone.
 .pp
 In order to use
 .I gone
 you must have the shell variable $shellpid available in your environment.
 If you are using "C" shell, put the line
 .IP
 setenv shellpid $$
 .PP
 in your .login file.
 With the Bourne shell, put the lines
 .IP
 shellpid=$$
 .br
 export shellpid
 .PP
 in your .profile.
 .SH NOTES
 .PP
 Compile with :
 .IP
 cc -DBSD gone.c -ljobs -o gone
 .PP
 if sigsys(2) is available.
 Otherwise use :
 .IP
 cc -DVANILLA gone.c -o gone
 .SH DIAGNOSTICS
 Tells you how many minutes are left to logout time.
 .br
 Quits if it can't find $shellpid.
 .SH BUGS
 You can fool
 .I gone
 by providing a bogus $shellpid.
 .I Gone
 can't properly log you off if you are su'ed to another user.
 .SH AUTHOR
 Oscar Nierstrasz at the University of Toronto.
 .SH SEE ALSO
 csh(1), sh(1), getuid(2), getpwent(3), crypt(3), environ(5), getenv(3),
 ioctl(2), signal(2), sigsys(2), sigset(2), alarm(2), kill(2).
Rosebud
chmod 0644 gone.1
echo gone.c
sed 's/^ //' > gone.c << 'Rosebud'
 
 /*
  * FILE:	GONE.C
  * AUTHOR:	Oscar Nierstrasz
  *
  * Usage:	gone [timeout]
  *
  * Locks the keyboard. 
  * Prevents idle fingers from mucking with
  * your terminal while you dash downstairs
  * to the versatec.
  *
  * Gone will timeout after at most 15 minutes.
  * (Default is 5 minutes.)
  * If you put the line
  *
  *	setenv shellpid=$$
  *
  * in your .login (with csh), gone will
  * automatically log you off upon a timeout.
  * (use export with sh -- see environ (5)
  *
  * Compile : 
  *	cc -DBSD gone.c -ljobs -o gone		(Berkeley UNIX)
  * or :
  *	cc -DVANILLA gone.c -o gone		(Vanilla UNIX)
  */
 
 
 #include <stdio.h>
 #include <sgtty.h>
 #include <signal.h>
 #include <pwd.h>
 
 #define	TRUE	1
 #define	FALSE	0
 #define	MAX	100
 #define	TIMEOUT	10	/* minutes */
 #define	MAXTIME	15
 #define	MINUTE	60
 #define	SHELL	"shellpid"
 #define	FOREVER	"forever"
 #define	LONG	"'Tis long, my love, but I shall wait for thee ... \n"
 #define	T	"... %d minutes\n"
 #define	T1	"Oh where, pray tell, could my true love be?\n"
 #define	BYE	"Alas!  I am forsaken!\nFarewell, farewell cruel world! ...\n"
 #define	LOCKED	"Keyboard locked; enter password to unlock\n"
 #define	BACK	"Back within %d minute%c\n"
 #define	BADPID	"Can't kill process %d\n"
 #define	BADPASS	"incorrect password\n"
 #define	BADCC	"Re-compile with -DBSD or -DVANILLA ...\n"
 #define	M1	"%cCan't find shell variable $%s\n\n"
 #define	M2	"In the C shell run:\n\tsetenv %s $$\n\n"
 #define	M3	"In the Bourne shell run:\n\t%s=$$\n\texport shellpid\n"
 #define	BELL	'\07'
 
 struct	passwd *getpwuid();
 char	*crypt(), *getenv();
 int	timeout, min=0, pid, nomsg = TRUE;
 
 main(argc,argv)
 int	argc;
 char	**argv;
 {
 	struct	passwd *pwptr;
 	char	*shell, p[MAX], pw[MAX], *try;
 	int	nullpw, locked = TRUE, forever = FALSE, badcc = TRUE;
 	int	checktime(), goodbye(), msg();
 
 #ifdef BSD
 	badcc = FALSE;
 #endif
 #ifdef VANILLA
 	badcc = FALSE;
 #endif
 	if (badcc) {
 		fprintf(stderr, BADCC);
 		exit(1);
 		}
 
 	if (argc == 2){
 		if (strcmp(argv[1], FOREVER) == 0)
 			forever = TRUE;
 		else {
 			timeout = atoi(argv[1]);
 			if (timeout == 0)
 				timeout = TIMEOUT;
 			if (timeout > MAXTIME)
 				timeout = MAXTIME;
 			}
 	}
 	else	timeout = TIMEOUT;
 
 	if ((shell = getenv(SHELL)) == NULL) {
 		fprintf(stderr, M1, BELL, SHELL);
 		fprintf(stderr, M2, SHELL);
 		fprintf(stderr, M3, SHELL);
 		exit(1);
 	}
 	else	pid = atoi(shell); /* process id of login shell */
 
 #ifdef BSD
 	sigset(SIGINT, msg);
 	sigset(SIGQUIT, msg);
 	sigset(SIGTSTP, msg);
 	sigset(SIGALRM, checktime);
 	sigset(SIGHUP, goodbye);
 #endif
 
 #ifdef VANILLA
 	signal(SIGINT, msg);
 	signal(SIGQUIT, msg);
 	signal(SIGALRM, checktime);
 	signal(SIGHUP, goodbye);
 #endif
 	echo_off();
 
 	pwptr = getpwuid(getuid());
 	strcpy(pw,pwptr->pw_passwd); /* get encrypted password */
 	nullpw = strlen(pw) == 0; /* TRUE if no password */
 
 	if (forever)
 		fprintf(stderr, LONG);
 	else {
 		fprintf(stderr, BACK, timeout,
 			(timeout==1)?' ':'s');
 		alarm(MINUTE);
 		}
 	while(locked){
 		getline(p,stdin);
 		if (nullpw) {
 			if (strlen(p) == 0)
 				locked = FALSE;
 			else	printf(BADPASS);
 		}
 		else{
 			try = crypt(p,pw); /* test the password */
 			if (strcmp(try,pw) == 0)
 				locked = FALSE;
 			else	printf(BADPASS);
 		}
 	}
 	echo_on();
 }
 
 checktime(){
 	int	t;
 
 	min++;
 	t = timeout - min;
 	if (t <= 0)
 		goodbye();
 	else if (t == 1)
 		fprintf(stderr, T1);
 	else	fprintf(stderr, T, t);
 #ifdef BSD
 	sigset(SIGALRM, checktime); /* reset SIGALRM */
 #endif
 #ifdef VANILLA
 	signal(SIGALRM, checktime); /* reset SIGALRM */
 #endif
 	alarm(MINUTE);
 }
 
 goodbye(){
 	echo_on();
 	putchar(BELL);
 	fprintf(stderr, BYE);
 	if (pid != NULL)
 		if (kill(pid, SIGKILL) != 0) /* shouldn't happen */
 			fprintf(stderr, BADPID, pid);
 	exit(0);
 }
 
 msg(){
 #ifdef VANILLA
 	signal(SIGINT, msg);
 	signal(SIGQUIT, msg);
 #endif
 	if (nomsg){
 		fprintf(stderr, LOCKED);
 		nomsg = FALSE;
 	}
 }
 
 getline(s,file)
 char	*s;
 FILE	*file;
 {
 	/* get a line of input up to MAX characters	*/
 	/* return length of input or EOF or MAX		*/
 	int	i=0;
 	char	c;
 
 	while ((c=fgetc(file)) != '\n'){
 		if (c == EOF){
 			rewind(file);
 			return(EOF);
 		}
 		s[i] = c;
 		i++;
 		if (i == MAX){
 			s[i-1] = '\0';
 			return(MAX);
 		}
 	}
 	s[i] = '\0';
 	return(i);
 }
 echo_off()
 {
 	struct sgttyb ttybuf;
 
 	gtty(0, &ttybuf);
 	ttybuf.sg_flags &= ~ECHO;
 	stty(0, &ttybuf);
 }
 echo_on()
 {
 	struct sgttyb ttybuf;
 
 	gtty(0, &ttybuf);
 	ttybuf.sg_flags |= ECHO;
 	stty(0, &ttybuf);
 }
Rosebud
chmod 0644 gone.c