2 * Copyright (C) 2009 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <apr_general.h>
28 #include <apr_network_io.h>
29 #include <apr_getopt.h>
30 #include <apr_strings.h>
31 #include <apr_thread_proc.h>
33 #include <apr_portable.h>
35 #include "hostinfod.h"
37 static void main_loop (void);
38 static void set_reread_socket_dir (const apr_pollfd_t *);
39 static void do_reread_socket_dir (void);
41 typedef void (*poll_callback) (const apr_pollfd_t *);
43 const char *conf_file = DEFAULT_CONF_FILE;
44 char *socket_dir = NULL;
45 char *guests_file = NULL;
48 int verbose_set_on_cmdline = 0;
50 int foreground_set_on_cmdline = 0;
52 int messages_to_stderr = 1;
54 static int reread_socket_dir = 1;
57 apr_pool_t *pool = NULL;
58 static apr_pollset_t *set;
63 printf ("hostinfod (virt-hostinfo daemon)\n"
64 "Copyright (C) 2009 Red Hat Inc.\n"
67 " hostinfod [--options]\n"
70 " --help Display full usage\n"
71 " -c file | --config file\n"
72 " Configuration file (default: %s)\n"
73 " -f | --foreground\n"
74 " Run in the foreground (don't fork)\n"
75 " -v Enable verbose messages (sent to syslog, and to\n"
76 " stderr if -d option is given)\n",
81 main (int argc, char *argv[])
83 static const apr_getopt_option_t options[] = {
84 { "config", 'c', TRUE, "configuration file" },
85 { "foreground", 'f', FALSE, "run in foreground (don't fork)" },
86 { "verbose", 'v', FALSE, "enable verbose messages" },
87 { "help", '?', FALSE, "display help" },
96 apr_pool_create (&pool, NULL);
98 apr_getopt_init (&opt, pool, argc, argv);
102 socket_dir = apr_pstrdup (pool, DEFAULT_SOCKET_DIR);
103 guests_file = apr_pstrdup (pool, DEFAULT_GUESTS_FILE);
106 while ((r = apr_getopt_long (opt, options, &c, &optarg)) == APR_SUCCESS) {
110 /* If the user is specifying this on the command line, then
111 * it should exist. They may have typo'd the name.
113 if (access (conf_file, R_OK) == -1) {
114 perrorf ("%s", conf_file);
120 foreground_set_on_cmdline = 1;
124 verbose_set_on_cmdline = 1;
134 fprintf (stderr, "%s: unknown command line option\n", argv[0]);
138 /* Read the config file. */
139 read_main_conf_file ();
141 /* Monitor the socket directory. */
142 monitor_socket_dir ();
144 /* Create the initial pollset, just containing inotify socket. */
145 r = apr_pollset_create (&set, 1024 /* ? */, pool, 0);
146 if (r != APR_SUCCESS) {
147 paprerror (r, "apr_pollset_create");
151 r = apr_os_sock_put (&tsock, &sockets_inotify_fd, pool);
152 if (r != APR_SUCCESS) {
153 paprerror (r, "apr_os_sock_put");
156 apr_pollfd_t *tpollfd = apr_palloc (pool, sizeof *tpollfd);
158 tpollfd->desc_type = APR_POLL_SOCKET;
159 tpollfd->reqevents = APR_POLLIN;
160 tpollfd->rtnevents = 0;
161 tpollfd->desc.s = tsock;
162 tpollfd->client_data = set_reread_socket_dir;
163 r = apr_pollset_add (set, tpollfd);
164 if (r != APR_SUCCESS) {
165 paprerror (r, "apr_pollset_add");
174 /* After we detach from the terminal, all further messages
175 * should just go to syslog.
177 messages_to_stderr = 0;
180 message (PACKAGE_STRING);
191 apr_int32_t numdescs;
192 const apr_pollfd_t *descs;
196 /* A socket has appeared or disappeared from the socket directory. */
197 if (reread_socket_dir) {
198 do_reread_socket_dir ();
199 reread_socket_dir = 0;
203 r = apr_pollset_poll (set, 0, &numdescs, &descs);
204 if (r != APR_SUCCESS) {
205 paprerror (r, "apr_pollset_poll");
209 /* Perform the callbacks. */
210 for (i = 0; i < numdescs; ++i) {
211 poll_callback callback;
213 callback = descs[i].client_data;
214 callback (&descs[i]);
220 set_reread_socket_dir (const apr_pollfd_t *_)
222 reread_socket_dir = 1;
226 do_reread_socket_dir (void)
230 debug ("reading socket directory");
232 /* Discard anything which appears on the inotify socket. We will
233 * reread the whole directory each time.
235 while (read (sockets_inotify_fd, buf, sizeof buf) > 0)