home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-09-11 | 40.6 KB | 1,748 lines |
- Subject: v13i077: Utilities to monitor usage on system
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Steven Grimm <koreth@ssyx.UCSC.EDU>
- Posting-number: Volume 13, Issue 77
- Archive-name: budpak
-
- The "buddy system."
-
- This is a collection of utilities for monitoring other users on the system.
- It runs on 4.3BSD on a VAX, and 4.2BSD on a Sun 3/160 and an ISI Optimum V.
- I have no idea whether it works (or even compiles) on SysV or not.
-
- +New! Improved! Now 100% Artificial-+-+-----------------------------------+
- |# # @@@ **** &&&&& $$$$$ % %| |Steven Grimm |
- |# # @ @ * * & $ % %+-+ ARPA: koreth@ssyx.ucsc.edu |
- |### @ @ **** &&&& $ %%%%%| | UUCP: ...!ucbvax!ucscc!ssyx!koreth|
- |# # @ @ * * & $ % %+-+ ______________________________|
- |# # @@@ * ** &&&&& $ % %| | |"Let's see what's out there."|
- +-----with NutraSour(TM)! No natural colors or preservatives!------------+
-
-
- ------------ (chop here) ------------
- # This is a shell archive. Remove anything before this line
- # then unpack it by saving it in a file and typing "sh file"
- # (Files unpacked will be owned by you and have default permissions).
- # This archive contains the following files:
- # ./MANIFEST
- # ./Makefile
- # ./aliases
- # ./budpak.1
- # ./buds.1
- # ./buds.c
- # ./cbuds.1
- # ./cbuds.c
- # ./mbuds.1
- # ./mbuds.c
- # ./monitor.1
- # ./monitor.c
- # ./rbuds.1
- # ./rbuds.c
- # ./wbuds.1
- # ./wbuds.c
- #
- if `test ! -s ./MANIFEST`
- then
- echo "writing ./MANIFEST"
- cat > ./MANIFEST << '\Rogue\Monster\'
- This shar should contain the following files:
-
- Makefile - A makefile for BudPak.
- budpak.1
- buds.1
- cbuds.1
- mbuds.1
- monitor.1
- rbuds.1
- wbuds.1 - Documentation for the BudPak utilities. Use [nt]roff -man.
- buds.c
- cbuds.c
- mbuds.c
- monitor.c
- rbuds.c
- wbuds.c - BudPak source code.
- aliases - Aliases for setting "single" and "horny" flags (see buds.6)
-
- Read budpak.1 for an overview of the utilities provided.
- \Rogue\Monster\
- else
- echo "will not over write ./MANIFEST"
- fi
- if `test ! -s ./Makefile`
- then
- echo "writing ./Makefile"
- cat > ./Makefile << '\Rogue\Monster\'
- #
- # BUDPAK 1.0
- #
- # Written by Jon Luini (niteowl@ssyx.ucsc.edu)
- # ...!uunet!ucbvax!ucscc!ssyx!niteowl
- # and Steven Grimm (koreth@ssyx.ucsc.edu)
- # ...!uunet!ucbvax!ucscc!ssyx!koreth
- #
- CFLAGS= -g
- BINDIR= /usr/local
- BINARIES= buds cbuds mbuds monitor rbuds wbuds
-
- BudPak: $(BINARIES)
- buds : buds.c
- cc $(CFLAGS) buds.c -o buds
- cbuds: cbuds.c
- cc $(CFLAGS) cbuds.c -o cbuds
- mbuds: mbuds.c
- cc $(CFLAGS) mbuds.c -o mbuds
- monitor: monitor.c
- cc $(CFLAGS) monitor.c -o monitor
- rbuds: rbuds.c
- cc $(CFLAGS) rbuds.c -o rbuds
- wbuds: wbuds.c
- cc $(CFLAGS) wbuds.c -o wbuds
- \Rogue\Monster\
- else
- echo "will not over write ./Makefile"
- fi
- if `test ! -s ./aliases`
- then
- echo "writing ./aliases"
- cat > ./aliases << '\Rogue\Monster\'
- alias single chmod g+x \`tty\`
- alias horny chmod o+x \`tty\`
- \Rogue\Monster\
- else
- echo "will not over write ./aliases"
- fi
- if `test ! -s ./budpak.1`
- then
- echo "writing ./budpak.1"
- cat > ./budpak.1 << '\Rogue\Monster\'
- .TH BUDPAK 1 BUDPAK
- .UC 4
- .SH NAME
- buds, wbuds, mbuds, monitor, rbuds, cbuds \- The Buddy System
- .SH SYNOPSIS
- .B buds
- [
- .I options
- ]
- .PP
- .B wbuds
- .PP
- .B mbuds
- [ user1 user2 user3 ... ]
- .PP
- .B monitor
- [
- .I options
- ] [ user1 user2 user3 ... ]
- .PP
- .B rbuds
- .PP
- .B cbuds
- .SH DESCRIPTION
- .I BudPak
- is a collection of silly utilities to monitor the activities of other users on
- the system. It consists of six programs of varying uselessness:
- .PP
- .TP
- .I buds
- This is the program that started it all. It was suggested by Mark Axelrod
- (deckard@ucscb.ucsc.edu), who was displeased with the
- .I whom
- utility's inability to handle large alternate usernames (our
- .I whom
- reads in a file called
- .B .whom
- in the user's home directory, so that short real names can be substituted for
- account names).
- .I buds
- and its friends allow tremendous (well, 37 characters) aliases. The
- .I buds
- program itself simply lists the people who are online and in a file called
- .B .buddy
- in the your home directory.
- .TP
- .I wbuds
- This command looks at your buddies and tells you what they're up to.
- .TP
- .I mbuds
- .I mbuds
- checks /usr/spool/mail and tells you which buddies have mail, and how much
- of it they have.
- .TP
- .I monitor
- This is perhaps the most interesting program of the bunch, which isn't saying
- a whole lot. It constantly monitors /etc/utmp and tells you when buddies log
- on or off.
- .TP
- .I rbuds
- .I rbuds
- is a handy utility that allows several aliases to be kept for each buddy.
- It randomly selects aliases from a file called
- .B .rbuds
- in your home directory.
- .TP
- .I cbuds
- This is a silly hack that was necessary when we wrote
- .I rbuds\fR.
- It converts a
- .B .buddy
- file to a
- .B .rbuds
- file, so that you don't have to retype the whole thing. If you use
- .B .rbuds
- from the start, you'll never need to use
- .I cbuds.
- .PP
- .PP
- The \fB.buddy\fR file in your home directory contains a list of account
- names and a \fIbuddy alias\fR for each name. A buddy alias can be up
- to 37 characters, and is typically a user's real name, or a nickname or
- some other information. The format of the \fB.buddy\fR file is simply
- <account> <space> <alias> <newline> for each buddy. For instance:
- .PP
- .PP
- root Mister SuperUser
- zooker Donuts! Feed me donuts!
- harris David Harris, accountant at large
- .PP
- .PP
- Other utilities can affect your \fB.buddy\fR file; see rbuds(1) for
- the most useful one.
- .SH "SEE ALSO"
- buds(1), wbuds(1), mbuds(1), monitor(1), rbuds(1), cbuds(1)
- .SH AUTHORS
- Jon Luini, niteowl@ssyx.ucsc.edu (\fIbuds\fR and the original \fImonitor\fR)
- .PP
- Steven Grimm, koreth@ssyx.ucsc.edu (everything else)
- .SH BUGS
- .I BudPak
- is far too simple to have any bugs.
-
- \Rogue\Monster\
- else
- echo "will not over write ./budpak.1"
- fi
- if `test ! -s ./buds.1`
- then
- echo "writing ./buds.1"
- cat > ./buds.1 << '\Rogue\Monster\'
- .TH BUDS 1 BUDPAK
- .UC 4
- .SH NAME
- buds \- list of other users
- .SH SYNOPSIS
- .B buds
- [
- .I options
- ]
- .SH DESCRIPTION
- .I buds
- tells you who's online at the moment, and prints some statistics about
- them. Foremost is the \fIbuddy alias\fR, which is a long (up to 37 characters)
- string containing a user's real name, nickname, or other information.
- See budpak(1) for more information. A typical line of \fIbuds\fR output
- is:
- .PP
- .PP
- Mister SuperUser wb 13 hs p3 (root) 0:47 [ucbvax]
- .PP
- .PP
- "Mister SuperUser" is the buddy alias for "root" (whose real username is
- in the third to last column of the listing). "w" and "b" indicates that
- he's writable (see mesg(1)) and biffable (see biff(1)). He has been idle
- for 13 minutes. "h" is the "horny" flag -- it indicates that root wants it,
- and wants it bad. "s" means that he's single ("h" without "s" can mean
- trouble, so watch it!) "p3" is the name of the tty that root is on; in this
- example, it's rlogin port 3. 0:47 is the amount of time he's been
- logged on. The last field only appears when the user is logged in from a
- remote host, and contains the name of the remote host (ucbvax, in this
- example.)
- .SH OPTIONS
- .TP
- .I \-w
- Only lists writable users.
- .TP
- .I \-b
- Only lists biffable users.
- .TP
- .I \-i
- Only lists users who have been idle for one minute or more.
- .TP
- .I \-h
- Only lists horny users.
- .TP
- .I \-s
- Only lists single users.
- .TP
- .I \-d
- Doesn't substitute buddy aliases for usernames. This flag is actually pretty
- useless, since real usernames are printed anyway.
- .TP
- .I \-a
- List all users who are online, whether they're in \fB.buddy\fR or not.
- .TP
- .I \-S
- Doesn't print the load average at the end of the buddy listing. The load average
- is only printed on systems which support the rwho(1C) service.
- .SH AUTHOR
- Jon Luini, niteowl@ssyx.ucsc.edu
- .SH FILES
- .TP
- /etc/utmp
- .TP
- $HOME/.buddy \-
- Buddy alias file.
- .SH "SEE ALSO"
- monitor(1), rbuds(1), budpak(1)
-
- \Rogue\Monster\
- else
- echo "will not over write ./buds.1"
- fi
- if `test ! -s ./buds.c`
- then
- echo "writing ./buds.c"
- cat > ./buds.c << '\Rogue\Monster\'
- /**
- *** buds.c --> the ORIGINAL (completely rewritten) budpak utility
- *** this (and all) versions
- *** by Jon Luini, niteowl@ssyx.ucsc.edu
- ***
- *** A couple of modifications by Steven Grimm, koreth@ssyx.ucsc.edu
- ***
- *** 1:32:11 A.M. Saturday, November 14th 1987
- **/
-
- #include <stdio.h>
- #include <utmp.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/time.h>
-
- /*
- ** Comment out the following #define statement if your machine isn't listed
- ** in its own /etc/rwhod section. The /etc/rwhod section is used for a fast
- ** load average estimate.
- */
- #define RWHOD
-
- /*
- ** The following define is a prefix that will be removed from the remote
- ** hostnames of people who are rlogged-in. For instance, at UCSC we have
- ** machines called "ucsca", "ucscb", "ucscc", and so on. Our prefix is
- ** "ucsc", so that the aforementioned machine names will show up as "a",
- ** "b", and "c", respectively, in the remote host part of the buddy listing.
- ** If you don't want a prefix, set it to something silly like "zzzzzzzzz"
- ** that will never occur.
- */
- #define PREFIX "ucsc"
-
- #define TRUE 1
- #define FALSE 0
- #define UTMP "/etc/utmp" /* the location of utmp */
- #define MAX_USERS 80 /* Maximum number of users possible */
-
- #define IDLE 002 /* is user idle for longer than 60 seconds? */
- #define RITABLE 020 /* Is each user's tty ritable? */
- #define BIFF 0100 /* User have biff set? */
- #define SINGLE 0010 /* User have single set? */
- #define HORNY 0001 /* User have HoRnY set? */
- #define C_IDLE 0000001 /* list only if user is idle */
- #define C_RITEABLE 0000010 /* list only if writeable */
- #define C_BIFF 0000100 /* list only if biffable */
- #define C_SINGLE 0001000 /* list only if user is single */
- #define C_HORNY 0010000 /* list only if HoRnY */
- #define DONT_SUB 0100000 /* Don't substitute the login with the alias */
- #define LIST_ALL 01000000 /* List all users, not just buddies */
-
- struct BUD {
- char login[8]; /* login name */
- char alias[50]; /* alias of login */
- char line[8]; /* tty name */
- char host[16]; /* host name, if remote */
- long time; /* time on */
- int idle; /* time idle */
- int buddy; /* is the user a buddy? */
- unsigned long perm; /* perm of the buds tty */
- } buddy[MAX_USERS];
-
- char *month[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- };
-
- char *space(), /* function for printing spaces */
- *lentime(), /* funtion to print time buddy has been on */
- hostname[10]; /* the hostname of this machine */
- unsigned long mode; /* the mode of the command line params */
- int num_usrs = 0, /* total number of users online */
- num_buds = 0, /* total number of buddies online */
- compare(), /* algorithm used for qsort */
- shortf; /* flag to tell buds to be in short mode */
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int bflag = FALSE;
-
- while (*argv) {
- if (**argv == '-') {
- ++*argv;
- while (**argv) {
- switch (**argv) {
- case 'w': mode |= C_RITEABLE; break;
- case 'b': mode |= C_BIFF; break;
- case 'i': mode |= C_IDLE; break;
- case 'h': mode |= C_HORNY; break;
- case 's': mode |= C_SINGLE; break;
- case 'd': mode |= DONT_SUB; break;
- case 'a': mode |= LIST_ALL; break;
- case 'S': shortf = TRUE; break;
- default : printf("'%c': bad flag\n",
- **argv); bflag = TRUE;
- }
- ++*argv;
- }
- }
- ++argv;
- }
-
- if (bflag) { /** print usage screen **/
- puts("Usage: buds [-wbihsdaS]");
- puts("\tw \tlist only writeable users");
- puts("\tb \tlist only biffable users");
- puts("\ti \tlist only idle users");
- puts("\th \tlist only horny users");
- puts("\ts \tlist only single users");
- puts("\td \tdon't substitute buddy aliases");
- puts("\ta \tlist all users on");
- #ifdef RWHOD
- puts("\tS \trun buds in Short mode.. dont print the load (faster)");
- #endif
- exit(-1);
- }
-
- init();
- get_usrs();
- if (!(mode & DONT_SUB)) get_buds();
- qsort((char *) &buddy[0], num_usrs, sizeof(struct BUD), compare);
- print_out();
- }
-
- compare(name1, name2) /** the compare function for qsort **/
- struct BUD *name1, *name2; {
- return(strncmp(name1->alias, name2->alias, 40));
- }
-
- init() { /** zero the buddy struct array **/
- register int i;
-
- for (i = 0; i < MAX_USERS; i++)
- bzero(&buddy[i], sizeof(buddy[i]));
- }
-
- get_usrs() { /** get the user online in putthem in buddy struct array **/
- struct utmp butane;
- int fd, i = 0;
-
- if ((fd = open(UTMP, 0)) == -1) {
- perror("reading users");
- exit(-1);
- }
-
- while (read(fd, &butane, sizeof(struct utmp))) {
- if (butane.ut_name[0]) {
- strncpy(buddy[i].login, butane.ut_name, 8);
- strncpy(buddy[i].alias, butane.ut_name, 8);
- strncpy(buddy[i].line, butane.ut_line, 8);
- strcpy(buddy[i].host, butane.ut_host);
- buddy[i].time = butane.ut_time;
- status(&buddy[i]);
- i++;
- }
- }
- num_usrs = i;
- close(fd);
- }
-
- status(buddy) /** get the ttystatus of each buddy **/
- struct BUD *buddy;
- {
- struct stat sbuf;
- char tty[14];
- long now;
-
- sprintf(tty, "/dev/%s", buddy->line);
- if (stat(tty, &sbuf) == -1) {
- perror("getting tty status");
- buddy->perm = 0;
- return(-1);
- }
- time(&now);
- buddy->perm = 0;
- if ((now - sbuf.st_atime) >= 60) {
- buddy->perm |= IDLE;
- buddy->idle = now - sbuf.st_atime;
- }
- if (sbuf.st_mode & RITABLE) buddy->perm |= RITABLE;
- if (sbuf.st_mode & BIFF) buddy->perm |= BIFF;
- if (sbuf.st_mode & HORNY) buddy->perm |= HORNY;
- if (sbuf.st_mode & SINGLE) buddy->perm |= SINGLE;
- }
-
- int get_buds() { /** check the ~/.buddy for valid buddies **/
- FILE *fp;
- char budpath[100], login[8], alias[40];
- register int i;
-
- sprintf(budpath, "%s/.buddy", getenv("HOME"));
- if ((fp = fopen(budpath, "r")) == NULL) {
- perror("getting buddies");
- return(-1);
- }
- while (!feof(fp)) {
- fscanf(fp, "%s %[^\n]\n", login, alias);
- for (i = 0; i < num_usrs; i++)
- if (!strcmp(buddy[i].login, login)) {
- strncpy(buddy[i].alias, alias, 40);
- buddy[i].buddy = TRUE;
- }
- }
- return(1);
- }
-
- print_out() { /** print the final output to the screen **/
- struct tm *t;
- char idle[2], buf[14], host[20];
- register int i;
- long now;
- int valid[MAX_USERS], lav[2];
-
- num_buds = 0;
- gethostname(buf, 14);
- strncpy(hostname, buf, 5);
- hostname[5] = '\0';
-
- /** check to see whether buddy should be printed **/
- for (i = 0; i < num_usrs; i++) {
- valid[i] = TRUE;
- if (mode & LIST_ALL)
- valid[i] = TRUE; else
- if (!buddy[i].buddy && (!(mode & DONT_SUB)))
- valid[i] = FALSE;
- else valid[i] = TRUE;
- if (mode & C_RITEABLE)
- if (!(buddy[i].perm & RITABLE)) valid[i] = FALSE;
- if (mode & C_BIFF)
- if (!(buddy[i].perm & BIFF)) valid[i] = FALSE;
- if (mode & C_IDLE)
- if (!(buddy[i].perm & IDLE)) valid[i] = FALSE;
- if (mode & C_HORNY)
- if (!(buddy[i].perm & HORNY)) valid[i] = FALSE;
- if (mode & C_SINGLE)
- if (!(buddy[i].perm & SINGLE)) valid[i] = FALSE;
- if (valid[i] && buddy[i].buddy) num_buds++;
- }
-
- time(&now);
- t = localtime(&now);
-
- if (!shortf)
- printf("%d buddies out of %d users on %s : %s %d at %d:%02d%s\n",
- num_buds, num_usrs, hostname, month[t->tm_mon], t->tm_mday,
- t->tm_hour > 12 ? t->tm_hour-12 : t->tm_hour == 0 ? 12 : t->tm_hour,
- t->tm_min, t->tm_hour > 11 ? "pm" : "am");
-
- puts("===================================================================");
- for (i = 0; i < num_usrs; i++) {
- if (buddy[i].line[strlen(buddy[i].line)-2] == 'p')
- sprintf(host, "[%s]", !strncmp(buddy[i].host, PREFIX, sizeof(PREFIX)-1) ?
- buddy[i].host+sizeof(PREFIX)-1 : buddy[i].host);
- else strcpy(host, "");
-
- if (valid[i]) {
- if (buddy[i].idle >= 60) sprintf(idle, "%02d", buddy[i].idle / 60);
- else strcpy(idle, "--");
- printf("%-40.40s %c%c %s %c%c %2.2s (%s)%s%s %s\n",
- buddy[i].alias,
- buddy[i].perm & RITABLE ? 'w' : '-',
- buddy[i].perm & BIFF ? 'b' : '-',
- idle,
- buddy[i].perm & HORNY ? 'h' : '-',
- buddy[i].perm & SINGLE ? 's' : '-',
- strcmp(buddy[i].line, "console") ? &buddy[i].line[3] : "co",
- buddy[i].login, space(7-strlen(buddy[i].login)),
- lentime(now - buddy[i].time),
- host);
- }
- }
- #ifdef RWHOD
- if (!shortf) {
- load(lav);
- printf("================== Load: %2.2f %2.2f %2.2f ===========================\n",
- lav[0]/100.0, lav[1]/100.0, lav[2]/100.0);
- } else
- #endif /* RWHOD */
- puts("===================================================================");
- }
-
- char *space(len) /** returns a blank string of length 'len' **/
- int len;
- {
- register int i;
- static char tmp[100];
-
- strcpy(tmp, "");
- for (i = 0; i < len; i++) strcat(tmp, " ");
- return(tmp);
- }
-
- char *lentime (time) /** returns the time on in readable format **/
- long time;
- {
- static char buffer[32], /* A buffer for formatted time */
- *s; /* A pointer to the formatted time */
- int minutes, /* Number of minutes past the hour */
- hours; /* The number of hours past midnight */
-
- hours = time / 3600;
- minutes = (time % 3600) / 60;
- s = &buffer[31];
- *s-- = '\0';
- *s-- = minutes % 10 + '0';
- *s-- = minutes / 10 + '0';
- if (hours > 23)
- {
- hours %= 24;
- *s-- = '?';
- }
- else
- *s-- = ':';
- *s-- = hours % 10 + '0';
- *s = (hours >= 10) ? hours / 10 + '0' : ' ';
- return(s);
- }
-
- #ifdef RWHOD
- #include <protocols/rwhod.h>
-
- load(load_buf)
- int *load_buf;
- {
- struct whod wbuf;
- char whod_path[80];
- int fd;
-
- sprintf(whod_path, "/usr/spool/rwho/whod\.%s", hostname);
- if ((fd = open(whod_path, 0)) == -1) {
- perror("getting load");
- load_buf[0] = 0;
- load_buf[1] = 0;
- load_buf[2] = 0;
- return(-1);
- }
- read(fd, (char *) &wbuf, sizeof(struct whod));
- load_buf[0] = wbuf.wd_loadav[0];
- load_buf[1] = wbuf.wd_loadav[1];
- load_buf[2] = wbuf.wd_loadav[2];
- close(fd);
- }
-
- #endif /* RWHOD */
- \Rogue\Monster\
- else
- echo "will not over write ./buds.c"
- fi
- if `test ! -s ./cbuds.1`
- then
- echo "writing ./cbuds.1"
- cat > ./cbuds.1 << '\Rogue\Monster\'
- .TH CBUDS 1 BUDPAK
- .UC 4
- .SH NAME
- cbuds \- Convert a .buddy file to a .rbuds file.
- .SH SYNOPSIS
- .B cbuds
- .SH DESCRIPTION
- .I Cbuds
- reads in a
- .B .buddy
- file (from the user's home directory) and creates a
- .B .rbuds
- file (also in the user's home directory). See rbuds(1) for more information
- about the format of the .rbuds file.
- .SH AUTHOR
- Steven Grimm, koreth@ssyx.ucsc.edu
- .SH "SEE ALSO"
- rbuds(1)
- \Rogue\Monster\
- else
- echo "will not over write ./cbuds.1"
- fi
- if `test ! -s ./cbuds.c`
- then
- echo "writing ./cbuds.c"
- cat > ./cbuds.c << '\Rogue\Monster\'
- #include <stdio.h>
- #include <ctype.h>
-
- char *getenv();
-
- main()
- {
- FILE *bud, *rbud;
- char f1[99], f2[99];
-
- strcpy(f1, getenv("HOME"));
- strcpy(f2, f1);
- strcat(f1, "/.buddy");
- strcat(f2, "/.rbuds");
-
- if ((bud = fopen(f1, "r")) == NULL)
- {
- printf("Couldn't open %s for read.\n", f1);
- exit(-1);
- }
- if (access(f2, 0) == 0)
- {
- char x;
- printf("%s already exists. Overwrite? ", f2);
- fflush(stdout);
- x = getchar();
- if (toupper(x) != 'Y')
- {
- fclose(bud);
- exit(-1);
- }
- }
- if ((rbud = fopen(f2, "w+")) == NULL)
- {
- printf("Couldn't open %s for write.\n", f2);
- exit(-1);
- }
-
- while (! feof(bud))
- {
- char login[8], budname[99];
- fscanf(bud, "%s %[^\n]\n", login, budname);
- fprintf(rbud, "*%s\n%s\n", login, budname);
- }
- fclose(bud);
- fclose(rbud);
- }
-
- \Rogue\Monster\
- else
- echo "will not over write ./cbuds.c"
- fi
- if `test ! -s ./mbuds.1`
- then
- echo "writing ./mbuds.1"
- cat > ./mbuds.1 << '\Rogue\Monster\'
- .TH MBUDS 1 BUDPAK
- .UC 4
- .SH NAME
- mbuds \- Check buddies for mail
- .SH SYNOPSIS
- .B mbuds
- [
- .I user1
- .I user2
- .I user3
- \&... ]
- .SH DESCRIPTION
- .I Mbuds
- scans the file \fB.buddy\fR in the user's home directory (see budpak(1))
- and checks the users
- listed therein for mail. If there are some users whose mailboxes (which
- are assumed to be located in /usr/spool/mail) aren't empty, their names,
- their aliases in the .buddy file, and the length of their mailbox files
- are printed.
- .PP
- If login names are specified,
- .I mbuds
- scans those users' mailboxes and lists them (using the above format) whether
- they have mail or not.
- .SH AUTHOR
- Steven Grimm, koreth@ssyx.ucsc.edu
- .SH "SEE ALSO"
- buds(1), wbuds(1), monitor(1), rbuds(1), budpak(1)
- \Rogue\Monster\
- else
- echo "will not over write ./mbuds.1"
- fi
- if `test ! -s ./mbuds.c`
- then
- echo "writing ./mbuds.c"
- cat > ./mbuds.c << '\Rogue\Monster\'
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- char *getlogin(), *getenv(), *malloc();
-
- /*
- ** MBUDS - Check for buddies' mail
- **
- ** Usage: mbuds [login1 login2 login3...]
- **
- ** If no logins are specified, mbuds prints everyone in the user's .buddy
- ** file who has mail. Otherwise, only the specified logins are selected
- ** from the .buddy file, and are printed whether they have mail or not.
- */
-
- struct bud {
- char login[8];
- char name[40];
- struct bud *next;
- };
-
- struct bud *start;
-
- /* Read in a .buddy file and make a linked list out of it. */
- readbuds()
- {
- struct bud *end;
- FILE *fp;
- char budfile[80];
- strcpy(budfile, getenv("HOME"));
- strcat(budfile, "/.buddy");
- if ((fp=fopen(budfile, "r"))==NULL)
- {
- printf("No .buddy file.\n");
- return 0;
- }
- start = end = (struct bud *)NULL;
- while (! feof(fp))
- {
- struct bud *newnode;
- newnode = (struct bud *)malloc(sizeof(struct bud));
- newnode->login[0] = 0;
- newnode->next = (struct bud *)NULL;
- fscanf(fp, "%s %39[^\n]\n", newnode->login, newnode->name);
- if (strlen(newnode->login))
- {
- if (end)
- end->next = newnode;
- else
- start = newnode;
- end = newnode;
- }
- }
- return 1;
- }
-
- /* Scan the linked list for entries that aren't in the command line arguments
- and chop them out. */
- scanlist(argc, argv)
- int argc;
- char **argv;
- {
- struct bud *now, *then, *temp;
- if (argc < 2)
- return;
- argv++;
- argc--;
- then = (struct bud *)NULL;
- now = start;
- while (now)
- {
- int i;
- for (i = 0; i < argc; ++i)
- if (! strcmp(argv[i], now->login))
- break;
- if (i >= argc) /* Loop finished = name not found */
- {
- if (then)
- {
- temp = now;
- then->next = now->next;
- now = now->next;
- free(temp);
- }
- else
- {
- temp = now;
- start = now->next;
- now = start;
- free(temp);
- }
- }
- else
- {
- then = now;
- now = now->next;
- argv[i] = argv[argc]; /* Trim the list so it's */
- argc--; /* faster to search */
- }
- }
- }
-
- checkmail(bud)
- struct bud *bud;
- {
- struct stat buf;
- if (stat(bud->login, &buf) < 0)
- return 0;
- return (int)buf.st_size;
- }
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- struct bud *now;
- int maillen;
- chdir("/usr/spool/mail");
- if (! readbuds())
- exit(-1);
- scanlist(argc, argv);
- now = start;
- while (now)
- {
- maillen = checkmail(now);
- if (argc > 1 || maillen)
- {
- printf("%7s %-40s %6d bytes\n", now->login,
- now->name, maillen);
- }
- now = now->next;
- }
- }
-
- \Rogue\Monster\
- else
- echo "will not over write ./mbuds.c"
- fi
- if `test ! -s ./monitor.1`
- then
- echo "writing ./monitor.1"
- cat > ./monitor.1 << '\Rogue\Monster\'
- .TH MONITOR 1 BUDPAK
- .UC 4
- .SH NAME
- monitor \- Notify about logins and logouts
- .SH SYNOPSIS
- .B monitor
- [
- .I options
- ] [ user1 user2 user3 ... ]
- .SH DESCRIPTION
- .I Monitor
- is a utility that notifies the user when certain other people log on and off.
- Pass the usernames of the people to monitor on the command line. When one of
- the monitored people logs on, a short message is printed containing his
- username and alias in the user's
- .B .buddy
- file (see budpak(1)), if he has an alias there. If the \-o option
- (see below) is used, a short message is also printed when one of the
- monitored users logs off. The messages can be changed using the \-m option.
- .SH OPTIONS
- .TP
- .I \-o
- Users specified after the \-o option are monitored for both logins and
- logouts. Only logins are monitored for users specified before the \-o
- option.
- .TP
- .I \-c
- The \-c option prevents the program from printing its messages when "cbreak"
- mode is on. Cbreak is active in programs such as vi, which can easily be
- messed up by messages appearing at random on the screen. The messages are
- printed as soon as cbreak mode is deactivated (e.g., when you leave vi).
- .TP
- .I \-n
- The \-n option prevents \fImonitor\fR from printing users' real account
- names if there are aliases in the \fB.buddy\fR file.
- .TP
- .I \-N
- The \-N option prevents \fImonitor\fR from printing aliases from a \fB.buddy\fR
- file.
- .TP
- .I \-q
- The \-q (quiet) option suppresses \fImonitor\fR's startup message.
- .TP
- .I \-b
- The \-b flag stops \fImonitor\fR from beeping when it prints messages.
- .TP
- .I \-t
- The \-t flag causes \fImonitor\fR to print the name of the tty a monitoree
- is on, as well as his name.
- .TP
- .I \-d
- The \-d option causes \fImonitor\fR to terminate when any of the specified
- users logs on. This is useful if you're waiting for someone, and don't
- want to have to search for \fImonitor\fR's PID to kill it.
- .TP
- .I \-m
- The \-m option takes login names from a file called
- .B .monitor
- in the user's home directory, rather than from the command line. The format of
- the
- .B .monitor
- file is as follows: The first line is a message that's printed out when one
- of the users logs on (with a "%s" where the login name and/or buddy alias is
- to be placed). The second line is the logout message (again, with a "%s"
- where the username should go). The following lines are the login names that
- the user wants to watch for logins only (i.e., logouts aren't printed). Then,
- optionally, a line containing only a pound sign ("#") character can be followed
- by the login names of users to monitor for both logins and logouts. Note that
- it's possible to have the login/logout messages, then a pound sign and a list
- of users; that will monitor both logins and logouts of everyone listed in the
- .B .monitor
- file. A
- .B .monitor
- file might look like:
-
- Wow! %s is here!
- Drat. There goes %s.
- jones
- martin
- #
- root
- zooker
- harris
-
- .SH AUTHOR
- Steven Grimm, koreth@ssyx.ucsc.edu
- .SH FILES
- .TP
- /etc/utmp
- .TP
- $HOME/.monitor \-
- The file of login names to monitor, and the alert strings for logins and
- logouts.
- .TP
- $HOME/.buddy \-
- Buddy alias file.
- .SH "SEE ALSO"
- buds(1), rbuds(1), budpak(1)
- .SH BUGS
- .I Monitor
- doesn't allow different login and logout messages for individual buddies.
-
-
-
- \Rogue\Monster\
- else
- echo "will not over write ./monitor.1"
- fi
- if `test ! -s ./monitor.c`
- then
- echo "writing ./monitor.c"
- cat > ./monitor.c << '\Rogue\Monster\'
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <utmp.h>
- #include <signal.h>
- #include <sgtty.h>
-
- /*
- ** MONITOR - Watch people log on and off
- **
- ** Original program by Jon Luini
- ** niteowl@ssyx.ucsc.edu
- ** This version by Steven Grimm
- ** koreth@ssyx.ucsc.edu
- **
- ** Operation:
- **
- ** Monitor scans the file /etc/utmp and checks each entry to see if its
- ** tty is in the binary tree of ttys belonging to buddies (actually, the
- ** tree is a structure with lots of information about the buddy). If the
- ** tty is used by a buddy, Monitor compares the login names of the buddy and
- ** the person using the tty. If they're not equal, the buddy who used to
- ** be on the tty has logged off and a message to that effect may be printed.
- ** The buddy is deleted from the tty tree and added to the second tree,
- ** the buddy tree. If the tty isn't in the tty tree, the login name of the
- ** buddy is searched for in the second binary tree, which is sorted by login
- ** names. If the name is found, the buddy is added to the tty tree and a
- ** logon message is printed out.
- ** The /etc/utmp file isn't scanned if it hasn't been modified since the
- ** last time Monitor passed through it.
- */
-
- #define UTMP "/etc/utmp"
- #define WAIT 15 /* Seconds between status checks */
-
- char *ttyname(), *getenv(), *rindex();
-
- struct buddy {
- char tty[8]; /* Tty name */
- char login[8]; /* Login name */
- char budname[40]; /* .buddy file name, if any */
- int logoff; /* Flag: Monitor logoffs? */
- struct buddy *lchild, /* Binary search tree pointers */
- *rchild,
- *parent;
- };
-
- struct buddy *buddy, *tty;
-
- char logonmsg[80], /* Gets printed when someone logs on */
- logoffmsg[80], /* Gets printed when someone logs off */
- whichtty[8], /* Which tty this was started on */
- login[8]; /* Name of the user who started this */
-
- int check_off = 0, /* Flag: Check logoffs */
- die = 0, /* Flag: Die when someone comes on */
- quiet = 0, /* Flag: Start quietly */
- nobeep = 0, /* Flag: Don't beep */
- noreal = 0, /* Flag: Don't print account names */
- nofake = 0, /* Flag: Don't print buddy aliases */
- dotty = 0, /* Flag: Print a user's tty */
- cblock = 0; /* Flag: Don't interrupt cbreak */
-
- /* Search for a buddy. Pass a 0 in "type" to search for a login name, or a
- 1 to search for a tty. */
- struct buddy *bst_search(tree, key, type)
- struct buddy *tree;
- char *key;
- int type;
- {
- int comp;
- while (tree)
- {
- if (type)
- {
- if (! (comp=strcmp(key, tree->tty)))
- return tree;
- }
- else
- if (! (comp=strcmp(key, tree->login)))
- return tree;
- if (comp < 0)
- tree = tree->lchild;
- else
- tree = tree->rchild;
- }
- return tree;
- }
-
- /* Add a node to a tree (the node can have children). Pass the tree type,
- as in bst_search above. */
- bst_add(tree, node, type)
- struct buddy *tree, *node;
- int type;
- {
- int comp;
- if (! node)
- return 1;
- while (tree)
- {
- if (type)
- {
- if (! (comp=strcmp(node->tty, tree->tty)))
- return 0;
- }
- else
- if (! (comp=strcmp(node->login, tree->login)))
- return 0;
- if (comp < 0)
- {
- if (tree->lchild)
- tree = tree->lchild;
- else
- {
- tree->lchild = node;
- node->parent = tree;
- break;
- }
- }
- else
- {
- if (tree->rchild)
- tree = tree->rchild;
- else
- {
- tree->rchild = node;
- node->parent = tree;
- break;
- }
- }
- }
- if (tree)
- return 1;
- else
- return 0; /* This should never happen */
- }
-
- /* Delete a node from a tree. Returns the node that has taken the deleted
- node's place in the tree. */
- struct buddy *bst_delete(node, type)
- struct buddy *node;
- int type;
- {
- if (node->parent)
- {
- if (node == node->parent->lchild)
- {
- node->parent->lchild = node->rchild;
- if (node->rchild)
- node->rchild->parent = node->parent;
- if (node->lchild)
- bst_add(node->parent, node->lchild, type);
- return node->rchild;
- }
- else if (node == node->parent->rchild)
- {
- node->parent->rchild = node->lchild;
- if (node->lchild)
- node->lchild->parent = node->parent;
- if (node->rchild)
- bst_add(node->parent, node->rchild, type);
- return node->lchild;
- }
- else
- fprintf(stderr, "\r\nBinary tree error!\r\n");
- }
- else if (node->lchild)
- {
- node->lchild->parent = 0;
- if (node->rchild)
- bst_add(node->lchild, node->rchild, type);
- return node->lchild;
- }
- else if (node->rchild)
- {
- node->rchild->parent = 0;
- if (node->lchild)
- bst_add(node->rchild, node->lchild, type);
- return node->rchild;
- }
- else
- return (struct buddy *)0;
- }
-
- /* Handle one entry from the utmp file. */
- doutmp(entry)
- struct utmp *entry;
- {
- struct buddy *bud, *newbud;
- if (tty) /* Only check logoffs if there are buddies on */
- {
- bud = bst_search(tty, entry->ut_line, 1);
- if (bud)
- {
- if (strcmp(bud->login, entry->ut_name))
- {
- if (bud->logoff)
- domsg(logoffmsg, bud);
- newbud = bst_delete(bud);
- if (bud == tty)
- tty = newbud;
- free(bud);
- }
- return;
- }
- }
- if (buddy)
- {
- bud = bst_search(buddy, entry->ut_name, 0);
- if (bud)
- {
- newbud = (struct buddy *) malloc(sizeof(struct buddy));
- *newbud = *bud;
- strcpy(newbud->tty, entry->ut_line);
- newbud->parent =
- newbud->lchild =
- newbud->rchild = (struct buddy *) 0;
- if (tty)
- bst_add(tty, newbud, 1);
- else
- tty = newbud;
- domsg(logonmsg, newbud);
- if (die)
- exit(0);
- }
- }
- }
-
- /* Process the utmp file. Returns 0 if the user has logged off. */
- process()
- {
- int hand, status=1;
- struct utmp entry;
- hand = open(UTMP, 0);
- while (read(hand, &entry, sizeof(entry)) > 0)
- {
- if (! strcmp(entry.ut_line, whichtty))
- if (strcmp(entry.ut_name, login))
- status = 0;
- doutmp(&entry);
- }
- close(hand);
- return status;
- }
-
- /* Print the logoff message for a buddy. */
- domsg(message, bud)
- char *message;
- struct buddy *bud;
- {
- char budname[60], text[256];
- if ((! bud->budname[0]) || nofake)
- strcpy(budname, bud->login);
- else if (bud->budname[0] && !noreal)
- sprintf(budname, "%s (%s)", bud->budname, bud->login);
- else if (bud->budname[0])
- sprintf(budname, "%s", bud->budname);
- if (dotty)
- {
- strcat(budname, " on ");
- strcat(budname, bud->tty);
- }
- sprintf(text, message, budname);
- fprintf(stderr, "\r\n%s\r\n", text);
- if (! nobeep)
- putc(7, stderr);
- }
-
- /* Read in the .buddy file and assign aliases to the buddies in the buddy
- tree. */
- readbuddy()
- {
- char fname[256], login[8], budname[40];
- struct buddy *bud;
- FILE *fp;
- strcpy(fname, getenv("HOME"));
- strcat(fname, "/.buddy");
- if (!(fp = fopen(fname, "r")))
- return 1;
- while (! feof(fp))
- {
- fscanf(fp, "%s %[^\n]\n", login, budname);
- bud = bst_search(buddy, login, 0);
- if (bud)
- strcpy(bud->budname, budname);
- }
- fclose(fp);
- }
-
- /* Initialize the login and whichtty variables. */
- initvars()
- {
- char ttypath[256], *ri;
- strcpy(login, getenv("USER"));
- strcpy(ttypath, ttyname(2));
- ri = rindex(ttypath, '/');
- if (! ri)
- ri = ttypath;
- else
- ++ri;
- strcpy(whichtty, ri);
- buddy = tty = (struct buddy *)0;
- }
-
- /* Add a user to the buddy tree. */
- adduser(name)
- char *name;
- {
- struct buddy *newbud;
- newbud = (struct buddy *) malloc(sizeof(struct buddy));
- newbud->parent =
- newbud->lchild =
- newbud->rchild = (struct buddy *) 0;
- newbud->tty[0] = newbud->budname[0] = 0;
- newbud->logoff = check_off;
- strcpy(newbud->login, name);
- if (buddy)
- bst_add(buddy, newbud, 0);
- else
- buddy = newbud;
- }
-
- /* Read in a .monitor file. */
- readmonitor()
- {
- FILE *fp;
- char fname[256], user[80];
- strcpy(fname, getenv("HOME"));
- strcat(fname, "/.monitor");
- if (!(fp=fopen(fname, "r")))
- {
- printf("Monitor: Error opening %s.\n", fname);
- return 0;
- }
- fscanf(fp, "%[^\n]\n%[^\n]\n", logonmsg, logoffmsg);
- while (! feof(fp))
- {
- fscanf(fp, "%s\n", user);
- if (strcmp(user, "#"))
- adduser(user);
- else
- check_off = 1;
- }
- fclose(fp);
- return 1;
- }
-
- /* Check the last modify date of a file. */
- long lastmod(file)
- char *file;
- {
- struct stat buf;
- stat(file, &buf);
- return buf.st_mtime;
- }
-
- /* Check the tty for cbreak mode. */
- cbreak()
- {
- struct sgttyb tty;
- gtty(0, &tty);
- return tty.sg_flags & CBREAK;
- }
-
- /* Main program. */
- main(argc, argv)
- int argc;
- char **argv;
- {
- long lastutmp, lu;
- initvars();
- strcpy(logonmsg, "%s has logged on.");
- strcpy(logoffmsg, "%s has logged off.");
- while (*++argv)
- {
- if (argv[0][0] == '-')
- switch (argv[0][1])
- {
- case 'o':
- check_off = 1;
- break;
- case 'm':
- readmonitor();
- break;
- case 'c':
- cblock = 1;
- break;
- case 'd':
- die = 1;
- break;
- case 'q':
- quiet = 1;
- break;
- case 'n':
- noreal = 1;
- break;
- case 'N':
- nofake = 1;
- break;
- case 'b':
- nobeep = 1;
- break;
- case 't':
- dotty = 1;
- break;
- default:
- printf("%c: unknown flag\n",
- argv[0][1]);
- break;
- }
- else
- adduser(argv[0]);
- }
- if (! quiet)
- printf("Monitor: running on %s.\n", whichtty);
- if (fork()) /* Shove myself in the background */
- exit(0);
- signal(SIGHUP, SIG_IGN); /* Ignore some signals so that */
- signal(SIGINT, SIG_IGN); /* w won't think we're the user's */
- signal(SIGQUIT, SIG_IGN); /* current process. */
- if (! buddy)
- {
- printf("Monitor: No users selected (using default)\n");
- adduser("root");
- strcpy(buddy->budname, "God");
- }
- readbuddy();
- lastutmp = 0;
- while (1)
- {
- if ((!cblock)||(!cbreak()))
- {
- lu = lastmod(UTMP);
- if (lu != lastutmp)
- {
- lastutmp = lu;
- if (! process())
- exit(0);
- }
- }
- sleep(WAIT);
- }
- }
-
-
-
- \Rogue\Monster\
- else
- echo "will not over write ./monitor.c"
- fi
- if `test ! -s ./rbuds.1`
- then
- echo "writing ./rbuds.1"
- cat > ./rbuds.1 << '\Rogue\Monster\'
- .TH RBUDS 1 BUDPAK
- .UC 4
- .SH NAME
- rbuds \- Construct a random .buddy file
- .SH SYNOPSIS
- .B rbuds
- [
- .I \-b
- ]
- .SH DESCRIPTION
- .I Rbuds
- allows users to keep lists of aliases for buddies on the system, and select
- random names from those lists to put in a .buddy file. The input to
- .I rbuds
- is the file
- .B .rbuds
- in the user's home directory, which contains data in the following format:
- .PP
- *login1
- Buddy Alias 1 for login 1
- Buddy Alias 2 for login 1
- Buddy Alias 3 for login 1
- *login2
- Buddy Alias for login 2
- *login3
- Buddy Alias 1 for login 3
- Buddy Alias 2 for login 3
- .
- .
- .
- .PP
- Up to 128 aliases per buddy are allowed. When
- .I rbuds
- is run, it reads in all the buddy aliases for a login name and selects a
- random one to output to the
- .B .buddy
- file in the user's home directory.
- .SH OPTIONS
- .TP
- .I \-b
- The \-b option causes
- .I rbuds
- to put itself in the background as soon as it begins executing. This is
- primarily intended for users with large .rbuds files who want to put the
- .I rbuds
- command in their .login files without having to wait longer to log in.
- .SH AUTHOR
- Steven Grimm, koreth@ssyx.ucsc.edu
- .SH FILES
- $HOME/.buddy \- The output
- .br
- $HOME/.rbuds \- The input
- .SH "SEE ALSO"
- buds(1), mbuds(1), wbuds(1), monitor(1), budpak(1), cbuds(1)
- .SH BUGS
- Buddy aliases can't begin with asterisks.
-
- \Rogue\Monster\
- else
- echo "will not over write ./rbuds.1"
- fi
- if `test ! -s ./rbuds.c`
- then
- echo "writing ./rbuds.c"
- cat > ./rbuds.c << '\Rogue\Monster\'
- #include <stdio.h>
-
- /*
- ** RBUDS - make a .buddy file from a .rbuds file.
- **
- ** .rbuds is in the format
- **
- ** *login1
- ** Buddy Alias 0
- ** *login2
- ** Buddy Alias 1
- ** Buddy Alias 2
- ** Buddy Alias 3
- **
- ** Buddy aliases can't begin with asterisks. Up to 128 choices per login
- ** name are allowed.
- **
- ** If the -b option is used, rbuds puts itself in the background.
- */
-
- char *getenv();
-
- char oldlogin[8], curlogin[8];
- char budnames[40][128];
- FILE *rbuds, *buddy;
-
- /* Read in the names for a person and return an index into budnames[]
- corresponding to the name that'll be used. */
- getname()
- {
- int i=0;
- budnames[i][0] = ' ';
- while (! feof(rbuds))
- {
- fscanf(rbuds, "%[^\n]\n", budnames[i]);
- if (budnames[i][0] == '*')
- break;
- i++;
- }
- if (budnames[i][0] == '*')
- strcpy(curlogin, budnames[i]+1);
- return (random() % i);
- }
-
- main(argc, argv)
- char **argv;
- {
- char fname[128], bname[128];
- if (argc == 2 && !strcmp(argv[1], "-b"))
- if (fork())
- exit(0);
- srandom(getpid());
- strcpy(fname, getenv("HOME"));
- strcpy(bname, fname);
- strcat(fname, "/.rbuds");
- strcat(bname, "/.buddy");
- if (! (rbuds = fopen(fname, "r")))
- {
- fprintf(stderr, "rbuds: No .rbuds file!\n");
- exit(-1);
- }
- if (! (buddy = fopen(bname, "w+")))
- {
- fprintf(stderr, "rbuds: Couldn't open .buddy!\n");
- exit(-1);
- }
- fscanf(rbuds, "*%s\n", curlogin);
- while (! feof(rbuds))
- {
- strcpy(oldlogin, curlogin);
- fprintf(buddy, "%s %s\n", oldlogin, budnames[getname()]);
- }
- fclose(buddy);
- fclose(rbuds);
- }
-
- \Rogue\Monster\
- else
- echo "will not over write ./rbuds.c"
- fi
- if `test ! -s ./wbuds.1`
- then
- echo "writing ./wbuds.1"
- cat > ./wbuds.1 << '\Rogue\Monster\'
- .TH WBUDS 1 BUDPAK
- .UC 4
- .SH NAME
- wbuds \- See what buddies are doing
- .SH SYNOPSIS
- .B wbuds
- .SH DESCRIPTION
- .I Wbuds
- executes the "w" command, but only selects those users who are in the caller's
- ".buddy" file. It replaces the statistics reported by "w" with the aliases
- in the .buddy file.
- .SH AUTHOR
- Steven Grimm, koreth@ssyx.ucsc.edu
- .SH FILES
- /usr/ucb/w - the "w" command
- .SH "SEE ALSO"
- w(1), buds(1), budpak(1)
- .SH BUGS
- .I Wbuds
- assumes that the output of /usr/ucb/w is in a specific format.
- .PP
- .I Wbuds
- doesn't support the -s option to /usr/ucb/w, and can't restrict its
- output to certain users.
-
- \Rogue\Monster\
- else
- echo "will not over write ./wbuds.1"
- fi
- if `test ! -s ./wbuds.c`
- then
- echo "writing ./wbuds.c"
- cat > ./wbuds.c << '\Rogue\Monster\'
- #include <stdio.h>
-
- /*
- ** wbuds
- **
- ** Tells you what everyone in your .buddy file is doing.
- */
-
- #define W "/usr/ucb/w"
-
- extern char *getenv();
- extern FILE *popen();
-
- main()
- {
- FILE *buddy, *w;
- char budfile[128], budname[16], buddud[128];
- char buds[128][16], rbuds[128][60];
- int numbuds=0, i;
- strcpy(budfile, getenv("HOME"));
- strcat(budfile, "/.buddy");
- if ((buddy = fopen(budfile, "r")) == NULL)
- {
- printf("No .buddy file!\n");
- exit(-1);
- }
- while (! feof(buddy))
- {
- budname[0] = 0;
- fscanf(buddy, "%s", budname);
- if (! budname[0])
- continue;
- fscanf(buddy, "%[^\n]", buddud);
- getc(buddy);
- buddud[38] = 0;
- while (buddud[0] == 10) /* Strip tabs. */
- strcpy(buddud, buddud+1);
- strcpy(rbuds[numbuds], buddud);
- strcpy(buds[numbuds++], budname);
- }
- fclose(buddy);
- if ((w = popen(W, "r")) == NULL)
- {
- printf("%s isn't working.\n", W);
- exit(-1);
- }
- fscanf(w, "%[^\n]", buddud); /* Get the load, etc. */
- getc(w);
- printf("%s\n", buddud);
- printf("%-8s%-39s%s\n", "Login", "Name", "What");
- fscanf(w, "%[^\n]", buddud); /* Get the column headers. */
- getc(w);
- while (! feof(w))
- {
- buddud[0]=0;
- fscanf(w, "%[^\n]", buddud);
- buddud[8]=0;
- while (buddud[strlen(buddud)-1] == ' ')
- buddud[strlen(buddud)-1]=0;
- getc(w);
- for (i=0; i<numbuds; ++i)
- if (! strcmp(buddud, buds[i]))
- printf("%-7s%-40s%s\n", buddud, rbuds[i], &buddud[47]);
- }
- pclose(w);
- }
- \Rogue\Monster\
- else
- echo "will not over write ./wbuds.c"
- fi
- echo "Finished archive 1 of 1"
- # if you want to concatenate archives, remove anything after this line
- exit
-
-
-