"vulture" - status line display program
Mikel Manitius
mikel at flmis06.codas.att.com
Tue Feb 16 01:48:36 AEST 1988
[ Here's my "vulture" program, it tells time, load average, login/out
activity, who your mail is from when it arrives, and a few other
things. It should run on any System V, and I've even convinved it
to run on BSD, fairly easily. It needs an ANSI terminal with a
25th status line, or a UNIX Pc console. ]
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
# Makefile
# README
# vulture.1
# path.c
# vulture.c
# This archive created: Mon Feb 15 10:42:22 1988
# By: Mikel Manitius (mikel at codas.att.com)
#
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'Makefile'" '(175 characters)'
if test -f 'Makefile'
then
echo shar: "will not over-write existing file 'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
CFLAGS = -O
DFLAGS = -DMAXUSERS=8 -Du3b1
LFLAGS =
BINDIR = /usa/mikel/bin
PROGRM = vulture
$(PROGRM): $(PROGRM).c
cc $(CFLAGS) $(DFLAGS) -o $(PROGRM) $(PROGRM).c $(LFLAGS);
SHAR_EOF
if test 175 -ne "`wc -c < 'Makefile'`"
then
echo shar: "error transmitting 'Makefile'" '(should have been 175 characters)'
fi
fi
echo shar: "extracting 'README'" '(1366 characters)'
if test -f 'README'
then
echo shar: "will not over-write existing file 'README'"
else
cat << \SHAR_EOF > 'README'
this is a breif explanation of some of the tuneable
constants in the source. Please not that you may
have to tune MAXUSERS to the maximum number of users
that can simultanously log onto your system, it is
by default set to a very low number (ie: workstation).
NRUN - scan for idle terminals every (NRUN * TIME_INTERVAL) seconds.
TIME_INTERVAL - how often timestamps are printed.
CRUISE_CONTROL - how often the main loop is executted (seconds).
IDLE_UNIT - unit of idle time for new footnote to be printed.
MAX_IDLE - maximum number of idle footnote messages defined.
LOGOUT_TIME - number of seconds a user must be idle to be logged off.
PF_SIZE - size (in spaces) of a PF key label).
STAMP_COL - At what collumn to print the timestamp.
NCOLS - number of collumns on the status line.
MSG_START - starting position of a normal message.
MSG_MAXLEN - maximum length of a normal message.
MSG_INTERVAL - minimum interval (in seconds) between messages.
MAX_MSG_AGE - maximum age of message before it is erased.
MAIL - name of enviorment variable pointing to mail file.
INFO_MSG - message to use when informing of new mail.
MAIL_DIR - directory of mail queue file (if no MAIL in enviorment).
Mikel Manitius
+1 305 869-2462
mikel at codas.att.com
AT&T (Network Operations Group)
151 S. Wymore Rd. (Rm 349)
Altamonte Springs, FL
32714
SHAR_EOF
if test 1366 -ne "`wc -c < 'README'`"
then
echo shar: "error transmitting 'README'" '(should have been 1366 characters)'
fi
fi
echo shar: "extracting 'vulture.1'" '(3142 characters)'
if test -f 'vulture.1'
then
echo shar: "will not over-write existing file 'vulture.1'"
else
cat << \SHAR_EOF > 'vulture.1'
.TH VULTURE 1 "mikel"
.SH NAME
vulture \- monitor incomming mail and login/logout activity
.SH SYNOPSIS
vulture [ \-t ] [ \-k ] [ \-f ] [ \-s ] [ \-i ]
.PP
vulture [ \-tkfsi ]
.SH DESCRIPTION
.I Vulture
is a system status program that monitors certain activity in
the system, or activity related to it's user. This activity
is reported on the 25th status line of a capable ANSI terminal,
or an AT&T 3b1 console.
.PP
If desired, the file
.I /etc/utmp
is monitored for login and logout information. It is also scanned
periodically even if not touched, to check for other users enabeling
or disableing messages (ie: via the
.I mesg
command)
.PP
The file
.I /usr/mail/$LOGNAME
is monitored for the arrival of new mail. If new mail arrives for the
invoking user, a message annoucing such mail, including the path
of the originating author will be printed on the status line.
Network mail headers will also be parsed to determine paths. If
a path is too long to fit neatly on the status line, the path
will be truncated to the form "...!host!user".
.PP
If a user reads his mail (ie: the queue file shrinks) the contents
of the status line will be erased. The status line will also be
erased if it contains a message older than 5 minutes.
.PP
If desired,
.I vulture
will print a timestamp every 37 seconds on the status line, this
is very handy if the user needs to keep track of time.
A "status word" will be printed at the beginning of the status line
to indicate if the user is active or idle. Normally the word will
show
.I "On Line",
however if the user becomes idle, it may show such
words as
.I "comatose"
or a flashing
.I "idle".
The amount of time used to
determine if a user is idle, and the messages printed, are configurable
within the source.
.I Vulture
may be given several arguments on the command line, these may be any of:
.TP 5
.B \-l
Print information about users loging on or off of the system.
.TP 5
.B \-t
Print the timestamp every 37 seconds.
.PP
.TP 5
.B \-i
Inform about other users being idle. This option will not work
without an the
.B \-l
option being selected.
.PP
.TP 5
.B \-f
Aupon startup, don't fork off into the background.
.PP
.TP 5
.B \-k
If the user becomes idle, warn him, and then terminte his session.
.PP
.TP 5
.B \-s
Do not print the "status word".
.PP
.TP 5
.B \-w
The console is a 3b1 monitor, use appropriate ioctl(2) calls
to put the message on the footer line.
.PP
All output on the status line is done in half intesity video
(assuming the terminal is capable). Messages are announced
with a bell (^G) being sent to terminal. Multiple mesasges
will be delayed at least 5 seconds to give the user time to
see each one.
.SH BUGS
Doesn't always parse complicated ">From" lines proprerly.
Doesn't always warn about other users being idle.
.SH FILES
.nf
/etc/utmp list of users currently logged in
/usr/mail/$LOGNAME mail queued for user
/dev/tty* used to figure out other's idle time
.fi
.SH SEE ALSO
mail(1), who(1), mesg(1), date(1), stty(1)
.SH DIAGNOSTICS
Any error messages after startup will be printed
on the 25th status line.
.SH AUTHOR
Mikel Manitius \- AT&T Information Systems
SHAR_EOF
if test 3142 -ne "`wc -c < 'vulture.1'`"
then
echo shar: "error transmitting 'vulture.1'" '(should have been 3142 characters)'
fi
fi
echo shar: "extracting 'path.c'" '(798 characters)'
if test -f 'path.c'
then
echo shar: "will not over-write existing file 'path.c'"
else
cat << \SHAR_EOF > 'path.c'
#include <stdio.h>
#include <ctype.h>
char *getaddr(fp)
FILE *fp;
{
char x[25];
char y[25];
char line[BUFSIZ];
char user[BUFSIZ];
char host[BUFSIZ];
static char path[BUFSIZ];
path[0] = '\0';
for(;;) {
if(fgets(line, BUFSIZ, fp) == NULL) break;
if(strncmp(line, ">From ", 6) != 0) break;
sscanf(line, ">From %s%s%s%s%s%s%s%s%s%s",
user, x, x, x, x, y, x, x, x, host);
if(isdigit(y[0]))
strcpy(host, x);
if(strcmp(user, "uucp") == 0 ||
strcmp(user, "3bnet") == 0) {
if(path[0] == '\0')
strcpy(path, host);
else
sprintf(path, "%s!%s", path, host);
} else if(path[0] == '\0')
sprintf(path, "%s!%s", host, user);
else
sprintf(path, "%s!%s!%s", path, host, user);
}
if(strncmp(path, "3bnet!", 6) == 0)
return(path + 6);
else
return(path);
}
SHAR_EOF
if test 798 -ne "`wc -c < 'path.c'`"
then
echo shar: "error transmitting 'path.c'" '(should have been 798 characters)'
fi
fi
echo shar: "extracting 'vulture.c'" '(16067 characters)'
if test -f 'vulture.c'
then
echo shar: "will not over-write existing file 'vulture.c'"
else
cat << \SHAR_EOF > 'vulture.c'
static char *sccsid = "@(#)vulture.c Mikel Manitius AT&T 86-07-25";
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/sysinfo.h>
#include <sys/stat.h>
#include <signal.h>
#include <nlist.h>
#include <fcntl.h>
#include <time.h>
#include <utmp.h>
#include <pwd.h>
#ifdef u3b1
#include <sys/window.h>
#endif
/*
* vulture - drive the status line with system info messages.
*
* Mikel Manitius (mikel at codas.att.com)
*/
#ifdef BUFSIZ
#undef BUFSIZ
#endif
#ifndef MAXUSERS
#define MAXUSERS 8
#endif
#define BUFSIZ 256
#define TRUE 1
#define FALSE 0
#define NRUN 3
#define TIME_INTERVAL 37
#define CRUISE_CONTROL 5
#define IDLE_UNIT 120
#define MAX_IDLE 4
#define LOGOUT_TIME 10*60*60
#define PF_SIZE 8
#define NCOLS 78
#define STAMP_COL 10
#define MSG_START 19
#define MSG_MAXLEN 42
#define MSG_INTERVAL 5
#define MAX_MSG_AGE 5*60
#define MAIL "MAIL"
#define INFO_MSG "New mail arrived from"
#define MAIL_DIR "/usr/mail"
#define KMEM "/dev/kmem"
#define SYSTEM "/unix"
#define EQ(x,y) (strcmp(x,y) == 0)
#ifdef u3b1
char date_str[100]; /* date information */
char info_str[100]; /* information string */
struct utdata utd;
#endif
struct sysinfo sinf;
struct footnote
{
int how;
char *word;
} footnote[] = {
{ 0, "On Line " },
{ 0, " idle " },
{ 0, "sleeping" },
{ 0, "comatose" },
{ 1, " idle " },
0,
};
struct list
{
int u_msg; /* are messages enabled */
int u_idle; /* is user's terminal idle */
char u_user[8]; /* name of user */
char u_line[12]; /* user's tty */
};
struct nlist nl[] = {
{ "sysinfo" },
#define NL_SYSINFO 0
{ 0 }
};
int u_fd;
int n_old; /* number of entries in old user list */
int n_new; /* number of entries in new user linst */
int memfd; /* file descriptor for /dev/kmem */
int count = 0; /* number of cycles to 5 min load avg */
int aflag = FALSE; /* report load average instead of stat wosd */
int tflag = FALSE; /* print time stamp */
int iflag = FALSE; /* report idle users */
int fflag = FALSE; /* don't fork */
int kflag = FALSE; /* kill if idle */
int sflag = FALSE; /* don't print status word */
int lflag = FALSE; /* report logins and logouts */
int wflag = FALSE; /* a 3b1 window */
int m_open = FALSE; /* is the mail file open */
int loginsh; /* pid of envoking user's login shell */
int lastlong = FALSE; /* was the last message a long one */
int msg_age = 0; /* age of message currently displayed */
int idle_count = 0; /* how long since last utmp read */
int expire();
long now_occ;
long now_que;
double now_load;
char *mail;
char *pname; /* set to addr of argv[0] */
char *getenv();
char *getaddr();
FILE *m_fp; /* file pointer to mail file */
struct list old[MAXUSERS]; /* list of users on before new scan */
struct list new[MAXUSERS]; /* list of users on after new scan */
struct utmp ut;
struct stat st;
struct passwd *pw;
struct passwd *getpwuid();
quit(qc)
int qc;
{
utd.ut_text[0] = '\0';
ioctl(0, WIOCSETTEXT, &utd);
exit(qc);
}
hour()
{
int now;
char obuff[100];
struct tm *tm;
struct tm *localtime();
if(tflag) {
time(&now);
tm = localtime(&now);
if(aflag) {
load();
#ifdef u3b1
if(wflag)
sprintf(date_str, "L: %5.2f %2d:%02d:%02d",
now_load, tm->tm_hour, tm->tm_min, tm->tm_sec);
else
#endif
sprintf(obuff, "\0337\033[2m\033[25HL: %5.2f %2d:%02d:%02d \033[0m\0338",
now_load, tm->tm_hour, tm->tm_min, tm->tm_sec);
} else
#ifdef u3b1
if(wflag)
sprintf(date_str, " %2d:%02d:%02d",
tm->tm_hour, tm->tm_min, tm->tm_sec);
else
#endif
sprintf(obuff, "\0337\033[2m\033[25;%dH%2d:%02d:%02d \033[0m\0338",
STAMP_COL,
tm->tm_hour, tm->tm_min, tm->tm_sec);
#ifdef u3b1
if(wflag) {
sprintf(utd.ut_text, "%s %s", date_str, info_str);
ioctl(0, WIOCSETTEXT, &utd);
} else
#endif
write(1, obuff, strlen(obuff));
} else if(aflag) {
load();
#ifdef u3b1
if(wflag)
sprintf(date_str, "L: %5.2f ", now_load);
else
#endif
sprintf(obuff, "\0337\033[2m\033[25HL: %5.2f\033[0m\0338",
now_load);
#ifdef u3b1
if(wflag) {
sprintf(utd.ut_text, "%s %s", date_str, info_str);
ioctl(0, WIOCSETTEXT, &utd);
} else
#endif
write(1, obuff, strlen(obuff));
}
if(msg_age) {
msg_age += TIME_INTERVAL;
if(msg_age >= MAX_MSG_AGE)
expire();
}
idle_count++;
signal(SIGALRM, hour);
alarm(TIME_INTERVAL);
}
populate(pp)
struct list pp[MAXUSERS];
{
int n = 0;
int now;
char perm[10];
char file[BUFSIZ];
time(&now);
lseek(u_fd, 0L, 0);
while(read(u_fd, (char *)&ut, sizeof(ut)))
if(ut.ut_type == USER_PROCESS) {
ut.ut_user[7] = '\0';
ut.ut_line[11] = '\0';
strcpy(pp[n].u_user, ut.ut_user);
strcpy(pp[n].u_line, ut.ut_line);
sprintf(file, "/dev/%s", pp[n].u_line);
stat(file, &st);
sprintf(perm, "%o", st.st_mode);
switch(perm[4]) {
case '2':
case '3':
case '6':
case '7':
pp[n].u_msg = TRUE;
break;
default:
pp[n].u_msg = FALSE;
break;
}
if((now - st.st_mtime) >= IDLE_UNIT)
pp[n].u_idle = TRUE;
else
pp[n].u_idle = FALSE;
n++;
}
return(n);
}
char *fname(user)
char *user;
{
int i;
i = strlen(user) - 1;
while(user[i] != '!')
i--;
return(user + i+1);
}
hunt()
{
int o; /* index to old user list */
int n; /* index to new user list */
int found; /* has what we're looking for been found */
n_new = populate(new);
for(o=0;o < n_old;o++) {
found = FALSE;
for(n=0;n < n_new;n++)
if(EQ(new[n].u_user, old[o].u_user)
&& EQ(new[n].u_line, old[o].u_line))
found = TRUE;
if(!found && strncmp(old[o].u_line, "sxt", 3) != 0)
logout(o);
}
for(n=0;n < n_new;n++) {
found = FALSE;
for(o=0;o < n_old;o++)
if(EQ(new[n].u_user, old[o].u_user)
&& EQ(new[n].u_line, old[o].u_line)) {
if(new[n].u_msg != old[o].u_msg)
message(n);
if((new[n].u_idle != old[o].u_idle) && iflag)
do_idle(n);
found = TRUE;
}
if(!found && strncmp(new[n].u_line, "sxt", 3) != 0)
login(n);
}
}
message(n)
int n;
{
char buff[BUFSIZ];
sprintf(buff, "User %s on %s now has messages %s",
new[n].u_user,
new[n].u_line,
(new[n].u_msg) ? "on" : "off");
yelp(buff);
}
do_idle(n)
int n;
{
char buff[BUFSIZ];
if(new[n].u_idle)
sprintf(buff, "User %s on %s has now gone idle",
new[n].u_user,
new[n].u_line);
else
sprintf(buff, "User %s on %s is no longer idle",
new[n].u_user,
new[n].u_line);
yelp(buff);
}
login(n)
int n;
{
char buff[BUFSIZ];
sprintf(buff, "User %s just logged in on %s%s",
new[n].u_user,
new[n].u_line,
(new[n].u_msg) ? "" : " (msg n)");
yelp(buff);
}
logout(o)
int o;
{
char buff[BUFSIZ];
sprintf(buff, "User %s just logged off of %s.",
old[o].u_user,
old[o].u_line);
yelp(buff);
}
main(argc, argv)
int argc;
char *argv[];
{
int i;
int j;
int fk;
long now;
long idle;
long oidle;
long old_time;
long old_mail;
long old_size;
pname = argv[0];
#ifdef u3b1
utd.ut_num = WTXTSLK2;
strcpy(date_str, " ");
#endif
for(i=1;i < argc;i++)
switch(argv[i][0]) {
case '-':
for(j=1;argv[i][j] != '\0';j++)
switch(argv[i][j]) {
case 't':
tflag++;
break;
case 'f':
fflag++;
break;
case 'k':
kflag++;
break;
case 'a':
aflag++;
sflag++;
break;
case 's':
sflag++;
break;
case 'i':
iflag++;
break;
case 'l':
lflag++;
break;
#ifdef u3b1
case 'P':
wflag++;
utd.ut_num = WTXTPROMPT;
break;
case 'C':
wflag++;
utd.ut_num = WTXTCMD;
break;
case '1':
wflag++;
utd.ut_num = WTXTSLK1;
break;
case '2':
wflag++;
utd.ut_num = WTXTSLK2;
break;
case 'w':
wflag++;
break;
#endif
default:
usage();
break;
}
break;
default:
usage();
break;
}
u_fd = open(UTMP_FILE, 0);
if(u_fd < 0) {
perror(UTMP_FILE);
exit(u_fd);
}
loginsh = getppid();
if(!fflag) {
fk = fork();
if(fk) {
#ifdef DEBUG
printf("%d\n", fk);
#endif
exit(0);
}
}
if(aflag) {
memfd = open(KMEM, O_RDONLY);
if(memfd < 0) {
yelp("open /dev/kmem failed!");
exit(-1);
}
if(nlist(SYSTEM, nl) < 0) {
yelp("nlist /unix failed!");
exit(-1);
}
if(nl[NL_SYSINFO].n_value == 0) {
yelp("No namelist member for load average!");
exit(-1);
}
do_read();
now_occ = sinf.runocc;
now_que = sinf.runque;
}
#ifdef JERK
chdir("/dev");
#endif
mail = getenv(MAIL);
if(mail == NULL) {
pw = getpwuid(getuid());
if(pw == NULL) {
printf("%s: cannot determine mail file.\n", pname);
exit(-1);
}
sprintf(mail, "%s/%s", MAIL_DIR, pw->pw_name);
}
n_old = populate(old);
stat(UTMP_FILE, &st);
old_time = st.st_mtime;
if(stat(mail, &st) == 0) {
old_mail = st.st_mtime;
old_size = st.st_size;
m_fp = fopen(mail, "r");
if(m_fp != NULL) {
#ifdef DEBUG
yelp("mail open succeeded");
#endif
m_open = TRUE;
fseek(m_fp, 0L, 2);
}
#ifdef DEBUG
else
yelp("mail open fail");
#endif
} else {
old_mail = 0;
old_size = 0;
}
signal(SIGALRM, hour);
signal(SIGUSR1, expire);
alarm(TIME_INTERVAL);
alarm(TIME_INTERVAL);
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
#ifdef u3b1
if(wflag)
signal(SIGTERM, quit);
#endif
if(!sflag)
squeal(footnote[0].word, footnote[0].how);
if(tflag) {
msg_age = MAX_MSG_AGE; /* to clear screen initially */
hour();
} else {
lastlong = TRUE;
expire();
}
for(;;) {
for(;;) {
if(lflag && stat(UTMP_FILE, &st) == 0
&&(st.st_mtime > old_time || idle_count >= NRUN)) {
old_time = st.st_mtime;
idle_count = 0;
break;
}
if(stat(mail, &st) == 0) {
if((st.st_mtime > old_mail
&& st.st_size > old_size) || !m_open) {
#ifdef DEBUG
yelp("new mail");
#endif
old_mail = st.st_mtime;
old_size = st.st_size;
newmail();
} else if(st.st_size < old_size) {
fclose(m_fp);
m_open = FALSE;
m_fp = fopen(mail, "r");
if(m_fp == NULL) {
yelp("* Warning: Cannot open mail file!");
continue;
}
fseek(m_fp, 0L, 2);
stat(mail, &st);
old_mail = st.st_mtime;
old_size = st.st_size;
m_open = TRUE;
expire();
}
#ifdef DEBUG
else
yelp("no new mail");
#endif
} else {
#ifdef DEBUG
yelp("can't stat mail file");
#endif
fclose(m_fp);
m_open = FALSE;
old_mail = 0;
old_size = 0;
}
fstat(0, &st);
time(&now);
idle = now - st.st_atime;
status(idle);
oidle = idle;
sleep(CRUISE_CONTROL);
}
if(lflag) {
n_new = populate(new);
hunt();
n_old = populate(old);
}
}
}
yelp(buff)
char *buff;
{
int i;
int start; /* starting collumn of message on screen */
int length; /* length of string to be printed */
int adjust; /* length of adjustment to center message */
char num[25];
char obuff[BUFSIZ]; /* output buffer */
#ifdef u3b1
if(wflag) {
info_str[0] = '\0';
length = strlen(buff);
adjust = (MSG_MAXLEN - length) / 2;
for(i=0;i < adjust;i++)
strcat(info_str, " ");
strcat(info_str, buff);
sprintf(utd.ut_text, "%s %s", date_str, info_str);
write(1, "\7", 1);
ioctl(0, WIOCSETTEXT, &utd);
sleep(MSG_INTERVAL);
msg_age = MSG_INTERVAL;
return;
}
#endif
obuff[0] = '\0';
if(lastlong) {
strcat(obuff, "\0337\033[25;");
sprintf(num, "%d", MSG_START - (PF_SIZE+1));
strcat(obuff, num);
strcat(obuff, "H \0338");
lastlong = FALSE;
}
length = strlen(buff);
if(length > MSG_MAXLEN) {
adjust = ((MSG_MAXLEN + PF_SIZE+1) - length) / 2;
start = MSG_START - (PF_SIZE+1);
lastlong = TRUE;
} else {
adjust = (MSG_MAXLEN - length) / 2;
start = MSG_START;
}
strcat(obuff, "\7\0337\033[2m\033[25;");
sprintf(num, "%d", start);
strcat(obuff, num);
strcat(obuff, "H");
for(i=0;i < adjust;i++)
strcat(obuff, " ");
strcat(obuff, buff);
adjust = NCOLS - (start + adjust + length);
for(i=0;i < adjust;i++)
strcat(obuff, " ");
strcat(obuff, "\033[m\0338");
write(1, obuff, strlen(obuff));
sleep(MSG_INTERVAL);
msg_age = MSG_INTERVAL;
}
newmail()
{
int i;
char *path;
char who[BUFSIZ];
char msg[BUFSIZ];
char user[BUFSIZ];
char host[BUFSIZ];
char line[BUFSIZ];
if(!m_open) {
m_fp = fopen(mail, "r");
if(m_fp == NULL) {
yelp("* Warning: Cannot open mail file!");
return;
}
m_open = TRUE;
}
while(fgets(line, BUFSIZ, m_fp) != NULL)
if(strncmp(line, "From", 4) == 0) {
if(line[4] == ':') continue;
sscanf(line + 5, "%s", who);
if(strcmp(who, "uucp") == 0 ||
strcmp(who, "pedns") == 0 ||
strcmp(who, "3bnet") == 0 ||
strcmp(who, "usenet") == 0) {
path = getaddr(m_fp);
if(path[0] == '\0') {
sprintf(msg, "%s %s", INFO_MSG, who);
yelp(msg);
continue;
}
i = rindex2(path, '!') + 1;
if(strlen(path)+strlen(INFO_MSG)+6 > MSG_MAXLEN)
sprintf(msg, "%s ...!%s",
INFO_MSG, path + i);
else
sprintf(msg, "%s %s", INFO_MSG, path);
} else {
sscanf(line, "From %s", user);
sprintf(msg, "%s %s", INFO_MSG, user);
}
yelp(msg);
}
}
usage()
{
#ifdef u3b1
fprintf(stderr, "usage: %s [ -listkf ] [ -w [ -1 | -2 | -P | -C ] ]\n", pname);
#else
fprintf(stderr, "usage: %s [ -listkf ] \n", pname);
#endif
exit(-1);
}
squeal(buff, flash)
int flash;
char *buff;
{
char obuff[BUFSIZ];
#ifdef u3b1
if(wflag)
return;
#endif
sprintf(obuff, "\0337\033[%cm\033[25H%s\033[m\0338",
(flash) ? '5' : '2', buff);
write(1, obuff, strlen(obuff));
}
status(idle)
long idle;
{
static long oidle;
if(idle > (LOGOUT_TIME - 60) && idle < LOGOUT_TIME && kflag)
yelp("Warning: Terminate if idle for 1 more minute");
else if(idle >= LOGOUT_TIME && kflag) {
yelp("Terminated due to rigormourtis of the hand");
kill(loginsh, SIGHUP);
} else if(!sflag) {
idle /= IDLE_UNIT;
if(idle > MAX_IDLE)
idle = MAX_IDLE;
if(idle != oidle)
squeal(footnote[idle].word, footnote[idle].how);
oidle = idle;
}
}
char *getaddr(fp)
FILE *fp;
{
char x[25];
char y[25];
char line[BUFSIZ];
char user[BUFSIZ];
char host[BUFSIZ];
static char path[BUFSIZ];
path[0] = '\0';
for(;;) {
if(fgets(line, BUFSIZ, fp) == NULL) break;
if(strncmp(line, ">From ", 6) != 0) {
if(strcmp(user, "uucp") == 0)
sprintf(path, "%s!%s", path, user);
break;
}
sscanf(line, ">From %s%s%s%s%s%s%s%s%s%s",
user, x, x, x, x, y, x, x, x, host);
if(isdigit(y[0]))
strcpy(host, x);
if(strcmp(user, "uucp") == 0) {
if(path[0] == '\0')
strcpy(path, host);
else
sprintf(path, "%s!%s", path, host);
} else if(path[0] == '\0')
sprintf(path, "%s!%s", host, user);
else
sprintf(path, "%s!%s!%s", path, host, user);
}
return(path);
}
index(str, ch)
char ch;
char *str;
{
int i;
int len;
len = strlen(str) - 1;
for(i=0;str[i] != ch;i++)
if(len == i)
return(-1);
return(i);
}
rindex2(str, ch)
char ch;
char *str;
{
int i;
for(i=strlen(str) - 1;str[i] != ch;i--)
if(i == 0)
return(-1);
for(--i;str[i] != ch;i--)
if(i == 0)
return(-1);
return(i);
}
expire()
{
int i;
int start;
char obuff[BUFSIZ];
signal(SIGUSR1, expire);
#ifdef u3b1
if(wflag) {
info_str[0] = '\0';
strcpy(utd.ut_text, date_str);
ioctl(0, WIOCSETTEXT, &utd);
msg_age = 0;
return;
}
#endif
if(lastlong && !tflag)
start = MSG_START - (PF_SIZE + 1);
else
start = MSG_START;
sprintf(obuff, "\0337\033[25;%dH", start);
for(i=0;i < (NCOLS - start);i++)
strcat(obuff, " ");
strcat(obuff, "\0338");
write(1, obuff, strlen(obuff));
lastlong = FALSE;
msg_age = 0;
}
load()
{
long nocc, nque;
do_read();
nocc = sinf.runocc;
nque = sinf.runque;
now_load = ((double) (nque - now_que)) / ((double) (nocc - now_occ));
now_occ = nocc;
now_que = nque;
}
do_read()
{
if(lseek(memfd, (long)nl[NL_SYSINFO].n_value, 0) < 0) {
yelp("Cannot seek /dev/kmem!");
exit(-1);
}
if(read(memfd, (char *)&sinf, sizeof(sinf)) != sizeof(sinf)) {
yelp("Cannot read /dev/kmem!");
exit(-1);
}
}
SHAR_EOF
if test 16067 -ne "`wc -c < 'vulture.c'`"
then
echo shar: "error transmitting 'vulture.c'" '(should have been 16067 characters)'
fi
fi
exit 0
# End of shell archive
--
Mikel Manitius @ AT&T
mikel at codas.att.com
More information about the Unix-pc.sources
mailing list