home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1241 / lock.c next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  11.5 KB  |  502 lines

  1. /****************************************************************************/
  2. /**                                                                        **/
  3. /** LOCK.C      (c)    Antony Joseph O'Sullivan        09th December  1988 **/
  4. /**                                                                        **/
  5. /**                    Updated to include flags        21st September 1989 **/
  6. /**                    Updated to include stats        18th December  1989 **/
  7. /**                                                                        **/
  8. /** Antony O'Sullivan     | ajos1@uk.ac.reading.cs.csug                    **/
  9. /** Dept of Computer Sci. | ajos1%rosemary@uk.ac.reading.cs.onion          **/
  10. /** Reading University    | ajos1%uk.ac.reading.cs.csug@uk.ac.nsfnet-relay **/
  11. /** U.K.                  | ajos@uk.ac.ed.cs.tardis                        **/
  12. /**                                                                        **/
  13. /****************************************************************************/
  14. #include <signal.h>
  15. #include <stdio.h>
  16. #include <time.h>
  17. #include <pwd.h>
  18.  
  19. /* -------------------------- Begin User Varibles -------------------------- */
  20.  
  21. /*
  22.  * Number of seconds until timeout
  23.  * #define LOGOUT 900
  24.  * #define MAX    3600
  25.  */
  26.  
  27. #define LOGOUT 300        /* 05 minute default */
  28. #define MAX 900            /* 15 minute maximum */
  29.  
  30. /* --------------------------- End User Varibles --------------------------- */
  31.  
  32. #define MAXFILE 40        /* Maximum length for pathname */
  33. #define MAXLINE 30        /* Maximum of lines to be printed */
  34.  
  35. extern char *optarg;
  36. extern int optind, opterr;
  37.  
  38. struct passwd *pwd;
  39. int attempt = 0, info = 0, line = 0;
  40. int hlp(), logout(), message(), texit(), ver(), warning();
  41. char *crypt(), *getpass(), *print(), *rind();
  42. long in, now, out, tim;
  43.  
  44. /*
  45.  * Varibles for argument handling
  46.  */
  47. int rc = 0, tm = 0, hp = 0, kl = 0, vr = 0;
  48. static char ch, rcfile[MAXFILE];
  49.  
  50. main(argc, argv)
  51.    int argc;
  52.    char **argv;
  53. {
  54.    /*
  55.     * varibles for program
  56.     */
  57.    char *pass;
  58.    int count;
  59.  
  60.    rcfile[0] = 0;
  61.  
  62.    /*
  63.     * Redirect some of the software interrupt routines
  64.     */
  65.    signal(SIGALRM, logout);
  66.    signal(SIGINT, message);
  67.    signal(SIGQUIT, message);
  68.    signal(SIGTSTP, message);
  69.    signal(SIGTERM, message);
  70.  
  71.    /*
  72.     * The line below allows a tidy kill with signal 1, by running 'texit' but
  73.     * this is risky if signal 1 can be produced on a keyboard
  74.     * signal(SIGHUP,texit); - DISABLED
  75.     */
  76.  
  77.    /*
  78.     * WARNING - The next 4 lines of code must be run before any reference to
  79.     * 'pwd' can be made, else you may have big hassles. :-)
  80.     * 
  81.     * See if name exists. Use of getpwuid is more consistent than getlogin in
  82.     * determining the name of the user, (ie) works in SU and SCREEN.
  83.     */
  84.  
  85.    if ((pwd = getpwuid(getuid())) == NULL) {
  86.       fprintf(stderr, "Lock: cannot get user name, check environment\n");
  87.       exit(-1);
  88.    }
  89.    /*
  90.     * Sort out the arguments and so on.
  91.     */
  92.    opterr = 0;
  93.    while ((ch = getopt(argc, argv, "t:T:f:F:hHvVkK")) != EOF) {
  94.       switch (ch) {
  95.       case 'h':
  96.       case 'H':
  97.      hp = 1;
  98.      break;
  99.       case 'v':
  100.       case 'V':
  101.      vr = 1;
  102.      break;
  103.       case 'k':
  104.       case 'K':
  105.      if (getuid() == 0) {
  106.         printf("Superuser can not run lock with a 'killall' flag.\n");
  107.         sleep(3);
  108.      } else {
  109.         kl = 1;
  110.      }
  111.      break;
  112.       case 't':
  113.       case 'T':
  114.      tim = atoi(optarg);
  115.      tm = 1;
  116.      break;
  117.       case 'f':
  118.       case 'F':
  119.      count = 0;
  120.      while ((*optarg != 0) || (count < MAXFILE)) {
  121.         rcfile[count++] = *optarg++;
  122.      }
  123.      rcfile[count] = 0;
  124.      rc = 1;
  125.      break;
  126.       default:
  127.      break;
  128.       }
  129.    }
  130.  
  131.    /*
  132.     * If version flag given then run 'version'
  133.     */
  134.    if (vr == 1)
  135.       ver();
  136.  
  137.    /*
  138.     * If help flag given then run 'hlp'
  139.     */
  140.    if (hp == 1)
  141.       hlp();
  142.  
  143.    /*
  144.     * If version or help flag is given then quit
  145.     */
  146.    if (hp == 1 || vr == 1)
  147.       exit(0);
  148.  
  149.    /*
  150.     * Set up timer to produce timeout signal If time flag set, then check
  151.     * ranges
  152.     */
  153.    if (tm == 1) {
  154.       if (tim <= 0 || tim > MAX) {
  155.      printf("\nSorry, the time limits are between 1 and %d seconds\n", MAX);
  156.      printf("Resetting time limit to default value.....\n");
  157.      tim = LOGOUT;
  158.      sleep(3);
  159.       }
  160.    } else {
  161.       /*
  162.        * Else just use defined time :- LOGOUT
  163.        */
  164.       tim = LOGOUT;
  165.    }
  166.  
  167.    /*
  168.     * Now timeout is known then set the alarm
  169.     */
  170.    alarm(tim);
  171.    out = (time(&in) + tim);
  172.  
  173.    /*
  174.     * Display 'title' screen
  175.     */
  176.    screen(rcfile, pwd->pw_dir);
  177.    printf("Lock times out in %s.\n", print(tim));
  178.  
  179.  
  180.    /*
  181.     * Set important varibles to 0
  182.     */
  183.    count = 0;
  184.    attempt = 0;
  185.    info = 0;
  186.    line = 0;
  187.  
  188.    /*
  189.     * Loop until password entered
  190.     */
  191.    for (;;) {
  192.       pass = getpass("Passwd: ");
  193.       time(&now);
  194.  
  195.       /*
  196.        * If password entered, exit
  197.        */
  198.       if (strcmp(crypt(pass, pwd->pw_passwd), pwd->pw_passwd) == NULL)
  199.      break;
  200.  
  201.       /*
  202.        * Display 'help' screen
  203.        */
  204.       if ((!strcmp(pass, "help")) || (pass[0] == '?')) {
  205.      printf("\n    User: %s <%s>", pwd->pw_gecos, pwd->pw_name);
  206.      printf("  %s\n", ctime(&now));
  207.      printf("\t   Lock began at  %s", ctime(&in));
  208.      printf("\t   Lock stops at  %s", ctime(&out));
  209.      printf("\t     Times out in %s.\n\n", print(out - now));
  210.      printf("\t  The Passwd is the password you log in with.\n\n");
  211.      printf("\t   If you are unable to unlock your terminal,\n");
  212.      printf("\tLogin on another terminal and kill this one off.\n");
  213.      printf("\t\t The process number is %d.\n", getpid());
  214.      printf("\t\t     (eg) 'kill -9 %d'\n\n", getpid());
  215.      if (count == 4)
  216.         count--;
  217.      info++;
  218.       }
  219.       /*
  220.        * If 5 attempts made at password, redraw 'title' screen
  221.        */
  222.       if (++count == 5) {
  223.      count = 0;
  224.      screen(rcfile, pwd->pw_dir);
  225.       }
  226.       /*
  227.        * Warn if time to timeout is less than 3 minutes
  228.        */
  229.       if (((out - now) / 60) < 3) {
  230.      printf("Times out in %s!!\n", print(out - now));
  231.      putchar(07);
  232.       }
  233.       attempt++;
  234.       fflush(stdout);
  235.    }
  236.  
  237.    /*
  238.     * Greet their return
  239.     */
  240.    printf("\nHello ");
  241.    while (*pwd->pw_gecos && *pwd->pw_gecos != ' ')
  242.       printf("%c", *pwd->pw_gecos++);
  243.    printf("\n\n");
  244.    /*
  245.     * Print warnings of incorrect passwd attempts
  246.     */
  247.    warning();
  248. }
  249.  
  250. /*
  251.  * Test if a character is a straight text character, if it is then return its
  252.  * value, else return EOF, so file reading is terminated.
  253.  */
  254. int
  255. format(ch, file)
  256.    int ch;
  257.    char *file;
  258. {
  259.    if ((ch == '\n') || (ch == EOF) || (ch >= 32 && ch <= 126)) {
  260.       if (ch == '\n')
  261.      line++;
  262.       if (line <= MAXLINE) {
  263.      return (ch);
  264.       } else {
  265.      return (EOF);
  266.       }
  267.    } else {
  268.       printf("\nTwat! '%s' is not a straight text file!!!\n", rind(file));
  269.       return (EOF);
  270.    }
  271. }
  272.  
  273. /*
  274.  * Hlp (Help) function - Gives usage
  275.  */
  276. int
  277. hlp()
  278. {
  279.    printf("\n\tLock : reserves or \'locks\' a terminal for up to ");
  280.    printf("%s.\n", (LOGOUT > MAX) ? print(LOGOUT) : print(MAX));
  281.    printf("\tUsage: lock [-f file] [-t time] [-h] [-k] [-v]\n\n");
  282.    return (0);
  283. }
  284.  
  285. /*
  286.  * Timeout function
  287.  */
  288. int
  289. logout()
  290. {
  291.    register int i, c, p;
  292.  
  293.    for (i = 0; i < 30; i++)
  294.       printf("\n");
  295.    printf("Lock: lock timed out after %s.\n", print(tim));
  296.  
  297.    printf("\n\n      Attempting Logout - Please wait.\n\n");
  298.  
  299.    /*
  300.     * Reset terminal, in case of lock from a sub-shell
  301.     */
  302.    system("reset");
  303.  
  304.    /*
  305.     * If no 'killall' flag, then...
  306.     */
  307.    if (kl == 0) {
  308.       /*
  309.        * Kill lock's parent, hopefully the login shell of the user
  310.        */
  311.       kill(getppid(), 9);
  312.    } else {
  313.       /*
  314.        * else killall.....
  315.        * 
  316.        * Kill all processes from 1 to 30000, except 'lock' and its parent shell.
  317.        * Then kill parent shell to finish off
  318.        */
  319.       c = getpid();
  320.       p = getppid();
  321.       for (i = 1; i <= 30000; i++) {
  322.      if (i != c && i != p) {
  323.         kill(i, 9);
  324.      }
  325.       }
  326.       kill(p, 9);
  327.       /*
  328.        * NOT REACHED
  329.        * 
  330.        */
  331.       kill(c, 9);
  332.       exit(0);
  333.    }
  334. }
  335.  
  336. /*
  337.  * Other software interrupt handler
  338.  * 
  339.  * Ie traps CRTL-C,Z,D, etc
  340.  * 
  341.  */
  342. int
  343. message()
  344. {
  345.    fprintf(stderr, "Lock: Type in passwd. Times out in %s.\n", print(out - time(&now)));
  346.    fflush(stderr);
  347. }
  348.  
  349. /*
  350.  * Return the time supplied in hours and minutes in a string
  351.  */
  352. char *
  353. print(t)
  354.    long t;
  355. {
  356.    static char str[30];
  357.    if ((t / 60) == 1) {
  358.       sprintf(str, "%d minute %d%d seconds", t / 60, (t % 60) / 10, (t % 60) % 10);
  359.    } else {
  360.       sprintf(str, "%d minutes %d%d seconds", t / 60, (t % 60) / 10, (t % 60) % 10);
  361.    }
  362.    return (str);
  363. }
  364.  
  365. /*
  366.  * Return a filename from a given pathname
  367.  */
  368. char *
  369. rind(str)
  370.    char *str;
  371. {
  372.    static char res[MAXFILE];
  373.    int a = 0;
  374.    while (*str != 0) {
  375.       if (*str == '/') {
  376.      a = 0;
  377.       } else {
  378.      res[a++] = *str;
  379.       }
  380.       str++;
  381.    }
  382.    res[a] = 0;
  383.    return (res);
  384. }
  385.  
  386. /*
  387.  * Display lock 'title' screen. Either [-f file], $HOME/.lockrc or default
  388.  */
  389. screen(myfile, dir)
  390.    char *dir, *myfile;
  391. {
  392.    FILE *inf;
  393.    static char file[100];
  394.    int ch, count, format();
  395.  
  396.    for (count = 0; count < 30; count++)
  397.       printf("\n");
  398.    sprintf(file, "%s%s", dir, "/.lockrc");
  399.  
  400.    /*
  401.     * If "<myfile>" exists, print it first
  402.     */
  403.    if ((inf = fopen(myfile, "r")) != NULL) {
  404.       while ((ch = format(getc(inf), myfile)) != EOF)
  405.      printf("%c", ch);
  406.       printf("\n");
  407.       fclose(inf);
  408.    }
  409.    /*
  410.     * Else if $HOME/.lockrc exists, print it
  411.     */
  412.    else if ((inf = fopen(file, "r")) != NULL) {
  413.       while ((ch = format(getc(inf), file)) != EOF)
  414.      printf("%c", ch);
  415.       printf("\n");
  416.       fclose(inf);
  417.    }
  418.    /*
  419.     * Otherwise display default screen
  420.     */
  421.    else {
  422.       printf("           PLEASE LEAVE THIS TERMINAL -IT IS IN USE AT THE MOMENT.\n\n");
  423.       printf("              KEEP OFF THE KEYBOARD - GONE TO THE PRINTER ROOM.\n\n");
  424.       printf("                    Type In Your Password to use Terminal\n");
  425.       printf("                              (type ? for help)\n");
  426.       printf("\n\n\n\n\n\n\n");
  427.    }
  428.    fflush(stdout);
  429. }
  430.  
  431. /*
  432.  * Tidy Exit function that exits lock when it catches a certain signal
  433.  *
  434.  * This is not currently used, I think it is a bit to dangerous, a user
  435.  * might unlock a terminal from somewhere else on campus and leave
  436.  * themselves open to anything.
  437.  */
  438. texit()
  439. {
  440.    int i;
  441.  
  442.    for (i = 0; i < 30; i++)
  443.       printf("\n");
  444.    printf("Lock: User interupt with external signal.\n");
  445.  
  446.    printf("\n\n      Attempting Tidy exit - Please wait.\n\n");
  447.  
  448.    /*
  449.     * Reset terminal, in case of lock from a sub-shell
  450.     */
  451.    system("reset");
  452.    /*
  453.     * Print warnings of incorrect passwd attempts
  454.     */
  455.    warning();
  456.    /*
  457.     * Kill lock
  458.     */
  459.    exit(0);
  460. }
  461.  
  462. /*
  463.  * Version function to printout 'version' message
  464.  */
  465. int
  466. ver()
  467. {
  468.    time(&now);
  469.    printf("\n%s\n", ctime(&now));
  470.    printf("\t*************************************************************\n");
  471.    printf("\t** LOCK.C (c) Antony Joseph O'Sullivan 09th December  1988 **\n");
  472.    printf("\t**            Department of Computer Sience,               **\n");
  473.    printf("\t**            Reading University, Berkshire, England.      **\n");
  474.    printf("\t**                                                         **\n");
  475.    printf("\t** LOCK.C     Updated to include flags 21st September 1989 **\n");
  476.    printf("\t** LOCK.C     Updated to include stats 18th December  1989 **\n");
  477.    printf("\t*************************************************************\n");
  478.    printf("\n");
  479.    return (0);
  480. }
  481.  
  482. /*
  483.  * Print warnings of incorrect passwd attempts
  484.  */
  485. int
  486. warning()
  487. {
  488.    /*
  489.     * Warn of more than one attempt of passwd and so on
  490.     */
  491.    if (attempt > 0) {
  492.       printf("Warning:\n");
  493.       if ((attempt - info) > 0) {
  494.      printf("\tAttempts on password = %d\n", (attempt - info));
  495.       }
  496.       if (info > 0) {
  497.      printf("\tAttempts on help (?) = %d\n", info);
  498.       }
  499.       printf("\n\n");
  500.    }
  501. }
  502.