43
ups_t *upstable = NULL;
42
static ups_t *upstable = NULL;
45
int execwait, verbose = 0, maxsdorder = 0, testmode = 0;
44
static int verbose = 0, maxsdorder = 0, testmode = 0, exec_error = 0;
47
46
/* timer - keeps us from getting stuck if a driver hangs */
48
int maxstartdelay = 45;
47
static int maxstartdelay = 45;
50
49
/* Directory where driver executables live */
51
const char * driverpath;
50
static char *driverpath = NULL;
53
52
/* passthrough to the drivers: chroot path and new user name */
54
char *pt_root = NULL, *pt_user = NULL;
53
static char *pt_root = NULL, *pt_user = NULL;
55
static sigset_t nut_upsdrvctl_sigmask;
56
static struct sigaction sa;
56
58
void do_upsconf_args(char *upsname, char *var, char *val)
62
/* handle global declarations */
61
64
if (!strcmp(var, "maxstartdelay"))
62
65
maxstartdelay = atoi(val);
64
if (!strcmp(var, "driverpath"))
67
if (!strcmp(var, "driverpath")) {
65
71
driverpath = xstrdup(val);
74
/* ignore anything else - it's probably for main */
203
/* reap exiting children */
204
static void sigchld(int sig)
209
/* break free of drivers that don't start up quickly */
210
static void sigalrm(int sig)
212
upslogx(LOG_NOTICE, "Startup timer elapsed, continuing...");
216
static void forkexec(const char *prog, ups_t *ups)
214
static void waitpid_timeout(int sig)
220
static void forkexec(const char *prog, char **argv, ups_t *ups)
230
if (pid != 0) { /* parent */
233
sigemptyset(&nut_upsdrvctl_sigmask);
234
sa.sa_mask = nut_upsdrvctl_sigmask;
236
sa.sa_handler = waitpid_timeout;
237
sigaction(SIGALRM, &sa, NULL);
239
if (ups->maxstartdelay != -1)
240
alarm(ups->maxstartdelay);
242
alarm(maxstartdelay);
244
ret = waitpid(pid, &wstat, 0);
246
signal(SIGALRM, SIG_IGN);
250
upslogx(LOG_WARNING, "Startup timer elapsed, continuing...");
255
if (WIFEXITED(wstat) == 0) {
256
upslogx(LOG_WARNING, "Driver exited abnormally");
261
if (WEXITSTATUS(wstat) != 0) {
262
upslogx(LOG_WARNING, "Driver failed to start"
263
" (exit status=%d)", WEXITSTATUS(wstat));
268
/* the rest only work when WIFEXITED is nonzero */
270
if (WIFSIGNALED(wstat)) {
271
upslog(LOG_WARNING, "Driver died after signal %d",
281
ret = execv(prog, argv);
283
/* shouldn't get here */
287
static void start_driver(ups_t *ups)
289
char dfn[SMALLBUF], *argv[8];
218
290
int ret, arg = 0;
221
/* TODO: consider redoing this with wait() depending on portability */
223
/* parent spins until the child exits */
293
snprintf(dfn, sizeof(dfn), "%s/%s", driverpath, ups->driver);
294
ret = stat(dfn, &fs);
234
/* catching this will unset execwait */
235
signal(SIGCHLD, sigchld);
237
/* give us a way out if the child gets stuck */
238
signal(SIGALRM, sigalrm);
240
if (ups->maxstartdelay != -1)
241
alarm(ups->maxstartdelay);
243
alarm(maxstartdelay);
245
/* spin until the child is done */
250
signal(SIGALRM, SIG_IGN);
297
fatal("Can't start %s", dfn);
256
printf("exec: %s -a %s", prog, ups->upsname);
258
argv[arg++] = xstrdup(prog);
300
printf("exec: %s -a %s", dfn, ups->upsname);
302
argv[arg++] = xstrdup(dfn);
259
304
argv[arg++] = "-a";
260
305
argv[arg++] = ups->upsname;
283
330
argv[arg++] = NULL;
290
ret = execv(prog, argv);
292
/* should not be reached */
296
static void start_driver(ups_t *ups)
302
snprintf(dfn, sizeof(dfn), "%s/%s", driverpath, ups->driver);
303
ret = stat(dfn, &fs);
306
fatal("Can't start %s", dfn);
332
forkexec(dfn, argv, ups);
311
335
/* start user-selected driver */
358
382
printf(" stop <ups> only stop driver for UPS <ups>\n");
359
383
printf(" shutdown shutdown all UPS drivers in ups.conf\n");
360
384
printf(" shutdown <ups> only shutdown UPS <ups>\n");
364
389
static void shutdown_driver(ups_t *ups)
367
391
char *argv[7], dfn[SMALLBUF];
369
/* parent spins until the child exits */
380
/* wait for child to return */
381
signal(SIGCHLD, sigchld);
383
/* give us a way out if the child gets stuck */
384
signal(SIGALRM, sigalrm);
386
if (ups->maxstartdelay != -1)
387
alarm(ups->maxstartdelay);
389
alarm(maxstartdelay);
395
signal(SIGALRM, SIG_IGN);
402
393
snprintf(dfn, sizeof(dfn), "%s/%s", driverpath, ups->driver);
405
printf("exec: %s -a %s -d 0 -k\n", dfn, ups->upsname);
396
printf("exec: %s -a %s -k\n", dfn, ups->upsname);
409
402
argv[2] = xstrdup(ups->upsname);
418
ret = execv(dfn, argv);
420
/* should not be reached */
406
forkexec(dfn, argv, ups);
424
409
static void shutdown_one_driver(char *upsname)
515
522
printf("*** Testing mode: not calling exec/kill\n");
517
driverpath = xstrdup(DRVPATH); /* set default */
524
driverpath = xstrdup(DRVPATH); /* set default */
526
atexit(exit_cleanup);
519
528
if (!strcmp(argv[0], "start")) {
523
532
start_all_drivers();
525
534
start_one_driver(argv[1]);
530
542
if (!strcmp(argv[0], "stop")) {
534
546
stop_all_drivers();
536
548
stop_one_driver(argv[1]);
541
556
if (!strcmp(argv[0], "shutdown")) {
545
560
shutdown_all_drivers();
547
562
shutdown_one_driver(argv[1]);
552
570
fatalx("Error: unrecognized command [%s]\n", argv[0]);