79
76
/* signal handling things */
80
77
static struct sigaction sa;
81
static sigset_t upsm_sigmask;
78
static sigset_t nut_upsmon_sigmask;
84
81
#define shutdown_how SHUT_RDWR
213
210
/* this shouldn't happen (LOGIN checks it earlier) */
214
211
if ((ups->upsname == NULL) || (strlen(ups->upsname) == 0)) {
215
upslogx(LOG_ERR, "Set master on UPS [%s] failed: empty upsname");
212
upslogx(LOG_ERR, "Set master on UPS [%s] failed: empty upsname",
294
292
/* we require a upsname now */
295
293
if ((ups->upsname == NULL) || (strlen(ups->upsname) == 0)) {
296
upslogx(LOG_ERR, "Login to UPS [%s] failed: empty upsname");
294
upslogx(LOG_ERR, "Login to UPS [%s] failed: empty upsname",
416
415
/* create the flag file if necessary */
417
static void setpdflag(void)
416
static void set_pdflag(void)
421
if (powerdownflag != NULL) {
422
pdf = fopen(powerdownflag, "w");
424
upslogx(LOG_ERR, "Failed to create power down flag!");
427
fprintf(pdf, "%s", SDMAGIC);
423
pdf = fopen(powerdownflag, "w");
425
upslogx(LOG_ERR, "Failed to create power down flag!");
429
fprintf(pdf, "%s", SDMAGIC);
432
433
/* the actual shutdown procedure */
454
455
if (geteuid() != 0)
455
456
upslogx(LOG_WARNING, "Not root, shutdown may fail");
459
460
ret = system(shutdowncmd);
462
463
upslogx(LOG_ERR, "Unable to call shutdown command: %s\n",
466
/* if instructed to go into the infinite loop, then do so */
471
/* hopefully not reached */
475
470
/* set forced shutdown flag so other upsmons know what's going on here */
478
473
char buf[SMALLBUF];
476
/* this shouldn't happen */
478
upslogx(LOG_ERR, "setfsd: programming error: no UPS name set [%s]",
481
483
debug("Setting FSD on UPS %s\n", ups->sys);
484
snprintf(buf, sizeof(buf), "FSD %s\n", ups->upsname);
486
snprintf(buf, sizeof(buf), "FSD\n");
485
snprintf(buf, sizeof(buf), "FSD %s\n", ups->upsname);
488
487
ret = upscli_sendline(&ups->conn, buf, strlen(buf));
491
490
upslogx(LOG_ERR, "FSD set on UPS %s failed: %s", ups->sys,
492
upscli_strerror(&ups->conn));
491
upscli_strerror(&ups->conn));
496
495
ret = upscli_readline(&ups->conn, buf, sizeof(buf));
498
upslogx(LOG_ERR, "FSD set on UPS %s failed: %s", ups->sys,
499
upscli_strerror(&ups->conn));
498
503
if (!strncmp(buf, "OK", 2))
502
upslogx(LOG_ERR, "FSD set on UPS %s failed: %s", ups->sys,
503
upscli_strerror(&ups->conn));
505
upslogx(LOG_ERR, "FSD set on UPS %s failed: %s", ups->sys,
506
/* protocol error: upsd said something other than "OK" */
507
upslogx(LOG_ERR, "FSD set on UPS %s failed: %s", ups->sys, buf);
509
510
static void set_alarm(void)
520
static int old_get_var(utype *ups, const char *var, char *buf, size_t bufsize)
522
debug("old_get_var: %s / %s\n", ups->sys, var);
524
if (!strcmp(var, "numlogins"))
525
return upscli_getvar(&ups->conn, ups->upsname, "numlogins",
528
if (!strcmp(var, "status"))
529
return upscli_getvar(&ups->conn, ups->upsname, "status",
532
upslogx(LOG_ERR, "old_get_var: programming error: var=%s", var);
536
static int new_get_var(utype *ups, const char *var, char *buf, size_t bufsize)
521
static int get_var(utype *ups, const char *var, char *buf, size_t bufsize)
524
unsigned int numq, numa;
539
525
const char *query[4];
542
/* can't do the new stuff without a UPS name set */
544
/* this shouldn't happen (we now require upsnames) */
528
/* this shouldn't happen */
545
529
if (!ups->upsname) {
546
upslogx(LOG_INFO, "UPS [%s]: no upsname set, forcing compatibility mode",
530
upslogx(LOG_ERR, "get_var: programming error: no UPS name set [%s]",
549
return old_get_var(ups, var, buf, bufsize);
568
upslogx(LOG_ERR, "new_get_var: programming error: var=%s", var);
551
upslogx(LOG_ERR, "get_var: programming error: var=%s", var);
572
debug("new_get_var: %s / %s\n", ups->sys, var);
555
debug("get_var: %s / %s\n", ups->sys, var);
574
557
ret = upscli_get(&ups->conn, numq, query, &numa, &answer);
578
561
/* detect old upsd */
579
562
if (upscli_upserror(&ups->conn) == UPSCLI_ERR_UNKCOMMAND) {
581
upslogx(LOG_INFO, "UPS [%s]: using compatibility mode",
564
upslogx(LOG_ERR, "UPS [%s]: Too old to monitor",
585
return old_get_var(ups, var, buf, bufsize);
588
569
/* some other error */
603
static int get_var(utype *ups, const char *var, char *buf, size_t bufsize)
606
return old_get_var(ups, var, buf, bufsize);
608
/* try it the new way */
609
return new_get_var(ups, var, buf, bufsize);
612
584
static void slavesync(void)
1007
975
upslogx(LOG_INFO, "UPS: %s (%s) (power value %d)", tmp->sys,
1008
flag_isset(tmp->status, ST_MASTER) ? "master" : "slave",
976
flag_isset(tmp->status, ST_MASTER) ? "master" : "slave",
1011
979
upslogx(LOG_INFO, "UPS: %s (monitoring only)", tmp->sys);
1013
upscli_splitname(tmp->sys, &tmp->upsname, &tmp->hostname, &tmp->port);
981
tmp->upsname = tmp->hostname = NULL;
983
if (upscli_splitname(tmp->sys, &tmp->upsname, &tmp->hostname,
985
upslogx(LOG_ERR, "Error: unable to split UPS name [%s]",
1015
989
if (!tmp->upsname)
1016
990
upslogx(LOG_WARNING, "Warning: UPS [%s]: no upsname set!",
1274
1248
/* called for fatal errors in parseconf like malloc failures */
1275
void upsmon_err(const char *errmsg)
1249
static void upsmon_err(const char *errmsg)
1277
1251
upslogx(LOG_ERR, "Fatal error in parseconf(upsmon.conf): %s", errmsg);
1319
1293
snprintfcat(errmsg, sizeof(errmsg), " %s",
1320
1294
ctx.arglist[i]);
1322
upslogx(LOG_WARNING, errmsg);
1296
upslogx(LOG_WARNING, "%s", errmsg);
1335
1309
/* SIGQUIT, SIGTERM handler */
1336
1310
static void set_exit_flag(int sig)
1338
upslogx(LOG_INFO, "Signal %d: exiting", sig);
1342
1315
static void ups_free(utype *ups)
1407
1378
/* install handlers for a few signals */
1408
1379
static void setup_signals(void)
1410
sigemptyset(&upsm_sigmask);
1411
sa.sa_mask = upsm_sigmask;
1381
sigemptyset(&nut_upsmon_sigmask);
1382
sa.sa_mask = nut_upsmon_sigmask;
1412
1383
sa.sa_flags = 0;
1414
1385
sa.sa_handler = sigpipe;
1562
1533
if (!strstr(status, "FSD"))
1563
1534
clearflag(&ups->status, ST_FSD);
1567
1538
/* split up the status words and parse each one separately */
1568
while (stat != NULL) {
1569
ptr = strchr(stat, ' ');
1539
while (statword != NULL) {
1540
ptr = strchr(statword, ' ');
1573
debug(" parsing: [%s]: ", stat);
1544
debug(" parsing: [%s]: ", statword);
1575
if (!strcasecmp(stat, "OL"))
1546
if (!strcasecmp(statword, "OL"))
1576
1547
ups_on_line(ups);
1577
if (!strcasecmp(stat, "OB"))
1548
if (!strcasecmp(statword, "OB"))
1578
1549
ups_on_batt(ups);
1579
if (!strcasecmp(stat, "LB"))
1550
if (!strcasecmp(statword, "LB"))
1580
1551
ups_low_batt(ups);
1581
if (!strcasecmp(stat, "RB"))
1552
if (!strcasecmp(statword, "RB"))
1582
1553
upsreplbatt(ups);
1584
1555
/* do it last to override any possible OL */
1585
if (!strcasecmp(stat, "FSD"))
1556
if (!strcasecmp(statword, "FSD"))
1588
1559
update_crittimer(ups);
1648
/* remove the power down flag if it exists and is the proper form */
1649
static void clearpdf(void)
1619
/* see if the powerdownflag file is there and proper */
1620
static int pdflag_status(void)
1652
1623
char buf[SMALLBUF];
1626
return 0; /* unusable */
1654
1628
pdf = fopen(powerdownflag, "r");
1656
if (pdf == NULL) /* no such file, nothing to do */
1631
return 0; /* not there */
1659
1633
/* if it exists, see if it has the right text in it */
1669
1643
* solution: don't let mere mortals edit that configuration file.
1672
if (!strncmp(buf, SDMAGIC, strlen(SDMAGIC))) /* ok, it's from us */
1646
if (!strncmp(buf, SDMAGIC, strlen(SDMAGIC)))
1647
return 1; /* exists and looks good */
1649
return -1; /* error: something else is in there */
1652
/* only remove the flag file if it's actually from us */
1653
static void clear_pdflag(void)
1657
ret = pdflag_status();
1660
upslogx(LOG_ERR, "POWERDOWNFLAG (%s) does not contain"
1661
"the upsmon magic string - disabling!", powerdownflag);
1662
powerdownflag = NULL;
1666
/* it's from us, so we can remove it */
1673
1668
unlink(powerdownflag);
1675
upslogx(LOG_INFO, "%s doesn't seem to be a proper flag file. Disabling.",
1677
powerdownflag = NULL;
1671
/* exit with success only if it exists and is proper */
1672
static int check_pdflag(void)
1676
ret = pdflag_status();
1679
upslogx(LOG_ERR, "POWERDOWNFLAG (%s) does not contain "
1680
"the upsmon magic string", powerdownflag);
1681
return EXIT_FAILURE;
1685
/* not there - this is not a shutdown event */
1686
printf("Power down flag is not set\n");
1687
return EXIT_FAILURE;
1691
upslogx(LOG_ERR, "Programming error: pdflag_status returned %d",
1693
return EXIT_FAILURE;
1696
/* only thing left - must be time for a shutdown */
1697
printf("Power down flag is set\n");
1698
return EXIT_SUCCESS;
1681
1701
static void help(const char *progname)
1690
1710
printf(" - stop: stop monitoring and exit\n");
1691
1711
printf(" -D raise debugging level\n");
1692
1712
printf(" -h display this help\n");
1693
printf(" -i go into an infinite loop after calling shutdown\n");
1713
printf(" -K checks POWERDOWNFLAG, sets exit code to 0 if set\n");
1694
1714
printf(" -p always run privileged (disable privileged parent)\n");
1695
1715
printf(" -u <user> run child as user <user> (ignored when using -p)\n");
1699
1720
/* set all the notify values to a default */
1717
1738
signal(SIGUSR1, SIG_IGN);
1718
1739
signal(SIGUSR2, SIG_IGN);
1720
ret = read(pipe, &ch, 1);
1741
ret = read(fd, &ch, 1);
1723
1744
if (errno == ENOENT)
1730
1751
fatalx("upsmon parent: got bogus pipe command %c", ch);
1732
1753
/* have to do this here - child is unprivileged */
1735
1756
ret = system(shutdowncmd);
1738
1759
upslogx(LOG_ERR, "parent: Unable to call shutdown command: %s\n",
1745
1766
/* fire up the split parent/child scheme */
1746
static void start_pipe(char *user)
1767
static void start_pipe(const char *user)
1749
1770
struct passwd *new_uid = NULL;
1751
/* default to the --with-user value from configure */
1772
/* default user = the --with-user value from configure */
1774
new_uid = get_user_pwent(user);
1776
new_uid = get_user_pwent(RUN_AS_USER);
1755
/* grab user data early, while we still have the console */
1756
if ((new_uid = get_user_pwent(user)) == NULL)
1778
/* check user data while we still have the console */
1757
1780
fatal("getpwnam(%s)", user);
1759
1782
ret = pipe(pipefd);
1928
1951
int main(int argc, char *argv[])
1953
int i, cmd, checking_flag = 0;
1934
1957
printf("Network UPS Tools upsmon %s\n", UPS_VERSION);
1936
while ((i = getopt(argc, argv, "+Ddhic:pu:V")) != EOF) {
1959
while ((i = getopt(argc, argv, "+Dhic:pu:VK")) != EOF) {
1952
1962
if (!strncmp(optarg, "fsd", strlen(optarg)))
1953
1963
cmd = SIGCMD_FSD;
2013
exit(check_pdflag());
1988
2015
if (shutdowncmd == NULL)
1989
2016
printf("Warning: no shutdown command defined!\n");
1991
2018
/* we may need to get rid of a flag from a previous shutdown */
1992
2019
if (powerdownflag != NULL)
1995
2022
if (totalpv < minsupplies) {
1996
2023
printf("\nFatal error: insufficient power configured!\n\n");