ofdbus/dbus/bus/main.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /* -*- mode: C; c-file-style: "gnu" -*- */
       
     2 /* main.c  main() for message bus
       
     3  *
       
     4  * Copyright (C) 2003  CodeFactory AB
       
     5  * Copyright (C) 2003  Red Hat, Inc.
       
     6  * Copyright (C) 2004  Imendio HB
       
     7  * Portion Copyright © 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
       
     8  *
       
     9  * Licensed under the Academic Free License version 2.1
       
    10  * 
       
    11  * This program is free software; you can redistribute it and/or modify
       
    12  * it under the terms of the GNU General Public License as published by
       
    13  * the Free Software Foundation; either version 2 of the License, or
       
    14  * (at your option) any later version.
       
    15  *
       
    16  * This program is distributed in the hope that it will be useful,
       
    17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    19  * GNU General Public License for more details.
       
    20  * 
       
    21  * You should have received a copy of the GNU General Public License
       
    22  * along with this program; if not, write to the Free Software
       
    23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    24  *
       
    25  */ 
       
    26 #include "bus.h"
       
    27 #include "driver.h"
       
    28 #ifndef __SYMBIAN32__
       
    29 #include <dbus/dbus-internals.h>
       
    30 #include <dbus/dbus-watch.h>
       
    31 #else
       
    32 #include "dbus-internals.h"
       
    33 #include "dbus-watch.h"
       
    34 #endif //__SYMBIAN32__
       
    35 #include <stdio.h>
       
    36 #include <stdlib.h>
       
    37 #include <string.h>
       
    38 #ifndef __SYMBIAN32__
       
    39 #include <signal.h>
       
    40 #endif
       
    41 #include <errno.h>
       
    42 #include "selinux.h"
       
    43 
       
    44 static BusContext *context;
       
    45 
       
    46 static int reload_pipe[2];
       
    47 #define RELOAD_READ_END 0
       
    48 #define RELOAD_WRITE_END 1
       
    49 
       
    50 #ifdef __SYMBIAN32__
       
    51 #if 0 
       
    52  #include <fcntl.h>
       
    53 
       
    54 int lock_file()
       
    55 {
       
    56 
       
    57 
       
    58 
       
    59        /*
       
    60        struct flock {
       
    61 	off_t	l_start;	 starting offset 
       
    62 	off_t	l_len;		 len = 0 means until end of file 
       
    63 	pid_t	l_pid;		 lock owner 
       
    64 	short	l_type;		 lock type: read/write, etc. 
       
    65 	short	l_whence;	 type of l_start 
       
    66 };
       
    67  l_type   l_whence  l_start  l_len  l_pid   */
       
    68 
       
    69 
       
    70     //	struct flock fl = { F_WRLCK, SEEK_SET, 0,       0,     0 };
       
    71     //	struct flock fl = { 0, 0, 0,F_WRLCK, SEEK_SET};
       
    72     	int fd;
       
    73     
       
    74       //  fl.l_pid = getpid();
       
    75     
       
    76     	
       
    77     	if ((fd = open(DBUS_LOCK_FILE, O_RDWR|O_CREAT|O_EXCL, 0666)) == -1) 
       
    78     	{
       
    79     //	perror("open file status");
       
    80     	return 0;
       
    81     	
       
    82     	}
       
    83     
       
    84    /* fcntl file lock not supported in openc 	
       
    85     	if (fcntl(fd, F_SETLKW, &fl) == -1) {
       
    86     		perror("fcntl");
       
    87 		close(fd);
       
    88     		return 0;
       
    89     	}
       
    90     
       
    91    */ 	
       
    92     close(fd);
       
    93 	return 1;
       
    94 
       
    95 }
       
    96 
       
    97 #endif
       
    98 
       
    99 #endif
       
   100 void
       
   101 signal_handler (int sig)
       
   102 {
       
   103 #ifndef __SYMBIAN32__
       
   104   DBusString str;
       
   105 
       
   106   switch (sig)
       
   107     {
       
   108 #ifdef DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX 
       
   109     case SIGIO: 
       
   110       /* explicit fall-through */
       
   111 #endif /* DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX  */
       
   112     case SIGHUP:
       
   113       _dbus_string_init_const (&str, "foo");
       
   114       if (!_dbus_write_socket (reload_pipe[RELOAD_WRITE_END], &str, 0, 1))
       
   115 	{
       
   116 	  _dbus_warn ("Unable to write to reload pipe.\n");
       
   117 	  exit (1);
       
   118 	}
       
   119       break;
       
   120 
       
   121     case SIGTERM:
       
   122       _dbus_loop_quit (bus_context_get_loop (context));
       
   123       break;
       
   124     }
       
   125 
       
   126 #endif
       
   127 }
       
   128 static void
       
   129 usage (void)
       
   130 {
       
   131   fprintf (stderr, DAEMON_NAME " [--version] [--session] [--system] [--config-file=FILE] [--print-address[=DESCRIPTOR]] [--print-pid[=DESCRIPTOR]] [--fork] [--nofork] [--introspect]\n");
       
   132   exit (1);
       
   133 }
       
   134 
       
   135 static void
       
   136 version (void)
       
   137 {
       
   138   printf ("D-Bus Message Bus Daemon %s\n"
       
   139           "Copyright (C) 2002, 2003 Red Hat, Inc., CodeFactory AB, and others\n"
       
   140           "This is free software; see the source for copying conditions.\n"
       
   141           "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
       
   142           VERSION);
       
   143   exit (0);
       
   144 }
       
   145 
       
   146 static void
       
   147 introspect (void)
       
   148 {
       
   149   DBusString xml;
       
   150   const char *v_STRING;  
       
   151 
       
   152   if (!_dbus_string_init (&xml))
       
   153     goto oom;
       
   154 
       
   155   if (!bus_driver_generate_introspect_string (&xml))
       
   156     {
       
   157       _dbus_string_free (&xml);
       
   158       goto oom;
       
   159     }
       
   160 
       
   161   v_STRING = _dbus_string_get_const_data (&xml);
       
   162   printf ("%s\n", v_STRING); 
       
   163 
       
   164   exit (0);
       
   165  
       
   166  oom:
       
   167   _dbus_warn ("Can not introspect - Out of memory\n");
       
   168   exit (1);
       
   169 }
       
   170 static void
       
   171 check_two_config_files (const DBusString *config_file,
       
   172                         const char       *extra_arg)
       
   173 {
       
   174   if (_dbus_string_get_length (config_file) > 0)
       
   175     {
       
   176       fprintf (stderr, "--%s specified but configuration file %s already requested\n",
       
   177                extra_arg, _dbus_string_get_const_data (config_file));
       
   178       exit (1);
       
   179     }
       
   180 }
       
   181 
       
   182 static void
       
   183 check_two_addr_descriptors (const DBusString *addr_fd,
       
   184                             const char       *extra_arg)
       
   185 {
       
   186   if (_dbus_string_get_length (addr_fd) > 0)
       
   187     {
       
   188       fprintf (stderr, "--%s specified but printing address to %s already requested\n",
       
   189                extra_arg, _dbus_string_get_const_data (addr_fd));
       
   190       exit (1);
       
   191     }
       
   192 }
       
   193 
       
   194 static void
       
   195 check_two_pid_descriptors (const DBusString *pid_fd,
       
   196                            const char       *extra_arg)
       
   197 {
       
   198   if (_dbus_string_get_length (pid_fd) > 0)
       
   199     {
       
   200       fprintf (stderr, "--%s specified but printing pid to %s already requested\n",
       
   201                extra_arg, _dbus_string_get_const_data (pid_fd));
       
   202       exit (1);
       
   203     }
       
   204 }
       
   205 
       
   206 static dbus_bool_t
       
   207 handle_reload_watch (DBusWatch    *watch,
       
   208 		     unsigned int  flags,
       
   209 		     void         *data)
       
   210 {
       
   211   DBusError error;
       
   212   DBusString str;
       
   213   _dbus_string_init (&str);
       
   214   if (_dbus_read_socket (reload_pipe[RELOAD_READ_END], &str, 1) != 1)
       
   215     {
       
   216       _dbus_warn ("Couldn't read from reload pipe.\n");
       
   217       exit (1);
       
   218     }
       
   219   _dbus_string_free (&str);
       
   220 
       
   221   dbus_error_init (&error);
       
   222   if (! bus_context_reload_config (context, &error))
       
   223     {
       
   224       _dbus_warn ("Unable to reload configuration: %s\n",
       
   225 		  error.message);
       
   226       dbus_error_free (&error);
       
   227       exit (1);
       
   228     }
       
   229   return TRUE;
       
   230 }
       
   231 
       
   232 
       
   233 static dbus_bool_t
       
   234 reload_watch_callback (DBusWatch    *watch,
       
   235 		       unsigned int  condition,
       
   236 		       void         *data)
       
   237 {
       
   238   return dbus_watch_handle (watch, condition);
       
   239 }
       
   240 
       
   241 static void
       
   242 setup_reload_pipe (DBusLoop *loop)
       
   243 {
       
   244   DBusError error;
       
   245   DBusWatch *watch;
       
   246 
       
   247   dbus_error_init (&error);
       
   248 
       
   249   if (!_dbus_full_duplex_pipe (&reload_pipe[0], &reload_pipe[1],
       
   250 			       TRUE, &error))
       
   251     {
       
   252       _dbus_warn ("Unable to create reload pipe: %s\n",
       
   253 		  error.message);
       
   254       dbus_error_free (&error);
       
   255       exit (1);
       
   256     }
       
   257 
       
   258   _dbus_fd_set_close_on_exec (reload_pipe[0]);
       
   259   _dbus_fd_set_close_on_exec (reload_pipe[1]);
       
   260 
       
   261   watch = _dbus_watch_new (reload_pipe[RELOAD_READ_END],
       
   262 			   DBUS_WATCH_READABLE, TRUE,
       
   263 			   handle_reload_watch, NULL, NULL);
       
   264 
       
   265   if (watch == NULL)
       
   266     {
       
   267       _dbus_warn ("Unable to create reload watch: %s\n",
       
   268 		  error.message);
       
   269       dbus_error_free (&error);
       
   270       exit (1);
       
   271     }
       
   272 
       
   273   if (!_dbus_loop_add_watch (loop, watch, reload_watch_callback,
       
   274 			     NULL, NULL))
       
   275     {
       
   276       _dbus_warn ("Unable to add reload watch to main loop: %s\n",
       
   277 		  error.message);
       
   278       dbus_error_free (&error);
       
   279       exit (1);
       
   280     }
       
   281 
       
   282 }
       
   283 
       
   284 
       
   285 int
       
   286 main (int argc, char **argv)
       
   287 {
       
   288   DBusError error;
       
   289   DBusString config_file;
       
   290   DBusString addr_fd;
       
   291   DBusString pid_fd;
       
   292   const char *prev_arg;
       
   293   int print_addr_fd;
       
   294   int print_pid_fd;
       
   295   int i;
       
   296   dbus_bool_t print_address;
       
   297   dbus_bool_t print_pid;
       
   298   int force_fork;
       
   299   #ifdef __SYMBIAN32__
       
   300   char systemconfpath[35];
       
   301 #endif
       
   302   
       
   303  // write(1, "hi daemon", 9); 
       
   304 
       
   305   if (!_dbus_string_init (&config_file))
       
   306     return 1;
       
   307 
       
   308   if (!_dbus_string_init (&addr_fd))
       
   309     return 1;
       
   310 
       
   311   if (!_dbus_string_init (&pid_fd))
       
   312     return 1;
       
   313 
       
   314   print_address = FALSE;
       
   315   print_pid = FALSE;
       
   316   force_fork = FORK_FOLLOW_CONFIG_FILE;
       
   317 
       
   318 #ifdef __SYMBIAN32__
       
   319 // Open C Does not have command arguments
       
   320 // Open C Does not have fork
       
   321 // force_fork = FORK_NEVER;
       
   322 // __SYMBIAN32__ uses system dbus only
       
   323 
       
   324 //  _dbus_string_append (&config_file, DBUS_SYSTEM_CONFIG_FILE);
       
   325     systemconfpath[0]= 'z';//Default
       
   326 
       
   327  	systemconfpath[0]=getSystemConfDriveLetter();
       
   328  	
       
   329  	systemconfpath[1]=':';
       
   330     systemconfpath[2]='\0';
       
   331 
       
   332   strcat(systemconfpath,"\\data\\dbus\\system.conf");
       
   333   _dbus_string_append (&config_file, systemconfpath);
       
   334   
       
   335   force_fork = FORK_NEVER;
       
   336   
       
   337 #else
       
   338   prev_arg = NULL;
       
   339   i = 1;
       
   340   while (i < argc)
       
   341     {
       
   342       const char *arg = argv[i];
       
   343 
       
   344       if (strcmp (arg, "--help") == 0 ||
       
   345           strcmp (arg, "-h") == 0 ||
       
   346           strcmp (arg, "-?") == 0)
       
   347         usage ();
       
   348       else if (strcmp (arg, "--version") == 0)
       
   349         version ();
       
   350       else if (strcmp (arg, "--introspect") == 0)
       
   351         introspect ();
       
   352       else if (strcmp (arg, "--nofork") == 0)
       
   353         force_fork = FORK_NEVER;
       
   354       else if (strcmp (arg, "--fork") == 0)
       
   355         force_fork = FORK_ALWAYS;
       
   356       else if (strcmp (arg, "--system") == 0)
       
   357         {
       
   358           check_two_config_files (&config_file, "system");
       
   359 
       
   360           if (!_dbus_string_append (&config_file, DBUS_SYSTEM_CONFIG_FILE))
       
   361             exit (1);
       
   362         }
       
   363       else if (strcmp (arg, "--session") == 0)
       
   364         {
       
   365           check_two_config_files (&config_file, "session");
       
   366 
       
   367           if (!_dbus_string_append (&config_file, DBUS_SESSION_CONFIG_FILE))
       
   368             exit (1);
       
   369         }
       
   370       else if (strstr (arg, "--config-file=") == arg)
       
   371         {
       
   372           const char *file;
       
   373 
       
   374           check_two_config_files (&config_file, "config-file");
       
   375           
       
   376           file = strchr (arg, '=');
       
   377           ++file;
       
   378 
       
   379           if (!_dbus_string_append (&config_file, file))
       
   380             exit (1);
       
   381         }
       
   382       else if (prev_arg &&
       
   383                strcmp (prev_arg, "--config-file") == 0)
       
   384         {
       
   385           check_two_config_files (&config_file, "config-file");
       
   386           
       
   387           if (!_dbus_string_append (&config_file, arg))
       
   388             exit (1);
       
   389         }
       
   390       else if (strcmp (arg, "--config-file") == 0)
       
   391         ; /* wait for next arg */
       
   392       else if (strstr (arg, "--print-address=") == arg)
       
   393         {
       
   394           const char *desc;
       
   395 
       
   396           check_two_addr_descriptors (&addr_fd, "print-address");
       
   397           
       
   398           desc = strchr (arg, '=');
       
   399           ++desc;
       
   400 
       
   401           if (!_dbus_string_append (&addr_fd, desc))
       
   402             exit (1);
       
   403 
       
   404           print_address = TRUE;
       
   405         }
       
   406       else if (prev_arg &&
       
   407                strcmp (prev_arg, "--print-address") == 0)
       
   408         {
       
   409           check_two_addr_descriptors (&addr_fd, "print-address");
       
   410           
       
   411           if (!_dbus_string_append (&addr_fd, arg))
       
   412             exit (1);
       
   413 
       
   414           print_address = TRUE;
       
   415         }
       
   416       else if (strcmp (arg, "--print-address") == 0)
       
   417         print_address = TRUE; /* and we'll get the next arg if appropriate */
       
   418       else if (strstr (arg, "--print-pid=") == arg)
       
   419         {
       
   420           const char *desc;
       
   421 
       
   422           check_two_pid_descriptors (&pid_fd, "print-pid");
       
   423           
       
   424           desc = strchr (arg, '=');
       
   425           ++desc;
       
   426 
       
   427           if (!_dbus_string_append (&pid_fd, desc))
       
   428             exit (1);
       
   429 
       
   430           print_pid = TRUE;
       
   431         }
       
   432       else if (prev_arg &&
       
   433                strcmp (prev_arg, "--print-pid") == 0)
       
   434         {
       
   435           check_two_pid_descriptors (&pid_fd, "print-pid");
       
   436           
       
   437           if (!_dbus_string_append (&pid_fd, arg))
       
   438             exit (1);
       
   439           
       
   440           print_pid = TRUE;
       
   441         }
       
   442       else if (strcmp (arg, "--print-pid") == 0)
       
   443         print_pid = TRUE; /* and we'll get the next arg if appropriate */
       
   444       else
       
   445         usage ();
       
   446       
       
   447       prev_arg = arg;
       
   448       
       
   449       ++i;
       
   450     }
       
   451 #endif // else (systems with command line arguments)
       
   452 
       
   453   if (_dbus_string_get_length (&config_file) == 0)
       
   454     {
       
   455       fprintf (stderr, "No configuration file specified.\n");
       
   456       usage ();
       
   457     }
       
   458 
       
   459   print_addr_fd = -1;
       
   460   if (print_address)
       
   461     {
       
   462       print_addr_fd = 1; /* stdout */
       
   463       if (_dbus_string_get_length (&addr_fd) > 0)
       
   464         {
       
   465           long val;
       
   466           int end;
       
   467           if (!_dbus_string_parse_int (&addr_fd, 0, &val, &end) ||
       
   468               end != _dbus_string_get_length (&addr_fd) ||
       
   469               val < 0 || val > _DBUS_INT_MAX)
       
   470             {
       
   471               fprintf (stderr, "Invalid file descriptor: \"%s\"\n",
       
   472                        _dbus_string_get_const_data (&addr_fd));
       
   473               exit (1);
       
   474             }
       
   475 
       
   476           print_addr_fd = val;
       
   477         }
       
   478     }
       
   479   _dbus_string_free (&addr_fd);
       
   480 
       
   481   print_pid_fd = -1;
       
   482   if (print_pid)
       
   483     {
       
   484       print_pid_fd = 1; /* stdout */
       
   485       if (_dbus_string_get_length (&pid_fd) > 0)
       
   486         {
       
   487           long val;
       
   488           int end;
       
   489           if (!_dbus_string_parse_int (&pid_fd, 0, &val, &end) ||
       
   490               end != _dbus_string_get_length (&pid_fd) ||
       
   491               val < 0 || val > _DBUS_INT_MAX)
       
   492             {
       
   493               fprintf (stderr, "Invalid file descriptor: \"%s\"\n",
       
   494                        _dbus_string_get_const_data (&pid_fd));
       
   495               exit (1);
       
   496             }
       
   497 
       
   498           print_pid_fd = val;
       
   499         }
       
   500     }
       
   501   _dbus_string_free (&pid_fd);
       
   502   
       
   503   #ifdef __SYMBIAN32__
       
   504   
       
   505   print_addr_fd=1;
       
   506  
       
   507  /*uncomment above line, if the bus address needs to be sent to the client starting the bus*/
       
   508  /* one more work around could be to write the address of the bus in the dbus_lock file, which can be read 
       
   509  from the client program if needed */
       
   510  
       
   511   #endif
       
   512 
       
   513   if (!bus_selinux_pre_init ())
       
   514     {
       
   515       _dbus_warn ("SELinux pre-initialization failed\n");
       
   516       exit (1);
       
   517     }
       
   518 
       
   519   dbus_error_init (&error);
       
   520   context = bus_context_new (&config_file, force_fork,
       
   521                              print_addr_fd, print_pid_fd,
       
   522                              &error);
       
   523   _dbus_string_free (&config_file);
       
   524   if (context == NULL)
       
   525     {
       
   526       _dbus_warn ("Failed to start message bus: %s\n",
       
   527                   error.message);
       
   528       dbus_error_free (&error);
       
   529       exit (1);
       
   530     }
       
   531 
       
   532   
       
   533   
       
   534   #ifndef __SYMBIAN32__
       
   535 setup_reload_pipe (bus_context_get_loop (context));
       
   536   _dbus_set_signal_handler (SIGHUP, signal_handler);
       
   537   _dbus_set_signal_handler (SIGTERM, signal_handler);
       
   538   #endif
       
   539   
       
   540 #ifdef DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX 
       
   541   _dbus_set_signal_handler (SIGIO, signal_handler);
       
   542 #endif /* DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX */
       
   543   
       
   544   _dbus_verbose ("We are on D-Bus...\n");
       
   545 #ifdef __SYMBIAN32__  
       
   546   lock_file();
       
   547 
       
   548 #endif  
       
   549  _dbus_loop_run (bus_context_get_loop (context));
       
   550 #ifdef __SYMBIAN32__    
       
   551   remove(DBUS_LOCK_FILE);
       
   552 #endif  
       
   553   bus_context_shutdown (context);
       
   554   bus_context_unref (context);
       
   555   bus_selinux_shutdown ();
       
   556 
       
   557   return 0;
       
   558 }