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