00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifdef HAVE_CONFIG_H
00027 # include <config.h>
00028 #endif
00029
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #include <unistd.h>
00034 #include <getopt.h>
00035 #include <pwd.h>
00036 #include <sys/types.h>
00037 #include <sys/stat.h>
00038 #include <fcntl.h>
00039 #include <errno.h>
00040 #include <signal.h>
00041
00042 #include <dbus/dbus.h>
00043 #include <dbus/dbus-glib.h>
00044
00045 #include "callout.h"
00046 #include "logger.h"
00047 #include "hald.h"
00048 #include "device_store.h"
00049 #include "device_info.h"
00050 #include "osspec.h"
00051 #include "hald_dbus.h"
00052
00059 static HalDeviceStore *global_device_list = NULL;
00060
00061 static HalDeviceStore *temporary_device_list = NULL;
00062
00063 static void
00064 gdl_store_changed (HalDeviceStore *store, HalDevice *device,
00065 gboolean is_added, gpointer user_data)
00066 {
00067 if (is_added)
00068 HAL_INFO (("Added device to GDL; udi=%s",
00069 hal_device_get_udi(device)));
00070 else
00071 HAL_INFO (("Removed device from GDL; udi=%s",
00072 hal_device_get_udi(device)));
00073
00074
00075
00076 if (is_added) {
00077 manager_send_signal_device_added (device);
00078 hal_callout_device (device, TRUE);
00079 } else {
00080 manager_send_signal_device_removed (device);
00081 hal_callout_device (device, FALSE);
00082 }
00083 }
00084
00085 static void
00086 gdl_property_changed (HalDeviceStore *store, HalDevice *device,
00087 const char *key, gboolean added, gboolean removed,
00088 gpointer user_data)
00089 {
00090 device_send_signal_property_modified (device, key, removed, added);
00091
00092
00093 if (added == FALSE && removed == FALSE)
00094 hal_callout_property (device, key);
00095 }
00096
00097 static void
00098 gdl_capability_added (HalDeviceStore *store, HalDevice *device,
00099 const char *capability, gpointer user_data)
00100 {
00101 manager_send_signal_new_capability (device, capability);
00102 hal_callout_capability (device, capability, TRUE);
00103 }
00104
00105 HalDeviceStore *
00106 hald_get_gdl (void)
00107 {
00108 if (global_device_list == NULL) {
00109 global_device_list = hal_device_store_new ();
00110
00111 g_signal_connect (global_device_list,
00112 "store_changed",
00113 G_CALLBACK (gdl_store_changed), NULL);
00114 g_signal_connect (global_device_list,
00115 "device_property_changed",
00116 G_CALLBACK (gdl_property_changed), NULL);
00117 g_signal_connect (global_device_list,
00118 "device_capability_added",
00119 G_CALLBACK (gdl_capability_added), NULL);
00120 }
00121
00122 return global_device_list;
00123 }
00124
00125 HalDeviceStore *
00126 hald_get_tdl (void)
00127 {
00128 if (temporary_device_list == NULL) {
00129 temporary_device_list = hal_device_store_new ();
00130
00131 }
00132
00133 return temporary_device_list;
00134 }
00135
00146 static void
00147 usage ()
00148 {
00149 fprintf (stderr, "\n" "usage : hald [--daemon=yes|no] [--help]\n");
00150 fprintf (stderr,
00151 "\n"
00152 " --daemon=yes|no Become a daemon\n"
00153 " --help Show this information and exit\n"
00154 "\n"
00155 "The HAL daemon detects devices present in the system and provides the\n"
00156 "org.freedesktop.Hal service through D-BUS. The commandline options given\n"
00157 "overrides the configuration given in "
00158 PACKAGE_SYSCONF_DIR "/hald.conf\n" "\n"
00159 "For more information visit http://freedesktop.org/Software/hal\n"
00160 "\n");
00161 }
00162
00163
00165 static dbus_bool_t opt_become_daemon = TRUE;
00166
00168 static char *opt_run_as = NULL;
00169
00176 int
00177 main (int argc, char *argv[])
00178 {
00179 DBusConnection *dbus_connection;
00180 GMainLoop *loop;
00181
00182
00183
00184
00185 while (1) {
00186 int c;
00187 int option_index = 0;
00188 const char *opt;
00189 static struct option long_options[] = {
00190 {"daemon", 1, NULL, 0},
00191 {"help", 0, NULL, 0},
00192 {NULL, 0, NULL, 0}
00193 };
00194
00195 c = getopt_long (argc, argv, "",
00196 long_options, &option_index);
00197 if (c == -1)
00198 break;
00199
00200 switch (c) {
00201 case 0:
00202 opt = long_options[option_index].name;
00203
00204 if (strcmp (opt, "help") == 0) {
00205 usage ();
00206 return 0;
00207 } else if (strcmp (opt, "daemon") == 0) {
00208 if (strcmp ("yes", optarg) == 0) {
00209 opt_become_daemon = TRUE;
00210 } else if (strcmp ("no", optarg) == 0) {
00211 opt_become_daemon = FALSE;
00212 } else {
00213 usage ();
00214 return 1;
00215 }
00216 }
00217 break;
00218
00219 default:
00220 usage ();
00221 return 1;
00222 break;
00223 }
00224 }
00225
00226 logger_init ();
00227 HAL_INFO (("HAL daemon version " PACKAGE_VERSION " starting up"));
00228
00229 HAL_DEBUG (("opt_become_daemon = %d", opt_become_daemon));
00230
00231 if (opt_become_daemon) {
00232 int child_pid;
00233 int dev_null_fd;
00234
00235 if (chdir ("/") < 0) {
00236 HAL_ERROR (("Could not chdir to /, errno=%d",
00237 errno));
00238 return 1;
00239 }
00240
00241 child_pid = fork ();
00242 switch (child_pid) {
00243 case -1:
00244 HAL_ERROR (("Cannot fork(), errno=%d", errno));
00245 break;
00246
00247 case 0:
00248
00249
00250 dev_null_fd = open ("/dev/null", O_RDWR);
00251
00252 if (dev_null_fd > 0) {
00253
00254 dup2 (dev_null_fd, 0);
00255 dup2 (dev_null_fd, 1);
00256 dup2 (dev_null_fd, 2);
00257 }
00258
00259 umask (022);
00260
00263 break;
00264
00265 default:
00266
00267 exit (0);
00268 break;
00269 }
00270
00271
00272 setsid ();
00273 }
00274
00275 if (opt_run_as != NULL) {
00276 uid_t uid;
00277 gid_t gid;
00278 struct passwd *pw;
00279
00280
00281 if ((pw = getpwnam (opt_run_as)) == NULL) {
00282 HAL_ERROR (("Could not lookup user %s, errno=%d",
00283 opt_run_as, errno));
00284 exit (1);
00285 }
00286
00287 uid = pw->pw_uid;
00288 gid = pw->pw_gid;
00289
00290 if (setgid (gid) < 0) {
00291 HAL_ERROR (("Failed to set GID to %d, errno=%d",
00292 gid, errno));
00293 exit (1);
00294 }
00295
00296 if (setuid (uid) < 0) {
00297 HAL_ERROR (("Failed to set UID to %d, errno=%d",
00298 uid, errno));
00299 exit (1);
00300 }
00301
00302 }
00303
00304 g_type_init ();
00305
00306
00307 dbus_connection = hald_dbus_init ();
00308
00309 loop = g_main_loop_new (NULL, FALSE);
00310
00311
00312 osspec_init (dbus_connection);
00313
00314 osspec_probe ();
00315
00316
00317 g_main_loop_run (loop);
00318
00319 return 0;
00320 }
00321