Path: utzoo!attcan!uunet!mcvax!hp4nl!botter!vulet!hans From: hans@let.vu.nl (Hans Varkevisser) Newsgroups: comp.sources.d Subject: autologout Keywords: autologout idle terminals Message-ID: <556@vulet.let.vu.nl.UUCP> Date: 13 Jan 89 13:23:16 GMT Organization: V.U. Letteren, Amsterdam, the Netherlands Lines: 281 I have changed the w.c program (BSD 4.3 w.c version 5.3) to a programm with the following options: I have renamed w.c to autologout.c. autologout -k kill all users with only one proces and 30 min idle Kill all users who are 120 minutes idle without looking to the proces autologout The same as w I don't send the complete file, I only send the diff file because of the copywrite of w.c. You can change the program to an other idle time etc. I have added some explanation in the file, because I needed the program very badly there is a bug in it. This bug must be solved but I don't have the time for it. The bug is: if the idle time > 120 the user is logout, but not always by killing the shell with the hangup signal. Sometimes child processes are killed with hangup instead and finaly the shell is killed. This is because I look at the lowest proces-id and not to the number of the shell pid. the diff file follows. cut here -------------------- cut here ---------------- cut here 7,14c7,11 < /* This programm is adapted from the programm w.c. < * There some changes and some features are deleted < * I add the autologout feature, the programm looks at the < * idle time and the number of processes. If the idle time is > 30 < * and the number of processes = 1 the the user is logout by kill signal < * Hans Varkevisser, Fac of Literature Free University the Netherlands < * let.vu.nl!hans or hans@let.vu.nl (UUCP) < */ --- > #ifndef lint > char copyright[] = > "@(#) Copyright (c) 1980 Regents of the University of California.\n\ > All rights reserved.\n"; > #endif not lint 17c14 < static char sccsid[] = "@(#)autologout.c 1.0 (Free University) 1/11/89"; --- > static char sccsid[] = "@(#)w.c 5.3 (Berkeley) 2/23/86"; 19a17,22 > /* > * w - print system status (who and what) > * > * This program is similar to the systat command on Tenex/Tops 10/20 > * It needs read permission on /dev/mem, /dev/kmem, and /dev/drum. > */ 104,119d106 < /* new variables for autologout */ < < #define KILL_SIGNAL "-1" /* use this for kill, -1 = hangup */ < < int tmp_pid = 0; /* temporary proces id */ < int tmp_uid = 0; /* temporary user id */ < int max_idle = 30; /* max idle time in minutes */ < int max_limit = 120; /* max limit time in minutes */ < int kill_on = 0; /* true if -k flag, kill idle process */ < int tot_proc = 0; /* total of processes */ < char tmp_itoa[10]; /* tmp var to convert int to string */ < char command[512]; /* command string for systemcall */ < int min_number = 100; /* user number less than min_number < * won't be affected < */ < 159,162d145 < case 'k': < kill_on++; < break; < 213a197,199 > if (header) { > /* Print time of day */ > prtat(&now); 214a201,206 > /* > * Print how long system has been up. > * (Found by looking for "boottime" in kernel) > */ > lseek(kmem, (long)nl[X_BOOTTIME].n_value, 0); > read(kmem, &boottime, sizeof (boottime)); 215a208,260 > uptime = now - boottime.tv_sec; > uptime += 30; > days = uptime / (60*60*24); > uptime %= (60*60*24); > hrs = uptime / (60*60); > uptime %= (60*60); > mins = uptime / 60; > > printf(" up"); > if (days > 0) > printf(" %d day%s,", days, days>1?"s":""); > if (hrs > 0 && mins > 0) { > printf(" %2d:%02d,", hrs, mins); > } else { > if (hrs > 0) > printf(" %d hr%s,", hrs, hrs>1?"s":""); > if (mins > 0) > printf(" %d min%s,", mins, mins>1?"s":""); > } > > /* Print number of users logged in to system */ > while (fread(&utmp, sizeof(utmp), 1, ut)) { > if (utmp.ut_name[0] != '\0') > nusers++; > } > rewind(ut); > printf(" %d user%s", nusers, nusers>1?"s":""); > > /* > * Print 1, 5, and 15 minute load averages. > * (Found by looking in kernel for avenrun). > */ > printf(", load average:"); > lseek(kmem, (long)nl[X_AVENRUN].n_value, 0); > read(kmem, avenrun, sizeof(avenrun)); > for (i = 0; i < (sizeof(avenrun)/sizeof(avenrun[0])); i++) { > if (i > 0) > printf(","); > printf(" %.2f", avenrun[i]); > } > printf("\n"); > if (firstchar == 'u') > exit(0); > > /* Headers for rest of output */ > if (lflag) > printf("User tty login@ idle JCPU PCPU what\n"); > else > printf("User tty idle what\n"); > fflush(stdout); > } > > 233d277 < tot_proc=0; 239,244c283,299 < tot_proc++; < < if (tmp_pid == 0) < tmp_pid=pr[i].w_pid; < tmp_uid=pr[i].w_uid; < --- > /* > * Meaning of debug fields following proc name is: > * & by itself: ignoring both SIGINT and QUIT. > * (==> this proc is not a candidate.) > * & : i is SIGINT status, q is quit. > * 0 == DFL, 1 == IGN, 2 == caught. > * *: proc pgrp == tty pgrp. > */ > if (debug) { > printf("\t\t%d\t%s", pr[i].w_pid, pr[i].w_args); > if ((j=pr[i].w_igintr) > 0) > if (j==IGINT) > printf(" &"); > else > printf(" & %d %d", j%3, j/3); > printf("\n"); > } 248a304,314 > if(pr[i].w_pid>curpid && (pr[i].w_igintr!=IGINT || empty)){ > curpid = pr[i].w_pid; > strcpy(doing, lflag ? pr[i].w_args : pr[i].w_comm); > #ifdef notdef > if (doing[0]==0 || doing[0]=='-' && doing[1]<=' ' || doing[0] == '?') { > strcat(doing, " ("); > strcat(doing, pr[i].w_comm); > strcat(doing, ")"); > } > #endif > } 250,275d315 < < /* -k flag log users out who are idle > 30 minutes */ < if (kill_on == 1) { < < /* convert int pid to string */ < itoa(tmp_pid,tmp_itoa); < < /* put command in command string */ < strcpy(command,"kill "); < strcat(command, KILL_SIGNAL); < strcat(command, " "); < < /* append pid to commandstring */ < strcat(command,tmp_itoa); < /* kill user for idle > 120 minutes don't look at processes*/ < < if ((tmp_uid > min_number) && ( idle >= max_limit)){ < /* execute a kill -1 on pid */ < system(command); < } < /* kill user for idle > 30 minutes and only one process running */ < if ((tmp_uid > min_number) && ( idle >= max_idle) && (tot_proc == 1)){ < /* execute a kill -1 on pid */ < system( command); < } < } else { 277,278d316 < } < tmp_pid=0; 302c340 < --- > 304,305c342 < printf("%d\t%d\t%-*.*s ", tmp_uid, tmp_pid, NMAX, NMAX, utmp.ut_name); < printf("%3d idle \n", idle ); --- > printf("%-*.*s ", NMAX, NMAX, utmp.ut_name); 306a344,374 > /* print tty user is on */ > if (lflag) > /* long form: all (up to) LMAX chars */ > printf("%-*.*s", LMAX, LMAX, utmp.ut_line); > else { > /* short form: 2 chars, skipping 'tty' if there */ > if (utmp.ut_line[0]=='t' && utmp.ut_line[1]=='t' && utmp.ut_line[2]=='y') > printf("%-2.2s", &utmp.ut_line[3]); > else > printf("%-2.2s", utmp.ut_line); > } > > if (lflag) > /* print when the user logged in */ > prtat(&utmp.ut_time); > > /* print idle time */ > if (idle >= 36 * 60) > printf("%2ddays ", (idle + 12 * 60) / (24 * 60)); > else > prttime(idle," "); > > if (lflag) { > /* print CPU time for all processes & children */ > prttime(jobtime," "); > /* print cpu time for interesting process */ > prttime(proctime," "); > } > > /* what user is doing, either command tail or args */ > printf(" %-.32s\n",doing); 606,633d673 < } < itoa(n,s) < char s[]; < int n; < { < int i, sign; < < if ((sign = n) < 0) < n = -n; < i = 0; < do { < s[i++] = n % 10 + '0'; < } while (( n /= 10 ) > 0 ); < if (sign < 0) < s[i++] = '-'; < s[i] = '\0'; < reverse(s); < } < reverse (s) < char s[]; < { < int c, i, j; < < for (i = 0, j = strlen(s)-1; i < j; i++, j--) { < c = s[i]; < s[i] = s[j]; < s[j] = c; < }