home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************/
- /** **/
- /** LOCK.C (c) Antony Joseph O'Sullivan 09th December 1988 **/
- /** **/
- /** Updated to include flags 21st September 1989 **/
- /** Updated to include stats 18th December 1989 **/
- /** **/
- /** Antony O'Sullivan | ajos1@uk.ac.reading.cs.csug **/
- /** Dept of Computer Sci. | ajos1%rosemary@uk.ac.reading.cs.onion **/
- /** Reading University | ajos1%uk.ac.reading.cs.csug@uk.ac.nsfnet-relay **/
- /** U.K. | ajos@uk.ac.ed.cs.tardis **/
- /** **/
- /****************************************************************************/
- #include <signal.h>
- #include <stdio.h>
- #include <time.h>
- #include <pwd.h>
-
- /* -------------------------- Begin User Varibles -------------------------- */
-
- /*
- * Number of seconds until timeout
- * #define LOGOUT 900
- * #define MAX 3600
- */
-
- #define LOGOUT 300 /* 05 minute default */
- #define MAX 900 /* 15 minute maximum */
-
- /* --------------------------- End User Varibles --------------------------- */
-
- #define MAXFILE 40 /* Maximum length for pathname */
- #define MAXLINE 30 /* Maximum of lines to be printed */
-
- extern char *optarg;
- extern int optind, opterr;
-
- struct passwd *pwd;
- int attempt = 0, info = 0, line = 0;
- int hlp(), logout(), message(), texit(), ver(), warning();
- char *crypt(), *getpass(), *print(), *rind();
- long in, now, out, tim;
-
- /*
- * Varibles for argument handling
- */
- int rc = 0, tm = 0, hp = 0, kl = 0, vr = 0;
- static char ch, rcfile[MAXFILE];
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- /*
- * varibles for program
- */
- char *pass;
- int count;
-
- rcfile[0] = 0;
-
- /*
- * Redirect some of the software interrupt routines
- */
- signal(SIGALRM, logout);
- signal(SIGINT, message);
- signal(SIGQUIT, message);
- signal(SIGTSTP, message);
- signal(SIGTERM, message);
-
- /*
- * The line below allows a tidy kill with signal 1, by running 'texit' but
- * this is risky if signal 1 can be produced on a keyboard
- * signal(SIGHUP,texit); - DISABLED
- */
-
- /*
- * WARNING - The next 4 lines of code must be run before any reference to
- * 'pwd' can be made, else you may have big hassles. :-)
- *
- * See if name exists. Use of getpwuid is more consistent than getlogin in
- * determining the name of the user, (ie) works in SU and SCREEN.
- */
-
- if ((pwd = getpwuid(getuid())) == NULL) {
- fprintf(stderr, "Lock: cannot get user name, check environment\n");
- exit(-1);
- }
- /*
- * Sort out the arguments and so on.
- */
- opterr = 0;
- while ((ch = getopt(argc, argv, "t:T:f:F:hHvVkK")) != EOF) {
- switch (ch) {
- case 'h':
- case 'H':
- hp = 1;
- break;
- case 'v':
- case 'V':
- vr = 1;
- break;
- case 'k':
- case 'K':
- if (getuid() == 0) {
- printf("Superuser can not run lock with a 'killall' flag.\n");
- sleep(3);
- } else {
- kl = 1;
- }
- break;
- case 't':
- case 'T':
- tim = atoi(optarg);
- tm = 1;
- break;
- case 'f':
- case 'F':
- count = 0;
- while ((*optarg != 0) || (count < MAXFILE)) {
- rcfile[count++] = *optarg++;
- }
- rcfile[count] = 0;
- rc = 1;
- break;
- default:
- break;
- }
- }
-
- /*
- * If version flag given then run 'version'
- */
- if (vr == 1)
- ver();
-
- /*
- * If help flag given then run 'hlp'
- */
- if (hp == 1)
- hlp();
-
- /*
- * If version or help flag is given then quit
- */
- if (hp == 1 || vr == 1)
- exit(0);
-
- /*
- * Set up timer to produce timeout signal If time flag set, then check
- * ranges
- */
- if (tm == 1) {
- if (tim <= 0 || tim > MAX) {
- printf("\nSorry, the time limits are between 1 and %d seconds\n", MAX);
- printf("Resetting time limit to default value.....\n");
- tim = LOGOUT;
- sleep(3);
- }
- } else {
- /*
- * Else just use defined time :- LOGOUT
- */
- tim = LOGOUT;
- }
-
- /*
- * Now timeout is known then set the alarm
- */
- alarm(tim);
- out = (time(&in) + tim);
-
- /*
- * Display 'title' screen
- */
- screen(rcfile, pwd->pw_dir);
- printf("Lock times out in %s.\n", print(tim));
-
-
- /*
- * Set important varibles to 0
- */
- count = 0;
- attempt = 0;
- info = 0;
- line = 0;
-
- /*
- * Loop until password entered
- */
- for (;;) {
- pass = getpass("Passwd: ");
- time(&now);
-
- /*
- * If password entered, exit
- */
- if (strcmp(crypt(pass, pwd->pw_passwd), pwd->pw_passwd) == NULL)
- break;
-
- /*
- * Display 'help' screen
- */
- if ((!strcmp(pass, "help")) || (pass[0] == '?')) {
- printf("\n User: %s <%s>", pwd->pw_gecos, pwd->pw_name);
- printf(" %s\n", ctime(&now));
- printf("\t Lock began at %s", ctime(&in));
- printf("\t Lock stops at %s", ctime(&out));
- printf("\t Times out in %s.\n\n", print(out - now));
- printf("\t The Passwd is the password you log in with.\n\n");
- printf("\t If you are unable to unlock your terminal,\n");
- printf("\tLogin on another terminal and kill this one off.\n");
- printf("\t\t The process number is %d.\n", getpid());
- printf("\t\t (eg) 'kill -9 %d'\n\n", getpid());
- if (count == 4)
- count--;
- info++;
- }
- /*
- * If 5 attempts made at password, redraw 'title' screen
- */
- if (++count == 5) {
- count = 0;
- screen(rcfile, pwd->pw_dir);
- }
- /*
- * Warn if time to timeout is less than 3 minutes
- */
- if (((out - now) / 60) < 3) {
- printf("Times out in %s!!\n", print(out - now));
- putchar(07);
- }
- attempt++;
- fflush(stdout);
- }
-
- /*
- * Greet their return
- */
- printf("\nHello ");
- while (*pwd->pw_gecos && *pwd->pw_gecos != ' ')
- printf("%c", *pwd->pw_gecos++);
- printf("\n\n");
- /*
- * Print warnings of incorrect passwd attempts
- */
- warning();
- }
-
- /*
- * Test if a character is a straight text character, if it is then return its
- * value, else return EOF, so file reading is terminated.
- */
- int
- format(ch, file)
- int ch;
- char *file;
- {
- if ((ch == '\n') || (ch == EOF) || (ch >= 32 && ch <= 126)) {
- if (ch == '\n')
- line++;
- if (line <= MAXLINE) {
- return (ch);
- } else {
- return (EOF);
- }
- } else {
- printf("\nTwat! '%s' is not a straight text file!!!\n", rind(file));
- return (EOF);
- }
- }
-
- /*
- * Hlp (Help) function - Gives usage
- */
- int
- hlp()
- {
- printf("\n\tLock : reserves or \'locks\' a terminal for up to ");
- printf("%s.\n", (LOGOUT > MAX) ? print(LOGOUT) : print(MAX));
- printf("\tUsage: lock [-f file] [-t time] [-h] [-k] [-v]\n\n");
- return (0);
- }
-
- /*
- * Timeout function
- */
- int
- logout()
- {
- register int i, c, p;
-
- for (i = 0; i < 30; i++)
- printf("\n");
- printf("Lock: lock timed out after %s.\n", print(tim));
-
- printf("\n\n Attempting Logout - Please wait.\n\n");
-
- /*
- * Reset terminal, in case of lock from a sub-shell
- */
- system("reset");
-
- /*
- * If no 'killall' flag, then...
- */
- if (kl == 0) {
- /*
- * Kill lock's parent, hopefully the login shell of the user
- */
- kill(getppid(), 9);
- } else {
- /*
- * else killall.....
- *
- * Kill all processes from 1 to 30000, except 'lock' and its parent shell.
- * Then kill parent shell to finish off
- */
- c = getpid();
- p = getppid();
- for (i = 1; i <= 30000; i++) {
- if (i != c && i != p) {
- kill(i, 9);
- }
- }
- kill(p, 9);
- /*
- * NOT REACHED
- *
- */
- kill(c, 9);
- exit(0);
- }
- }
-
- /*
- * Other software interrupt handler
- *
- * Ie traps CRTL-C,Z,D, etc
- *
- */
- int
- message()
- {
- fprintf(stderr, "Lock: Type in passwd. Times out in %s.\n", print(out - time(&now)));
- fflush(stderr);
- }
-
- /*
- * Return the time supplied in hours and minutes in a string
- */
- char *
- print(t)
- long t;
- {
- static char str[30];
- if ((t / 60) == 1) {
- sprintf(str, "%d minute %d%d seconds", t / 60, (t % 60) / 10, (t % 60) % 10);
- } else {
- sprintf(str, "%d minutes %d%d seconds", t / 60, (t % 60) / 10, (t % 60) % 10);
- }
- return (str);
- }
-
- /*
- * Return a filename from a given pathname
- */
- char *
- rind(str)
- char *str;
- {
- static char res[MAXFILE];
- int a = 0;
- while (*str != 0) {
- if (*str == '/') {
- a = 0;
- } else {
- res[a++] = *str;
- }
- str++;
- }
- res[a] = 0;
- return (res);
- }
-
- /*
- * Display lock 'title' screen. Either [-f file], $HOME/.lockrc or default
- */
- screen(myfile, dir)
- char *dir, *myfile;
- {
- FILE *inf;
- static char file[100];
- int ch, count, format();
-
- for (count = 0; count < 30; count++)
- printf("\n");
- sprintf(file, "%s%s", dir, "/.lockrc");
-
- /*
- * If "<myfile>" exists, print it first
- */
- if ((inf = fopen(myfile, "r")) != NULL) {
- while ((ch = format(getc(inf), myfile)) != EOF)
- printf("%c", ch);
- printf("\n");
- fclose(inf);
- }
- /*
- * Else if $HOME/.lockrc exists, print it
- */
- else if ((inf = fopen(file, "r")) != NULL) {
- while ((ch = format(getc(inf), file)) != EOF)
- printf("%c", ch);
- printf("\n");
- fclose(inf);
- }
- /*
- * Otherwise display default screen
- */
- else {
- printf(" PLEASE LEAVE THIS TERMINAL -IT IS IN USE AT THE MOMENT.\n\n");
- printf(" KEEP OFF THE KEYBOARD - GONE TO THE PRINTER ROOM.\n\n");
- printf(" Type In Your Password to use Terminal\n");
- printf(" (type ? for help)\n");
- printf("\n\n\n\n\n\n\n");
- }
- fflush(stdout);
- }
-
- /*
- * Tidy Exit function that exits lock when it catches a certain signal
- *
- * This is not currently used, I think it is a bit to dangerous, a user
- * might unlock a terminal from somewhere else on campus and leave
- * themselves open to anything.
- */
- texit()
- {
- int i;
-
- for (i = 0; i < 30; i++)
- printf("\n");
- printf("Lock: User interupt with external signal.\n");
-
- printf("\n\n Attempting Tidy exit - Please wait.\n\n");
-
- /*
- * Reset terminal, in case of lock from a sub-shell
- */
- system("reset");
- /*
- * Print warnings of incorrect passwd attempts
- */
- warning();
- /*
- * Kill lock
- */
- exit(0);
- }
-
- /*
- * Version function to printout 'version' message
- */
- int
- ver()
- {
- time(&now);
- printf("\n%s\n", ctime(&now));
- printf("\t*************************************************************\n");
- printf("\t** LOCK.C (c) Antony Joseph O'Sullivan 09th December 1988 **\n");
- printf("\t** Department of Computer Sience, **\n");
- printf("\t** Reading University, Berkshire, England. **\n");
- printf("\t** **\n");
- printf("\t** LOCK.C Updated to include flags 21st September 1989 **\n");
- printf("\t** LOCK.C Updated to include stats 18th December 1989 **\n");
- printf("\t*************************************************************\n");
- printf("\n");
- return (0);
- }
-
- /*
- * Print warnings of incorrect passwd attempts
- */
- int
- warning()
- {
- /*
- * Warn of more than one attempt of passwd and so on
- */
- if (attempt > 0) {
- printf("Warning:\n");
- if ((attempt - info) > 0) {
- printf("\tAttempts on password = %d\n", (attempt - info));
- }
- if (info > 0) {
- printf("\tAttempts on help (?) = %d\n", info);
- }
- printf("\n\n");
- }
- }
-