did some renaming of main dirs (apps, libs, etc.)
This commit is contained in:
commit
463c6ce880
3 files changed
+364
No files matched your search
@@ -0,0 +1,6 @@
|
||||
upsd: upsd.c
|
||||
cc -Os upsd.c -o upsd
|
||||
|
||||
install: upsd
|
||||
install -s -o root -g wheel -m 500 upsd /usr/local/sbin/upsd
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#define POLL_INTERVAL (1)
|
||||
|
||||
int fd = -1;
|
||||
|
||||
// Main program
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int lastflags = 0;
|
||||
bool cts,cd,dtr;
|
||||
|
||||
// check parameters
|
||||
if (argc < 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: pinout <device>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// open serial port
|
||||
if ((fd = open(argv[1], O_RDONLY | O_NDELAY)) < 0)
|
||||
{
|
||||
fprintf(stderr, "pinout: %s: %s\n", argv[1], sys_errlist[errno]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Main loop
|
||||
while (1)
|
||||
{
|
||||
int flags;
|
||||
|
||||
// Get the current line bits
|
||||
ioctl(fd, TIOCMGET, &flags);
|
||||
flags &= ~TIOCM_DTR;
|
||||
ioctl(fd, TIOCMSET, &flags);
|
||||
|
||||
// set state
|
||||
cts = (flags & TIOCM_CTS ? true : false);
|
||||
cd = (flags & TIOCM_CD ? true : false);
|
||||
dtr = (flags & TIOCM_DTR ? true : false);
|
||||
|
||||
if ( flags != lastflags )
|
||||
printf("cts=%s cd=%s dtr=%s\n",
|
||||
cts?"high":"low",
|
||||
cd?"high":"low",
|
||||
dtr?"high":"low"
|
||||
);
|
||||
lastflags = flags;
|
||||
|
||||
sleep(POLL_INTERVAL);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,293 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#define POLL_INTERVAL (1) // poll the ups this often (seconds)
|
||||
#define KILL_TIME (10) // ups needs this much time with shutdown signal
|
||||
#define SHUTDOWN_TIME (300) // halt system after this much time
|
||||
#define DEBOUNCE_TIME (5) // fluctuations less than this time don't count
|
||||
|
||||
#define SHUTDOWN_CMD "/sbin/halt -p"
|
||||
|
||||
#define INIT_BITS TIOCM_RTS
|
||||
#define KILL_BITS TIOCM_DTR
|
||||
#define BATT_GOOD_BITS TIOCM_CD
|
||||
#define POWER_GOOD_BITS TIOCM_CTS
|
||||
|
||||
int fd = -1;
|
||||
|
||||
enum
|
||||
{
|
||||
U_OK,
|
||||
U_LOW,
|
||||
U_FAIL
|
||||
};
|
||||
|
||||
void warn(int secondsleft)
|
||||
{
|
||||
//printf("warn\n");
|
||||
syslog(LOG_ALERT,"power failure. shutting down in %d seconds.",secondsleft);
|
||||
}
|
||||
|
||||
void lowmessage()
|
||||
{
|
||||
//printf("low\n");
|
||||
syslog(LOG_ALERT,"ups battery low.");
|
||||
}
|
||||
|
||||
void setline(int kill)
|
||||
{
|
||||
int flags;
|
||||
|
||||
// Get the current line bits
|
||||
ioctl(fd, TIOCMGET, &flags);
|
||||
|
||||
// and set ours
|
||||
flags |= INIT_BITS;
|
||||
if ( kill )
|
||||
{
|
||||
syslog(LOG_ALERT,"ups powerdown enabled.");
|
||||
flags |= KILL_BITS;
|
||||
}
|
||||
else
|
||||
{
|
||||
//syslog(LOG_ALERT,"reset ups. ups powerdown disabled.");
|
||||
flags &= ~KILL_BITS;
|
||||
}
|
||||
ioctl(fd, TIOCMSET, &flags);
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
//printf("init\n");
|
||||
setline(0);
|
||||
}
|
||||
|
||||
void killups()
|
||||
{
|
||||
//printf("killups\n");
|
||||
setline(1);
|
||||
}
|
||||
|
||||
void shutdown()
|
||||
{
|
||||
//printf("shutdown\n");
|
||||
syslog(LOG_ALERT,"shutting down.");
|
||||
system(SHUTDOWN_CMD);
|
||||
}
|
||||
|
||||
void cancel()
|
||||
{
|
||||
//printf("cancel\n");
|
||||
syslog(LOG_ALERT,"power returned. cancelling shutdown.");
|
||||
init();
|
||||
}
|
||||
|
||||
void flagdump(int flags)
|
||||
{
|
||||
int low = !((flags & BATT_GOOD_BITS) == BATT_GOOD_BITS);
|
||||
int fail = !((flags & POWER_GOOD_BITS) == POWER_GOOD_BITS);
|
||||
int init = ((flags & INIT_BITS) == INIT_BITS);
|
||||
int kill = ((flags & KILL_BITS) == KILL_BITS);
|
||||
|
||||
//printf("low=%d fail=%d init=%d kill=%d\n",low,fail,init,kill);
|
||||
}
|
||||
|
||||
int readline()
|
||||
{
|
||||
static int count = 0;
|
||||
static int state = U_OK;
|
||||
static int lastnextstate = U_OK;
|
||||
int nextstate;
|
||||
|
||||
int flags;
|
||||
|
||||
// Get the current line bits
|
||||
ioctl(fd, TIOCMGET, &flags);
|
||||
|
||||
flagdump(flags);
|
||||
|
||||
// nextstate = current line conditions
|
||||
nextstate = U_OK;
|
||||
if ( (flags & POWER_GOOD_BITS) != POWER_GOOD_BITS )
|
||||
{
|
||||
if ( (flags & BATT_GOOD_BITS) != BATT_GOOD_BITS )
|
||||
nextstate = U_LOW;
|
||||
else
|
||||
nextstate = U_FAIL;
|
||||
}
|
||||
|
||||
// count the time we've been in this new state
|
||||
if ( nextstate != lastnextstate )
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// keep this from overflowing
|
||||
if ( count <= DEBOUNCE_TIME )
|
||||
count += POLL_INTERVAL;
|
||||
}
|
||||
lastnextstate = nextstate;
|
||||
|
||||
// and if we exceed the threshold take the state as our current
|
||||
if ( count > DEBOUNCE_TIME )
|
||||
{
|
||||
state = nextstate;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void term()
|
||||
{
|
||||
syslog(LOG_NOTICE,"caught signal.");
|
||||
init();
|
||||
if ( fd != -1 )
|
||||
close(fd);
|
||||
syslog(LOG_NOTICE,"terminated.");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int main(int argc,char** argv)
|
||||
{
|
||||
// check parameters
|
||||
if (argc < 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: upsd <device>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// open serial port
|
||||
if ((fd = open(argv[1], O_RDONLY | O_NDELAY)) < 0)
|
||||
{
|
||||
fprintf(stderr, "upsd: %s: %s\n", argv[1], sys_errlist[errno]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// become a daemon
|
||||
switch (fork())
|
||||
{
|
||||
case 0: /* I am the child. */
|
||||
setsid();
|
||||
break;
|
||||
case -1: /* Failed to become daemon. */
|
||||
fprintf(stderr, "%s: can't create daemon.\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
default: /* I am the parent. */
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
// open syslog
|
||||
openlog("upsd",LOG_PID,LOG_DAEMON);
|
||||
syslog(LOG_NOTICE, "started on %s.",argv[1]);
|
||||
|
||||
// setup termination routine
|
||||
signal(SIGHUP,SIG_IGN);
|
||||
signal(SIGINT,term);
|
||||
signal(SIGKILL,term);
|
||||
signal(SIGTERM,term);
|
||||
|
||||
// init line
|
||||
init();
|
||||
|
||||
while(1)
|
||||
{
|
||||
static int count = 0;
|
||||
static int killtime = 0;
|
||||
static int laststate = U_OK;
|
||||
static int nextwarn = 0;
|
||||
int state;
|
||||
|
||||
// get current ups state
|
||||
state = readline();
|
||||
//printf("state = %s\n",state==U_OK?"OK":state==U_FAIL?"U_FAIL":"U_LOW");
|
||||
|
||||
// count the time we've been in this state
|
||||
if ( state == laststate )
|
||||
{
|
||||
count += POLL_INTERVAL;
|
||||
}
|
||||
|
||||
// don't count uptime (avoid overflow)
|
||||
if ( state == U_OK )
|
||||
{
|
||||
count = 0;
|
||||
killtime = 0;
|
||||
}
|
||||
|
||||
// if we just went back up let's reset
|
||||
if ( state == U_OK && state != laststate )
|
||||
{
|
||||
cancel();
|
||||
}
|
||||
|
||||
// if the battery is low let's handle it immediately
|
||||
if ( state == U_LOW )
|
||||
{
|
||||
// warn if we just got the signal!
|
||||
if ( laststate != U_LOW )
|
||||
lowmessage();
|
||||
|
||||
// set kill signal
|
||||
if ( killtime == 0 )
|
||||
{
|
||||
killups();
|
||||
killtime += POLL_INTERVAL;
|
||||
}
|
||||
else if ( killtime >= KILL_TIME )
|
||||
{
|
||||
shutdown();
|
||||
}
|
||||
else
|
||||
{
|
||||
killtime += POLL_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
// if the power is off handle
|
||||
if ( state == U_FAIL )
|
||||
{
|
||||
// if this is the first time let's setup
|
||||
if ( state != laststate )
|
||||
{
|
||||
nextwarn = 0;
|
||||
}
|
||||
|
||||
// kill within KILL_TIME of SHUTDOWN_TIME
|
||||
if ( count >= (SHUTDOWN_TIME - KILL_TIME) && killtime == 0 )
|
||||
{
|
||||
killups();
|
||||
killtime += POLL_INTERVAL;
|
||||
}
|
||||
|
||||
// and shutdown at appropriate time
|
||||
if ( count >= SHUTDOWN_TIME )
|
||||
{
|
||||
shutdown();
|
||||
}
|
||||
else if ( count >= nextwarn )
|
||||
{
|
||||
int secondsleft = (SHUTDOWN_TIME-count);
|
||||
if ( secondsleft >= 10 )
|
||||
{
|
||||
warn(SHUTDOWN_TIME-count);
|
||||
nextwarn += secondsleft/2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
laststate = state;
|
||||
|
||||
sleep(POLL_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user