starter: Avoid hiding global variable when checking PID file
[strongswan.git] / src / starter / starter.c
1 /* strongSwan IPsec starter
2 * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 */
14
15 #define _GNU_SOURCE
16
17 #include <sys/select.h>
18 #include <sys/types.h>
19 #include <sys/wait.h>
20 #include <sys/stat.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <signal.h>
24 #include <syslog.h>
25 #include <unistd.h>
26 #include <sys/time.h>
27 #include <time.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <pwd.h>
32 #include <grp.h>
33 #include <pthread.h>
34
35 #include <library.h>
36 #include <utils/backtrace.h>
37 #include <threading/thread.h>
38 #include <utils/debug.h>
39
40 #include "confread.h"
41 #include "files.h"
42 #include "starterstroke.h"
43 #include "invokecharon.h"
44 #include "cmp.h"
45
46 #ifndef LOG_AUTHPRIV
47 #define LOG_AUTHPRIV LOG_AUTH
48 #endif
49
50 #define CHARON_RESTART_DELAY 5
51
52 static const char* cmd_default = IPSEC_DIR "/charon";
53 static const char* pid_file_default = IPSEC_PIDDIR "/charon.pid";
54 static const char* starter_pid_file_default = IPSEC_PIDDIR "/starter.pid";
55
56 char *daemon_name = NULL;
57 char *cmd = NULL;
58 char *pid_file = NULL;
59 char *starter_pid_file = NULL;
60
61 static char *config_file = NULL;
62
63 /* logging */
64 static bool log_to_stderr = TRUE;
65 static bool log_to_syslog = TRUE;
66 static level_t current_loglevel = 1;
67
68 /**
69 * logging function for scepclient
70 */
71 static void starter_dbg(debug_t group, level_t level, char *fmt, ...)
72 {
73 char buffer[8192];
74 char *current = buffer, *next;
75 va_list args;
76
77 if (level <= current_loglevel)
78 {
79 if (log_to_stderr)
80 {
81 va_start(args, fmt);
82 vfprintf(stderr, fmt, args);
83 va_end(args);
84 fprintf(stderr, "\n");
85 }
86 if (log_to_syslog)
87 {
88 /* write in memory buffer first */
89 va_start(args, fmt);
90 vsnprintf(buffer, sizeof(buffer), fmt, args);
91 va_end(args);
92
93 /* do a syslog with every line */
94 while (current)
95 {
96 next = strchr(current, '\n');
97 if (next)
98 {
99 *(next++) = '\0';
100 }
101 syslog(LOG_INFO, "%s\n", current);
102 current = next;
103 }
104 }
105 }
106 }
107
108 /**
109 * Initialize logging to stderr/syslog
110 */
111 static void init_log(const char *program)
112 {
113 dbg = starter_dbg;
114
115 if (log_to_stderr)
116 {
117 setbuf(stderr, NULL);
118 }
119 if (log_to_syslog)
120 {
121 openlog(program, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);
122 }
123 }
124
125 /**
126 * Deinitialize logging to syslog
127 */
128 static void close_log()
129 {
130 if (log_to_syslog)
131 {
132 closelog();
133 }
134 }
135
136 /**
137 * Return codes defined by Linux Standard Base Core Specification 3.1
138 * in section 20.2. Init Script Actions
139 */
140 #define LSB_RC_SUCCESS 0 /* success */
141 #define LSB_RC_FAILURE 1 /* generic or unspecified error */
142 #define LSB_RC_INVALID_ARGUMENT 2 /* invalid or excess argument(s) */
143 #define LSB_RC_NOT_IMPLEMENTED 3 /* unimplemented feature (reload) */
144 #define LSB_RC_NOT_ALLOWED 4 /* user had insufficient privilege */
145 #define LSB_RC_NOT_INSTALLED 5 /* program is not installed */
146 #define LSB_RC_NOT_CONFIGURED 6 /* program is not configured */
147 #define LSB_RC_NOT_RUNNING 7 /* program is not running */
148
149 #define FLAG_ACTION_START_PLUTO 0x01
150 #define FLAG_ACTION_UPDATE 0x02
151 #define FLAG_ACTION_RELOAD 0x04
152 #define FLAG_ACTION_QUIT 0x08
153 #define FLAG_ACTION_LISTEN 0x10
154 #define FLAG_ACTION_START_CHARON 0x20
155
156 static unsigned int _action_ = 0;
157
158 /**
159 * Handle signals in the main thread
160 */
161 static void signal_handler(int signal)
162 {
163 switch (signal)
164 {
165 case SIGCHLD:
166 {
167 int status, exit_status = 0;
168 pid_t pid;
169 char *name = NULL;
170
171 while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
172 {
173 if (pid == starter_charon_pid())
174 {
175 if (asprintf(&name, " (%s)", daemon_name) < 0)
176 {
177 name = NULL;
178 }
179 }
180 if (WIFSIGNALED(status))
181 {
182 DBG2(DBG_APP, "child %d%s has been killed by sig %d\n",
183 pid, name?name:"", WTERMSIG(status));
184 }
185 else if (WIFSTOPPED(status))
186 {
187 DBG2(DBG_APP, "child %d%s has been stopped by sig %d\n",
188 pid, name?name:"", WSTOPSIG(status));
189 }
190 else if (WIFEXITED(status))
191 {
192 exit_status = WEXITSTATUS(status);
193 if (exit_status >= SS_RC_FIRST && exit_status <= SS_RC_LAST)
194 {
195 _action_ = FLAG_ACTION_QUIT;
196 }
197 DBG2(DBG_APP, "child %d%s has quit (exit code %d)\n",
198 pid, name?name:"", exit_status);
199 }
200 else
201 {
202 DBG2(DBG_APP, "child %d%s has quit", pid, name?name:"");
203 }
204 if (pid == starter_charon_pid())
205 {
206 starter_charon_sigchild(pid, exit_status);
207 }
208 }
209
210 if (name)
211 {
212 free(name);
213 }
214 }
215 break;
216
217 case SIGALRM:
218 _action_ |= FLAG_ACTION_START_CHARON;
219 break;
220
221 case SIGHUP:
222 _action_ |= FLAG_ACTION_UPDATE;
223 break;
224
225 case SIGTERM:
226 case SIGQUIT:
227 case SIGINT:
228 _action_ |= FLAG_ACTION_QUIT;
229 break;
230
231 case SIGUSR1:
232 _action_ |= FLAG_ACTION_RELOAD;
233 _action_ |= FLAG_ACTION_UPDATE;
234 break;
235
236 default:
237 DBG1(DBG_APP, "fsig(): unknown signal %d -- investigate", signal);
238 break;
239 }
240 }
241
242 /**
243 * Handle fatal signals raised by threads
244 */
245 static void fatal_signal_handler(int signal)
246 {
247 backtrace_t *backtrace;
248
249 DBG1(DBG_APP, "thread %u received %d", thread_current_id(), signal);
250 backtrace = backtrace_create(2);
251 backtrace->log(backtrace, stderr, TRUE);
252 backtrace->destroy(backtrace);
253
254 DBG1(DBG_APP, "killing ourself, received critical signal");
255 abort();
256 }
257
258 static bool check_pid(char *file)
259 {
260 struct stat stb;
261 FILE *pidfile;
262
263 if (stat(file, &stb) == 0)
264 {
265 pidfile = fopen(file, "r");
266 if (pidfile)
267 {
268 char buf[64];
269 pid_t pid = 0;
270 memset(buf, 0, sizeof(buf));
271 if (fread(buf, 1, sizeof(buf), pidfile))
272 {
273 buf[sizeof(buf) - 1] = '\0';
274 pid = atoi(buf);
275 }
276 fclose(pidfile);
277 if (pid && pid != getpid() && kill(pid, 0) == 0)
278 { /* such a process is running */
279 return TRUE;
280 }
281 }
282 DBG1(DBG_APP, "removing pidfile '%s', process not running", file);
283 unlink(file);
284 }
285 return FALSE;
286 }
287
288 /* Set daemon name and adjust command and pid filenames accordingly */
289 static bool set_daemon_name()
290 {
291 if (!daemon_name)
292 {
293 daemon_name = "charon";
294 }
295
296 if (asprintf(&cmd, IPSEC_DIR"/%s", daemon_name) < 0)
297 {
298 cmd = (char*)cmd_default;
299 }
300
301 if (asprintf(&pid_file, IPSEC_PIDDIR"/%s.pid", daemon_name) < 0)
302 {
303 pid_file = (char*)pid_file_default;
304 }
305
306 if (asprintf(&starter_pid_file, IPSEC_PIDDIR"/starter.%s.pid",
307 daemon_name) < 0)
308 {
309 starter_pid_file = (char*)starter_pid_file_default;
310 }
311
312 return TRUE;
313 }
314
315 static void cleanup()
316 {
317 if (cmd != cmd_default)
318 {
319 free(cmd);
320 }
321
322 if (pid_file != pid_file_default)
323 {
324 free(pid_file);
325 }
326
327 if (starter_pid_file != starter_pid_file_default)
328 {
329 free(starter_pid_file);
330 }
331 }
332
333 static void usage(char *name)
334 {
335 fprintf(stderr, "Usage: starter [--nofork] [--auto-update <sec>]\n"
336 " [--debug|--debug-more|--debug-all|--nolog]\n"
337 " [--attach-gdb] [--daemon <name>]\n"
338 " [--conf <path to ipsec.conf>]\n");
339 exit(LSB_RC_INVALID_ARGUMENT);
340 }
341
342 int main (int argc, char **argv)
343 {
344 starter_config_t *cfg = NULL;
345 starter_config_t *new_cfg;
346 starter_conn_t *conn, *conn2;
347 starter_ca_t *ca, *ca2;
348
349 struct sigaction action;
350 struct stat stb;
351
352 int i;
353 int id = 1;
354 struct timespec ts;
355 unsigned long auto_update = 0;
356 time_t last_reload;
357 bool no_fork = FALSE;
358 bool attach_gdb = FALSE;
359 bool load_warning = FALSE;
360 bool conftest = FALSE;
361
362 library_init(NULL, "starter");
363 atexit(library_deinit);
364
365 /* parse command line */
366 for (i = 1; i < argc; i++)
367 {
368 if (streq(argv[i], "--debug"))
369 {
370 current_loglevel = 2;
371 }
372 else if (streq(argv[i], "--debug-more"))
373 {
374 current_loglevel = 3;
375 }
376 else if (streq(argv[i], "--debug-all"))
377 {
378 current_loglevel = 4;
379 }
380 else if (streq(argv[i], "--nolog"))
381 {
382 current_loglevel = 0;
383 }
384 else if (streq(argv[i], "--nofork"))
385 {
386 no_fork = TRUE;
387 }
388 else if (streq(argv[i], "--attach-gdb"))
389 {
390 no_fork = TRUE;
391 attach_gdb = TRUE;
392 }
393 else if (streq(argv[i], "--auto-update") && i+1 < argc)
394 {
395 auto_update = atoi(argv[++i]);
396 if (!auto_update)
397 usage(argv[0]);
398 }
399 else if (streq(argv[i], "--daemon") && i+1 < argc)
400 {
401 daemon_name = argv[++i];
402 }
403 else if (streq(argv[i], "--conf") && i+1 < argc)
404 {
405 config_file = argv[++i];
406 }
407 else if (streq(argv[i], "--conftest"))
408 {
409 conftest = TRUE;
410 }
411 else
412 {
413 usage(argv[0]);
414 }
415 }
416
417 if (!set_daemon_name())
418 {
419 DBG1(DBG_APP, "unable to set daemon name");
420 exit(LSB_RC_FAILURE);
421 }
422 if (!config_file)
423 {
424 config_file = lib->settings->get_str(lib->settings,
425 "starter.config_file", CONFIG_FILE);
426 }
427
428 init_log("ipsec_starter");
429
430 if (conftest)
431 {
432 int status = LSB_RC_SUCCESS;
433
434 cfg = confread_load(config_file);
435 if (cfg == NULL || cfg->err > 0)
436 {
437 DBG1(DBG_APP, "config invalid!");
438 status = LSB_RC_INVALID_ARGUMENT;
439 }
440 else
441 {
442 DBG1(DBG_APP, "config OK");
443 }
444 if (cfg)
445 {
446 confread_free(cfg);
447 }
448 cleanup();
449 exit(status);
450 }
451
452 if (stat(cmd, &stb) != 0)
453 {
454 DBG1(DBG_APP, "IKE daemon '%s' not found", cmd);
455 cleanup();
456 exit(LSB_RC_FAILURE);
457 }
458
459 DBG1(DBG_APP, "Starting %sSwan "VERSION" IPsec [starter]...",
460 lib->settings->get_bool(lib->settings,
461 "charon.i_dont_care_about_security_and_use_aggressive_mode_psk",
462 FALSE) ? "weak" : "strong");
463
464 #ifdef LOAD_WARNING
465 load_warning = TRUE;
466 #endif
467
468 if (lib->settings->get_bool(lib->settings, "starter.load_warning", load_warning))
469 {
470 if (lib->settings->get_str(lib->settings, "charon.load", NULL))
471 {
472 DBG1(DBG_APP, "!! Your strongswan.conf contains manual plugin load options for charon.");
473 DBG1(DBG_APP, "!! This is recommended for experts only, see");
474 DBG1(DBG_APP, "!! http://wiki.strongswan.org/projects/strongswan/wiki/PluginLoad");
475 }
476 }
477
478 #ifndef STARTER_ALLOW_NON_ROOT
479 /* verify that we can start */
480 if (getuid() != 0)
481 {
482 DBG1(DBG_APP, "permission denied (must be superuser)");
483 cleanup();
484 exit(LSB_RC_NOT_ALLOWED);
485 }
486 #endif
487
488 if (check_pid(pid_file))
489 {
490 DBG1(DBG_APP, "%s is already running (%s exists) -- skipping daemon start",
491 daemon_name, pid_file);
492 }
493 else
494 {
495 _action_ |= FLAG_ACTION_START_CHARON;
496 }
497 if (stat(DEV_RANDOM, &stb) != 0)
498 {
499 DBG1(DBG_APP, "unable to start strongSwan IPsec -- no %s!", DEV_RANDOM);
500 cleanup();
501 exit(LSB_RC_FAILURE);
502 }
503
504 if (stat(DEV_URANDOM, &stb)!= 0)
505 {
506 DBG1(DBG_APP, "unable to start strongSwan IPsec -- no %s!", DEV_URANDOM);
507 cleanup();
508 exit(LSB_RC_FAILURE);
509 }
510
511 cfg = confread_load(config_file);
512 if (cfg == NULL || cfg->err > 0)
513 {
514 DBG1(DBG_APP, "unable to start strongSwan -- fatal errors in config");
515 if (cfg)
516 {
517 confread_free(cfg);
518 }
519 cleanup();
520 exit(LSB_RC_INVALID_ARGUMENT);
521 }
522
523 last_reload = time_monotonic(NULL);
524
525 if (check_pid(starter_pid_file))
526 {
527 DBG1(DBG_APP, "starter is already running (%s exists) -- no fork done",
528 starter_pid_file);
529 confread_free(cfg);
530 cleanup();
531 exit(LSB_RC_SUCCESS);
532 }
533
534 /* fork if we're not debugging stuff */
535 if (!no_fork)
536 {
537 log_to_stderr = FALSE;
538
539 switch (fork())
540 {
541 case 0:
542 {
543 int fnull;
544
545 close_log();
546
547 fnull = open("/dev/null", O_RDWR);
548 if (fnull >= 0)
549 {
550 dup2(fnull, STDIN_FILENO);
551 dup2(fnull, STDOUT_FILENO);
552 dup2(fnull, STDERR_FILENO);
553 close(fnull);
554 }
555
556 setsid();
557 init_log("ipsec_starter");
558 }
559 break;
560 case -1:
561 DBG1(DBG_APP, "can't fork: %s", strerror(errno));
562 break;
563 default:
564 confread_free(cfg);
565 cleanup();
566 exit(LSB_RC_SUCCESS);
567 }
568 }
569
570 /* save pid file in /var/run/starter[.daemon_name].pid */
571 {
572 FILE *fd = fopen(starter_pid_file, "w");
573
574 if (fd)
575 {
576 fprintf(fd, "%u\n", getpid());
577 fclose(fd);
578 }
579 }
580
581 /* we handle these signals only in pselect() */
582 memset(&action, 0, sizeof(action));
583 sigemptyset(&action.sa_mask);
584 sigaddset(&action.sa_mask, SIGHUP);
585 sigaddset(&action.sa_mask, SIGINT);
586 sigaddset(&action.sa_mask, SIGTERM);
587 sigaddset(&action.sa_mask, SIGQUIT);
588 sigaddset(&action.sa_mask, SIGALRM);
589 sigaddset(&action.sa_mask, SIGUSR1);
590 pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL);
591
592 /* install a handler for fatal signals */
593 action.sa_handler = fatal_signal_handler;
594 sigaction(SIGSEGV, &action, NULL);
595 sigaction(SIGILL, &action, NULL);
596 sigaction(SIGBUS, &action, NULL);
597 action.sa_handler = SIG_IGN;
598 sigaction(SIGPIPE, &action, NULL);
599
600 /* install main signal handler */
601 action.sa_handler = signal_handler;
602 sigaction(SIGHUP, &action, NULL);
603 sigaction(SIGINT, &action, NULL);
604 sigaction(SIGTERM, &action, NULL);
605 sigaction(SIGQUIT, &action, NULL);
606 sigaction(SIGALRM, &action, NULL);
607 sigaction(SIGUSR1, &action, NULL);
608 /* this is not blocked above as we want to receive it asynchronously */
609 sigaction(SIGCHLD, &action, NULL);
610
611 /* empty mask for pselect() call below */
612 sigemptyset(&action.sa_mask);
613
614 for (;;)
615 {
616 /*
617 * Stop charon (if started) and exit
618 */
619 if (_action_ & FLAG_ACTION_QUIT)
620 {
621 if (starter_charon_pid())
622 {
623 starter_stop_charon();
624 }
625 confread_free(cfg);
626 unlink(starter_pid_file);
627 cleanup();
628 DBG1(DBG_APP, "ipsec starter stopped");
629 close_log();
630 exit(LSB_RC_SUCCESS);
631 }
632
633 /*
634 * Delete all connections. Will be added below
635 */
636 if (_action_ & FLAG_ACTION_RELOAD)
637 {
638 _action_ &= ~FLAG_ACTION_RELOAD;
639 if (starter_charon_pid())
640 {
641 for (conn = cfg->conn_first; conn; conn = conn->next)
642 {
643 if (conn->state == STATE_ADDED)
644 {
645 if (starter_charon_pid())
646 {
647 if (conn->startup == STARTUP_ROUTE)
648 {
649 starter_stroke_unroute_conn(conn);
650 }
651 starter_stroke_del_conn(conn);
652 }
653 conn->state = STATE_TO_ADD;
654 }
655 }
656 for (ca = cfg->ca_first; ca; ca = ca->next)
657 {
658 if (ca->state == STATE_ADDED)
659 {
660 if (starter_charon_pid())
661 {
662 starter_stroke_del_ca(ca);
663 }
664 ca->state = STATE_TO_ADD;
665 }
666 }
667 }
668 }
669
670 /*
671 * Update configuration
672 */
673 if (_action_ & FLAG_ACTION_UPDATE)
674 {
675 _action_ &= ~FLAG_ACTION_UPDATE;
676 DBG2(DBG_APP, "Reloading config...");
677 new_cfg = confread_load(config_file);
678
679 if (new_cfg && (new_cfg->err == 0))
680 {
681 /* Switch to new config. New conn will be loaded below */
682
683 /* Look for new connections that are already loaded */
684 for (conn = cfg->conn_first; conn; conn = conn->next)
685 {
686 if (conn->state == STATE_ADDED)
687 {
688 for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next)
689 {
690 if (conn2->state == STATE_TO_ADD && starter_cmp_conn(conn, conn2))
691 {
692 conn->state = STATE_REPLACED;
693 conn2->state = STATE_ADDED;
694 conn2->id = conn->id;
695 break;
696 }
697 }
698 }
699 }
700
701 /* Remove conn sections that have become unused */
702 for (conn = cfg->conn_first; conn; conn = conn->next)
703 {
704 if (conn->state == STATE_ADDED)
705 {
706 if (starter_charon_pid())
707 {
708 if (conn->startup == STARTUP_ROUTE)
709 {
710 starter_stroke_unroute_conn(conn);
711 }
712 starter_stroke_del_conn(conn);
713 }
714 }
715 }
716
717 /* Look for new ca sections that are already loaded */
718 for (ca = cfg->ca_first; ca; ca = ca->next)
719 {
720 if (ca->state == STATE_ADDED)
721 {
722 for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next)
723 {
724 if (ca2->state == STATE_TO_ADD && starter_cmp_ca(ca, ca2))
725 {
726 ca->state = STATE_REPLACED;
727 ca2->state = STATE_ADDED;
728 break;
729 }
730 }
731 }
732 }
733
734 /* Remove ca sections that have become unused */
735 for (ca = cfg->ca_first; ca; ca = ca->next)
736 {
737 if (ca->state == STATE_ADDED)
738 {
739 if (starter_charon_pid())
740 {
741 starter_stroke_del_ca(ca);
742 }
743 }
744 }
745 confread_free(cfg);
746 cfg = new_cfg;
747 }
748 else
749 {
750 DBG1(DBG_APP, "can't reload config file due to errors -- keeping old one");
751 if (new_cfg)
752 {
753 confread_free(new_cfg);
754 }
755 }
756 last_reload = time_monotonic(NULL);
757 }
758
759 /*
760 * Start daemon
761 */
762 if (_action_ & FLAG_ACTION_START_CHARON)
763 {
764 _action_ &= ~FLAG_ACTION_START_CHARON;
765 if (!starter_charon_pid())
766 {
767 DBG2(DBG_APP, "Attempting to start %s...", daemon_name);
768 if (starter_start_charon(cfg, no_fork, attach_gdb))
769 {
770 /* schedule next try */
771 alarm(CHARON_RESTART_DELAY);
772 }
773 starter_stroke_configure(cfg);
774 }
775
776 for (ca = cfg->ca_first; ca; ca = ca->next)
777 {
778 if (ca->state == STATE_ADDED)
779 {
780 ca->state = STATE_TO_ADD;
781 }
782 }
783
784 for (conn = cfg->conn_first; conn; conn = conn->next)
785 {
786 if (conn->state == STATE_ADDED)
787 {
788 conn->state = STATE_TO_ADD;
789 }
790 }
791 }
792
793 /*
794 * Add stale conn and ca sections
795 */
796 if (starter_charon_pid())
797 {
798 for (ca = cfg->ca_first; ca; ca = ca->next)
799 {
800 if (ca->state == STATE_TO_ADD)
801 {
802 if (starter_charon_pid())
803 {
804 starter_stroke_add_ca(ca);
805 }
806 ca->state = STATE_ADDED;
807 }
808 }
809
810 for (conn = cfg->conn_first; conn; conn = conn->next)
811 {
812 if (conn->state == STATE_TO_ADD)
813 {
814 if (conn->id == 0)
815 {
816 /* affect new unique id */
817 conn->id = id++;
818 }
819 if (starter_charon_pid())
820 {
821 starter_stroke_add_conn(cfg, conn);
822 }
823 conn->state = STATE_ADDED;
824
825 if (conn->startup == STARTUP_START)
826 {
827 if (starter_charon_pid())
828 {
829 starter_stroke_initiate_conn(conn);
830 }
831 }
832 else if (conn->startup == STARTUP_ROUTE)
833 {
834 if (starter_charon_pid())
835 {
836 starter_stroke_route_conn(conn);
837 }
838 }
839 }
840 }
841 }
842
843 /*
844 * If auto_update activated, when to stop select
845 */
846 if (auto_update)
847 {
848 time_t now = time_monotonic(NULL);
849
850 ts.tv_sec = (now < last_reload + auto_update) ?
851 (last_reload + auto_update - now) : 0;
852 ts.tv_nsec = 0;
853 }
854
855 /*
856 * Wait for something to happen
857 */
858 if (!_action_ &&
859 pselect(0, NULL, NULL, NULL, auto_update ? &ts : NULL,
860 &action.sa_mask) == 0)
861 {
862 /* timeout -> auto_update */
863 _action_ |= FLAG_ACTION_UPDATE;
864 }
865 }
866 exit(LSB_RC_SUCCESS);
867 }