art@pilikia.pegasus.com (Authur W. Neilson III) (04/19/91)
Submitted-by: Authur W. Neilson III <art@pilikia.pegasus.com> Posting-number: Volume 18, Issue 55 Archive-name: upsd/patch03 Patch-To: upsd: Volume 18, Issue 5 This is an update to the UPS monitor daemon. The update consists of 3 new files and the patchfile, "Patch03". New features are the broadcast of power fail and restore messages from user specified ASCII files and a man page for upsd(1M). Unshar this article in your upsd source directory and feed the file "Patch03" to Larry Wall's patch utility like so: patch < Patch03 Mahalo! Art. -----8<----- cut here -----8<----- cut here -----8<----- cut here -----8<----- #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: Patch03 upsd.1 upsfail upsrest # Wrapped by root@pilikia on Mon Apr 15 23:27:34 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Patch03' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Patch03'\" else echo shar: Extracting \"'Patch03'\" \(15648 characters\) sed "s/^X//" >'Patch03' <<'END_OF_FILE' X*** HISTORY.orig Mon Apr 15 23:25:28 1991 X--- HISTORY Mon Apr 15 23:26:03 1991 X*************** X*** 1,3 **** X--- 1,4 ---- X+ X UPSD RELEASE HISTORY art@pilikia.pegasus.com X X Date Release Patch Description X*************** X*** 7,9 **** X--- 8,13 ---- X added version stuff. X 04/10/91 1.0 2 Added log file locking, only 1 upsd can be running X now. Also added date to version string. X+ 04/15/91 1.0 3 Added broadcast of power fail and restore messages, X+ defined message file names as new command line and X+ environment variable parameters. Also made man page. X*** MANIFEST.orig Mon Apr 15 23:25:28 1991 X--- MANIFEST Mon Apr 15 23:26:03 1991 X*************** X*** 8,11 **** X--- 8,14 ---- X funcs.c 1 Functions X main.c 1 Main program X ups 1 Init.d startup script X+ upsd.1 1 Upsd man page X+ upsfail 1 UPS failure message file X+ upsrest 1 UPS restore message file X version.h 1 Version control header X*** Makefile.orig Mon Apr 15 23:25:28 1991 X--- Makefile Mon Apr 15 23:26:03 1991 X*************** X*** 11,24 **** X CC = cc X DEFS = X CFLAGS = -O $(DEFS) X CFILES = main.c funcs.c X OFILES = main.o funcs.o X HFILES = common.h X! LIBES = X DESTDIR = /etc X INITDIR = /etc/init.d X RC2DIR = /etc/rc2.d X RC2NUM = 22 X X upsd: $(OFILES) X $(CC) $(CFLAGS) $(OFILES) -o $@ $(LIBES) X--- 11,27 ---- X CC = cc X DEFS = X CFLAGS = -O $(DEFS) X+ LIBES = X+ X CFILES = main.c funcs.c X OFILES = main.o funcs.o X HFILES = common.h X! X DESTDIR = /etc X INITDIR = /etc/init.d X RC2DIR = /etc/rc2.d X RC2NUM = 22 X+ MANDIR = /usr/catman/u_man/man1 X X upsd: $(OFILES) X $(CC) $(CFLAGS) $(OFILES) -o $@ $(LIBES) X*************** X*** 31,37 **** X chgrp sys $(DESTDIR)/upsd X chmod 550 $(DESTDIR)/upsd X X! install_rc: install X cp ups $(INITDIR)/ups X chown root $(INITDIR)/ups X chgrp sys $(INITDIR)/ups X--- 34,40 ---- X chgrp sys $(DESTDIR)/upsd X chmod 550 $(DESTDIR)/upsd X X! install_rc: X cp ups $(INITDIR)/ups X chown root $(INITDIR)/ups X chgrp sys $(INITDIR)/ups X*************** X*** 38,43 **** X--- 41,57 ---- X chmod 744 $(INITDIR)/ups X ln $(INITDIR)/ups $(RC2DIR)/S$(RC2NUM)ups X X+ install_msg: X+ cp upsfail upsrest $(DESTDIR) X+ chown root $(DESTDIR)/upsfail $(DESTDIR)/upsrest X+ chgrp sys $(DESTDIR)/upsfail $(DESTDIR)/upsrest X+ chmod 644 $(DESTDIR)/upsfail $(DESTDIR)/upsrest X+ X+ install_man: X+ rm -f $(MANDIR)/upsd.1.z X+ nroff -man upsd.1 > $(MANDIR)/upsd.1 X+ pack $(MANDIR)/upsd.1 X+ X indent: X @for f in $(CFILES); do \ X indent $$f; \ X*************** X*** 50,56 **** X rm -f upsd core *.o *.BAK Part* X X clobber: clean X! rm -f $(DESTDIR)/upsd $(INITDIR)/ups $(RC2DIR)/S$(RC2NUM)ups X X # dependencies X main.o: main.c $(HFILES) X--- 64,71 ---- X rm -f upsd core *.o *.BAK Part* X X clobber: clean X! rm -f $(DESTDIR)/upsd $(DESTDIR)/upsfail $(DESTDIR)/upsrest X! rm -f $(INITDIR)/ups $(RC2DIR)/S$(RC2NUM)ups X X # dependencies X main.o: main.c $(HFILES) X*** README.orig Mon Apr 15 23:25:28 1991 X--- README Mon Apr 15 23:26:03 1991 X*************** X*** 1,4 **** X! Tue Apr 02 23:24:20 HST 1991 art@pilikia.pegasus.com Pg. 1 X X X INTRODUCTION X--- 1,4 ---- X! upsd release 03/30/91 version 1.0 patchlevel 3 Pg. 1 X X X INTRODUCTION X*************** X*** 24,30 **** X in the /etc directory when the install target is made. X X X! Tue Apr 02 23:24:20 HST 1991 art@pilikia.pegasus.com Pg. 2 X X X COMMAND LINE OPTIONS X--- 24,30 ---- X in the /etc directory when the install target is made. X X X! upsd release 03/30/91 version 1.0 patchlevel 3 Pg. 2 X X X COMMAND LINE OPTIONS X*************** X*** 34,43 **** X take precedence to the environment variable settings, and are X as follows: X X! usage: upsd [-d tty][-c cmd][-l log][-t min] X -d tty pathname of UPS device X -c cmd pathname of shutdown command X! -l log pathname of UPS log file X -t min delay time in minutes X X The -d tty option must specify the full pathname (including the X--- 34,45 ---- X take precedence to the environment variable settings, and are X as follows: X X! usage: upsd [-d tty][-c cmd][-l file][-t min][-f file][-r file] X -d tty pathname of UPS device X -c cmd pathname of shutdown command X! -l file pathname of UPS log file X! -f file pathname of UPS fail message file X! -r file pathname of UPS restore message file X -t min delay time in minutes X X The -d tty option must specify the full pathname (including the X*************** X*** 53,61 **** X X Example: X X! upsd -d /dev/ttyFM00 -c "/etc/shutdown -y -g1 -i0" X X! The -l option specified the logfile upsd will write it's event X messages to, these messages give the date and time that the UPS X daemon started, switched to battery, switched back to online, X executed the shutdown command, or was terminated via SIGTERM. X--- 55,63 ---- X X Example: X X! upsd -c "/etc/shutdown -y -i0" X X! The -l option specifies the logfile upsd will write it's event X messages to, these messages give the date and time that the UPS X daemon started, switched to battery, switched back to online, X executed the shutdown command, or was terminated via SIGTERM. X*************** X*** 62,69 **** X X Example: X X! upsd -d /dev/ttyFM00 -c "/etc/shutdown -y -g1 -i0" -l /etc/upslog X X Finally, the -t option specifies the number of minutes to allow X the UPS to be on battery backup before executing the shutdown X sequence. This number must be between 1 and 30. Be careful not X--- 64,91 ---- X X Example: X X! upsd -l /etc/upslog X X+ The -f option specifies the path name of the failure message file X+ to broadcast to all users in the event of a power failure. The X+ failure message file is simply an ASCII text file which you can X+ create with an editor such as vi(1). If the file is not found by X+ upsd, no message will be broadcast upon power failure. X+ X+ Example: X+ X+ upsd -f /etc/upsfail X+ X+ The -r option specifies the path name of the restore message file X+ to broadcast to all users in the event of power restore. The X+ restore message file is simply an ASCII text file which you can X+ create with an editor such as vi(1). If the file is not found by X+ upsd, no message will be broadcast upon power restore. X+ X+ Example: X+ X+ upsd -f /etc/upsrest X+ X Finally, the -t option specifies the number of minutes to allow X the UPS to be on battery backup before executing the shutdown X sequence. This number must be between 1 and 30. Be careful not X*************** X*** 73,81 **** X X Example: X X! upsd -d /dev/ttyFM00 -c "/etc/shutdown -y -g1 -i0" -l /etc/upslog -t 10 X X! Tue Apr 02 23:24:20 HST 1991 art@pilikia.pegasus.com Pg. 3 X X X ENVIRONMENT VARIABLES X--- 95,103 ---- X X Example: X X! upsd -t 10 X X! upsd release 03/30/91 version 1.0 patchlevel 3 Pg. 3 X X X ENVIRONMENT VARIABLES X*************** X*** 88,95 **** X Environment Equivalent Default X Variable Command line option Value X UPSPORT -p /dev/ttyFM00 X! UPSSHUT -c "/etc/shutdown -y -g1 -i0" X UPSLOG -l /etc/upslog X UPSTIME -t 10 X X Note that the compiled in default values can be altered in common.h X--- 110,119 ---- X Environment Equivalent Default X Variable Command line option Value X UPSPORT -p /dev/ttyFM00 X! UPSSHUT -c "/etc/shutdown -y -i0" X UPSLOG -l /etc/upslog X+ UPSFAIL -f /etc/upsfail X+ UPSREST -r /etc/upsrest X UPSTIME -t 10 X X Note that the compiled in default values can be altered in common.h X*** common.h.orig Mon Apr 15 23:25:28 1991 X--- common.h Mon Apr 15 23:26:03 1991 X*************** X*** 22,39 **** X X #define ERR -1 /* error return value */ X #define SH "/bin/sh" /* shell to exec shutdown command */ X! #define ROOT "/" /* root directory for chdir */ X #define CONSOLE "/dev/console" /* console device */ X #define SECS_PER_MIN 60 /* number of secs in a minute */ X #define MAX_TIME 30 /* maximum delay time allowed */ X- #define SHUT_PERMS 0500 /* shutdown command permissions mask */ X #define LOG_PERMS 0600 /* logfile permissions on create */ X #define LOG_FLAGS O_WRONLY | O_CREAT | O_APPEND /* logfile open flags */ X X /* default tuneable parameter values */ X #define UPS_PORT "/dev/ttyFM00" /* UPS port device name */ X! #define UPS_SHUT "/etc/shutdown -y -g0" /* shutdown command */ X #define UPS_LOG "/etc/upslog" /* UPS log file pathname */ X #define UPS_TIME 10 /* default delay time (minutes) */ X X /* environment variable names */ X--- 22,41 ---- X X #define ERR -1 /* error return value */ X #define SH "/bin/sh" /* shell to exec shutdown command */ X! #define WALL "/etc/wall" /* utility to broadcast messages */ X #define CONSOLE "/dev/console" /* console device */ X+ #define ROOT "/" /* root directory for chdir */ X #define SECS_PER_MIN 60 /* number of secs in a minute */ X #define MAX_TIME 30 /* maximum delay time allowed */ X #define LOG_PERMS 0600 /* logfile permissions on create */ X #define LOG_FLAGS O_WRONLY | O_CREAT | O_APPEND /* logfile open flags */ X X /* default tuneable parameter values */ X #define UPS_PORT "/dev/ttyFM00" /* UPS port device name */ X! #define UPS_SHUT "/etc/shutdown -y -i0" /* shutdown command */ X #define UPS_LOG "/etc/upslog" /* UPS log file pathname */ X+ #define UPS_FAIL "/etc/upsfail" /* UPS fail message file name */ X+ #define UPS_REST "/etc/upsrest" /* UPS restore message file name */ X #define UPS_TIME 10 /* default delay time (minutes) */ X X /* environment variable names */ X*************** X*** 40,45 **** X--- 42,49 ---- X #define UPSPORT "UPSPORT" X #define UPSSHUT "UPSSHUT" X #define UPSLOG "UPSLOG" X+ #define UPSFAIL "UPSFAIL" X+ #define UPSREST "UPSREST" X #define UPSTIME "UPSTIME" X X /* UPS log messages */ X*************** X*** 54,59 **** X--- 58,65 ---- X extern char *ups_port; /* UPS device name */ X extern char *ups_shut; /* system shutdown command */ X extern char *ups_log; /* UPS log file name */ X+ extern char *ups_fail; /* UPS failure message file name */ X+ extern char *ups_rest; /* UPS restore message file name */ X extern int ups_time; /* delay time before shutdown */ X extern int ups_fd; /* UPS port descriptor */ X extern int log_fd; /* log file descriptor */ X*** funcs.c.orig Mon Apr 15 23:25:28 1991 X--- funcs.c Mon Apr 15 23:26:03 1991 X*************** X*** 26,31 **** X--- 26,35 ---- X ups_shut = s; X if ((s = getenv(UPSLOG)) != NULL) X ups_log = s; X+ if ((s = getenv(UPSFAIL)) != NULL) X+ ups_fail = s; X+ if ((s = getenv(UPSREST)) != NULL) X+ ups_rest = s; X if ((s = getenv(UPSTIME)) != NULL) X ups_time = atoi(s); X } X*************** X*** 52,58 **** X version(av[0]); X X /* parse the command line */ X! while ((c = getopt(ac, av, "d:c:l:t:")) != EOF) X switch (c) { X case 'd': /* device option */ X ups_port = optarg; X--- 56,62 ---- X version(av[0]); X X /* parse the command line */ X! while ((c = getopt(ac, av, "d:c:l:f:r:t:")) != EOF) X switch (c) { X case 'd': /* device option */ X ups_port = optarg; X*************** X*** 63,68 **** X--- 67,78 ---- X case 'l': /* logfile option */ X ups_log = optarg; X break; X+ case 'f': /* failure option */ X+ ups_fail = optarg; X+ break; X+ case 'r': /* restore option */ X+ ups_rest = optarg; X+ break; X case 't': /* time option */ X ups_time = atoi(optarg); X break; X*************** X*** 76,81 **** X--- 86,92 ---- X ** c h k o p t i o n s X ** X ** check runtime options X+ ** with various sanity tests X */ X void X chkoptions() X*************** X*** 103,111 **** X perror(ups_shut); X exit(1); X } X! /* and must be readable/executable by owner */ X! if (!(st.st_mode & SHUT_PERMS)) { X! fprintf(stderr, "%s must be readable/executable by owner\n", ups_port); X exit(1); X } X /* delay time must be > 0 and <= MAX_TIME */ X--- 114,122 ---- X perror(ups_shut); X exit(1); X } X! /* and must be a regular file */ X! if ((st.st_mode & S_IFMT) != S_IFREG) { X! fprintf(stderr, "%s not regular\n", ups_port); X exit(1); X } X /* delay time must be > 0 and <= MAX_TIME */ X*************** X*** 127,132 **** X--- 138,144 ---- X X void sigcatch(); X void writelog(); X+ void writeall(); X void shutdown(); X X if (!fork()) { X*************** X*** 166,171 **** X--- 178,186 ---- X } X writelog(BATTERY_MSG); X X+ /* broadcast failure message */ X+ writeall(ups_fail); X+ X /* set the alarm clock */ X alarm(ups_time * SECS_PER_MIN); X X*************** X*** 175,180 **** X--- 190,198 ---- X X writelog(ONLINE_MSG); X X+ /* broadcast restore message */ X+ writeall(ups_rest); X+ X close(log_fd); X close(ups_fd); X X*************** X*** 191,198 **** X--- 209,218 ---- X sigcatch() X { X writelog(TERM_MSG); X+ X close(log_fd); X close(ups_fd); X+ X exit(1); X } X X*************** X*** 221,226 **** X--- 241,275 ---- X } X X /* X+ ** w r i t e a l l X+ ** X+ ** write to all users X+ */ X+ void X+ writeall(fn) X+ char *fn; X+ { X+ struct stat st; X+ void attach(); X+ X+ /* message file must exist */ X+ if (stat(fn, &st) == ERR) X+ return; X+ X+ /* and must be a regular file */ X+ if ((st.st_mode & S_IFMT) != S_IFREG) X+ return; X+ X+ if (!fork()) { X+ X+ attach(CONSOLE); X+ X+ /* write message file to users */ X+ execlp(WALL, WALL, fn, NULL); X+ } X+ } X+ X+ /* X ** s h u t d o w n X ** X ** shutdown the system X*************** X*** 232,246 **** X X writelog(SHUTDOWN_MSG); X X! close(log_fd); X! close(ups_fd); X X! attach(CONSOLE); X X! chdir(ROOT); X X! /* execute shutdown command */ X! execlp(SH, SH, "-c", ups_shut, NULL); X } X X /* X--- 281,298 ---- X X writelog(SHUTDOWN_MSG); X X! close(ups_log); X! close(ups_port); X X! if (!fork()) { X! X! attach(CONSOLE); X X! chdir(ROOT); X X! /* execute shutdown command */ X! execlp(SH, SH, "-c", ups_shut, NULL); X! } X } X X /* X*************** X*** 314,323 **** X { X char *basename(); X X! fprintf(stderr, "usage: %s [-d tty][-c cmd][-l log][-t min][-v]\n", X! basename(s)); X fprintf(stderr, "\t-d tty\t\tpathname of UPS device\n"); X fprintf(stderr, "\t-c cmd\t\tpathname of shutdown command\n"); X! fprintf(stderr, "\t-l log\t\tpathname of UPS log file\n"); X fprintf(stderr, "\t-t min\t\tdelay time in minutes\n"); X } X--- 366,376 ---- X { X char *basename(); X X! fprintf(stderr, "usage: %s [-d tty][-c cmd][-l file][-f file][-r file][-t min]\n", basename(s)); X fprintf(stderr, "\t-d tty\t\tpathname of UPS device\n"); X fprintf(stderr, "\t-c cmd\t\tpathname of shutdown command\n"); X! fprintf(stderr, "\t-l file\t\tpathname of UPS log file\n"); X! fprintf(stderr, "\t-f file\t\tpathname of UPS fail message file\n"); X! fprintf(stderr, "\t-r file\t\tpathname of UPS restore message file\n"); X fprintf(stderr, "\t-t min\t\tdelay time in minutes\n"); X } X*** main.c.orig Mon Apr 15 23:25:28 1991 X--- main.c Mon Apr 15 23:26:03 1991 X*************** X*** 14,19 **** X--- 14,21 ---- X char *ups_port = UPS_PORT; X char *ups_shut = UPS_SHUT; X char *ups_log = UPS_LOG; X+ char *ups_fail = UPS_FAIL; X+ char *ups_rest = UPS_REST; X int ups_time = UPS_TIME; X X /* global descriptors */ X*** version.h.orig Mon Apr 15 23:25:28 1991 X--- version.h Mon Apr 15 23:26:03 1991 X*************** X*** 11,14 **** X #define RELEASE_DATE "03/30/91" X #define RELEASE 1 X #define REVISION 0 X! #define PATCHLEVEL 2 X--- 11,14 ---- X #define RELEASE_DATE "03/30/91" X #define RELEASE 1 X #define REVISION 0 X! #define PATCHLEVEL 3 END_OF_FILE if test 15648 -ne `wc -c <'Patch03'`; then echo shar: \"'Patch03'\" unpacked with wrong size! fi # end of 'Patch03' fi if test -f 'upsd.1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'upsd.1'\" else echo shar: Extracting \"'upsd.1'\" \(2916 characters\) sed "s/^X//" >'upsd.1' <<'END_OF_FILE' X.\"upsd release 03/30/91 version 1.0 patchlevel 3 X.TH UPSD 1M X.SH NAME Xupsd \- UPS monitor daemon X.SH SYNOPSIS X.B /etc/upsd X[\-d tty] [\-c cmd] [\-l file] [\-f file] [\-r file] [\-t min] X.SH DESCRIPTION X.I Upsd Xmonitors the serial port connected to an UPS device Xand will perform an unattended shutdown of the system Xif the UPS is on battery longer than a specified Xnumber of minutes. X.I Upsd Xneeds to watch a tty with modem control properties, Xand expects the UPS to raise DCD when it switches to Xbattery backup and drop DCD when it goes back to an Xonline state. X.SH OPTIONS X.I upsd Xhas the following command line options: X.IP "-d \fItty\fP" XSpecifies the full pathname (including the /dev prefix) Xto the tty device the UPS is on. This must be a modem Xcontrol type device. X.PP X.IP "-c \fIcmd\fP" XSpecifies the full pathname of the command to be executed Xto shut down the system. This command must be enclosed in Xquotes if it consists of 2 or more words. X.PP X.IP "-l \fIfile\fP" XSpecifies the logfile X.I upsd Xwill write it's event messages to, these messages give the Xdate and time that the UPS daemon started, switched to battery, Xswitched back to online, executed the shutdown command, or was Xterminated via SIGTERM. X.PP X.IP "-f \fIfile\fP" XSpecifies the path name of the failure message file to broadcast Xto all users in the event of a power failure. The failure message Xfile is simply an ASCII text file which you can create with an editor Xsuch as vi(1). If the file is not found by X.I upsd X, no message will be broadcast upon power failure. X.PP X.IP "-r \fIfile\fP" XSpecifies the path name of the restore message file to broadcast Xto all users in the event of power restore. The restore message Xfile is simply an ASCII text file which you can create with an editor Xsuch as vi(1). If the file is not found by X.I upsd X, no message will be broadcast upon power restore. X.PP X.IP "-t \fImin\fP" XSpecifies the number of minutes to allow the UPS to be on battery Xbackup before executing the shutdown sequence. This number must Xbe between 1 and 30. Be careful not to choose a value greater than Xthe number of minutes of battery time your UPS supports with your Xcurrent load. A value in the 5 to 10 minute range is probably sufficient. X.PP X.SH ENVIRONMENT VARIABLES XThe following environment variables can be set if that interface Xis preferred to the command line options. Note that command Xline options override the environment variable settings. X.sp XEnvironment Equivalent Default XVariable Command line option Value XUPSPORT -p /dev/ttyFM00 XUPSSHUT -c "/etc/shutdown -y -i0" XUPSLOG -l /etc/upslog XUPSFAIL -f /etc/upsfail XUPSREST -r /etc/upsrest XUPSTIME -t 10 X.sp X.SH FILES X/etc/upslog upsd event log X.br X/etc/upsfail upsd failure message file X.br X/etc/upsrest upsd restore message file X.SH SEE ALSO Xshutdown(1M), wall(1). X.SH AUTHOR XArthur W. Neilson III X.br Xart@pilikia.pegasus.com END_OF_FILE if test 2916 -ne `wc -c <'upsd.1'`; then echo shar: \"'upsd.1'\" unpacked with wrong size! fi # end of 'upsd.1' fi if test -f 'upsfail' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'upsfail'\" else echo shar: Extracting \"'upsfail'\" \(188 characters\) sed "s/^X//" >'upsfail' <<'END_OF_FILE' XUPS ONLINE POWER FAILED, UPS is now on battery backup power. XThe system will shut down automatically in 10 minutes if power Xis not restored. Please log off the system as soon as you can. END_OF_FILE if test 188 -ne `wc -c <'upsfail'`; then echo shar: \"'upsfail'\" unpacked with wrong size! fi # end of 'upsfail' fi if test -f 'upsrest' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'upsrest'\" else echo shar: Extracting \"'upsrest'\" \(99 characters\) sed "s/^X//" >'upsrest' <<'END_OF_FILE' XUPS ONLINE POWER RESTORED! UPS now on wall power. XYou may resume your work and proceed as normal. END_OF_FILE if test 99 -ne `wc -c <'upsrest'`; then echo shar: \"'upsrest'\" unpacked with wrong size! fi # end of 'upsrest' fi echo shar: End of shell archive. exit 0 -----8<----- cut here -----8<----- cut here -----8<----- cut here -----8<----- -- Arthur W. Neilson III | INET: art@pilikia.pegasus.com Bank of Hawaii Tech Support | UUCP: uunet!ucsd!nosc!pilikia!art exit 0 # Just in case... -- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM Sterling Software, IMD UUCP: uunet!sparky!kent Phone: (402) 291-8300 FAX: (402) 291-4362 Please send comp.sources.misc-related mail to kent@uunet.uu.net.