From: Charlie_Gibbs@mindlink.bc.ca (Charlie Gibbs)
Subject: Re: Need help on workstation...
Organization: MIND LINK! - British Columbia, Canada
Date: Mon, 4 Jan 1993 22:49:19 GMT

In article <4JAN199322260588@v9000> sd7047787@v9000 (SD7047787) writes:

>Hi!
>I have some problems on workstation. I know this is not the
>appropriate place to ask. But pardon me, I really need the answer fast and I
>dunno
>which usenet discussion list should I ask. So would some kind souls
>out there please help me:
>
>Problem Encounter: In the company I attached, ppl from different departments
>log into the few Sun workstations. They left for urgent meetings etc. quite
>oftenly without logging out from the station. This cause inconvience to
>others who came at random to use the stations.
>
>Solution Requirement: Is there any daemons/programs that came with Sun that
I
>can invoke so that
>users idled for a period of time will automatically be logged out? I know
that
>this is quite
>similar to a screen blanker. But I have no idea how to do/program it because
it
>is also required that the processes status and application programs eg. CAD
>program files etc. called/created by the user are saved before the user is
>logged out
>of the workstation.
>
>I am no experience user for workstation. I think it might not be possible to
>achieve the requirement. But I need advices. Please reply to my address
>as far as possible. All suggestions are welcomed! Thanx a million!!!

     I don't know where I found this, and I haven't had a chance to
try it out, but I thought it might be handy some day so I kept it:

--------------------------- cut here ------------------------------
/* "@(#) autologout.c by David Dickson" */
#include    <stdio.h>
#include    <signal.h>
#include    <string.h>
#include    <sys/types.h>
#include    <sys/stat.h>
#include    <utmp.h>
#define     GRACE       60  /* grace time (sec) for user reply */
#define     KWAIT       20  /* time to wait after kill (in sec.) */
#define     WARNING     1   /* a warning message */
#define     LOGOFF      2   /* a log-off message */
#define     NOLOGOFF    3   /* a log-off failure message */
#define     SEC         60  /* seconds per minute */
#define     TIMEMAX     20  /* maximum idle time (minutes) */

char        *ctime();       /* returns pointer to time string */
struct utmp *utmpp;         /* pointer to utmp file entry */
struct utmp *getutent();    /* returns next utmp file entry */

main()
{
    if (fork())             /* the parent process */
        exit(0);            /* exits */
    /* the child processes all utmp file entries: */
    while ((utmpp = getutent()) != (struct utmp *) NULL)
        check_idle();
    exit(0);    /* done, so bye */
}

check_idle()    /* select utmp entries older than TIMEMAX */
{
    char        dev[24], name[12];
    struct stat status, *pstat;
    time_t      idle, pres_time, start, time();

    pstat = &status;    /* point to status structure */
    if (utmpp->ut_type != USER_PROCESS) /* if not user process */
        return(0);                      /* skip the utmp entry */
    strcpy(dev, "/dev/");   /* add "/dev/" directory prefix */
    strcat(dev, utmpp->ut_line);    /* append basename of port */
    if (stat(dev, pstat))   /* if can't get status for port */
        bailout("can't get status of user's terminal", 1);
    pres_time = time((time_t *)0);  /* get current time */
    /* idle time is current time less last access time: */
    idle = (pres_time - pstat->st_atime) / SEC;
    if (idle < TIMEMAX)     /* if user was recently active */
        return(0);          /* ignore this utmp entry */
    strncpy(name, utmpp->ut_user, 8);   /* else get user name */
    name[8] = '\0';          /* null terminate user name string */
    mesg(WARNING, name, dev, (int)idle); /* send warning to user */
    if (stat(dev, pstat))
        bailout("can't get status of user's terminal", 2);
    start = pstat->st_atime;    /* start time for countdown */
    sleep(GRACE);
    if (stat(dev, pstat))
        bailout("can't get status of user's terminal", 3);
    if (start < pstat->st_atime)    /* user did something */
        return(0);
    else {  /* user abandoned terminal */
        if (!killit(utmpp->ut_pid))
            mesg(NOLOGOFF, name, dev, (int)idle); /* couldn't kill */
        else
            mesg(LOGOFF, name, dev, (int)idle); /* okay */
        return(0);
    }
}

mesg(flag, name, dev, idle) /* mail to user and log message */
int     flag, idle;     /* flag indicates message type */
char    *name, *dev;
{
    char    mbuf[256];  /* message buffer */
    time_t  tvec;
    FILE    *fopen(), *fp, *log, *mprog;

    time(&tvec);    /* store time in tvec */
    if ((log = fopen("/usr/adm/logoutlog", "a")) == (FILE *) NULL)
        bailout("can't open log file", 4);
    if (flag == WARNING) {  /* process warning message */
        if ((fp = fopen(dev, "w")) == (FILE *) NULL)
            bailout("can't open user's terminal", 5);
        fprintf(fp,
            "%s: You've been idle for %d min.\07\n", name, idle);
        fprintf(fp,
            "you'll be logged off in 60 sec. unless you hit return:");
        fclose(fp);
        fprintf(log, "** WARNING ** %s %s (%d min idle time) %s",
            name, dev+5, idle, ctime(&tvec)+3);
    }
    if (flag == LOGOFF) {   /* process log-off message */
        fprintf(log, "** LOGOFF ** %s %s (%d min idle time) %s",
            name, dev + 5, idle, ctime(&tvec) + 3);
        sprintf(mbuf, "/bin/mail %s", name);
        /* open pipe to mail program for writing */
        if ((mprog = popen(mbuf, "w")) == (FILE *) NULL)
            bailout("can't use /bin/mail program", 6);
        fprintf(mprog, "Subject: Excess Idle Time\nLogged \
off - excess idle time - %s %s\ntty = %s\n",
            name, ctime(&tvec), dev + 5);
        fclose(mprog);
    }
    if (flag == NOLOGOFF) {  /* send mail to root if can't kill */
        fprintf(log, "** LOGOFF-FAIL ** %s (pid = %d) \
%s (%d min idle time) %s",
            name, utmpp->ut_pid, dev+5, idle, ctime(&tvec)+3);
        sprintf(mbuf, "/bin/mail root");
        if ((mprog = popen(mbuf, "w")) == (FILE *) NULL)
            bailout("can't use /bin/mail program", 7);
        fprintf(mprog, "Subject: Can't logoff %s\nCan't Log off \
- %s %s\ntty = %s\n", name, name, ctime(&tvec), dev+5);
        fclose(mprog);
    }
    fclose(log);
    return(0);
}

killit(pid) /* terminate process using SIGHUP, then SIGKILL */
int pid;
{
    kill(pid, SIGHUP);  /* first send "hangup" signal */
    sleep(KWAIT);
    if (!kill(pid, 0)) {    /* SIGHUP might be ignored */
        kill(pid, SIGKILL); /* then send sure "kill" signal */
        sleep(KWAIT);
        if (!kill(pid, 0))
            return(0);  /* failure--refuses to die! */
        else
            return(1);  /* successful kill with SIGKILL */
    } else
        return(1);  /* successful kill with SIGHUP */
}

bailout(message, status) /* display error message and exit */
int     status;     /* exit status */
char    *message;   /* pointer to the error message */
{
    fprintf(stderr, "autologout: %s\n", message);
    exit(status);
}
--------------------------- cut here ------------------------------

     It probably doesn't do the sort of file saves etc. that you're
asking about.  That could be extremely difficult.  On the other hand,
I've gotten so tired of people abandoning terminals around here that
I tend to just cut them down without warning.  Maybe having to rebuild
a file or two might teach them to be more careful.

Charlie_Gibbs@mindlink.bc.ca
"I'm cursed with hair from HELL!"  -- Night Court