#include <apr_general.h>
#include <apr_network_io.h>
#include <apr_getopt.h>
+#include <apr_strings.h>
+#include <apr_thread_proc.h>
+#include <apr_poll.h>
+#include <apr_portable.h>
#include "hostinfod.h"
+static void main_loop (void);
+static void set_reread_socket_dir (const apr_pollfd_t *);
+static void do_reread_socket_dir (void);
+
+typedef void (*poll_callback) (const apr_pollfd_t *);
+
const char *conf_file = DEFAULT_CONF_FILE;
-const char *socket_dir = DEFAULT_SOCKET_DIR;
+char *socket_dir = NULL;
char *guests_file = NULL;
-int socket_dir_set_on_cmdline = 0;
-int debug = 0;
-int debug_set_on_cmdline = 0;
+
int verbose = 0;
int verbose_set_on_cmdline = 0;
int foreground = 0;
int foreground_set_on_cmdline = 0;
+
+int messages_to_stderr = 1;
+
+static int reread_socket_dir = 1;
+static int quit = 0;
+
apr_pool_t *pool = NULL;
+static apr_pollset_t *set;
static void
usage (void)
" --help Display full usage\n"
" -c file | --config file\n"
" Configuration file (default: %s)\n"
- " -d | --debug Enable debug messages to stderr (implies -v)\n"
" -f | --foreground\n"
" Run in the foreground (don't fork)\n"
- " -s dir | --socketdir dir\n"
- " Socket directory (default: %s)\n"
" -v Enable verbose messages (sent to syslog, and to\n"
" stderr if -d option is given)\n",
- DEFAULT_CONF_FILE, DEFAULT_SOCKET_DIR);
+ DEFAULT_CONF_FILE);
}
int
{
static const apr_getopt_option_t options[] = {
{ "config", 'c', TRUE, "configuration file" },
- { "debug", 'd', FALSE, "enable debug messages to stderr" },
{ "foreground", 'f', FALSE, "run in foreground (don't fork)" },
- { "socketdir", 's', TRUE, "socket directory" },
{ "verbose", 'v', FALSE, "enable verbose messages" },
{ "help", '?', FALSE, "display help" },
{ NULL, 0, 0, NULL },
apr_getopt_init (&opt, pool, argc, argv);
+ init_syslog ();
+
+ socket_dir = apr_pstrdup (pool, DEFAULT_SOCKET_DIR);
+ guests_file = apr_pstrdup (pool, DEFAULT_GUESTS_FILE);
+
+ /* Command line. */
while ((r = apr_getopt_long (opt, options, &c, &optarg)) == APR_SUCCESS) {
switch (c) {
case 'c':
* it should exist. They may have typo'd the name.
*/
if (access (conf_file, R_OK) == -1) {
- perror (conf_file);
+ perrorf ("%s", conf_file);
exit (1);
}
break;
- case 'd':
- debug = verbose = 1;
- debug_set_on_cmdline = verbose_set_on_cmdline = 1;
- break;
case 'f':
foreground = 1;
foreground_set_on_cmdline = 1;
break;
- case 's':
- socket_dir = optarg;
- socket_dir_set_on_cmdline = 1;
- break;
case 'v':
verbose = 1;
verbose_set_on_cmdline = 1;
exit (1);
}
+ /* Read the config file. */
read_main_conf_file ();
+ /* Monitor the socket directory. */
+ monitor_socket_dir ();
-
-
-
-
-
+ /* Create the initial pollset, just containing inotify socket. */
+ r = apr_pollset_create (&set, 1024 /* ? */, pool, 0);
+ if (r != APR_SUCCESS) {
+ paprerror (r, "apr_pollset_create");
+ exit (1);
+ }
+ apr_socket_t *tsock;
+ r = apr_os_sock_put (&tsock, &sockets_inotify_fd, pool);
+ if (r != APR_SUCCESS) {
+ paprerror (r, "apr_os_sock_put");
+ exit (1);
+ }
+ apr_pollfd_t *tpollfd = apr_palloc (pool, sizeof *tpollfd);
+ tpollfd->p = pool;
+ tpollfd->desc_type = APR_POLL_SOCKET;
+ tpollfd->reqevents = APR_POLLIN;
+ tpollfd->rtnevents = 0;
+ tpollfd->desc.s = tsock;
+ tpollfd->client_data = set_reread_socket_dir;
+ r = apr_pollset_add (set, tpollfd);
+ if (r != APR_SUCCESS) {
+ paprerror (r, "apr_pollset_add");
+ exit (1);
+ }
/* Daemonize. */
chdir ("/");
- if (!foreground)
+ if (!foreground) {
apr_proc_detach (1);
+ /* After we detach from the terminal, all further messages
+ * should just go to syslog.
+ */
+ messages_to_stderr = 0;
+ }
+ message (PACKAGE_STRING);
+ main_loop ();
apr_terminate ();
return 0;
}
+
+static void
+main_loop (void)
+{
+ apr_status_t r;
+ apr_int32_t numdescs;
+ const apr_pollfd_t *descs;
+ int i;
+
+ while (!quit) {
+ /* A socket has appeared or disappeared from the socket directory. */
+ if (reread_socket_dir) {
+ do_reread_socket_dir ();
+ reread_socket_dir = 0;
+ }
+
+ /* Poll. */
+ r = apr_pollset_poll (set, 0, &numdescs, &descs);
+ if (r != APR_SUCCESS) {
+ paprerror (r, "apr_pollset_poll");
+ exit (1);
+ }
+
+ /* Perform the callbacks. */
+ for (i = 0; i < numdescs; ++i) {
+ poll_callback callback;
+
+ callback = descs[i].client_data;
+ callback (&descs[i]);
+ }
+ }
+}
+
+static void
+set_reread_socket_dir (const apr_pollfd_t *_)
+{
+ reread_socket_dir = 1;
+}
+
+static void
+do_reread_socket_dir (void)
+{
+ char buf[256];
+
+ debug ("reading socket directory");
+
+ /* Discard anything which appears on the inotify socket. We will
+ * reread the whole directory each time.
+ */
+ while (read (sockets_inotify_fd, buf, sizeof buf) > 0)
+ ;
+
+
+
+
+
+
+
+
+
+
+
+}