SUMMARY: loggin out idled users

From: Alan K. Ho (librainc!ho@uunet.UU.NET)
Date: Fri Feb 14 1992 - 01:36:10 CST


Hi,

o.k. I think I've received all that I'm going to receive on the subject
of loggin out idled users even if they have openwin or sunview up with
a lock screen.

A couple of people suggested using the tcsh because it is a build
in feature to log out idled users.

***I have not tried this out...I don't know if it will work if you have a
   GUI up.

A couple of people actually sent me programs that they've written. I treid
one out and it worked great if I didn't have a GUI up. I think it monitored
the idle time of the login csh but not all the other csh (shelltools) that I
was working in. So, it logged me out even if I was still working. I'm sure
I can probably hack at the program to make it work when I get some time.

anyways, I will include a copy of the program.

thanks to:

bchivers
mann
fetrow
beig
sdo
phillips
eckhard

***********************************************************

/*
 * A program to sit quietly in the background and check for terminal
 * activity. Checks will be made once a minute. (Can be altered with
 * +arg.) If the terminal line has been idle more than 20 minutes
 * (can be altered with -arg), a system call will be made to kill the
 * parent process id. (So this should be run from the login shell.)
 *
 * This program will be useful if you loose your connection but your
 * session is not terminated. Written (stolen) 17 January 1992.
 *
 * Based on deadkill.c with modem code removed -- just kill the login
 * shell. deadkill.c was based directly on hangself.c, which in turn
 * is based heavily on my clock100 program (sleeps, checks activity,
 * and spits) and my hang_up program (spits to reset modem).
 *
 *
 * Brent Chivers Mail Stop Z268
 * Systems Engineer The MITRE Corporation
 * bchivers@mitre.org 7525 Colshire Drive
 * (703) 883-6734 McLean, VA 22102
 */

#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>

#define BELL "\007" /* ASCII bell character */
#define MINUTES * 60 /* convert to seconds (unit used by sleep) */
#define WARNINGS 3 /* number of warnings to give */

main (argc, argv)
char **argv;
{
    int check_time = 1; /* update interval (default 1 minute) */
    int hang_up_time = 20; /* try to hang up and reset the modem if idle this long */
    int check_secs; /* check_time in seconds */

    int parent; /* process id of shell that started us (we hope it's the login shell) */
    int pro; /* process id of forked child */
    char origlogin[20]; /* login name when started */
    char *getlogin(); /* method to obtain login name */
    char devname[20]; /* device file name */
    char *ttyname(); /* function to get device file name */
    struct stat stbuf; /* device status, especially access time */

    while (--argc > 0)
        {
        argv++;
        if (**argv == '-')
            {
            char *c = *argv;
            *c++; /* find character following "-" */
            if ((*c >= '0') && (*c <= '9'))
                hang_up_time = atoi (c);
              else
                badargs(*argv); /* print "bad argument message */
            }
          else if (**argv == '+')
            {
            char *c = *argv;
            *c++; /* find character following "+" */
            if ((*c >= '0') && (*c <= '9'))
                check_time = atoi (c);
              else
                badargs(*argv); /* print "bad argument message */
            }
          else if ((**argv >= '0') && (**argv <= '9'))
            hang_up_time = atoi (*argv);
          else
            badargs(*argv); /* print "bad argument message */
        }

    strcpy(origlogin,getlogin()); /* make note of original login */

    parent = getppid(); /* find out who started/owns us */
    pro = fork();

    if (pro)
        {
        printf ("Auto-Shell-Kill process created. PID: %d PPID: %d\n", pro, parent);
        printf ("Idle time will be checked "); /* we take special pains with singular/plural here */
        if (check_time == 1) printf ("once a minute");
                else printf ("every %d minutes", check_time);
#if (WARNINGS == 1)
        printf (".\nYou will receive a warning message after %d minutes of idle time.\n", hang_up_time);
#else
        printf (".\nYou will receive %d warning messages after %d minutes of idle time.\n", WARNINGS, hang_up_time);
#endif
        printf ("Process %d will be killed after %d minutes of idle time.\n",
            parent, ((WARNINGS * check_time) + hang_up_time));

        _exit(0);
        }

    strcpy(devname, ttyname(1)); /* get dev name */
    check_secs = check_time MINUTES; /* convert checking interval to seconds */
    hang_up_time = hang_up_time MINUTES; /* convert hang-up time limit to seconds */
                                                /* overwrite the minute value -- we don't need it anymore */
    while (1)
        {
        char thislogin[20]; /* current login name */
        char kill_command [40]; /* formatting buffer */
        register struct tm *nowt;
        long now, lastaction, diff;
        int idle; /* terminal busy? (boolean) */
        int warned; /* have we warned the user that we're going to kill the PPID (shell)? */
                                                /* it's nice to give a warning first, eh? */
        int i; /* loop counter */

        strcpy(thislogin,getlogin()); /* still logged in? */
        if (strcmp(origlogin, thislogin)) exit(0);

        time (&now);
        stat(devname, &stbuf); /* check terminal activity */
        lastaction = stbuf.st_atime;
        diff = now - lastaction; /* idle time in seconds */
        if (diff < 0) diff = 0;
        idle = (diff > hang_up_time);

        if (idle) /* if the line has been sitting idle, */
            {
            if (warned >= WARNINGS) /* and the user has already received enough warnings, */
                { /* then go ahead and kill this session */
                printf ("\n\n\t _______________________________________________\n");
                printf ("\t/\t\t\t\t\t\t\\\n");
                printf ("\t|\t\tTIME'S UP -- BYE BYE!!%s\t\t|\n", BELL);
                printf ("\t\\_______________________________________________/\n");
                system ("echo \"I've been idle too long.\" | /usr/ucb/mail -s \"killing idle login\" root\n");
                sprintf (kill_command, "kill -1 %d\n", parent); /* make the killer command */
                system (kill_command); /* become an orphan */
                /* printf (kill_command); /* just for testing... */
                }
              else
                {
                printf ("\n\n\t _______________________________________________\n");
                printf ("\t/\t\t\t\t\t\t\\\n");
                printf ("\t|\t");
#if (WARNINGS > 1)
                if (warned == (WARNINGS - 1)) printf ("LAST ");
#endif
                printf ("WARNING!!\tHANG-UP ALERT!!%s\t\t|\n", BELL);
                printf ("\t|\t\t\t\t\t\t|%s\n", BELL);
                printf ("\t| YOUR TERMINAL HAS BEEN IDLE TOO LONG!!%s\t|\n", BELL);
                printf ("\t| I WILL KILL YOUR SHELL IF THERE IS NO%s\t|\n", BELL);
                printf ("\t| ACTIVITY FROM YOUR END IN ");
                if ((check_time == 1) && ((WARNINGS == 1) || (warned == (WARNINGS - 1))))
                    printf ("60 SECONDS!!%s\t|\n", BELL);
                  else
                    printf ("%d MINUTES!!%s\t|\n", (check_time * (WARNINGS - warned)), BELL);
                printf ("\t\\_______________________________________________/\n");
                }
            warned++; /* the user has been warned now! */
            }
          else
            warned = 0; /* hang-up not iminent, no pending warnings */

        if (warned == WARNINGS) /* no more warnings before clobbering the modem */
            {
         /* printf ("\t\tThat was your last warning....\n"); */
            for ( i = 0 ; i < check_secs ; i++ )
                {
                sleep (1); /* wait a second */
                if (idle)
                    {
                    printf ("%s", BELL); /* then ring the terminal bell */
                    fflush (stdout);
                    }
                time (&now);
                stat(devname, &stbuf); /* check terminal activity */
                lastaction = stbuf.st_atime;
                diff = now - lastaction; /* idle time in seconds */
                if (diff < 0) diff = 0;
                idle = (diff > hang_up_time);
                }
            }
          else
            sleep (check_secs); /* wait a bit, then do it all again */
    }
}

badargs(botch) /* print bad argument message and exit */
char *botch; /* invalid argument */
{
    fprintf (stderr, "bad agument: %s\n", botch);
    fprintf (stderr, "usage: suicide [-/+interval] \n");
    listoptions();
}

listoptions() /* list valid options */
    {
    printf ("[-]number:\tidle time limit before warning and hang-up (default 20 minutes)\n");
    printf (" +number:\tidle check interval (default 1 minute)\n");
    printf ("[-]?:\t\tdisplay this help screen\n");
    exit (1);
    }



This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:06:36 CDT