marc@PostImage.COM (Marc Boucher) (05/07/91)
Yet another ups daemon. This one's good for people without a serial port to spare. (The hardware interface uses the game port) This code is being released because of the numerous requests I have received for it. I am placing it in the public domain. It's probably filled with local dependencies and will require some adaptation to your site. On powerloss, it stops cron, disables logins (by creating /etc/issue.linefail- when this file exists, our custom login program displays its contents and aborts the login attempt) and broadcasts a message to all logged in users (except those whose names start with "uu" [uucp logins]; again, a local assumption). The system is brought down only when the low battery condition is detected. If power returns before the battery becomes low, cron is restarted, /etc/issue.linefail removed and the users are notified. Brian E. Litzinger's peek driver must be installed in your kernel and available as /dev/peek. You can get it by anonymous FTP from svin02.info.win.tue.nl:/pub/sysvX86/peek.tar.z If you can't FTP, email me. -Marc. -- Marc Boucher Internet: marc@PostImage.COM BIX: mboucher Dir., Informatique Telephone: (514) 489-8989 FAX: 489-0242 (H) PostImage Inc. 6265 St-Jacques O., Montreal QC Canada H4B 1T8 #!/bin/sh # This is a shell archive (shar 3.20) # made 05/06/1991 19:14 UTC by marc@Cactus # Source directory /usr3/home/marc/upsd # # existing files WILL be overwritten # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 1136 -rw-r--r-- README # 2009 -rw------- CABLE # 223 -rw-r--r-- Makefile # 4411 -rw-r--r-- upsd.c # 286 -rwxr--r-- upsd.init # if touch 2>&1 | fgrep '[-amc]' > /dev/null then TOUCH=touch else TOUCH=true fi # ============= README ============== echo "x - extracting README (Text)" sed 's/^X//' << 'SHAR_EOF' > README && XYet another ups daemon. This one's good for people without a serial port to Xspare. (The hardware interface uses the game port) X XThis code is being released because of the numerous requests I have received Xfor it. I am placing it in the public domain. It's probably filled with local Xdependencies and will require some adaptation to your site. X XOn powerloss, it stops cron, disables logins (by creating /etc/issue.linefail- Xwhen this file exists, our custom login program displays its contents and Xaborts the login attempt) and broadcasts a message to all logged in users X(except those whose names start with "uu" [uucp logins]; again, a local Xassumption). The system is brought down only when the low battery condition Xis detected. If power returns before the battery becomes low, cron Xis restarted, /etc/issue.linefail removed and the users are notified. X XBrian E. Litzinger's peek driver must be installed in your kernel and available Xas /dev/peek. You can get it by anonymous FTP from X svin02.info.win.tue.nl:/pub/sysvX86/peek.tar.z X XIf you can't FTP, email me. X XMarc Boucher. XInternet: marc@PostImage.COM Telephone: +1 514 489-8989 SHAR_EOF $TOUCH -am 0506151391 README && chmod 0644 README || echo "restore of README failed" set `wc -c README`;Wc_c=$1 if test "$Wc_c" != "1136"; then echo original size 1136, current size $Wc_c fi # ============= CABLE ============== echo "x - extracting CABLE (Text)" sed 's/^X//' << 'SHAR_EOF' > CABLE && X XThe following cable will link any standard PC joystick port to Xany American Power Conversion UPS computer interface. This has been tested Xon an APC 520ES model UPS and on two different joystick cards. If your Xjoystick card has two ports, you can use either without reconfiguring Xthe software. The joystick buttons used for monitoring the UPS Xare those of the primary joystick. If you wish to keep using a primary Xjoystick on your system and still use this software, you will need to Xmodify the cable and software appropriately (i.e. wire buttons 6 and 7 Xinstead, figure out new port values for line fail and low battery). X X X UPS -> PC-Type Joystick port interface X -------------------------------------- X X XIBM PC Standard Joystick port American Power Conversion UPS X----------------------------- ----------------------------- X DB-15 connector(male) DB-9 connector (male) X X PIN # DESC Wiring PIN # DESC X 1 + 5VDC 1 hi=RS-232C shutdown input X 2 BUTTON 4 --------\ 2 hi=RS-232C fail X 3 POSITION 0 \---------- 3 closed=line fail X 4 GROUND ---------------------- 4 switch common X 5 N/C +--------- 5 closed=low battery X 6 POSITION 1 / 6 N/C X 7 BUTTON 5 --------+ 7 N/C X 8 + 5VDC 8 N/C X 9 + 5VDC 9 chassis ground X 10 BUTTON 6 X 11 POSITION 2 X 12 GROUND X 13 POSITION 3 X 14 BUTTON 7 X 15 GROUND X XNote: Due to the lack of output signals on the joystick port, the UPS X input that allows the UPS to shut down to conserve its batteries is X not supported. One possibility involves the use of the PC speaker X and some external circuitry... any takers ? - pascal@CAM.ORG X X X SHAR_EOF $TOUCH -am 0506151491 CABLE && chmod 0600 CABLE || echo "restore of CABLE failed" set `wc -c CABLE`;Wc_c=$1 if test "$Wc_c" != "2009"; then echo original size 2009, current size $Wc_c fi # ============= Makefile ============== echo "x - extracting Makefile (Text)" sed 's/^X//' << 'SHAR_EOF' > Makefile && X XINSTBIN=/usr/local/etc/upsd X Xupsd: upsd.c X cc -O -s -o upsd upsd.c -lc_s X mcs -d upsd X Xinstall: upsd X -mv -f $(INSTBIN) $(INSTBIN)- X rm -f $(INSTBIN)- X cp upsd $(INSTBIN) X chmod 100 $(INSTBIN) X Xclean: X rm -f *.o upsd core SHAR_EOF $TOUCH -am 1215193690 Makefile && chmod 0644 Makefile || echo "restore of Makefile failed" set `wc -c Makefile`;Wc_c=$1 if test "$Wc_c" != "223"; then echo original size 223, current size $Wc_c fi # ============= upsd.c ============== echo "x - extracting upsd.c (Text)" sed 's/^X//' << 'SHAR_EOF' > upsd.c && X/* X $Id: upsd.c,v 1.3 1991/05/06 19:10:34 marc Exp marc $ X XYet another ups daemon. This one's good for people without a serial port to Xspare. (The hardware interface uses the game port) X XThis code is being released because of the numerous requests I have received Xfor it. I am placing it in the public domain. It's probably filled with local Xdependencies and will require some adaptation to your site. X XOn powerloss, it stops cron, disables logins (by creating /etc/issue.linefail- Xwhen this file exists, our custom login program displays its contents and Xaborts the login attempt) and broadcasts a message to all logged in users X(except those whose names start with "uu" [uucp logins]; again, a local Xassumption). The system is brought down only when the low battery condition Xis detected. If power returns before the battery becomes low, cron Xis restarted, /etc/issue.linefail removed and the users are notified. X XBrian E. Litzinger's peek driver must be installed in your kernel and available Xas /dev/peek. You can get it by anonymous FTP from X svin02.info.win.tue.nl:/pub/sysvX86/peek.tar.z X XIf you can't FTP, email me. X XMarc Boucher. XInternet: marc@PostImage.COM Telephone: +1 514 489-8989 X X*/ X#include <fcntl.h> X#include <stdio.h> X#include <sys/types.h> X#include <sys/signal.h> X#include <sys/utsname.h> X#include <utmp.h> X X#include <sys/peek.h> X X#define INTERVAL 20 /* Time in seconds between checks */ X X#define PORTADDR 0x201 X X#define UPSF_LINEFAIL (1<<6) X#define UPSF_LOWBATT (1<<7) X X#define CONSOLE "/dev/console" X#define LOGFILE "/usr/adm/upslog" X#define ISSUEPOWER "/etc/issue.linefail" X Xvoid SendMsg(str, line) Xchar *str, *line; X{ X FILE *linefil; X X linefil=fopen(line, "w"); X if(linefil) { X time_t ti; X struct utsname unam; X char tibuf[40]; X X uname(&unam); X time(&ti); X cftime(tibuf, "%a %b %e %T %Y", &ti); X fprintf(linefil, "\n\007Broadcast Message from UPS daemon on %s [ %s ]...\n%s\n\n", unam.nodename, tibuf, str); X fclose(linefil); X } X} X Xvoid Broadcast(str) Xchar *str; X{ X struct utmp *uptr, *getutent(); X int console=0; X X setutent(); X while(uptr=getutent()) { X if((uptr->ut_type==USER_PROCESS)&&(strncmp(uptr->ut_user, "uu", 2))) { X char line[32]; X X sprintf(line, "/dev/%s", uptr->ut_line); X if(!strcmp(line, CONSOLE)) console=1; X SendMsg(str, line); X } X } X endutent(); X if(!console) SendMsg(str, CONSOLE); X} X Xvoid LogString(class, str) Xchar class; Xchar *str; X{ X char *datimebuf[255]; X time_t ti; X FILE *logfil; X X time(&ti); X cftime(datimebuf, "%D %T", &ti); X X logfil=fopen(LOGFILE, "a"); X X if(logfil) { X fprintf(logfil, "%c/%d %s - %s\n", class, getpid(), datimebuf, str); X fclose(logfil); X } X} X Xvoid LineFail() X{ X FILE *issuepower; X X LogString('F', "Line Fail"); X Broadcast("POWER FAILURE DETECTED: SYSTEM WILL SHUTDOWN IF UPS BATTERY BECOMES LOW"); X system("/etc/init.d/cron stop"); X issuepower=fopen(ISSUEPOWER, "w"); X if(!issuepower) LogString('E', "Can't open /etc/issue.linefail for writing"); X else { X fprintf(issuepower, "\nLogins have been disabled by the UPS daemon because of power failure.\n"); X fclose(issuepower); X } X} X Xvoid EndLineFail() X{ X X LogString('F', "Line Normal"); X Broadcast("GOOD NEWS: POWER HAS BEEN RESTORED."); X system("/etc/init.d/cron start"); X unlink(ISSUEPOWER); X} X Xvoid LowBattery() X{ X LogString('L', "Low Battery"); X Broadcast("UPS BATTERY IS LOW!!! SYSTEM GOING DOWN IN 40 SECONDS. LOGOUT NOW!"); X sleep(40); X Broadcast("UPS BATTERY IS LOW!!! SYSTEM GOING DOWN IMMEDIATELY!"); X LogString('L', "System going down"); X sync(); X unlink(ISSUEPOWER); X close(0); close(1); close(2); X open("/dev/console", O_RDWR); X open("/dev/console", O_RDWR); X open("/dev/console", O_RDWR); X sync(); X execlp("/etc/init", "init", "0", 0); X LogString('E', "Can't exec /etc/init!!!"); X sync(); X exit(1); X} X Xmain() X{ X int peekfd; X struct peek_t pd; X int linefail=0; X X if(fork()) exit(0); X X setpgrp(); X X chdir("/"); X X signal(SIGHUP, SIG_IGN); X signal(SIGINT, SIG_IGN); X X pd.port=PORTADDR; X X peekfd=open("/dev/peek", O_RDONLY); X if(peekfd==-1) { X LogString('E', "Can't open /dev/peek"); X exit(1); X } X X for(;;) { X if (ioctl(peekfd,PEEKIN,&pd)==-1) { X LogString('E', "ioctl() error"); X exit(1); X } X X if(pd.data&UPSF_LINEFAIL) { X if(linefail) { X linefail=0; X EndLineFail(); X } X } else if(!linefail) { X linefail=1; X LineFail(); X } X X if(!(pd.data&UPSF_LOWBATT)) LowBattery(); /* Never returns */ X X sleep(INTERVAL); X } X /* Not reached */ X} SHAR_EOF $TOUCH -am 0506151291 upsd.c && chmod 0644 upsd.c || echo "restore of upsd.c failed" set `wc -c upsd.c`;Wc_c=$1 if test "$Wc_c" != "4411"; then echo original size 4411, current size $Wc_c fi # ============= upsd.init ============== echo "x - extracting upsd.init (Text)" sed 's/^X//' << 'SHAR_EOF' > upsd.init && Xcase $1 in X'start') X ( cd /usr/local/etc ; PATH=.:$PATH ; upsd </dev/console >/dev/console 2>&1 ) X ;; X'stop') X pid=`/bin/ps -e | grep upsd | sed -e 's/^ *//' -e 's/ .*//'` X if [ "${pid}" != "" ] X then X /bin/kill ${pid} X fi X ;; X*) X echo "usage: /etc/init.d/upsd {start|stop}" X ;; Xesac SHAR_EOF $TOUCH -am 0506144791 upsd.init && chmod 0744 upsd.init || echo "restore of upsd.init failed" set `wc -c upsd.init`;Wc_c=$1 if test "$Wc_c" != "286"; then echo original size 286, current size $Wc_c fi exit 0