SYSTAT - Visual system status display program (V7/Xenix and up)
Brandon Allbery
bsa at ncoast.UUCP
Mon Nov 19 11:40:16 AEST 1984
The following C program is a visual system status display program. It
shows who's on the system and what processes are running. It was designed
for a small Xenix system, so it probably will (at the least) need to
have the screen display reformatted to work with Vaxen and other monstrosities;
at present it has room for 9 logins and 28 processes (with ps ax). I
have #defined the commands used for finding out who's on and what processes
are running; you can change them for v7 systems without ``finger'' or
for systems requiring more options to ``ps''. For more logins, you can
duplicate the code for splitting the process listing over two columns
into the who's on code and use ``who'' as the program (or do a direct
lookup into the utmp file).
This program, as formatted, will not run on a screen smaller than 64x16;
80x24 is preferred, and 132x24 or larger is even better. The larger
the screen, the more information can be shown.
Change S_USRWIN to reflect the number of lines to use to display the
list of current users; change WHO and PROC to the programs used to show
who's on and what's running; the #defines should be in the form of arguments
to execl(), but not null-terminated (the progreham does that for you).
For example: in the program as posted, the #defines are:
#define WHO "/usr/bin/finger"
#define PROC "/bin/ps", "ax"
With the exception of the use of ``finger'' for the users listing, this
program should be compilable on any system from V7 on; /vmunix users
will probably want to change the call to fork() in xopen() to a call
to vfork() (I think... what do *I* know of /vmunix ?).
Please send any improvements or bug reports/fixes to ncoast!bsa (full
path in the .signature, if the system crash didn't munge postnews).
---------------------- CUT HERE --------------------------------------
#include <curses.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
/*
* systat - show system status visually
*
* This program provides a window on the system. There are three windows
* involved: the top 8 lines are reserved for ``finger'', the bottom line for
* time and program status, and the rest for ``ps ax''. ps is split into
* two columns. If you need more space for logins, redesign it; I suggest
* using ``who'' as a first step. This was designed under Xenix, the only
* non-V7 feature used is ``finger'' (unless you count curses itself). This
* also shows why I left so little space for logins (6 users max. on Model
* 16 at present).
*/
WINDOW *usrwin, *procwin, *pswin;
unsigned rtime;
int redraw(), cleanup(), pfd[2];
struct passwd *getpwuid();
FILE *xopen();
char *index();
#define WHO "/usr/bin/finger"
#define PROC "/bin/ps", "ax"
#define S_USRWIN 8
#define MAILDIR "/usr/spool/mail/"
main()
{
struct sgttyb tty;
FILE *fp;
char line[39], ch, lmailbox[256], mailbox[256];
struct stat mbox, lmbox;
struct passwd *pwd;
long clock;
int pcnt;
if (gtty(1, &tty) < 0)
{
fprintf(stderr, "Output not to /dev/tty\n");
exit(-1);
}
strcpy(mailbox, MAILDIR);
strcpy(lmailbox, MAILDIR);
strcat(lmailbox, getlogin());
setpwent();
pwd = getpwuid(getuid());
strcat(mailbox, pwd->pw_name);
switch (tty.sg_ospeed)
{
case B110: /* pity the poor user of this! */
rtime = 120;
break;
case B300:
rtime = 60;
break;
case B1200:
rtime = 15;
break;
case B1800:
rtime = 10;
break;
case B2400:
rtime = 5;
break;
default:
if (tty.sg_ospeed < B2400)
rtime = 60;
else
rtime = 1;
}
initscr();
if (LINES < 16 || COLS < 64)
{
fprintf(stderr, "Must have at least an 64x16 screen.\n");
endwin();
}
usrwin = newwin(S_USRWIN, COLS, 0, 0);
procwin = newwin(LINES - S_USRWIN - 1, COLS, S_USRWIN, 0);
signal(SIGINT, cleanup);
signal(SIGQUIT, redraw);
for(;;)
{
werase(usrwin);
if ((fp = xopen(WHO, 0)) == NULL)
{
perror(WHO);
endwin();
exit(-1);
}
while ((ch = getc(fp)) != EOF)
waddch(usrwin, ch);
xclose(fp);
werase(procwin);
if ((fp = xopen(PROC, 0)) == NULL)
{
perror(PROC);
endwin();
exit(-1);
}
fgets(line, COLS / 2 - 1, fp);
waddstr(procwin, line);
wmove(procwin, 0, COLS / 2);
waddstr(procwin, line);
wmove(procwin, 1, 0);
pcnt = 2;
while (fgets(line, COLS / 2 - 1, fp) != NULL && pcnt < (LINES - S_USRWIN - 1) * 2)
{
wmove(procwin, pcnt / 2, (pcnt % 2 == 0? 0 : COLS / 2));
waddstr(procwin, line);
if (index(line, '\n') == 0)
while ((ch = getc(fp)) != '\n')
;
pcnt ++;
}
xclose(fp);
erase();
move(LINES - 1, 0);
time(&clock);
if (stat(mailbox, &mbox) < 0)
mbox.st_size = 0;
if (stat(lmailbox, &lmbox) < 0)
lmbox.st_size = 0;
printw("%s ", pwd->pw_name);
if (mbox.st_size > 0)
{
standout();
printw(" You have mail. ");
standend();
}
printw(" Login: %s ", getlogin());
if (lmbox.st_size > 0)
{
standout();
printw(" has mail ");
standend();
}
printw(" %s ", ctime(&clock));
move(LINES - 1, 0);
overwrite(usrwin, stdscr);
overwrite(procwin, stdscr);
refresh();
sleep(rtime);
}
}
redraw()
{
touchwin(stdscr);
refresh();
signal(SIGQUIT, redraw);
}
cleanup()
{
clear();
refresh();
endwin();
exit(0);
}
FILE *xopen(cmd, arg1, arg2, arg3, arg4)
char *cmd, *arg1, *arg2, *arg3, *arg4;
{
FILE *rfp;
pipe(pfd);
switch(fork())
{
case -1:
endwin();
perror("fork()");
exit(-1);
case 0:
break;
default:
close(pfd[1]);
if ((rfp = fdopen(pfd[0], "r")) == NULL)
{
endwin();
perror("fdopen()");
exit(-1);
}
return rfp;
}
close(pfd[0]);
close(1);
dup2(pfd[1], 1);
execl(cmd, cmd, arg1, arg2, arg3, arg4, 0);
endwin();
perror(cmd);
exit(-1);
}
xclose(fd)
FILE *fd;
{
fclose(fd);
wait(0);
}
--
Brandon Allbery @ North Coast Xenix | the.world!ucbvax!decvax!cwruecmp!
6504 Chestnut Road, Independence, Ohio | {atvax!}ncoast!{tdi1!}bsa
(216) 524-1416 \ 44131 | E1439 at CSUOHIO.BITNET (friend's acct.)
---------------------------------------+---------------------------------------
Forgive; we just had a system crash & lost a month's worth of work and patches.
More information about the Comp.sources.unix
mailing list