ofdbus/dbus/bus/activation.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /* -*- mode: C; c-file-style: "gnu" -*- */
       
     2 /* activation.c  Activation of services
       
     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 "activation.h"
       
    27 #include "desktop-file.h" 
       
    28 #include "services.h"
       
    29 #include "test.h"
       
    30 #include "utils.h"
       
    31 
       
    32 #ifndef __SYMBIAN32__
       
    33 #include <dbus/dbus-internals.h>
       
    34 #include <dbus/dbus-hash.h>
       
    35 #include <dbus/dbus-list.h>
       
    36 #include <dbus/dbus-shell.h>
       
    37 #include <dbus/dbus-spawn.h>
       
    38 #include <dbus/dbus-timeout.h>
       
    39 #include <dbus/dbus-sysdeps.h>
       
    40 #else
       
    41 #include "dbus-internals.h"
       
    42 #include "dbus-hash.h"
       
    43 #include "dbus-list.h"
       
    44 #include "dbus-shell.h"
       
    45 #include "dbus-spawn.h"
       
    46 #include "dbus-timeout.h"
       
    47 #include "dbus-sysdeps.h"
       
    48 #endif //__SYMBIAN32__
       
    49 #include <dirent.h>
       
    50 #include <errno.h>
       
    51 
       
    52 #define DBUS_SERVICE_SECTION "D-BUS Service"
       
    53 #define DBUS_SERVICE_NAME "Name"
       
    54 #define DBUS_SERVICE_EXEC "Exec"
       
    55 
       
    56 struct BusActivation
       
    57 {
       
    58   int refcount;
       
    59   DBusHashTable *entries;
       
    60   DBusHashTable *pending_activations;
       
    61   char *server_address;
       
    62   BusContext *context;
       
    63   int n_pending_activations; /**< This is in fact the number of BusPendingActivationEntry,
       
    64                               * i.e. number of pending activation requests, not pending
       
    65                               * activations per se
       
    66                               */
       
    67   DBusHashTable *directories;
       
    68 };
       
    69 
       
    70 typedef struct
       
    71 {
       
    72   int refcount;
       
    73   char *dir_c;
       
    74   DBusHashTable *entries;
       
    75 } BusServiceDirectory;
       
    76 
       
    77 typedef struct
       
    78 {
       
    79   int refcount;
       
    80   char *name;
       
    81   char *exec;
       
    82   unsigned long mtime;
       
    83   BusServiceDirectory *s_dir;
       
    84   char *filename;
       
    85 } BusActivationEntry;
       
    86 
       
    87 typedef struct BusPendingActivationEntry BusPendingActivationEntry;
       
    88 
       
    89 struct BusPendingActivationEntry
       
    90 {
       
    91   DBusMessage *activation_message;
       
    92   DBusConnection *connection;
       
    93 
       
    94   dbus_bool_t auto_activation;
       
    95 };
       
    96 
       
    97 typedef struct
       
    98 {
       
    99   int refcount;
       
   100   BusActivation *activation;
       
   101   char *service_name;
       
   102   char *exec;
       
   103   DBusList *entries;
       
   104   int n_entries;
       
   105   DBusBabysitter *babysitter;
       
   106   DBusTimeout *timeout;
       
   107   unsigned int timeout_added : 1;
       
   108 } BusPendingActivation;
       
   109 
       
   110 #if 0
       
   111 static BusServiceDirectory *
       
   112 bus_service_directory_ref (BusServiceDirectory *dir)
       
   113 {
       
   114   _dbus_assert (dir->refcount);
       
   115   
       
   116   dir->refcount++;
       
   117 
       
   118   return dir;
       
   119 }
       
   120 #endif
       
   121 
       
   122 static void
       
   123 bus_service_directory_unref (BusServiceDirectory *dir)
       
   124 {
       
   125   if (dir == NULL) 
       
   126     return; 
       
   127 
       
   128   _dbus_assert (dir->refcount > 0);
       
   129   dir->refcount--;
       
   130 
       
   131   if (dir->refcount > 0)
       
   132     return;
       
   133 
       
   134   if (dir->entries)
       
   135     _dbus_hash_table_unref (dir->entries);
       
   136 
       
   137   dbus_free (dir->dir_c);
       
   138   dbus_free (dir);
       
   139 }
       
   140 
       
   141 static void
       
   142 bus_pending_activation_entry_free (BusPendingActivationEntry *entry)
       
   143 {
       
   144   if (entry->activation_message)
       
   145     dbus_message_unref (entry->activation_message);
       
   146   
       
   147   if (entry->connection)
       
   148     dbus_connection_unref (entry->connection);
       
   149   
       
   150   dbus_free (entry);
       
   151 }
       
   152 
       
   153 static void
       
   154 handle_timeout_callback (DBusTimeout   *timeout,
       
   155                          void          *data)
       
   156 {
       
   157   BusPendingActivation *pending_activation = data;
       
   158 
       
   159   while (!dbus_timeout_handle (pending_activation->timeout))
       
   160     _dbus_wait_for_memory ();
       
   161 }
       
   162 
       
   163 static BusPendingActivation * 
       
   164 bus_pending_activation_ref (BusPendingActivation *pending_activation)
       
   165 {
       
   166   _dbus_assert (pending_activation->refcount > 0);
       
   167   pending_activation->refcount += 1;
       
   168 
       
   169   return pending_activation;
       
   170 }
       
   171 
       
   172 static void
       
   173 bus_pending_activation_unref (BusPendingActivation *pending_activation)
       
   174 {
       
   175   DBusList *link;
       
   176   
       
   177   if (pending_activation == NULL) /* hash table requires this */
       
   178     return;
       
   179 
       
   180   _dbus_assert (pending_activation->refcount > 0);
       
   181   pending_activation->refcount -= 1;
       
   182 
       
   183   if (pending_activation->refcount > 0)
       
   184     return;
       
   185   
       
   186   if (pending_activation->timeout_added)
       
   187     {
       
   188       _dbus_loop_remove_timeout (bus_context_get_loop (pending_activation->activation->context),
       
   189                                  pending_activation->timeout,
       
   190                                  handle_timeout_callback, pending_activation);
       
   191       pending_activation->timeout_added = FALSE;
       
   192     }
       
   193 
       
   194   if (pending_activation->timeout)
       
   195     _dbus_timeout_unref (pending_activation->timeout);
       
   196   
       
   197   if (pending_activation->babysitter)
       
   198     {
       
   199       if (!_dbus_babysitter_set_watch_functions (pending_activation->babysitter,
       
   200                                                  NULL, NULL, NULL,
       
   201                                                  pending_activation->babysitter,
       
   202                                                  NULL))
       
   203         _dbus_assert_not_reached ("setting watch functions to NULL failed");
       
   204       
       
   205       _dbus_babysitter_unref (pending_activation->babysitter);
       
   206     }
       
   207   
       
   208   dbus_free (pending_activation->service_name);
       
   209   dbus_free (pending_activation->exec);
       
   210 
       
   211   link = _dbus_list_get_first_link (&pending_activation->entries);
       
   212 
       
   213   while (link != NULL)
       
   214     {
       
   215       BusPendingActivationEntry *entry = link->data;
       
   216 
       
   217       bus_pending_activation_entry_free (entry);
       
   218 
       
   219       link = _dbus_list_get_next_link (&pending_activation->entries, link);
       
   220     }
       
   221   _dbus_list_clear (&pending_activation->entries);
       
   222 
       
   223   pending_activation->activation->n_pending_activations -=
       
   224     pending_activation->n_entries;
       
   225 
       
   226   _dbus_assert (pending_activation->activation->n_pending_activations >= 0);
       
   227   
       
   228   dbus_free (pending_activation);
       
   229 }
       
   230 
       
   231 static BusActivationEntry *
       
   232 bus_activation_entry_ref (BusActivationEntry *entry)
       
   233 {
       
   234   _dbus_assert (entry->refcount > 0);
       
   235   entry->refcount++;
       
   236 
       
   237   return entry;
       
   238 }
       
   239 
       
   240 static void
       
   241 bus_activation_entry_unref (BusActivationEntry *entry)
       
   242 {
       
   243   if (entry == NULL) /* hash table requires this */
       
   244     return;
       
   245   
       
   246   _dbus_assert (entry->refcount > 0);
       
   247   entry->refcount--;
       
   248   
       
   249   if (entry->refcount > 0) 
       
   250     return;
       
   251   
       
   252   dbus_free (entry->name);
       
   253   dbus_free (entry->exec);
       
   254   dbus_free (entry->filename);
       
   255 
       
   256   dbus_free (entry);
       
   257 }
       
   258 
       
   259 static dbus_bool_t
       
   260 update_desktop_file_entry (BusActivation       *activation,
       
   261                            BusServiceDirectory *s_dir,
       
   262                            DBusString          *filename,
       
   263                            BusDesktopFile      *desktop_file,
       
   264                            DBusError           *error)
       
   265 {
       
   266   char *name, *exec;
       
   267   BusActivationEntry *entry;
       
   268   DBusStat stat_buf;
       
   269   DBusString file_path;
       
   270 
       
   271   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
       
   272   
       
   273   name = NULL;
       
   274   exec = NULL;
       
   275   entry = NULL;
       
   276   
       
   277   if (!_dbus_string_init (&file_path))
       
   278     {
       
   279       BUS_SET_OOM (error);
       
   280       return FALSE;
       
   281     }
       
   282  
       
   283   if (!_dbus_string_append (&file_path, s_dir->dir_c) ||
       
   284       !_dbus_concat_dir_and_file (&file_path, filename))
       
   285     {
       
   286       BUS_SET_OOM (error);
       
   287       goto failed;
       
   288     }
       
   289  
       
   290   if (!_dbus_stat (&file_path, &stat_buf, NULL)) 
       
   291     {
       
   292       dbus_set_error (error, DBUS_ERROR_FAILED,
       
   293                       "Can't stat the service file\n");
       
   294       goto failed;
       
   295     }
       
   296  
       
   297   if (!bus_desktop_file_get_string (desktop_file,
       
   298                                     DBUS_SERVICE_SECTION,
       
   299                                     DBUS_SERVICE_NAME,
       
   300                                     &name,
       
   301                                     error))
       
   302     goto failed;
       
   303 
       
   304   if (!bus_desktop_file_get_string (desktop_file,
       
   305                                     DBUS_SERVICE_SECTION,
       
   306                                     DBUS_SERVICE_EXEC,
       
   307                                     &exec,
       
   308                                     error))
       
   309     goto failed;
       
   310 
       
   311   entry = _dbus_hash_table_lookup_string (s_dir->entries, 
       
   312                                           _dbus_string_get_const_data (filename));
       
   313   if (entry == NULL) /* New file */
       
   314     { 
       
   315       /* FIXME we need a better-defined algorithm for which service file to
       
   316        * pick than "whichever one is first in the directory listing"
       
   317        */
       
   318       if (_dbus_hash_table_lookup_string (activation->entries, name))
       
   319         {
       
   320           dbus_set_error (error, DBUS_ERROR_FAILED,
       
   321                           "Service %s already exists in activation entry list\n", name);
       
   322           goto failed;
       
   323         }
       
   324       
       
   325       entry = dbus_new0 (BusActivationEntry, 1);
       
   326       if (entry == NULL)
       
   327         {
       
   328           BUS_SET_OOM (error);
       
   329           goto failed;
       
   330         }
       
   331      
       
   332       entry->name = name;
       
   333       entry->exec = exec;
       
   334       entry->refcount = 1;
       
   335     
       
   336       entry->s_dir = s_dir;
       
   337       entry->filename = _dbus_strdup (_dbus_string_get_const_data (filename));
       
   338       if (!entry->filename)
       
   339         {
       
   340           BUS_SET_OOM (error);
       
   341           goto failed;
       
   342         }
       
   343 
       
   344       if (!_dbus_hash_table_insert_string (activation->entries, entry->name, bus_activation_entry_ref (entry)))
       
   345         {
       
   346           BUS_SET_OOM (error);
       
   347           goto failed;
       
   348         }
       
   349      
       
   350       if (!_dbus_hash_table_insert_string (s_dir->entries, entry->filename, bus_activation_entry_ref (entry)))
       
   351         {
       
   352           /* Revert the insertion in the entries table */
       
   353           _dbus_hash_table_remove_string (activation->entries, entry->name);
       
   354           BUS_SET_OOM (error);
       
   355           goto failed;
       
   356         }
       
   357 
       
   358       _dbus_verbose ("Added \"%s\" to list of services\n", entry->name);
       
   359     }
       
   360   else /* Just update the entry */
       
   361     {
       
   362       bus_activation_entry_ref (entry);
       
   363       _dbus_hash_table_remove_string (activation->entries, entry->name);
       
   364 
       
   365       if (_dbus_hash_table_lookup_string (activation->entries, name))
       
   366         {
       
   367           _dbus_verbose ("The new service name \"%s\" of service file \"%s\" already in cache, ignoring\n",
       
   368                          name, _dbus_string_get_const_data (&file_path));
       
   369           goto failed;
       
   370         }
       
   371  
       
   372       dbus_free (entry->name);
       
   373       dbus_free (entry->exec);
       
   374       entry->name = name;
       
   375       entry->exec = exec;
       
   376       if (!_dbus_hash_table_insert_string (activation->entries,
       
   377                                            entry->name, bus_activation_entry_ref(entry)))
       
   378         {
       
   379           BUS_SET_OOM (error);
       
   380           /* Also remove path to entries hash since we want this in sync with
       
   381            * the entries hash table */
       
   382           _dbus_hash_table_remove_string (entry->s_dir->entries, 
       
   383                                           entry->filename);
       
   384           bus_activation_entry_unref (entry);
       
   385           return FALSE;
       
   386         }
       
   387     }
       
   388   
       
   389   entry->mtime = stat_buf.mtime;
       
   390   
       
   391   _dbus_string_free (&file_path);
       
   392   bus_activation_entry_unref (entry);
       
   393 
       
   394   return TRUE;
       
   395 
       
   396 failed:
       
   397   dbus_free (name);
       
   398   dbus_free (exec);
       
   399   _dbus_string_free (&file_path);
       
   400 
       
   401   if (entry)
       
   402     bus_activation_entry_unref (entry);
       
   403   
       
   404   return FALSE;
       
   405 }
       
   406 
       
   407 static dbus_bool_t
       
   408 check_service_file (BusActivation       *activation,
       
   409                     BusActivationEntry  *entry,
       
   410                     BusActivationEntry **updated_entry,
       
   411                     DBusError           *error)
       
   412 {
       
   413   DBusStat stat_buf;
       
   414   dbus_bool_t retval;
       
   415   BusActivationEntry *tmp_entry;
       
   416   DBusString file_path;
       
   417   DBusString filename;
       
   418 
       
   419   retval = TRUE;
       
   420   tmp_entry = entry;
       
   421   
       
   422   _dbus_string_init_const (&filename, entry->filename);
       
   423   
       
   424   if (!_dbus_string_init (&file_path))
       
   425     {
       
   426       BUS_SET_OOM (error);
       
   427       return FALSE;
       
   428     }
       
   429  
       
   430   if (!_dbus_string_append (&file_path, entry->s_dir->dir_c) ||
       
   431       !_dbus_concat_dir_and_file (&file_path, &filename))
       
   432     {
       
   433       BUS_SET_OOM (error);
       
   434       retval = FALSE;
       
   435       goto out;
       
   436     }
       
   437   
       
   438   if (!_dbus_stat (&file_path, &stat_buf, NULL))
       
   439     {
       
   440       _dbus_verbose ("****** Can't stat file \"%s\", removing from cache\n",
       
   441                      _dbus_string_get_const_data (&file_path));
       
   442 
       
   443       _dbus_hash_table_remove_string (activation->entries, entry->name);
       
   444       _dbus_hash_table_remove_string (entry->s_dir->entries, entry->filename);
       
   445 
       
   446       tmp_entry = NULL;
       
   447       retval = TRUE;
       
   448       goto out;
       
   449     }
       
   450   else 
       
   451     {
       
   452       if (stat_buf.mtime > entry->mtime) 
       
   453         {
       
   454           BusDesktopFile *desktop_file;
       
   455           DBusError tmp_error;
       
   456           
       
   457           dbus_error_init (&tmp_error);
       
   458           
       
   459           desktop_file = bus_desktop_file_load (&file_path, &tmp_error);
       
   460           if (desktop_file == NULL)
       
   461             {
       
   462               _dbus_verbose ("Could not load %s: %s\n",
       
   463                              _dbus_string_get_const_data (&file_path), 
       
   464                              tmp_error.message);
       
   465               if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
       
   466                 {
       
   467                   dbus_move_error (&tmp_error, error);
       
   468                   retval = FALSE;
       
   469                   goto out;
       
   470                 }
       
   471               dbus_error_free (&tmp_error);
       
   472               retval = TRUE;
       
   473               goto out;
       
   474             }
       
   475          
       
   476           /* @todo We can return OOM or a DBUS_ERROR_FAILED error 
       
   477            *       Handle these both better
       
   478            */ 
       
   479           if (!update_desktop_file_entry (activation, entry->s_dir, &filename, desktop_file, &tmp_error))
       
   480             {
       
   481               bus_desktop_file_free (desktop_file);
       
   482               if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
       
   483                 {
       
   484                   dbus_move_error (&tmp_error, error);
       
   485                   retval = FALSE;
       
   486                   goto out;
       
   487                 }
       
   488               dbus_error_free (&tmp_error);
       
   489               retval = TRUE;
       
   490               goto out;
       
   491             }
       
   492          
       
   493           bus_desktop_file_free (desktop_file);
       
   494           retval = TRUE;
       
   495         }
       
   496     }
       
   497   
       
   498 out:
       
   499   _dbus_string_free (&file_path);
       
   500 
       
   501   if (updated_entry != NULL)
       
   502     *updated_entry = tmp_entry;
       
   503   return retval;
       
   504 }
       
   505 
       
   506 
       
   507 /* warning: this doesn't fully "undo" itself on failure, i.e. doesn't strip
       
   508  * hash entries it already added.
       
   509  */
       
   510 static dbus_bool_t
       
   511 update_directory (BusActivation       *activation,
       
   512                   BusServiceDirectory *s_dir,
       
   513                   DBusError           *error)
       
   514 {
       
   515   DBusDirIter *iter;
       
   516   DBusString dir, filename;
       
   517   BusDesktopFile *desktop_file;
       
   518   DBusError tmp_error;
       
   519   dbus_bool_t retval;
       
   520   BusActivationEntry *entry;
       
   521   DBusString full_path;
       
   522   
       
   523   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
       
   524   
       
   525   iter = NULL;
       
   526   desktop_file = NULL;
       
   527   
       
   528   _dbus_string_init_const (&dir, s_dir->dir_c);
       
   529   
       
   530   if (!_dbus_string_init (&filename))
       
   531     {
       
   532       BUS_SET_OOM (error);
       
   533       return FALSE;
       
   534     }
       
   535 
       
   536   if (!_dbus_string_init (&full_path))
       
   537     {
       
   538       BUS_SET_OOM (error);
       
   539       _dbus_string_free (&filename);
       
   540       return FALSE;
       
   541     }
       
   542 
       
   543   retval = FALSE;
       
   544 
       
   545   /* from this point it's safe to "goto out" */
       
   546   
       
   547   iter = _dbus_directory_open (&dir, error);
       
   548   if (iter == NULL)
       
   549     {
       
   550       _dbus_verbose ("Failed to open directory %s: %s\n",
       
   551                      s_dir->dir_c, 
       
   552                      error ? error->message : "unknown");
       
   553       goto out;
       
   554     }
       
   555   
       
   556   /* Now read the files */
       
   557   dbus_error_init (&tmp_error);
       
   558   while (_dbus_directory_get_next_file (iter, &filename, &tmp_error))
       
   559     {
       
   560       _dbus_assert (!dbus_error_is_set (&tmp_error));
       
   561       
       
   562       _dbus_string_set_length (&full_path, 0);
       
   563       
       
   564       if (!_dbus_string_ends_with_c_str (&filename, ".service"))
       
   565         {
       
   566           _dbus_verbose ("Skipping non-.service file %s\n",
       
   567                          _dbus_string_get_const_data (&filename));
       
   568           continue;
       
   569         }
       
   570 
       
   571       entry = _dbus_hash_table_lookup_string (s_dir->entries, _dbus_string_get_const_data (&filename));
       
   572       if (entry) /* Already has this service file in the cache */ 
       
   573         {
       
   574           if (!check_service_file (activation, entry, NULL, error))
       
   575             goto out;
       
   576 
       
   577           continue;
       
   578         }
       
   579       
       
   580       if (!_dbus_string_append (&full_path, s_dir->dir_c) ||
       
   581           !_dbus_concat_dir_and_file (&full_path, &filename))
       
   582         {
       
   583           BUS_SET_OOM (error);
       
   584           goto out;
       
   585         }
       
   586           
       
   587       /* New file */
       
   588       desktop_file = bus_desktop_file_load (&full_path, &tmp_error);
       
   589       if (desktop_file == NULL)
       
   590         {
       
   591           _dbus_verbose ("Could not load %s: %s\n",
       
   592                          _dbus_string_get_const_data (&full_path),
       
   593                          tmp_error.message);
       
   594 
       
   595           if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
       
   596             {
       
   597               dbus_move_error (&tmp_error, error);
       
   598               goto out;
       
   599             }
       
   600           
       
   601           dbus_error_free (&tmp_error);
       
   602           continue;
       
   603         }
       
   604 
       
   605       /* @todo We can return OOM or a DBUS_ERROR_FAILED error 
       
   606        *       Handle these both better
       
   607        */ 
       
   608       if (!update_desktop_file_entry (activation, s_dir, &filename, desktop_file, &tmp_error))
       
   609         {
       
   610           bus_desktop_file_free (desktop_file);
       
   611           desktop_file = NULL;
       
   612           
       
   613           _dbus_verbose ("Could not add %s to activation entry list: %s\n",
       
   614                          _dbus_string_get_const_data (&full_path), tmp_error.message);
       
   615 
       
   616           if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
       
   617             {
       
   618               dbus_move_error (&tmp_error, error);
       
   619               goto out;
       
   620             }
       
   621 
       
   622           dbus_error_free (&tmp_error);
       
   623           continue;
       
   624         }
       
   625       else
       
   626         {
       
   627           bus_desktop_file_free (desktop_file);
       
   628           desktop_file = NULL;
       
   629           continue;
       
   630         }
       
   631     }
       
   632 
       
   633   if (dbus_error_is_set (&tmp_error))
       
   634     {
       
   635       dbus_move_error (&tmp_error, error);
       
   636       goto out;
       
   637     }
       
   638   
       
   639   retval = TRUE;
       
   640 
       
   641  out:
       
   642   if (!retval)
       
   643     _DBUS_ASSERT_ERROR_IS_SET (error);
       
   644   else
       
   645     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
       
   646   
       
   647   if (iter != NULL)
       
   648     _dbus_directory_close (iter);
       
   649   _dbus_string_free (&filename);
       
   650   _dbus_string_free (&full_path);
       
   651   
       
   652   return retval;
       
   653 }
       
   654 
       
   655 BusActivation*
       
   656 bus_activation_new (BusContext        *context,
       
   657                     const DBusString  *address,
       
   658                     DBusList         **directories,
       
   659                     DBusError         *error)
       
   660 {
       
   661   BusActivation *activation;
       
   662   DBusList      *link;
       
   663   char          *dir;
       
   664   
       
   665   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
       
   666   
       
   667   activation = dbus_new0 (BusActivation, 1);
       
   668   if (activation == NULL)
       
   669     {
       
   670       BUS_SET_OOM (error);
       
   671       return NULL;
       
   672     }
       
   673   
       
   674   activation->refcount = 1;
       
   675   activation->context = context;
       
   676   activation->n_pending_activations = 0;
       
   677   
       
   678   if (!_dbus_string_copy_data (address, &activation->server_address))
       
   679     {
       
   680       BUS_SET_OOM (error);
       
   681       goto failed;
       
   682     }
       
   683   
       
   684   activation->entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
       
   685                                              (DBusFreeFunction)bus_activation_entry_unref);
       
   686   if (activation->entries == NULL)
       
   687     {      
       
   688       BUS_SET_OOM (error);
       
   689       goto failed;
       
   690     }
       
   691 
       
   692   activation->pending_activations = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
       
   693                                                           (DBusFreeFunction)bus_pending_activation_unref);
       
   694 
       
   695   if (activation->pending_activations == NULL)
       
   696     {
       
   697       BUS_SET_OOM (error);
       
   698       goto failed;
       
   699     }
       
   700 
       
   701   activation->directories = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
       
   702                                                   (DBusFreeFunction)bus_service_directory_unref);
       
   703   
       
   704   if (activation->directories == NULL) 
       
   705     {
       
   706       BUS_SET_OOM (error);
       
   707       goto failed;
       
   708     }
       
   709  
       
   710   /* Load service files */
       
   711   link = _dbus_list_get_first_link (directories);
       
   712   while (link != NULL)
       
   713     {
       
   714       BusServiceDirectory *s_dir;
       
   715       
       
   716       dir = _dbus_strdup ((const char *) link->data);
       
   717       if (!dir)
       
   718         {
       
   719           BUS_SET_OOM (error);
       
   720           goto failed;
       
   721         }
       
   722       
       
   723       s_dir = dbus_new0 (BusServiceDirectory, 1);
       
   724       if (!s_dir)
       
   725         {
       
   726           dbus_free (dir);
       
   727           BUS_SET_OOM (error);
       
   728           goto failed;
       
   729         }
       
   730 
       
   731       s_dir->refcount = 1;
       
   732       s_dir->dir_c = dir;
       
   733       
       
   734       s_dir->entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
       
   735                                              (DBusFreeFunction)bus_activation_entry_unref);
       
   736 
       
   737       if (!s_dir->entries)
       
   738         {
       
   739           bus_service_directory_unref (s_dir);
       
   740           BUS_SET_OOM (error);
       
   741           goto failed;
       
   742         }
       
   743 
       
   744       if (!_dbus_hash_table_insert_string (activation->directories, s_dir->dir_c, s_dir))
       
   745         {
       
   746           bus_service_directory_unref (s_dir);
       
   747           BUS_SET_OOM (error);
       
   748           goto failed;
       
   749         }
       
   750 
       
   751       /* only fail on OOM, it is ok if we can't read the directory */
       
   752       if (!update_directory (activation, s_dir, error))
       
   753         { 
       
   754           if (dbus_error_has_name (error, DBUS_ERROR_NO_MEMORY)) 
       
   755             goto failed;
       
   756           else
       
   757             dbus_error_free (error);
       
   758         }
       
   759 
       
   760       link = _dbus_list_get_next_link (directories, link);
       
   761     }
       
   762 
       
   763   return activation;
       
   764   
       
   765  failed:
       
   766   bus_activation_unref (activation);  
       
   767   return NULL;
       
   768 }
       
   769 
       
   770 BusActivation *
       
   771 bus_activation_ref (BusActivation *activation)
       
   772 {
       
   773   _dbus_assert (activation->refcount > 0);
       
   774   
       
   775   activation->refcount += 1;
       
   776 
       
   777   return activation;
       
   778 }
       
   779 
       
   780 void
       
   781 bus_activation_unref (BusActivation *activation)
       
   782 {
       
   783   _dbus_assert (activation->refcount > 0);
       
   784 
       
   785   activation->refcount -= 1;
       
   786 
       
   787   if (activation->refcount > 0)
       
   788     return;
       
   789   
       
   790   dbus_free (activation->server_address);
       
   791   if (activation->entries)
       
   792     _dbus_hash_table_unref (activation->entries);
       
   793   if (activation->pending_activations)
       
   794     _dbus_hash_table_unref (activation->pending_activations);
       
   795   if (activation->directories)  
       
   796     _dbus_hash_table_unref (activation->directories);
       
   797   
       
   798   dbus_free (activation);
       
   799 }
       
   800 
       
   801 static void
       
   802 child_setup (void *data)
       
   803 {
       
   804   BusActivation *activation = data;
       
   805   const char *type;
       
   806   
       
   807   /* If no memory, we simply have the child exit, so it won't try
       
   808    * to connect to the wrong thing.
       
   809    */
       
   810   if (!_dbus_setenv ("DBUS_STARTER_ADDRESS", activation->server_address))
       
   811     _dbus_exit (1);
       
   812   
       
   813   type = bus_context_get_type (activation->context);
       
   814   if (type != NULL)
       
   815     {
       
   816       if (!_dbus_setenv ("DBUS_STARTER_BUS_TYPE", type))
       
   817         _dbus_exit (1);
       
   818 
       
   819       if (strcmp (type, "session") == 0)
       
   820         {
       
   821           if (!_dbus_setenv ("DBUS_SESSION_BUS_ADDRESS",
       
   822                              activation->server_address))
       
   823             _dbus_exit (1);
       
   824         }
       
   825       else if (strcmp (type, "system") == 0)
       
   826         {
       
   827           if (!_dbus_setenv ("DBUS_SYSTEM_BUS_ADDRESS",
       
   828                              activation->server_address))
       
   829             _dbus_exit (1);
       
   830         }
       
   831     }
       
   832 }
       
   833 
       
   834 typedef struct
       
   835 {
       
   836   BusPendingActivation *pending_activation;
       
   837   DBusPreallocatedHash *hash_entry;
       
   838 } RestorePendingData;
       
   839 
       
   840 static void
       
   841 restore_pending (void *data)
       
   842 {
       
   843   RestorePendingData *d = data;
       
   844 
       
   845   _dbus_assert (d->pending_activation != NULL);
       
   846   _dbus_assert (d->hash_entry != NULL);
       
   847 
       
   848   _dbus_verbose ("Restoring pending activation for service %s, has timeout = %d\n",
       
   849                  d->pending_activation->service_name,
       
   850                  d->pending_activation->timeout_added);
       
   851   
       
   852   _dbus_hash_table_insert_string_preallocated (d->pending_activation->activation->pending_activations,
       
   853                                                d->hash_entry,
       
   854                                                d->pending_activation->service_name, d->pending_activation);
       
   855 
       
   856   bus_pending_activation_ref (d->pending_activation);
       
   857   
       
   858   d->hash_entry = NULL;
       
   859 }
       
   860 
       
   861 static void
       
   862 free_pending_restore_data (void *data)
       
   863 {
       
   864   RestorePendingData *d = data;
       
   865 
       
   866   if (d->hash_entry)
       
   867     _dbus_hash_table_free_preallocated_entry (d->pending_activation->activation->pending_activations,
       
   868                                               d->hash_entry);
       
   869 
       
   870   bus_pending_activation_unref (d->pending_activation);
       
   871   
       
   872   dbus_free (d);
       
   873 }
       
   874 
       
   875 static dbus_bool_t
       
   876 add_restore_pending_to_transaction (BusTransaction       *transaction,
       
   877                                     BusPendingActivation *pending_activation)
       
   878 {
       
   879   RestorePendingData *d;
       
   880 
       
   881   d = dbus_new (RestorePendingData, 1);
       
   882   if (d == NULL)
       
   883     return FALSE;
       
   884   
       
   885   d->pending_activation = pending_activation;
       
   886   d->hash_entry = _dbus_hash_table_preallocate_entry (d->pending_activation->activation->pending_activations);
       
   887   
       
   888   bus_pending_activation_ref (d->pending_activation);
       
   889   
       
   890   if (d->hash_entry == NULL ||
       
   891       !bus_transaction_add_cancel_hook (transaction, restore_pending, d,
       
   892                                         free_pending_restore_data))
       
   893     {
       
   894       free_pending_restore_data (d);
       
   895       return FALSE;
       
   896     }
       
   897 
       
   898   _dbus_verbose ("Saved pending activation to be restored if the transaction fails\n");
       
   899   
       
   900   return TRUE;
       
   901 }
       
   902 
       
   903 dbus_bool_t
       
   904 bus_activation_service_created (BusActivation  *activation,
       
   905                                 const char     *service_name,
       
   906                                 BusTransaction *transaction,
       
   907                                 DBusError      *error)
       
   908 {
       
   909   BusPendingActivation *pending_activation;
       
   910   DBusMessage *message;
       
   911   DBusList *link;
       
   912 
       
   913   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
       
   914   
       
   915   /* Check if it's a pending activation */
       
   916   pending_activation = _dbus_hash_table_lookup_string (activation->pending_activations, service_name);
       
   917 
       
   918   if (!pending_activation)
       
   919     return TRUE;
       
   920 
       
   921   link = _dbus_list_get_first_link (&pending_activation->entries);
       
   922   while (link != NULL)
       
   923     {
       
   924       BusPendingActivationEntry *entry = link->data;
       
   925       DBusList *next = _dbus_list_get_next_link (&pending_activation->entries, link);
       
   926       
       
   927       if (dbus_connection_get_is_connected (entry->connection))
       
   928         {
       
   929           /* Only send activation replies to regular activation requests. */
       
   930           if (!entry->auto_activation)
       
   931             {
       
   932               dbus_uint32_t result;
       
   933               
       
   934               message = dbus_message_new_method_return (entry->activation_message);
       
   935               if (!message)
       
   936                 {
       
   937                   BUS_SET_OOM (error);
       
   938                   goto error;
       
   939                 }
       
   940 
       
   941               result = DBUS_START_REPLY_SUCCESS;
       
   942               
       
   943               if (!dbus_message_append_args (message,
       
   944                                              DBUS_TYPE_UINT32, &result,
       
   945                                              DBUS_TYPE_INVALID))
       
   946                 {
       
   947                   dbus_message_unref (message);
       
   948                   BUS_SET_OOM (error);
       
   949                   goto error;
       
   950                 }
       
   951               
       
   952               if (!bus_transaction_send_from_driver (transaction, entry->connection, message))
       
   953                 {
       
   954                   dbus_message_unref (message);
       
   955                   BUS_SET_OOM (error);
       
   956                   goto error;
       
   957                 }
       
   958               
       
   959               dbus_message_unref (message);
       
   960             }
       
   961         }
       
   962       
       
   963       link = next;
       
   964     }
       
   965 
       
   966   return TRUE;
       
   967 
       
   968  error:
       
   969   return FALSE;
       
   970 }
       
   971 
       
   972 dbus_bool_t
       
   973 bus_activation_send_pending_auto_activation_messages (BusActivation  *activation,
       
   974                                                       BusService     *service,
       
   975                                                       BusTransaction *transaction,
       
   976                                                       DBusError      *error)
       
   977 {
       
   978   BusPendingActivation *pending_activation;
       
   979   DBusList *link;
       
   980 
       
   981   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
       
   982   
       
   983   /* Check if it's a pending activation */
       
   984   pending_activation = _dbus_hash_table_lookup_string (activation->pending_activations,
       
   985                                                        bus_service_get_name (service));
       
   986 
       
   987   if (!pending_activation)
       
   988     return TRUE;
       
   989 
       
   990   link = _dbus_list_get_first_link (&pending_activation->entries);
       
   991   while (link != NULL)
       
   992     {
       
   993       BusPendingActivationEntry *entry = link->data;
       
   994       DBusList *next = _dbus_list_get_next_link (&pending_activation->entries, link);
       
   995 
       
   996       if (entry->auto_activation && dbus_connection_get_is_connected (entry->connection))
       
   997         {
       
   998           DBusConnection *addressed_recipient;
       
   999           
       
  1000           addressed_recipient = bus_service_get_primary_owners_connection (service);
       
  1001 
       
  1002           /* Check the security policy, which has the side-effect of adding an
       
  1003            * expected pending reply.
       
  1004            */
       
  1005           if (!bus_context_check_security_policy (activation->context, transaction,
       
  1006                                                   entry->connection,
       
  1007                                                   addressed_recipient,
       
  1008                                                   addressed_recipient,
       
  1009                                                   entry->activation_message, error))
       
  1010             goto error;
       
  1011 
       
  1012           if (!bus_transaction_send (transaction, addressed_recipient, entry->activation_message))
       
  1013             {
       
  1014               BUS_SET_OOM (error);
       
  1015               goto error;
       
  1016             }
       
  1017         }
       
  1018 
       
  1019       link = next;
       
  1020     }
       
  1021 
       
  1022   if (!add_restore_pending_to_transaction (transaction, pending_activation))
       
  1023     {
       
  1024       _dbus_verbose ("Could not add cancel hook to transaction to revert removing pending activation\n");
       
  1025       BUS_SET_OOM (error);
       
  1026       goto error;
       
  1027     }
       
  1028   
       
  1029   _dbus_hash_table_remove_string (activation->pending_activations, bus_service_get_name (service));
       
  1030 
       
  1031   return TRUE;
       
  1032 
       
  1033  error:
       
  1034   return FALSE;
       
  1035 }
       
  1036 
       
  1037 /**
       
  1038  * FIXME @todo the error messages here would ideally be preallocated
       
  1039  * so we don't need to allocate memory to send them.
       
  1040  * Using the usual tactic, prealloc an OOM message, then
       
  1041  * if we can't alloc the real error send the OOM error instead.
       
  1042  */
       
  1043 static dbus_bool_t
       
  1044 try_send_activation_failure (BusPendingActivation *pending_activation,
       
  1045                              const DBusError      *how)
       
  1046 {
       
  1047   BusActivation *activation;
       
  1048   DBusList *link;
       
  1049   BusTransaction *transaction;
       
  1050   
       
  1051   activation = pending_activation->activation;
       
  1052 
       
  1053   transaction = bus_transaction_new (activation->context);
       
  1054   if (transaction == NULL)
       
  1055     return FALSE;
       
  1056   
       
  1057   link = _dbus_list_get_first_link (&pending_activation->entries);
       
  1058   while (link != NULL)
       
  1059     {
       
  1060       BusPendingActivationEntry *entry = link->data;
       
  1061       DBusList *next = _dbus_list_get_next_link (&pending_activation->entries, link);
       
  1062       
       
  1063       if (dbus_connection_get_is_connected (entry->connection))
       
  1064         {
       
  1065           if (!bus_transaction_send_error_reply (transaction,
       
  1066                                                  entry->connection,
       
  1067                                                  how,
       
  1068                                                  entry->activation_message))
       
  1069             goto error;
       
  1070         }
       
  1071       
       
  1072       link = next;
       
  1073     }
       
  1074 
       
  1075   bus_transaction_execute_and_free (transaction);
       
  1076   
       
  1077   return TRUE;
       
  1078 
       
  1079  error:
       
  1080   if (transaction)
       
  1081     bus_transaction_cancel_and_free (transaction);
       
  1082   return FALSE;
       
  1083 }
       
  1084 
       
  1085 /**
       
  1086  * Free the pending activation and send an error message to all the
       
  1087  * connections that were waiting for it.
       
  1088  */
       
  1089 static void
       
  1090 pending_activation_failed (BusPendingActivation *pending_activation,
       
  1091                            const DBusError      *how)
       
  1092 {
       
  1093   /* FIXME use preallocated OOM messages instead of bus_wait_for_memory() */
       
  1094   while (!try_send_activation_failure (pending_activation, how))
       
  1095     _dbus_wait_for_memory ();
       
  1096 
       
  1097   /* Destroy this pending activation */
       
  1098   _dbus_hash_table_remove_string (pending_activation->activation->pending_activations,
       
  1099                                   pending_activation->service_name);
       
  1100 }
       
  1101 
       
  1102 static dbus_bool_t
       
  1103 babysitter_watch_callback (DBusWatch     *watch,
       
  1104                            unsigned int   condition,
       
  1105                            void          *data)
       
  1106 {
       
  1107   BusPendingActivation *pending_activation = data;
       
  1108   dbus_bool_t retval;
       
  1109   DBusBabysitter *babysitter;
       
  1110 
       
  1111   babysitter = pending_activation->babysitter;
       
  1112   
       
  1113   _dbus_babysitter_ref (babysitter);
       
  1114   
       
  1115   retval = dbus_watch_handle (watch, condition);
       
  1116 
       
  1117   /* FIXME this is broken in the same way that
       
  1118    * connection watches used to be; there should be
       
  1119    * a separate callback for status change, instead
       
  1120    * of doing "if we handled a watch status might
       
  1121    * have changed"
       
  1122    *
       
  1123    * Fixing this lets us move dbus_watch_handle
       
  1124    * calls into dbus-mainloop.c
       
  1125    */
       
  1126   
       
  1127   if (_dbus_babysitter_get_child_exited (babysitter))
       
  1128     {
       
  1129       DBusError error;
       
  1130       DBusHashIter iter;
       
  1131       
       
  1132       dbus_error_init (&error);
       
  1133       _dbus_babysitter_set_child_exit_error (babysitter, &error);
       
  1134 
       
  1135       /* Destroy all pending activations with the same exec */
       
  1136       _dbus_hash_iter_init (pending_activation->activation->pending_activations,
       
  1137                             &iter);
       
  1138       while (_dbus_hash_iter_next (&iter))
       
  1139         {
       
  1140           BusPendingActivation *p = _dbus_hash_iter_get_value (&iter);
       
  1141          
       
  1142           if (p != pending_activation && strcmp (p->exec, pending_activation->exec) == 0)
       
  1143             pending_activation_failed (p, &error);
       
  1144         }
       
  1145       
       
  1146       /* Destroys the pending activation */
       
  1147       pending_activation_failed (pending_activation, &error);
       
  1148 
       
  1149       dbus_error_free (&error);
       
  1150     }
       
  1151   
       
  1152   _dbus_babysitter_unref (babysitter);
       
  1153 
       
  1154   return retval;
       
  1155 }
       
  1156 
       
  1157 static dbus_bool_t
       
  1158 add_babysitter_watch (DBusWatch      *watch,
       
  1159                       void           *data)
       
  1160 {
       
  1161   BusPendingActivation *pending_activation = data;
       
  1162 
       
  1163   return _dbus_loop_add_watch (bus_context_get_loop (pending_activation->activation->context),
       
  1164                                watch, babysitter_watch_callback, pending_activation,
       
  1165                                NULL);
       
  1166 }
       
  1167 
       
  1168 static void
       
  1169 remove_babysitter_watch (DBusWatch      *watch,
       
  1170                          void           *data)
       
  1171 {
       
  1172   BusPendingActivation *pending_activation = data;
       
  1173   
       
  1174   _dbus_loop_remove_watch (bus_context_get_loop (pending_activation->activation->context),
       
  1175                            watch, babysitter_watch_callback, pending_activation);
       
  1176 }
       
  1177 
       
  1178 static dbus_bool_t
       
  1179 pending_activation_timed_out (void *data)
       
  1180 {
       
  1181   BusPendingActivation *pending_activation = data;
       
  1182   DBusError error;
       
  1183   
       
  1184   /* Kill the spawned process, since it sucks
       
  1185    * (not sure this is what we want to do, but
       
  1186    * may as well try it for now)
       
  1187    */
       
  1188   if (pending_activation->babysitter) 
       
  1189     _dbus_babysitter_kill_child (pending_activation->babysitter);
       
  1190 
       
  1191   dbus_error_init (&error);
       
  1192 
       
  1193   dbus_set_error (&error, DBUS_ERROR_TIMED_OUT,
       
  1194                   "Activation of %s timed out",
       
  1195                   pending_activation->service_name);
       
  1196 
       
  1197   pending_activation_failed (pending_activation, &error);
       
  1198 
       
  1199   dbus_error_free (&error);
       
  1200 
       
  1201   return TRUE;
       
  1202 }
       
  1203 
       
  1204 static void
       
  1205 cancel_pending (void *data)
       
  1206 {
       
  1207   BusPendingActivation *pending_activation = data;
       
  1208 
       
  1209   _dbus_verbose ("Canceling pending activation of %s\n",
       
  1210                  pending_activation->service_name);
       
  1211 
       
  1212   if (pending_activation->babysitter)
       
  1213     _dbus_babysitter_kill_child (pending_activation->babysitter);
       
  1214   
       
  1215   _dbus_hash_table_remove_string (pending_activation->activation->pending_activations,
       
  1216                                   pending_activation->service_name);
       
  1217 }
       
  1218 
       
  1219 static void
       
  1220 free_pending_cancel_data (void *data)
       
  1221 {
       
  1222   BusPendingActivation *pending_activation = data;
       
  1223   
       
  1224   bus_pending_activation_unref (pending_activation);
       
  1225 }
       
  1226 
       
  1227 static dbus_bool_t
       
  1228 add_cancel_pending_to_transaction (BusTransaction       *transaction,
       
  1229                                    BusPendingActivation *pending_activation)
       
  1230 {  
       
  1231   if (!bus_transaction_add_cancel_hook (transaction, cancel_pending,
       
  1232                                         pending_activation,
       
  1233                                         free_pending_cancel_data))
       
  1234     return FALSE;
       
  1235 
       
  1236   bus_pending_activation_ref (pending_activation); 
       
  1237   
       
  1238   _dbus_verbose ("Saved pending activation to be canceled if the transaction fails\n");
       
  1239   
       
  1240   return TRUE;
       
  1241 }
       
  1242 
       
  1243 static dbus_bool_t 
       
  1244 update_service_cache (BusActivation *activation, DBusError *error)
       
  1245 {
       
  1246   DBusHashIter iter;
       
  1247  
       
  1248   _dbus_hash_iter_init (activation->directories, &iter);
       
  1249   while (_dbus_hash_iter_next (&iter))
       
  1250     {
       
  1251       DBusError tmp_error;
       
  1252       BusServiceDirectory *s_dir;
       
  1253 
       
  1254       s_dir = _dbus_hash_iter_get_value (&iter);
       
  1255 
       
  1256       dbus_error_init (&tmp_error);
       
  1257       if (!update_directory (activation, s_dir, &tmp_error))
       
  1258         {
       
  1259           if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
       
  1260             {
       
  1261               dbus_move_error (&tmp_error, error);
       
  1262               return FALSE;
       
  1263             }
       
  1264 
       
  1265           dbus_error_free (&tmp_error);
       
  1266           continue;
       
  1267         }
       
  1268     }
       
  1269   
       
  1270   return TRUE;
       
  1271 }
       
  1272 
       
  1273 static BusActivationEntry *
       
  1274 activation_find_entry (BusActivation *activation, 
       
  1275                        const char    *service_name,
       
  1276                        DBusError     *error)
       
  1277 {
       
  1278   BusActivationEntry *entry;
       
  1279   
       
  1280   entry = _dbus_hash_table_lookup_string (activation->entries, service_name);
       
  1281   if (!entry)
       
  1282     { 
       
  1283       if (!update_service_cache (activation, error)) 
       
  1284         return NULL;
       
  1285 
       
  1286       entry = _dbus_hash_table_lookup_string (activation->entries,
       
  1287                                               service_name);
       
  1288     }
       
  1289   else 
       
  1290     {
       
  1291       BusActivationEntry *updated_entry;
       
  1292 
       
  1293       if (!check_service_file (activation, entry, &updated_entry, error)) 
       
  1294         return NULL;
       
  1295 
       
  1296       entry = updated_entry;
       
  1297     }
       
  1298 
       
  1299   if (!entry) 
       
  1300     {
       
  1301       dbus_set_error (error, DBUS_ERROR_SERVICE_UNKNOWN,
       
  1302                       "The name %s was not provided by any .service files",
       
  1303                       service_name);
       
  1304       return NULL;
       
  1305     }
       
  1306 
       
  1307   return entry;
       
  1308 }
       
  1309 
       
  1310 dbus_bool_t
       
  1311 bus_activation_activate_service (BusActivation  *activation,
       
  1312                                  DBusConnection *connection,
       
  1313                                  BusTransaction *transaction,
       
  1314                                  dbus_bool_t     auto_activation,
       
  1315                                  DBusMessage    *activation_message,
       
  1316                                  const char     *service_name,
       
  1317                                  DBusError      *error)
       
  1318 {
       
  1319   BusActivationEntry *entry;
       
  1320   BusPendingActivation *pending_activation;
       
  1321   BusPendingActivationEntry *pending_activation_entry;
       
  1322   DBusMessage *message;
       
  1323   DBusString service_str;
       
  1324   char **argv;
       
  1325   int argc;
       
  1326   dbus_bool_t retval;
       
  1327   DBusHashIter iter;
       
  1328   dbus_bool_t activated;
       
  1329   
       
  1330   activated = TRUE;
       
  1331 
       
  1332   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
       
  1333 
       
  1334   if (activation->n_pending_activations >=
       
  1335       bus_context_get_max_pending_activations (activation->context))
       
  1336     {
       
  1337       dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
       
  1338                       "The maximum number of pending activations has been reached, activation of %s failed",
       
  1339                       service_name);
       
  1340       return FALSE;
       
  1341     }
       
  1342 
       
  1343   entry = activation_find_entry (activation, service_name, error);
       
  1344   if (!entry) 
       
  1345     return FALSE;
       
  1346 
       
  1347   /* Bypass the registry lookup if we're auto-activating, bus_dispatch would not
       
  1348    * call us if the service is already active.
       
  1349    */
       
  1350   if (!auto_activation)
       
  1351     {
       
  1352       /* Check if the service is active */
       
  1353       _dbus_string_init_const (&service_str, service_name);
       
  1354       if (bus_registry_lookup (bus_context_get_registry (activation->context), &service_str) != NULL)
       
  1355         {
       
  1356           dbus_uint32_t result;
       
  1357           
       
  1358           _dbus_verbose ("Service \"%s\" is already active\n", service_name);
       
  1359       
       
  1360           message = dbus_message_new_method_return (activation_message);
       
  1361 
       
  1362           if (!message)
       
  1363             {
       
  1364               _dbus_verbose ("No memory to create reply to activate message\n");
       
  1365               BUS_SET_OOM (error);
       
  1366               return FALSE;
       
  1367             }
       
  1368 
       
  1369           result = DBUS_START_REPLY_ALREADY_RUNNING;
       
  1370           
       
  1371           if (!dbus_message_append_args (message,
       
  1372                                          DBUS_TYPE_UINT32, &result,
       
  1373                                          DBUS_TYPE_INVALID))
       
  1374             {
       
  1375               _dbus_verbose ("No memory to set args of reply to activate message\n");
       
  1376               BUS_SET_OOM (error);
       
  1377               dbus_message_unref (message);
       
  1378               return FALSE;
       
  1379             }
       
  1380 
       
  1381           retval = bus_transaction_send_from_driver (transaction, connection, message);
       
  1382           dbus_message_unref (message);
       
  1383           if (!retval)
       
  1384             {
       
  1385               _dbus_verbose ("Failed to send reply\n");
       
  1386               BUS_SET_OOM (error);
       
  1387             }
       
  1388 
       
  1389           return retval;
       
  1390         }
       
  1391     }
       
  1392   
       
  1393   pending_activation_entry = dbus_new0 (BusPendingActivationEntry, 1);
       
  1394   if (!pending_activation_entry)
       
  1395     {
       
  1396       _dbus_verbose ("Failed to create pending activation entry\n");
       
  1397       BUS_SET_OOM (error);
       
  1398       return FALSE;
       
  1399     }
       
  1400 
       
  1401   pending_activation_entry->auto_activation = auto_activation;
       
  1402 
       
  1403   pending_activation_entry->activation_message = activation_message;
       
  1404   dbus_message_ref (activation_message);
       
  1405   pending_activation_entry->connection = connection;
       
  1406   dbus_connection_ref (connection);
       
  1407   
       
  1408   /* Check if the service is being activated */
       
  1409   pending_activation = _dbus_hash_table_lookup_string (activation->pending_activations, service_name);
       
  1410   if (pending_activation)
       
  1411     {
       
  1412       if (!_dbus_list_append (&pending_activation->entries, pending_activation_entry))
       
  1413         {
       
  1414           _dbus_verbose ("Failed to append a new entry to pending activation\n");
       
  1415           
       
  1416           BUS_SET_OOM (error);
       
  1417           bus_pending_activation_entry_free (pending_activation_entry);
       
  1418           return FALSE;
       
  1419         }
       
  1420 
       
  1421       pending_activation->n_entries += 1;
       
  1422       pending_activation->activation->n_pending_activations += 1;
       
  1423     }
       
  1424   else
       
  1425     {
       
  1426       pending_activation = dbus_new0 (BusPendingActivation, 1);
       
  1427       if (!pending_activation)
       
  1428         {
       
  1429           _dbus_verbose ("Failed to create pending activation\n");
       
  1430           
       
  1431           BUS_SET_OOM (error);
       
  1432           bus_pending_activation_entry_free (pending_activation_entry);          
       
  1433           return FALSE;
       
  1434         }
       
  1435 
       
  1436       pending_activation->activation = activation;
       
  1437       pending_activation->refcount = 1;
       
  1438       
       
  1439       pending_activation->service_name = _dbus_strdup (service_name);
       
  1440       if (!pending_activation->service_name)
       
  1441         {
       
  1442           _dbus_verbose ("Failed to copy service name for pending activation\n");
       
  1443           
       
  1444           BUS_SET_OOM (error);
       
  1445           bus_pending_activation_unref (pending_activation);
       
  1446           bus_pending_activation_entry_free (pending_activation_entry);          
       
  1447           return FALSE;
       
  1448         }
       
  1449 
       
  1450       pending_activation->exec = _dbus_strdup (entry->exec);
       
  1451       if (!pending_activation->exec)
       
  1452         {
       
  1453           _dbus_verbose ("Failed to copy service exec for pending activation\n");
       
  1454           BUS_SET_OOM (error);
       
  1455           bus_pending_activation_unref (pending_activation);
       
  1456           bus_pending_activation_entry_free (pending_activation_entry);
       
  1457           return FALSE;
       
  1458         }
       
  1459 
       
  1460       pending_activation->timeout =
       
  1461         _dbus_timeout_new (bus_context_get_activation_timeout (activation->context),
       
  1462                            pending_activation_timed_out,
       
  1463                            pending_activation,
       
  1464                            NULL);
       
  1465       if (!pending_activation->timeout)
       
  1466         {
       
  1467           _dbus_verbose ("Failed to create timeout for pending activation\n");
       
  1468           
       
  1469           BUS_SET_OOM (error);
       
  1470           bus_pending_activation_unref (pending_activation);
       
  1471           bus_pending_activation_entry_free (pending_activation_entry);
       
  1472           return FALSE;
       
  1473         }
       
  1474 
       
  1475       if (!_dbus_loop_add_timeout (bus_context_get_loop (activation->context),
       
  1476                                    pending_activation->timeout,
       
  1477                                    handle_timeout_callback,
       
  1478                                    pending_activation,
       
  1479                                    NULL))
       
  1480         {
       
  1481           _dbus_verbose ("Failed to add timeout for pending activation\n");
       
  1482           
       
  1483           BUS_SET_OOM (error);
       
  1484           bus_pending_activation_unref (pending_activation);
       
  1485           bus_pending_activation_entry_free (pending_activation_entry);          
       
  1486           return FALSE;
       
  1487         }
       
  1488 
       
  1489       pending_activation->timeout_added = TRUE;
       
  1490       
       
  1491       if (!_dbus_list_append (&pending_activation->entries, pending_activation_entry))
       
  1492         {
       
  1493           _dbus_verbose ("Failed to add entry to just-created pending activation\n");
       
  1494           
       
  1495           BUS_SET_OOM (error);
       
  1496           bus_pending_activation_unref (pending_activation);
       
  1497           bus_pending_activation_entry_free (pending_activation_entry);          
       
  1498           return FALSE;
       
  1499         }
       
  1500 
       
  1501       pending_activation->n_entries += 1;
       
  1502       pending_activation->activation->n_pending_activations += 1;
       
  1503     
       
  1504       activated = FALSE;
       
  1505       _dbus_hash_iter_init (activation->pending_activations, &iter);
       
  1506       while (_dbus_hash_iter_next (&iter))
       
  1507         {
       
  1508           BusPendingActivation *p = _dbus_hash_iter_get_value (&iter);
       
  1509           
       
  1510           if (strcmp (p->exec, entry->exec) == 0) 
       
  1511             {
       
  1512               activated = TRUE;
       
  1513               break;
       
  1514             }
       
  1515         }
       
  1516      
       
  1517       if (!_dbus_hash_table_insert_string (activation->pending_activations,
       
  1518                                            pending_activation->service_name,
       
  1519                                            pending_activation))
       
  1520         {
       
  1521           _dbus_verbose ("Failed to put pending activation in hash table\n");
       
  1522           
       
  1523           BUS_SET_OOM (error);
       
  1524           bus_pending_activation_unref (pending_activation);
       
  1525           return FALSE;
       
  1526         }
       
  1527     }
       
  1528   
       
  1529   if (!add_cancel_pending_to_transaction (transaction, pending_activation))
       
  1530     {
       
  1531       _dbus_verbose ("Failed to add pending activation cancel hook to transaction\n");
       
  1532       BUS_SET_OOM (error);
       
  1533       _dbus_hash_table_remove_string (activation->pending_activations,
       
  1534                                       pending_activation->service_name);
       
  1535 
       
  1536       return FALSE;
       
  1537     }
       
  1538   
       
  1539   if (activated)
       
  1540     return TRUE;
       
  1541   #ifndef __SYMBIAN32__
       
  1542 
       
  1543   /* Now try to spawn the process */
       
  1544   if (!_dbus_shell_parse_argv (entry->exec, &argc, &argv, error))
       
  1545     {
       
  1546       _dbus_verbose ("Failed to parse command line: %s\n", entry->exec);
       
  1547       _DBUS_ASSERT_ERROR_IS_SET (error);
       
  1548       
       
  1549       _dbus_hash_table_remove_string (activation->pending_activations,
       
  1550                                       pending_activation->service_name);
       
  1551 
       
  1552       return FALSE;
       
  1553     }
       
  1554 
       
  1555   _dbus_verbose ("Spawning %s ...\n", argv[0]);
       
  1556   #else
       
  1557   
       
  1558    _dbus_verbose ("Spawning %s ...\n", entry->exec);
       
  1559    #endif
       
  1560    
       
  1561    #ifdef __SYMBIAN32__
       
  1562    if (!_dbus_spawn_async_with_babysitter (&pending_activation->babysitter, &entry->exec,
       
  1563                                           child_setup, activation, 
       
  1564                                           error))
       
  1565    #else
       
  1566   if (!_dbus_spawn_async_with_babysitter (&pending_activation->babysitter, argv,
       
  1567                                           child_setup, activation, 
       
  1568                                           error))
       
  1569     {
       
  1570       _dbus_verbose ("Failed to spawn child\n");
       
  1571       _DBUS_ASSERT_ERROR_IS_SET (error);
       
  1572       dbus_free_string_array (argv);
       
  1573 
       
  1574       return FALSE;
       
  1575     }
       
  1576 
       
  1577   dbus_free_string_array (argv);
       
  1578 
       
  1579   _dbus_assert (pending_activation->babysitter != NULL);
       
  1580   
       
  1581   if (!_dbus_babysitter_set_watch_functions (pending_activation->babysitter,
       
  1582                                              add_babysitter_watch,
       
  1583                                              remove_babysitter_watch,
       
  1584                                              NULL,
       
  1585                                              pending_activation,
       
  1586                                              NULL))
       
  1587     {
       
  1588       BUS_SET_OOM (error);
       
  1589       _dbus_verbose ("Failed to set babysitter watch functions\n");
       
  1590       return FALSE;
       
  1591     }
       
  1592    #endif  
       
  1593   return TRUE;
       
  1594 }
       
  1595 
       
  1596 dbus_bool_t
       
  1597 bus_activation_list_services (BusActivation *activation,
       
  1598 			      char        ***listp,
       
  1599 			      int           *array_len)
       
  1600 {
       
  1601   int i, j, len;
       
  1602   char **retval;
       
  1603   DBusHashIter iter;
       
  1604 
       
  1605   len = _dbus_hash_table_get_n_entries (activation->entries);
       
  1606   retval = dbus_new (char *, len + 1);
       
  1607 
       
  1608   if (retval == NULL)
       
  1609     return FALSE;
       
  1610 
       
  1611   _dbus_hash_iter_init (activation->entries, &iter);
       
  1612   i = 0;
       
  1613   while (_dbus_hash_iter_next (&iter))
       
  1614     {
       
  1615       BusActivationEntry *entry = _dbus_hash_iter_get_value (&iter);
       
  1616 
       
  1617       retval[i] = _dbus_strdup (entry->name);
       
  1618       if (retval[i] == NULL)
       
  1619 	goto error;
       
  1620 
       
  1621       i++;
       
  1622     }
       
  1623 
       
  1624   retval[i] = NULL;
       
  1625 
       
  1626   if (array_len)
       
  1627     *array_len = len;
       
  1628 
       
  1629   *listp = retval;
       
  1630   return TRUE;
       
  1631 
       
  1632  error:
       
  1633   for (j = 0; j < i; j++)
       
  1634     dbus_free (retval[i]);
       
  1635   dbus_free (retval);
       
  1636 
       
  1637   return FALSE;
       
  1638 }
       
  1639   
       
  1640 
       
  1641 #ifdef DBUS_BUILD_TESTS
       
  1642 
       
  1643 #include <stdio.h>
       
  1644 
       
  1645 #define SERVICE_NAME_1 "MyService1"
       
  1646 #define SERVICE_NAME_2 "MyService2"
       
  1647 #define SERVICE_NAME_3 "MyService3"
       
  1648 
       
  1649 #define SERVICE_FILE_1 "service-1.service"
       
  1650 #define SERVICE_FILE_2 "service-2.service"
       
  1651 #define SERVICE_FILE_3 "service-3.service"
       
  1652 
       
  1653 static dbus_bool_t
       
  1654 test_create_service_file (DBusString *dir,
       
  1655                           const char *filename, 
       
  1656                           const char *name, 
       
  1657                           const char *exec)
       
  1658 {
       
  1659   DBusString  file_name, full_path;
       
  1660   FILE        *file;
       
  1661   dbus_bool_t  ret_val;
       
  1662 
       
  1663   ret_val = TRUE;
       
  1664   _dbus_string_init_const (&file_name, filename);
       
  1665 
       
  1666   if (!_dbus_string_init (&full_path))
       
  1667     return FALSE;
       
  1668 
       
  1669   if (!_dbus_string_append (&full_path, _dbus_string_get_const_data (dir)) ||
       
  1670       !_dbus_concat_dir_and_file (&full_path, &file_name))
       
  1671     {
       
  1672       ret_val = FALSE;
       
  1673       goto out;
       
  1674     }
       
  1675   
       
  1676   file = fopen (_dbus_string_get_const_data (&full_path), "w");
       
  1677   if (!file)
       
  1678     {
       
  1679       ret_val = FALSE;
       
  1680       goto out;
       
  1681     }
       
  1682 
       
  1683   fprintf (file, "[D-BUS Service]\nName=%s\nExec=%s\n", name, exec);
       
  1684   fclose (file);
       
  1685 
       
  1686 out:
       
  1687   _dbus_string_free (&full_path);
       
  1688   return ret_val;
       
  1689 }
       
  1690 
       
  1691 static dbus_bool_t
       
  1692 test_remove_service_file (DBusString *dir, const char *filename)
       
  1693 {
       
  1694   DBusString  file_name, full_path;
       
  1695   dbus_bool_t ret_val;
       
  1696   
       
  1697   ret_val = TRUE;
       
  1698  
       
  1699   _dbus_string_init_const (&file_name, filename);
       
  1700 
       
  1701   if (!_dbus_string_init (&full_path))
       
  1702     return FALSE;
       
  1703 
       
  1704   if (!_dbus_string_append (&full_path, _dbus_string_get_const_data (dir)) ||
       
  1705       !_dbus_concat_dir_and_file (&full_path, &file_name))
       
  1706     {
       
  1707       ret_val = FALSE;
       
  1708       goto out;
       
  1709     }
       
  1710 
       
  1711   if (!_dbus_delete_file (&full_path, NULL))
       
  1712     {
       
  1713       ret_val = FALSE;
       
  1714       goto out;
       
  1715     }
       
  1716 
       
  1717 out:
       
  1718   _dbus_string_free (&full_path);
       
  1719   return ret_val;
       
  1720 }
       
  1721 
       
  1722 static dbus_bool_t
       
  1723 test_remove_directory (DBusString *dir)
       
  1724 {
       
  1725   DBusDirIter *iter;
       
  1726   DBusString   filename, full_path;
       
  1727   dbus_bool_t  ret_val;
       
  1728   
       
  1729   ret_val = TRUE;
       
  1730   
       
  1731   if (!_dbus_string_init (&filename))
       
  1732     return FALSE;
       
  1733 
       
  1734   if (!_dbus_string_init (&full_path))
       
  1735     {
       
  1736       _dbus_string_free (&filename);
       
  1737       return FALSE;
       
  1738     }
       
  1739     
       
  1740   iter = _dbus_directory_open (dir, NULL);
       
  1741   if (iter == NULL)
       
  1742     {
       
  1743       ret_val = FALSE;
       
  1744       goto out;
       
  1745     }
       
  1746   
       
  1747   while (_dbus_directory_get_next_file (iter, &filename, NULL)) 
       
  1748     {
       
  1749       if (!test_remove_service_file (dir, _dbus_string_get_const_data (&filename)))
       
  1750         {
       
  1751           ret_val = FALSE;
       
  1752           goto out;
       
  1753         }
       
  1754     }
       
  1755   _dbus_directory_close (iter);
       
  1756 
       
  1757   if (!_dbus_delete_directory (dir, NULL))
       
  1758     {
       
  1759       ret_val = FALSE;
       
  1760       goto out;
       
  1761     }
       
  1762 
       
  1763 out:
       
  1764   _dbus_string_free (&filename);
       
  1765   _dbus_string_free (&full_path);
       
  1766 
       
  1767   return ret_val;
       
  1768 }
       
  1769 
       
  1770 static dbus_bool_t
       
  1771 init_service_reload_test (DBusString *dir)
       
  1772 {
       
  1773   DBusStat stat_buf;
       
  1774  
       
  1775   if (!_dbus_stat (dir, &stat_buf, NULL))
       
  1776     {
       
  1777       if (!_dbus_create_directory (dir, NULL))
       
  1778         return FALSE;
       
  1779     }
       
  1780   else 
       
  1781     {
       
  1782       if (!test_remove_directory (dir))
       
  1783         return FALSE;
       
  1784 
       
  1785       if (!_dbus_create_directory (dir, NULL))
       
  1786         return FALSE;
       
  1787     }
       
  1788 
       
  1789   /* Create one initial file */
       
  1790   if (!test_create_service_file (dir, SERVICE_FILE_1, SERVICE_NAME_1, "exec-1"))
       
  1791     return FALSE;
       
  1792 
       
  1793   return TRUE;
       
  1794 }
       
  1795 
       
  1796 static dbus_bool_t
       
  1797 cleanup_service_reload_test (DBusString *dir)
       
  1798 {
       
  1799   if (!test_remove_directory (dir))
       
  1800     return FALSE;
       
  1801 
       
  1802   return TRUE;
       
  1803 }
       
  1804 
       
  1805 typedef struct 
       
  1806 {
       
  1807   BusActivation *activation;
       
  1808   const char    *service_name;
       
  1809   dbus_bool_t    expecting_find;
       
  1810 } CheckData;
       
  1811 
       
  1812 static dbus_bool_t
       
  1813 check_func (void *data)
       
  1814 {
       
  1815   CheckData          *d;
       
  1816   BusActivationEntry *entry;
       
  1817   DBusError           error;
       
  1818   dbus_bool_t         ret_val;
       
  1819   
       
  1820   ret_val = TRUE;
       
  1821   d = data;
       
  1822   
       
  1823   dbus_error_init (&error);
       
  1824  
       
  1825   entry = activation_find_entry (d->activation, d->service_name, &error);
       
  1826   if (entry == NULL)
       
  1827     {
       
  1828       if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 
       
  1829         {
       
  1830           ret_val = TRUE;
       
  1831         }
       
  1832       else
       
  1833         {
       
  1834           if (d->expecting_find)
       
  1835             ret_val = FALSE;
       
  1836         }
       
  1837       
       
  1838       dbus_error_free (&error);
       
  1839     }
       
  1840   else 
       
  1841     {
       
  1842       if (!d->expecting_find)
       
  1843         ret_val = FALSE;
       
  1844     }
       
  1845 
       
  1846   return ret_val;
       
  1847 }
       
  1848 
       
  1849 static dbus_bool_t
       
  1850 do_test (const char *description, dbus_bool_t oom_test, CheckData *data)
       
  1851 {
       
  1852   dbus_bool_t err;
       
  1853 
       
  1854   if (oom_test)
       
  1855     err = !_dbus_test_oom_handling (description, check_func, data);
       
  1856   else
       
  1857     err = !check_func (data);
       
  1858 
       
  1859   if (err) 
       
  1860     _dbus_assert_not_reached ("Test failed");
       
  1861 
       
  1862   return TRUE;
       
  1863 }
       
  1864 
       
  1865 static dbus_bool_t
       
  1866 do_service_reload_test (DBusString *dir, dbus_bool_t oom_test)
       
  1867 {
       
  1868   BusActivation *activation;
       
  1869   DBusString     address;
       
  1870   DBusList      *directories;
       
  1871   CheckData      d;
       
  1872   
       
  1873   directories = NULL;
       
  1874   _dbus_string_init_const (&address, "");
       
  1875  
       
  1876   if (!_dbus_list_append (&directories, _dbus_string_get_data (dir)))
       
  1877     return FALSE; 
       
  1878 
       
  1879   activation = bus_activation_new (NULL, &address, &directories, NULL);
       
  1880   if (!activation)
       
  1881     return FALSE;
       
  1882 
       
  1883   d.activation = activation;
       
  1884   
       
  1885   /* Check for existing service file */
       
  1886   d.expecting_find = TRUE;
       
  1887   d.service_name = SERVICE_NAME_1;
       
  1888 
       
  1889   if (!do_test ("Existing service file", oom_test, &d))
       
  1890     return FALSE;
       
  1891 
       
  1892   /* Check for non-existing service file */
       
  1893   d.expecting_find = FALSE;
       
  1894   d.service_name = SERVICE_NAME_3;
       
  1895 
       
  1896   if (!do_test ("Nonexisting service file", oom_test, &d))
       
  1897     return FALSE;
       
  1898 
       
  1899   /* Check for added service file */
       
  1900   if (!test_create_service_file (dir, SERVICE_FILE_2, SERVICE_NAME_2, "exec-2"))
       
  1901     return FALSE;
       
  1902 
       
  1903   d.expecting_find = TRUE;
       
  1904   d.service_name = SERVICE_NAME_2;
       
  1905   
       
  1906   if (!do_test ("Added service file", oom_test, &d))
       
  1907     return FALSE;
       
  1908   
       
  1909   /* Check for removed service file */
       
  1910   if (!test_remove_service_file (dir, SERVICE_FILE_2))
       
  1911     return FALSE;
       
  1912 
       
  1913   d.expecting_find = FALSE;
       
  1914   d.service_name = SERVICE_FILE_2;
       
  1915 
       
  1916   if (!do_test ("Removed service file", oom_test, &d))
       
  1917     return FALSE;
       
  1918   
       
  1919   /* Check for updated service file */
       
  1920   
       
  1921   _dbus_sleep_milliseconds (1000); /* Sleep a second to make sure the mtime is updated */
       
  1922 
       
  1923   if (!test_create_service_file (dir, SERVICE_FILE_1, SERVICE_NAME_3, "exec-3"))
       
  1924     return FALSE;
       
  1925 
       
  1926   d.expecting_find = TRUE;
       
  1927   d.service_name = SERVICE_NAME_3;
       
  1928 
       
  1929   if (!do_test ("Updated service file, part 1", oom_test, &d))
       
  1930     return FALSE;
       
  1931 
       
  1932   d.expecting_find = FALSE;
       
  1933   d.service_name = SERVICE_NAME_1;
       
  1934 
       
  1935   if (!do_test ("Updated service file, part 2", oom_test, &d))
       
  1936     return FALSE; 
       
  1937 
       
  1938   bus_activation_unref (activation);
       
  1939   _dbus_list_clear (&directories);
       
  1940 
       
  1941   return TRUE;
       
  1942 }
       
  1943 
       
  1944 dbus_bool_t
       
  1945 bus_activation_service_reload_test (const DBusString *test_data_dir)
       
  1946 {
       
  1947   DBusString directory;
       
  1948   DBusStat stat_buf;	
       
  1949   if (!_dbus_string_init (&directory))
       
  1950     return FALSE;
       
  1951   
       
  1952   if (!_dbus_string_append (&directory, _dbus_get_tmpdir()))
       
  1953     return FALSE;
       
  1954   if (!_dbus_stat (&directory, &stat_buf, NULL))
       
  1955     {
       
  1956       if (!_dbus_create_directory (&directory, NULL))
       
  1957         return FALSE;
       
  1958     }
       
  1959   
       
  1960   if (!_dbus_string_append (&directory, "/dbus-reload-test-") ||
       
  1961       !_dbus_generate_random_ascii (&directory, 6))
       
  1962      {
       
  1963        return FALSE;
       
  1964      }
       
  1965    
       
  1966   /* Do normal tests */
       
  1967   if (!init_service_reload_test (&directory))
       
  1968     _dbus_assert_not_reached ("could not initiate service reload test");
       
  1969  
       
  1970   if (!do_service_reload_test (&directory, FALSE))
       
  1971     ; /* Do nothing? */
       
  1972   
       
  1973   /* Do OOM tests */
       
  1974   if (!init_service_reload_test (&directory))
       
  1975     _dbus_assert_not_reached ("could not initiate service reload test");
       
  1976  
       
  1977   if (!do_service_reload_test (&directory, TRUE))
       
  1978     ; /* Do nothing? */
       
  1979  
       
  1980   /* Cleanup test directory */
       
  1981   if (!cleanup_service_reload_test (&directory))
       
  1982     return FALSE;
       
  1983   
       
  1984   _dbus_string_free (&directory);
       
  1985   
       
  1986   return TRUE;
       
  1987 }
       
  1988 
       
  1989 #endif /* DBUS_BUILD_TESTS */