Main Page | Modules | Data Structures | File List | Data Fields | Related Pages

hald.c

00001 /***************************************************************************
00002  * CVSID: $Id: hald.c,v 1.4 2004/04/21 18:44:41 david Exp $
00003  *
00004  * hald.c : main startup for HAL daemon
00005  *
00006  * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
00007  *
00008  * Licensed under the Academic Free License version 2.0
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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     /*hal_device_print (device);*/
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     /* only execute the callouts if the property _changed_ */
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     /* We require root to sniff mii registers */
00183     /*opt_run_as = HAL_USER; */
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             /* child */
00249 
00250             dev_null_fd = open ("/dev/null", O_RDWR);
00251             /* ignore if we can't open /dev/null */
00252             if (dev_null_fd > 0) {
00253                 /* attach /dev/null to stdout, stdin, stderr */
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             /* parent */
00267             exit (0);
00268             break;
00269         }
00270 
00271         /* Create session */
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     /* set up the dbus services */
00307     dbus_connection = hald_dbus_init ();
00308 
00309     loop = g_main_loop_new (NULL, FALSE);
00310 
00311     /* initialize operating system specific parts */
00312     osspec_init (dbus_connection);
00313     /* and detect devices */
00314     osspec_probe ();
00315 
00316     /* run the main loop and serve clients */
00317     g_main_loop_run (loop);
00318 
00319     return 0;
00320 }
00321 

Generated on Sat Apr 24 19:57:44 2004 for HAL by doxygen 1.3.6-20040222