Home | History | Annotate | Download | only in bus
      1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
      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  *
      8  * Licensed under the Academic Free License version 2.1
      9  *
     10  * This program is free software; you can redistribute it and/or modify
     11  * it under the terms of the GNU General Public License as published by
     12  * the Free Software Foundation; either version 2 of the License, or
     13  * (at your option) any later version.
     14  *
     15  * This program is distributed in the hope that it will be useful,
     16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18  * GNU General Public License for more details.
     19  *
     20  * You should have received a copy of the GNU General Public License
     21  * along with this program; if not, write to the Free Software
     22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     23  *
     24  */
     25 
     26 #include <config.h>
     27 #include "activation.h"
     28 #include "activation-exit-codes.h"
     29 #include "desktop-file.h"
     30 #include "dispatch.h"
     31 #include "services.h"
     32 #include "test.h"
     33 #include "utils.h"
     34 #include <dbus/dbus-internals.h>
     35 #include <dbus/dbus-hash.h>
     36 #include <dbus/dbus-list.h>
     37 #include <dbus/dbus-shell.h>
     38 #include <dbus/dbus-spawn.h>
     39 #include <dbus/dbus-timeout.h>
     40 #include <dbus/dbus-sysdeps.h>
     41 #ifdef HAVE_ERRNO_H
     42 #include <errno.h>
     43 #endif
     44 
     45 struct BusActivation
     46 {
     47   int refcount;
     48   DBusHashTable *entries;
     49   DBusHashTable *pending_activations;
     50   char *server_address;
     51   BusContext *context;
     52   int n_pending_activations; /**< This is in fact the number of BusPendingActivationEntry,
     53                               * i.e. number of pending activation requests, not pending
     54                               * activations per se
     55                               */
     56   DBusHashTable *directories;
     57   DBusHashTable *environment;
     58 };
     59 
     60 typedef struct
     61 {
     62   int refcount;
     63   char *dir_c;
     64   DBusHashTable *entries;
     65 } BusServiceDirectory;
     66 
     67 typedef struct
     68 {
     69   int refcount;
     70   char *name;
     71   char *exec;
     72   char *user;
     73   char *systemd_service;
     74   unsigned long mtime;
     75   BusServiceDirectory *s_dir;
     76   char *filename;
     77 } BusActivationEntry;
     78 
     79 typedef struct BusPendingActivationEntry BusPendingActivationEntry;
     80 
     81 struct BusPendingActivationEntry
     82 {
     83   DBusMessage *activation_message;
     84   DBusConnection *connection;
     85 
     86   dbus_bool_t auto_activation;
     87 };
     88 
     89 typedef struct
     90 {
     91   int refcount;
     92   BusActivation *activation;
     93   char *service_name;
     94   char *exec;
     95   char *systemd_service;
     96   DBusList *entries;
     97   int n_entries;
     98   DBusBabysitter *babysitter;
     99   DBusTimeout *timeout;
    100   unsigned int timeout_added : 1;
    101 } BusPendingActivation;
    102 
    103 #if 0
    104 static BusServiceDirectory *
    105 bus_service_directory_ref (BusServiceDirectory *dir)
    106 {
    107   _dbus_assert (dir->refcount);
    108 
    109   dir->refcount++;
    110 
    111   return dir;
    112 }
    113 #endif
    114 
    115 static void
    116 bus_service_directory_unref (BusServiceDirectory *dir)
    117 {
    118   if (dir == NULL)
    119     return;
    120 
    121   _dbus_assert (dir->refcount > 0);
    122   dir->refcount--;
    123 
    124   if (dir->refcount > 0)
    125     return;
    126 
    127   if (dir->entries)
    128     _dbus_hash_table_unref (dir->entries);
    129 
    130   dbus_free (dir->dir_c);
    131   dbus_free (dir);
    132 }
    133 
    134 static void
    135 bus_pending_activation_entry_free (BusPendingActivationEntry *entry)
    136 {
    137   if (entry->activation_message)
    138     dbus_message_unref (entry->activation_message);
    139 
    140   if (entry->connection)
    141     dbus_connection_unref (entry->connection);
    142 
    143   dbus_free (entry);
    144 }
    145 
    146 static void
    147 handle_timeout_callback (DBusTimeout   *timeout,
    148                          void          *data)
    149 {
    150   BusPendingActivation *pending_activation = data;
    151 
    152   while (!dbus_timeout_handle (pending_activation->timeout))
    153     _dbus_wait_for_memory ();
    154 }
    155 
    156 static BusPendingActivation *
    157 bus_pending_activation_ref (BusPendingActivation *pending_activation)
    158 {
    159   _dbus_assert (pending_activation->refcount > 0);
    160   pending_activation->refcount += 1;
    161 
    162   return pending_activation;
    163 }
    164 
    165 static void
    166 bus_pending_activation_unref (BusPendingActivation *pending_activation)
    167 {
    168   DBusList *link;
    169 
    170   if (pending_activation == NULL) /* hash table requires this */
    171     return;
    172 
    173   _dbus_assert (pending_activation->refcount > 0);
    174   pending_activation->refcount -= 1;
    175 
    176   if (pending_activation->refcount > 0)
    177     return;
    178 
    179   if (pending_activation->timeout_added)
    180     {
    181       _dbus_loop_remove_timeout (bus_context_get_loop (pending_activation->activation->context),
    182                                  pending_activation->timeout,
    183                                  handle_timeout_callback, pending_activation);
    184       pending_activation->timeout_added = FALSE;
    185     }
    186 
    187   if (pending_activation->timeout)
    188     _dbus_timeout_unref (pending_activation->timeout);
    189 
    190   if (pending_activation->babysitter)
    191     {
    192       if (!_dbus_babysitter_set_watch_functions (pending_activation->babysitter,
    193                                                  NULL, NULL, NULL,
    194                                                  pending_activation->babysitter,
    195                                                  NULL))
    196         _dbus_assert_not_reached ("setting watch functions to NULL failed");
    197 
    198       _dbus_babysitter_unref (pending_activation->babysitter);
    199     }
    200 
    201   dbus_free (pending_activation->service_name);
    202   dbus_free (pending_activation->exec);
    203   dbus_free (pending_activation->systemd_service);
    204 
    205   link = _dbus_list_get_first_link (&pending_activation->entries);
    206 
    207   while (link != NULL)
    208     {
    209       BusPendingActivationEntry *entry = link->data;
    210 
    211       bus_pending_activation_entry_free (entry);
    212 
    213       link = _dbus_list_get_next_link (&pending_activation->entries, link);
    214     }
    215   _dbus_list_clear (&pending_activation->entries);
    216 
    217   pending_activation->activation->n_pending_activations -=
    218     pending_activation->n_entries;
    219 
    220   _dbus_assert (pending_activation->activation->n_pending_activations >= 0);
    221 
    222   dbus_free (pending_activation);
    223 }
    224 
    225 static BusActivationEntry *
    226 bus_activation_entry_ref (BusActivationEntry *entry)
    227 {
    228   _dbus_assert (entry->refcount > 0);
    229   entry->refcount++;
    230 
    231   return entry;
    232 }
    233 
    234 static void
    235 bus_activation_entry_unref (BusActivationEntry *entry)
    236 {
    237   if (entry == NULL) /* hash table requires this */
    238     return;
    239 
    240   _dbus_assert (entry->refcount > 0);
    241   entry->refcount--;
    242 
    243   if (entry->refcount > 0)
    244     return;
    245 
    246   dbus_free (entry->name);
    247   dbus_free (entry->exec);
    248   dbus_free (entry->user);
    249   dbus_free (entry->filename);
    250   dbus_free (entry->systemd_service);
    251 
    252   dbus_free (entry);
    253 }
    254 
    255 static dbus_bool_t
    256 update_desktop_file_entry (BusActivation       *activation,
    257                            BusServiceDirectory *s_dir,
    258                            DBusString          *filename,
    259                            BusDesktopFile      *desktop_file,
    260                            DBusError           *error)
    261 {
    262   char *name, *exec, *user, *exec_tmp, *systemd_service;
    263   BusActivationEntry *entry;
    264   DBusStat stat_buf;
    265   DBusString file_path;
    266   DBusError tmp_error;
    267 
    268   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    269 
    270   name = NULL;
    271   exec = NULL;
    272   user = NULL;
    273   exec_tmp = NULL;
    274   entry = NULL;
    275   systemd_service = NULL;
    276 
    277   dbus_error_init (&tmp_error);
    278 
    279   if (!_dbus_string_init (&file_path))
    280     {
    281       BUS_SET_OOM (error);
    282       return FALSE;
    283     }
    284 
    285   if (!_dbus_string_append (&file_path, s_dir->dir_c) ||
    286       !_dbus_concat_dir_and_file (&file_path, filename))
    287     {
    288       BUS_SET_OOM (error);
    289       goto failed;
    290     }
    291 
    292   if (!_dbus_stat (&file_path, &stat_buf, NULL))
    293     {
    294       dbus_set_error (error, DBUS_ERROR_FAILED,
    295                       "Can't stat the service file\n");
    296       goto failed;
    297     }
    298 
    299   if (!bus_desktop_file_get_string (desktop_file,
    300                                     DBUS_SERVICE_SECTION,
    301                                     DBUS_SERVICE_NAME,
    302                                     &name,
    303                                     error))
    304     goto failed;
    305 
    306   if (!bus_desktop_file_get_string (desktop_file,
    307                                     DBUS_SERVICE_SECTION,
    308                                     DBUS_SERVICE_EXEC,
    309                                     &exec_tmp,
    310                                     error))
    311     goto failed;
    312 
    313   /* user is not _required_ unless we are using system activation */
    314   if (!bus_desktop_file_get_string (desktop_file,
    315                                     DBUS_SERVICE_SECTION,
    316                                     DBUS_SERVICE_USER,
    317                                     &user, &tmp_error))
    318     {
    319       _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
    320       /* if we got OOM, then exit */
    321       if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
    322         {
    323           dbus_move_error (&tmp_error, error);
    324           goto failed;
    325         }
    326       else
    327         {
    328           /* if we have error because we didn't find anything then continue */
    329           dbus_error_free (&tmp_error);
    330           dbus_free (user);
    331           user = NULL;
    332         }
    333     }
    334   _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
    335 
    336   /* systemd service is never required */
    337   if (!bus_desktop_file_get_string (desktop_file,
    338                                     DBUS_SERVICE_SECTION,
    339                                     DBUS_SERVICE_SYSTEMD_SERVICE,
    340                                     &systemd_service, &tmp_error))
    341     {
    342       _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
    343       /* if we got OOM, then exit */
    344       if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
    345         {
    346           dbus_move_error (&tmp_error, error);
    347           goto failed;
    348         }
    349       else
    350         {
    351           /* if we have error because we didn't find anything then continue */
    352           dbus_error_free (&tmp_error);
    353           dbus_free (systemd_service);
    354           systemd_service = NULL;
    355         }
    356     }
    357 
    358   _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
    359 
    360   entry = _dbus_hash_table_lookup_string (s_dir->entries,
    361                                           _dbus_string_get_const_data (filename));
    362 
    363   exec = strdup (_dbus_replace_install_prefix (exec_tmp));
    364 
    365   if (entry == NULL) /* New file */
    366     {
    367       /* FIXME we need a better-defined algorithm for which service file to
    368        * pick than "whichever one is first in the directory listing"
    369        */
    370       if (_dbus_hash_table_lookup_string (activation->entries, name))
    371         {
    372           dbus_set_error (error, DBUS_ERROR_FAILED,
    373                           "Service %s already exists in activation entry list\n", name);
    374           goto failed;
    375         }
    376 
    377       entry = dbus_new0 (BusActivationEntry, 1);
    378       if (entry == NULL)
    379         {
    380           BUS_SET_OOM (error);
    381           goto failed;
    382         }
    383 
    384       entry->name = name;
    385       entry->exec = exec;
    386       entry->user = user;
    387       entry->systemd_service = systemd_service;
    388       entry->refcount = 1;
    389 
    390       entry->s_dir = s_dir;
    391       entry->filename = _dbus_strdup (_dbus_string_get_const_data (filename));
    392       if (!entry->filename)
    393         {
    394           BUS_SET_OOM (error);
    395           goto failed;
    396         }
    397 
    398       if (!_dbus_hash_table_insert_string (activation->entries, entry->name, bus_activation_entry_ref (entry)))
    399         {
    400           BUS_SET_OOM (error);
    401           goto failed;
    402         }
    403 
    404       if (!_dbus_hash_table_insert_string (s_dir->entries, entry->filename, bus_activation_entry_ref (entry)))
    405         {
    406           /* Revert the insertion in the entries table */
    407           _dbus_hash_table_remove_string (activation->entries, entry->name);
    408           BUS_SET_OOM (error);
    409           goto failed;
    410         }
    411 
    412       _dbus_verbose ("Added \"%s\" to list of services\n", entry->name);
    413     }
    414   else /* Just update the entry */
    415     {
    416       bus_activation_entry_ref (entry);
    417       _dbus_hash_table_remove_string (activation->entries, entry->name);
    418 
    419       if (_dbus_hash_table_lookup_string (activation->entries, name))
    420         {
    421           _dbus_verbose ("The new service name \"%s\" of service file \"%s\" already in cache, ignoring\n",
    422                          name, _dbus_string_get_const_data (&file_path));
    423           goto failed;
    424         }
    425 
    426       dbus_free (entry->name);
    427       dbus_free (entry->exec);
    428       dbus_free (entry->user);
    429       dbus_free (entry->systemd_service);
    430       entry->systemd_service = systemd_service;
    431       entry->name = name;
    432       entry->exec = exec;
    433       entry->user = user;
    434       if (!_dbus_hash_table_insert_string (activation->entries,
    435                                            entry->name, bus_activation_entry_ref(entry)))
    436         {
    437           BUS_SET_OOM (error);
    438           /* Also remove path to entries hash since we want this in sync with
    439            * the entries hash table */
    440           _dbus_hash_table_remove_string (entry->s_dir->entries,
    441                                           entry->filename);
    442           bus_activation_entry_unref (entry);
    443           return FALSE;
    444         }
    445     }
    446 
    447   entry->mtime = stat_buf.mtime;
    448 
    449   _dbus_string_free (&file_path);
    450   bus_activation_entry_unref (entry);
    451 
    452   return TRUE;
    453 
    454 failed:
    455   dbus_free (name);
    456   dbus_free (exec_tmp);
    457   dbus_free (user);
    458   dbus_free (systemd_service);
    459   _dbus_string_free (&file_path);
    460 
    461   if (entry)
    462     bus_activation_entry_unref (entry);
    463 
    464   return FALSE;
    465 }
    466 
    467 static dbus_bool_t
    468 check_service_file (BusActivation       *activation,
    469                     BusActivationEntry  *entry,
    470                     BusActivationEntry **updated_entry,
    471                     DBusError           *error)
    472 {
    473   DBusStat stat_buf;
    474   dbus_bool_t retval;
    475   BusActivationEntry *tmp_entry;
    476   DBusString file_path;
    477   DBusString filename;
    478 
    479   retval = TRUE;
    480   tmp_entry = entry;
    481 
    482   _dbus_string_init_const (&filename, entry->filename);
    483 
    484   if (!_dbus_string_init (&file_path))
    485     {
    486       BUS_SET_OOM (error);
    487       return FALSE;
    488     }
    489 
    490   if (!_dbus_string_append (&file_path, entry->s_dir->dir_c) ||
    491       !_dbus_concat_dir_and_file (&file_path, &filename))
    492     {
    493       BUS_SET_OOM (error);
    494       retval = FALSE;
    495       goto out;
    496     }
    497 
    498   if (!_dbus_stat (&file_path, &stat_buf, NULL))
    499     {
    500       _dbus_verbose ("****** Can't stat file \"%s\", removing from cache\n",
    501                      _dbus_string_get_const_data (&file_path));
    502 
    503       _dbus_hash_table_remove_string (activation->entries, entry->name);
    504       _dbus_hash_table_remove_string (entry->s_dir->entries, entry->filename);
    505 
    506       tmp_entry = NULL;
    507       retval = TRUE;
    508       goto out;
    509     }
    510   else
    511     {
    512       if (stat_buf.mtime > entry->mtime)
    513         {
    514           BusDesktopFile *desktop_file;
    515           DBusError tmp_error;
    516 
    517           dbus_error_init (&tmp_error);
    518 
    519           desktop_file = bus_desktop_file_load (&file_path, &tmp_error);
    520           if (desktop_file == NULL)
    521             {
    522               _dbus_verbose ("Could not load %s: %s\n",
    523                              _dbus_string_get_const_data (&file_path),
    524                              tmp_error.message);
    525               if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
    526                 {
    527                   dbus_move_error (&tmp_error, error);
    528                   retval = FALSE;
    529                   goto out;
    530                 }
    531               dbus_error_free (&tmp_error);
    532               retval = TRUE;
    533               goto out;
    534             }
    535 
    536           /* @todo We can return OOM or a DBUS_ERROR_FAILED error
    537            *       Handle these both better
    538            */
    539           if (!update_desktop_file_entry (activation, entry->s_dir, &filename, desktop_file, &tmp_error))
    540             {
    541               bus_desktop_file_free (desktop_file);
    542               if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
    543                 {
    544                   dbus_move_error (&tmp_error, error);
    545                   retval = FALSE;
    546                   goto out;
    547                 }
    548               dbus_error_free (&tmp_error);
    549               retval = TRUE;
    550               goto out;
    551             }
    552 
    553           bus_desktop_file_free (desktop_file);
    554           retval = TRUE;
    555         }
    556     }
    557 
    558 out:
    559   _dbus_string_free (&file_path);
    560 
    561   if (updated_entry != NULL)
    562     *updated_entry = tmp_entry;
    563   return retval;
    564 }
    565 
    566 
    567 /* warning: this doesn't fully "undo" itself on failure, i.e. doesn't strip
    568  * hash entries it already added.
    569  */
    570 static dbus_bool_t
    571 update_directory (BusActivation       *activation,
    572                   BusServiceDirectory *s_dir,
    573                   DBusError           *error)
    574 {
    575   DBusDirIter *iter;
    576   DBusString dir, filename;
    577   BusDesktopFile *desktop_file;
    578   DBusError tmp_error;
    579   dbus_bool_t retval;
    580   BusActivationEntry *entry;
    581   DBusString full_path;
    582 
    583   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    584 
    585   iter = NULL;
    586   desktop_file = NULL;
    587 
    588   _dbus_string_init_const (&dir, s_dir->dir_c);
    589 
    590   if (!_dbus_string_init (&filename))
    591     {
    592       BUS_SET_OOM (error);
    593       return FALSE;
    594     }
    595 
    596   if (!_dbus_string_init (&full_path))
    597     {
    598       BUS_SET_OOM (error);
    599       _dbus_string_free (&filename);
    600       return FALSE;
    601     }
    602 
    603   retval = FALSE;
    604 
    605   /* from this point it's safe to "goto out" */
    606 
    607   iter = _dbus_directory_open (&dir, error);
    608   if (iter == NULL)
    609     {
    610       _dbus_verbose ("Failed to open directory %s: %s\n",
    611                      s_dir->dir_c,
    612                      error ? error->message : "unknown");
    613       goto out;
    614     }
    615 
    616   /* Now read the files */
    617   dbus_error_init (&tmp_error);
    618   while (_dbus_directory_get_next_file (iter, &filename, &tmp_error))
    619     {
    620       _dbus_assert (!dbus_error_is_set (&tmp_error));
    621 
    622       _dbus_string_set_length (&full_path, 0);
    623 
    624       if (!_dbus_string_ends_with_c_str (&filename, ".service"))
    625         {
    626           _dbus_verbose ("Skipping non-.service file %s\n",
    627                          _dbus_string_get_const_data (&filename));
    628           continue;
    629         }
    630 
    631       entry = _dbus_hash_table_lookup_string (s_dir->entries, _dbus_string_get_const_data (&filename));
    632       if (entry) /* Already has this service file in the cache */
    633         {
    634           if (!check_service_file (activation, entry, NULL, error))
    635             goto out;
    636 
    637           continue;
    638         }
    639 
    640       if (!_dbus_string_append (&full_path, s_dir->dir_c) ||
    641           !_dbus_concat_dir_and_file (&full_path, &filename))
    642         {
    643           BUS_SET_OOM (error);
    644           goto out;
    645         }
    646 
    647       /* New file */
    648       desktop_file = bus_desktop_file_load (&full_path, &tmp_error);
    649       if (desktop_file == NULL)
    650         {
    651           _dbus_verbose ("Could not load %s: %s\n",
    652                          _dbus_string_get_const_data (&full_path),
    653                          tmp_error.message);
    654 
    655           if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
    656             {
    657               dbus_move_error (&tmp_error, error);
    658               goto out;
    659             }
    660 
    661           dbus_error_free (&tmp_error);
    662           continue;
    663         }
    664 
    665       /* @todo We can return OOM or a DBUS_ERROR_FAILED error
    666        *       Handle these both better
    667        */
    668       if (!update_desktop_file_entry (activation, s_dir, &filename, desktop_file, &tmp_error))
    669         {
    670           bus_desktop_file_free (desktop_file);
    671           desktop_file = NULL;
    672 
    673           _dbus_verbose ("Could not add %s to activation entry list: %s\n",
    674                          _dbus_string_get_const_data (&full_path), tmp_error.message);
    675 
    676           if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
    677             {
    678               dbus_move_error (&tmp_error, error);
    679               goto out;
    680             }
    681 
    682           dbus_error_free (&tmp_error);
    683           continue;
    684         }
    685       else
    686         {
    687           bus_desktop_file_free (desktop_file);
    688           desktop_file = NULL;
    689           continue;
    690         }
    691     }
    692 
    693   if (dbus_error_is_set (&tmp_error))
    694     {
    695       dbus_move_error (&tmp_error, error);
    696       goto out;
    697     }
    698 
    699   retval = TRUE;
    700 
    701  out:
    702   if (!retval)
    703     _DBUS_ASSERT_ERROR_IS_SET (error);
    704   else
    705     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    706 
    707   if (iter != NULL)
    708     _dbus_directory_close (iter);
    709   _dbus_string_free (&filename);
    710   _dbus_string_free (&full_path);
    711 
    712   return retval;
    713 }
    714 
    715 static dbus_bool_t
    716 populate_environment (BusActivation *activation)
    717 {
    718   DBusString   key;
    719   DBusString   value;
    720   int          i;
    721   char       **environment;
    722   dbus_bool_t  retval = FALSE;
    723 
    724   environment = _dbus_get_environment ();
    725 
    726   if (environment == NULL)
    727     return FALSE;
    728 
    729   if (!_dbus_string_init (&key))
    730     {
    731         dbus_free_string_array (environment);
    732         return FALSE;
    733     }
    734 
    735   if (!_dbus_string_init (&value))
    736     {
    737       _dbus_string_free (&key);
    738       dbus_free_string_array (environment);
    739       return FALSE;
    740     }
    741 
    742   for (i = 0; environment[i] != NULL; i++)
    743     {
    744       if (!_dbus_string_append (&key, environment[i]))
    745         break;
    746 
    747       if (_dbus_string_split_on_byte (&key, '=', &value))
    748         {
    749           char *hash_key, *hash_value;
    750 
    751           if (!_dbus_string_steal_data (&key, &hash_key))
    752             break;
    753 
    754           if (!_dbus_string_steal_data (&value, &hash_value))
    755             break;
    756 
    757           if (!_dbus_hash_table_insert_string (activation->environment,
    758                                                hash_key, hash_value))
    759             break;
    760         }
    761       _dbus_string_set_length (&key, 0);
    762       _dbus_string_set_length (&value, 0);
    763     }
    764 
    765   if (environment[i] != NULL)
    766     goto out;
    767 
    768   retval = TRUE;
    769 out:
    770 
    771   _dbus_string_free (&key);
    772   _dbus_string_free (&value);
    773   dbus_free_string_array (environment);
    774 
    775   return retval;
    776 }
    777 
    778 dbus_bool_t
    779 bus_activation_reload (BusActivation     *activation,
    780                        const DBusString  *address,
    781                        DBusList         **directories,
    782                        DBusError         *error)
    783 {
    784   DBusList      *link;
    785   char          *dir;
    786 
    787   if (activation->server_address != NULL)
    788     dbus_free (activation->server_address);
    789   if (!_dbus_string_copy_data (address, &activation->server_address))
    790     {
    791       BUS_SET_OOM (error);
    792       goto failed;
    793     }
    794 
    795   if (activation->entries != NULL)
    796     _dbus_hash_table_unref (activation->entries);
    797   activation->entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
    798                                              (DBusFreeFunction)bus_activation_entry_unref);
    799   if (activation->entries == NULL)
    800     {
    801       BUS_SET_OOM (error);
    802       goto failed;
    803     }
    804 
    805   if (activation->directories != NULL)
    806     _dbus_hash_table_unref (activation->directories);
    807   activation->directories = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
    808                                                   (DBusFreeFunction)bus_service_directory_unref);
    809 
    810   if (activation->directories == NULL)
    811     {
    812       BUS_SET_OOM (error);
    813       goto failed;
    814     }
    815 
    816   link = _dbus_list_get_first_link (directories);
    817   while (link != NULL)
    818     {
    819       BusServiceDirectory *s_dir;
    820 
    821       dir = _dbus_strdup ((const char *) link->data);
    822       if (!dir)
    823         {
    824           BUS_SET_OOM (error);
    825           goto failed;
    826         }
    827 
    828       s_dir = dbus_new0 (BusServiceDirectory, 1);
    829       if (!s_dir)
    830         {
    831           dbus_free (dir);
    832           BUS_SET_OOM (error);
    833           goto failed;
    834         }
    835 
    836       s_dir->refcount = 1;
    837       s_dir->dir_c = dir;
    838 
    839       s_dir->entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
    840                                              (DBusFreeFunction)bus_activation_entry_unref);
    841 
    842       if (!s_dir->entries)
    843         {
    844           bus_service_directory_unref (s_dir);
    845           BUS_SET_OOM (error);
    846           goto failed;
    847         }
    848 
    849       if (!_dbus_hash_table_insert_string (activation->directories, s_dir->dir_c, s_dir))
    850         {
    851           bus_service_directory_unref (s_dir);
    852           BUS_SET_OOM (error);
    853           goto failed;
    854         }
    855 
    856       /* only fail on OOM, it is ok if we can't read the directory */
    857       if (!update_directory (activation, s_dir, error))
    858         {
    859           if (dbus_error_has_name (error, DBUS_ERROR_NO_MEMORY))
    860             goto failed;
    861           else
    862             dbus_error_free (error);
    863         }
    864 
    865       link = _dbus_list_get_next_link (directories, link);
    866     }
    867 
    868   return TRUE;
    869  failed:
    870   return FALSE;
    871 }
    872 
    873 BusActivation*
    874 bus_activation_new (BusContext        *context,
    875                     const DBusString  *address,
    876                     DBusList         **directories,
    877                     DBusError         *error)
    878 {
    879   BusActivation *activation;
    880   DBusList      *link;
    881   char          *dir;
    882 
    883   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    884 
    885   activation = dbus_new0 (BusActivation, 1);
    886   if (activation == NULL)
    887     {
    888       BUS_SET_OOM (error);
    889       return NULL;
    890     }
    891 
    892   activation->refcount = 1;
    893   activation->context = context;
    894   activation->n_pending_activations = 0;
    895 
    896   if (!bus_activation_reload (activation, address, directories, error))
    897     goto failed;
    898 
    899    /* Initialize this hash table once, we don't want to lose pending
    900    * activations on reload. */
    901   activation->pending_activations = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
    902                                                           (DBusFreeFunction)bus_pending_activation_unref);
    903 
    904   if (activation->pending_activations == NULL)
    905     {
    906       BUS_SET_OOM (error);
    907       goto failed;
    908     }
    909 
    910   activation->environment = _dbus_hash_table_new (DBUS_HASH_STRING,
    911                                                   (DBusFreeFunction) dbus_free,
    912                                                   (DBusFreeFunction) dbus_free);
    913 
    914   if (activation->environment == NULL)
    915     {
    916       BUS_SET_OOM (error);
    917       goto failed;
    918     }
    919 
    920   if (!populate_environment (activation))
    921     {
    922       BUS_SET_OOM (error);
    923       goto failed;
    924     }
    925 
    926   return activation;
    927 
    928  failed:
    929   bus_activation_unref (activation);
    930   return NULL;
    931 }
    932 
    933 BusActivation *
    934 bus_activation_ref (BusActivation *activation)
    935 {
    936   _dbus_assert (activation->refcount > 0);
    937 
    938   activation->refcount += 1;
    939 
    940   return activation;
    941 }
    942 
    943 void
    944 bus_activation_unref (BusActivation *activation)
    945 {
    946   _dbus_assert (activation->refcount > 0);
    947 
    948   activation->refcount -= 1;
    949 
    950   if (activation->refcount > 0)
    951     return;
    952 
    953   dbus_free (activation->server_address);
    954   if (activation->entries)
    955     _dbus_hash_table_unref (activation->entries);
    956   if (activation->pending_activations)
    957     _dbus_hash_table_unref (activation->pending_activations);
    958   if (activation->directories)
    959     _dbus_hash_table_unref (activation->directories);
    960   if (activation->environment)
    961     _dbus_hash_table_unref (activation->environment);
    962 
    963   dbus_free (activation);
    964 }
    965 
    966 static dbus_bool_t
    967 add_bus_environment (BusActivation *activation,
    968                      DBusError     *error)
    969 {
    970   const char *type;
    971 
    972   if (!bus_activation_set_environment_variable (activation,
    973                                                 "DBUS_STARTER_ADDRESS",
    974                                                 activation->server_address,
    975                                                 error))
    976     return FALSE;
    977 
    978   type = bus_context_get_type (activation->context);
    979   if (type != NULL)
    980     {
    981       if (!bus_activation_set_environment_variable (activation,
    982                                                     "DBUS_STARTER_BUS_TYPE", type,
    983                                                     error))
    984         return FALSE;
    985 
    986       if (strcmp (type, "session") == 0)
    987         {
    988           if (!bus_activation_set_environment_variable (activation,
    989                                                         "DBUS_SESSION_BUS_ADDRESS",
    990                                                         activation->server_address,
    991                                                         error))
    992             return FALSE;
    993         }
    994       else if (strcmp (type, "system") == 0)
    995         {
    996           if (!bus_activation_set_environment_variable (activation,
    997                                                         "DBUS_SYSTEM_BUS_ADDRESS",
    998                                                         activation->server_address,
    999                                                         error))
   1000             return FALSE;
   1001         }
   1002     }
   1003 
   1004   return TRUE;
   1005 }
   1006 
   1007 typedef struct
   1008 {
   1009   BusPendingActivation *pending_activation;
   1010   DBusPreallocatedHash *hash_entry;
   1011 } RestorePendingData;
   1012 
   1013 static void
   1014 restore_pending (void *data)
   1015 {
   1016   RestorePendingData *d = data;
   1017 
   1018   _dbus_assert (d->pending_activation != NULL);
   1019   _dbus_assert (d->hash_entry != NULL);
   1020 
   1021   _dbus_verbose ("Restoring pending activation for service %s, has timeout = %d\n",
   1022                  d->pending_activation->service_name,
   1023                  d->pending_activation->timeout_added);
   1024 
   1025   _dbus_hash_table_insert_string_preallocated (d->pending_activation->activation->pending_activations,
   1026                                                d->hash_entry,
   1027                                                d->pending_activation->service_name, d->pending_activation);
   1028 
   1029   bus_pending_activation_ref (d->pending_activation);
   1030 
   1031   d->hash_entry = NULL;
   1032 }
   1033 
   1034 static void
   1035 free_pending_restore_data (void *data)
   1036 {
   1037   RestorePendingData *d = data;
   1038 
   1039   if (d->hash_entry)
   1040     _dbus_hash_table_free_preallocated_entry (d->pending_activation->activation->pending_activations,
   1041                                               d->hash_entry);
   1042 
   1043   bus_pending_activation_unref (d->pending_activation);
   1044 
   1045   dbus_free (d);
   1046 }
   1047 
   1048 static dbus_bool_t
   1049 add_restore_pending_to_transaction (BusTransaction       *transaction,
   1050                                     BusPendingActivation *pending_activation)
   1051 {
   1052   RestorePendingData *d;
   1053 
   1054   d = dbus_new (RestorePendingData, 1);
   1055   if (d == NULL)
   1056     return FALSE;
   1057 
   1058   d->pending_activation = pending_activation;
   1059   d->hash_entry = _dbus_hash_table_preallocate_entry (d->pending_activation->activation->pending_activations);
   1060 
   1061   bus_pending_activation_ref (d->pending_activation);
   1062 
   1063   if (d->hash_entry == NULL ||
   1064       !bus_transaction_add_cancel_hook (transaction, restore_pending, d,
   1065                                         free_pending_restore_data))
   1066     {
   1067       free_pending_restore_data (d);
   1068       return FALSE;
   1069     }
   1070 
   1071   _dbus_verbose ("Saved pending activation to be restored if the transaction fails\n");
   1072 
   1073   return TRUE;
   1074 }
   1075 
   1076 dbus_bool_t
   1077 bus_activation_service_created (BusActivation  *activation,
   1078                                 const char     *service_name,
   1079                                 BusTransaction *transaction,
   1080                                 DBusError      *error)
   1081 {
   1082   BusPendingActivation *pending_activation;
   1083   DBusMessage *message;
   1084   DBusList *link;
   1085 
   1086   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   1087 
   1088   /* Check if it's a pending activation */
   1089   pending_activation = _dbus_hash_table_lookup_string (activation->pending_activations, service_name);
   1090 
   1091   if (!pending_activation)
   1092     return TRUE;
   1093 
   1094   link = _dbus_list_get_first_link (&pending_activation->entries);
   1095   while (link != NULL)
   1096     {
   1097       BusPendingActivationEntry *entry = link->data;
   1098       DBusList *next = _dbus_list_get_next_link (&pending_activation->entries, link);
   1099 
   1100       if (dbus_connection_get_is_connected (entry->connection))
   1101         {
   1102           /* Only send activation replies to regular activation requests. */
   1103           if (!entry->auto_activation)
   1104             {
   1105               dbus_uint32_t result;
   1106 
   1107               message = dbus_message_new_method_return (entry->activation_message);
   1108               if (!message)
   1109                 {
   1110                   BUS_SET_OOM (error);
   1111                   goto error;
   1112                 }
   1113 
   1114               result = DBUS_START_REPLY_SUCCESS;
   1115 
   1116               if (!dbus_message_append_args (message,
   1117                                              DBUS_TYPE_UINT32, &result,
   1118                                              DBUS_TYPE_INVALID))
   1119                 {
   1120                   dbus_message_unref (message);
   1121                   BUS_SET_OOM (error);
   1122                   goto error;
   1123                 }
   1124 
   1125               if (!bus_transaction_send_from_driver (transaction, entry->connection, message))
   1126                 {
   1127                   dbus_message_unref (message);
   1128                   BUS_SET_OOM (error);
   1129                   goto error;
   1130                 }
   1131 
   1132               dbus_message_unref (message);
   1133             }
   1134         }
   1135 
   1136       link = next;
   1137     }
   1138 
   1139   return TRUE;
   1140 
   1141  error:
   1142   return FALSE;
   1143 }
   1144 
   1145 dbus_bool_t
   1146 bus_activation_send_pending_auto_activation_messages (BusActivation  *activation,
   1147                                                       BusService     *service,
   1148                                                       BusTransaction *transaction,
   1149                                                       DBusError      *error)
   1150 {
   1151   BusPendingActivation *pending_activation;
   1152   DBusList *link;
   1153 
   1154   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   1155 
   1156   /* Check if it's a pending activation */
   1157   pending_activation = _dbus_hash_table_lookup_string (activation->pending_activations,
   1158                                                        bus_service_get_name (service));
   1159 
   1160   if (!pending_activation)
   1161     return TRUE;
   1162 
   1163   link = _dbus_list_get_first_link (&pending_activation->entries);
   1164   while (link != NULL)
   1165     {
   1166       BusPendingActivationEntry *entry = link->data;
   1167       DBusList *next = _dbus_list_get_next_link (&pending_activation->entries, link);
   1168 
   1169       if (entry->auto_activation && dbus_connection_get_is_connected (entry->connection))
   1170         {
   1171           DBusConnection *addressed_recipient;
   1172 
   1173           addressed_recipient = bus_service_get_primary_owners_connection (service);
   1174 
   1175           /* Resume dispatching where we left off in bus_dispatch() */
   1176           if (!bus_dispatch_matches (transaction,
   1177                                      entry->connection,
   1178                                      addressed_recipient,
   1179                                      entry->activation_message, error))
   1180             goto error;
   1181         }
   1182 
   1183       link = next;
   1184     }
   1185 
   1186   if (!add_restore_pending_to_transaction (transaction, pending_activation))
   1187     {
   1188       _dbus_verbose ("Could not add cancel hook to transaction to revert removing pending activation\n");
   1189       BUS_SET_OOM (error);
   1190       goto error;
   1191     }
   1192 
   1193   _dbus_hash_table_remove_string (activation->pending_activations, bus_service_get_name (service));
   1194 
   1195   return TRUE;
   1196 
   1197  error:
   1198   return FALSE;
   1199 }
   1200 
   1201 /**
   1202  * FIXME @todo the error messages here would ideally be preallocated
   1203  * so we don't need to allocate memory to send them.
   1204  * Using the usual tactic, prealloc an OOM message, then
   1205  * if we can't alloc the real error send the OOM error instead.
   1206  */
   1207 static dbus_bool_t
   1208 try_send_activation_failure (BusPendingActivation *pending_activation,
   1209                              const DBusError      *how)
   1210 {
   1211   BusActivation *activation;
   1212   DBusList *link;
   1213   BusTransaction *transaction;
   1214 
   1215   activation = pending_activation->activation;
   1216 
   1217   transaction = bus_transaction_new (activation->context);
   1218   if (transaction == NULL)
   1219     return FALSE;
   1220 
   1221   link = _dbus_list_get_first_link (&pending_activation->entries);
   1222   while (link != NULL)
   1223     {
   1224       BusPendingActivationEntry *entry = link->data;
   1225       DBusList *next = _dbus_list_get_next_link (&pending_activation->entries, link);
   1226 
   1227       if (dbus_connection_get_is_connected (entry->connection))
   1228         {
   1229           if (!bus_transaction_send_error_reply (transaction,
   1230                                                  entry->connection,
   1231                                                  how,
   1232                                                  entry->activation_message))
   1233             goto error;
   1234         }
   1235 
   1236       link = next;
   1237     }
   1238 
   1239   bus_transaction_execute_and_free (transaction);
   1240 
   1241   return TRUE;
   1242 
   1243  error:
   1244   if (transaction)
   1245     bus_transaction_cancel_and_free (transaction);
   1246   return FALSE;
   1247 }
   1248 
   1249 /**
   1250  * Free the pending activation and send an error message to all the
   1251  * connections that were waiting for it.
   1252  */
   1253 static void
   1254 pending_activation_failed (BusPendingActivation *pending_activation,
   1255                            const DBusError      *how)
   1256 {
   1257   /* FIXME use preallocated OOM messages instead of bus_wait_for_memory() */
   1258   while (!try_send_activation_failure (pending_activation, how))
   1259     _dbus_wait_for_memory ();
   1260 
   1261   /* Destroy this pending activation */
   1262   _dbus_hash_table_remove_string (pending_activation->activation->pending_activations,
   1263                                   pending_activation->service_name);
   1264 }
   1265 
   1266 /**
   1267  * Depending on the exit code of the helper, set the error accordingly
   1268  */
   1269 static void
   1270 handle_servicehelper_exit_error (int        exit_code,
   1271                                  DBusError *error)
   1272 {
   1273   switch (exit_code)
   1274     {
   1275     case BUS_SPAWN_EXIT_CODE_NO_MEMORY:
   1276       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
   1277                       "Launcher could not run (out of memory)");
   1278       break;
   1279     case BUS_SPAWN_EXIT_CODE_SETUP_FAILED:
   1280       dbus_set_error (error, DBUS_ERROR_SPAWN_SETUP_FAILED,
   1281                       "Failed to setup environment correctly");
   1282       break;
   1283     case BUS_SPAWN_EXIT_CODE_NAME_INVALID:
   1284       dbus_set_error (error, DBUS_ERROR_SPAWN_SERVICE_INVALID,
   1285                       "Bus name is not valid or missing");
   1286       break;
   1287     case BUS_SPAWN_EXIT_CODE_SERVICE_NOT_FOUND:
   1288       dbus_set_error (error, DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND,
   1289                       "Bus name not found in system service directory");
   1290       break;
   1291     case BUS_SPAWN_EXIT_CODE_PERMISSIONS_INVALID:
   1292       dbus_set_error (error, DBUS_ERROR_SPAWN_PERMISSIONS_INVALID,
   1293                       "The permission of the setuid helper is not correct");
   1294       break;
   1295     case BUS_SPAWN_EXIT_CODE_FILE_INVALID:
   1296       dbus_set_error (error, DBUS_ERROR_SPAWN_PERMISSIONS_INVALID,
   1297                       "The service file is incorrect or does not have all required attributes");
   1298       break;
   1299     case BUS_SPAWN_EXIT_CODE_EXEC_FAILED:
   1300       dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
   1301                       "Cannot launch daemon, file not found or permissions invalid");
   1302       break;
   1303     case BUS_SPAWN_EXIT_CODE_INVALID_ARGS:
   1304       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
   1305                       "Invalid arguments to command line");
   1306       break;
   1307     case BUS_SPAWN_EXIT_CODE_CHILD_SIGNALED:
   1308       dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_SIGNALED,
   1309                       "Launched child was signaled, it probably crashed");
   1310       break;
   1311     default:
   1312       dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_EXITED,
   1313                       "Launch helper exited with unknown return code %i", exit_code);
   1314       break;
   1315     }
   1316 }
   1317 
   1318 static dbus_bool_t
   1319 babysitter_watch_callback (DBusWatch     *watch,
   1320                            unsigned int   condition,
   1321                            void          *data)
   1322 {
   1323   BusPendingActivation *pending_activation = data;
   1324   dbus_bool_t retval;
   1325   DBusBabysitter *babysitter;
   1326   dbus_bool_t uses_servicehelper;
   1327 
   1328   babysitter = pending_activation->babysitter;
   1329 
   1330   _dbus_babysitter_ref (babysitter);
   1331 
   1332   retval = dbus_watch_handle (watch, condition);
   1333 
   1334   /* There are two major cases here; are we the system bus or the session?  Here this
   1335    * is distinguished by whether or not we use a setuid helper launcher.  With the launch helper,
   1336    * some process exit codes are meaningful, processed by handle_servicehelper_exit_error.
   1337    *
   1338    * In both cases though, just ignore when a process exits with status 0; it's possible for
   1339    * a program to (misguidedly) "daemonize", and that appears to us as an exit.  This closes a race
   1340    * condition between this code and the child process claiming the bus name.
   1341    */
   1342   uses_servicehelper = bus_context_get_servicehelper (pending_activation->activation->context) != NULL;
   1343 
   1344   /* FIXME this is broken in the same way that
   1345    * connection watches used to be; there should be
   1346    * a separate callback for status change, instead
   1347    * of doing "if we handled a watch status might
   1348    * have changed"
   1349    *
   1350    * Fixing this lets us move dbus_watch_handle
   1351    * calls into dbus-mainloop.c
   1352    */
   1353   if (_dbus_babysitter_get_child_exited (babysitter))
   1354     {
   1355       DBusError error;
   1356       DBusHashIter iter;
   1357       dbus_bool_t activation_failed;
   1358       int exit_code = 0;
   1359 
   1360       dbus_error_init (&error);
   1361 
   1362       _dbus_babysitter_set_child_exit_error (babysitter, &error);
   1363 
   1364       /* Explicitly check for SPAWN_CHILD_EXITED to avoid overwriting an
   1365        * exec error */
   1366       if (dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED)
   1367           && _dbus_babysitter_get_child_exit_status (babysitter, &exit_code))
   1368         {
   1369           activation_failed = exit_code != 0;
   1370 
   1371           dbus_error_free(&error);
   1372 
   1373           if (activation_failed)
   1374             {
   1375               if (uses_servicehelper)
   1376                 handle_servicehelper_exit_error (exit_code, &error);
   1377               else
   1378                 _dbus_babysitter_set_child_exit_error (babysitter, &error);
   1379             }
   1380         }
   1381       else
   1382         {
   1383           activation_failed = TRUE;
   1384         }
   1385 
   1386       if (activation_failed)
   1387         {
   1388           /* Destroy all pending activations with the same exec */
   1389           _dbus_hash_iter_init (pending_activation->activation->pending_activations,
   1390                                 &iter);
   1391           while (_dbus_hash_iter_next (&iter))
   1392             {
   1393               BusPendingActivation *p = _dbus_hash_iter_get_value (&iter);
   1394 
   1395               if (p != pending_activation && strcmp (p->exec, pending_activation->exec) == 0)
   1396                 pending_activation_failed (p, &error);
   1397             }
   1398 
   1399           /* Destroys the pending activation */
   1400           pending_activation_failed (pending_activation, &error);
   1401 
   1402           dbus_error_free (&error);
   1403         }
   1404     }
   1405 
   1406   _dbus_babysitter_unref (babysitter);
   1407 
   1408   return retval;
   1409 }
   1410 
   1411 static dbus_bool_t
   1412 add_babysitter_watch (DBusWatch      *watch,
   1413                       void           *data)
   1414 {
   1415   BusPendingActivation *pending_activation = data;
   1416 
   1417   return _dbus_loop_add_watch (bus_context_get_loop (pending_activation->activation->context),
   1418                                watch, babysitter_watch_callback, pending_activation,
   1419                                NULL);
   1420 }
   1421 
   1422 static void
   1423 remove_babysitter_watch (DBusWatch      *watch,
   1424                          void           *data)
   1425 {
   1426   BusPendingActivation *pending_activation = data;
   1427 
   1428   _dbus_loop_remove_watch (bus_context_get_loop (pending_activation->activation->context),
   1429                            watch, babysitter_watch_callback, pending_activation);
   1430 }
   1431 
   1432 static dbus_bool_t
   1433 pending_activation_timed_out (void *data)
   1434 {
   1435   BusPendingActivation *pending_activation = data;
   1436   DBusError error;
   1437 
   1438   /* Kill the spawned process, since it sucks
   1439    * (not sure this is what we want to do, but
   1440    * may as well try it for now)
   1441    */
   1442   if (pending_activation->babysitter)
   1443     _dbus_babysitter_kill_child (pending_activation->babysitter);
   1444 
   1445   dbus_error_init (&error);
   1446 
   1447   dbus_set_error (&error, DBUS_ERROR_TIMED_OUT,
   1448                   "Activation of %s timed out",
   1449                   pending_activation->service_name);
   1450 
   1451   pending_activation_failed (pending_activation, &error);
   1452 
   1453   dbus_error_free (&error);
   1454 
   1455   return TRUE;
   1456 }
   1457 
   1458 static void
   1459 cancel_pending (void *data)
   1460 {
   1461   BusPendingActivation *pending_activation = data;
   1462 
   1463   _dbus_verbose ("Canceling pending activation of %s\n",
   1464                  pending_activation->service_name);
   1465 
   1466   if (pending_activation->babysitter)
   1467     _dbus_babysitter_kill_child (pending_activation->babysitter);
   1468 
   1469   _dbus_hash_table_remove_string (pending_activation->activation->pending_activations,
   1470                                   pending_activation->service_name);
   1471 }
   1472 
   1473 static void
   1474 free_pending_cancel_data (void *data)
   1475 {
   1476   BusPendingActivation *pending_activation = data;
   1477 
   1478   bus_pending_activation_unref (pending_activation);
   1479 }
   1480 
   1481 static dbus_bool_t
   1482 add_cancel_pending_to_transaction (BusTransaction       *transaction,
   1483                                    BusPendingActivation *pending_activation)
   1484 {
   1485   if (!bus_transaction_add_cancel_hook (transaction, cancel_pending,
   1486                                         pending_activation,
   1487                                         free_pending_cancel_data))
   1488     return FALSE;
   1489 
   1490   bus_pending_activation_ref (pending_activation);
   1491 
   1492   _dbus_verbose ("Saved pending activation to be canceled if the transaction fails\n");
   1493 
   1494   return TRUE;
   1495 }
   1496 
   1497 static dbus_bool_t
   1498 update_service_cache (BusActivation *activation, DBusError *error)
   1499 {
   1500   DBusHashIter iter;
   1501 
   1502   _dbus_hash_iter_init (activation->directories, &iter);
   1503   while (_dbus_hash_iter_next (&iter))
   1504     {
   1505       DBusError tmp_error;
   1506       BusServiceDirectory *s_dir;
   1507 
   1508       s_dir = _dbus_hash_iter_get_value (&iter);
   1509 
   1510       dbus_error_init (&tmp_error);
   1511       if (!update_directory (activation, s_dir, &tmp_error))
   1512         {
   1513           if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
   1514             {
   1515               dbus_move_error (&tmp_error, error);
   1516               return FALSE;
   1517             }
   1518 
   1519           dbus_error_free (&tmp_error);
   1520           continue;
   1521         }
   1522     }
   1523 
   1524   return TRUE;
   1525 }
   1526 
   1527 static BusActivationEntry *
   1528 activation_find_entry (BusActivation *activation,
   1529                        const char    *service_name,
   1530                        DBusError     *error)
   1531 {
   1532   BusActivationEntry *entry;
   1533 
   1534   entry = _dbus_hash_table_lookup_string (activation->entries, service_name);
   1535   if (!entry)
   1536     {
   1537       if (!update_service_cache (activation, error))
   1538         return NULL;
   1539 
   1540       entry = _dbus_hash_table_lookup_string (activation->entries,
   1541                                               service_name);
   1542     }
   1543   else
   1544     {
   1545       BusActivationEntry *updated_entry;
   1546 
   1547       if (!check_service_file (activation, entry, &updated_entry, error))
   1548         return NULL;
   1549 
   1550       entry = updated_entry;
   1551     }
   1552 
   1553   if (!entry)
   1554     {
   1555       dbus_set_error (error, DBUS_ERROR_SERVICE_UNKNOWN,
   1556                       "The name %s was not provided by any .service files",
   1557                       service_name);
   1558       return NULL;
   1559     }
   1560 
   1561   return entry;
   1562 }
   1563 
   1564 static char **
   1565 bus_activation_get_environment (BusActivation *activation)
   1566 {
   1567   char **environment;
   1568   int i, length;
   1569   DBusString entry;
   1570   DBusHashIter iter;
   1571 
   1572   length = _dbus_hash_table_get_n_entries (activation->environment);
   1573 
   1574   environment = dbus_new0 (char *, length + 1);
   1575 
   1576   if (environment == NULL)
   1577     return NULL;
   1578 
   1579   i = 0;
   1580   _dbus_hash_iter_init (activation->environment, &iter);
   1581 
   1582   if (!_dbus_string_init (&entry))
   1583     {
   1584       dbus_free_string_array (environment);
   1585       return NULL;
   1586     }
   1587 
   1588   while (_dbus_hash_iter_next (&iter))
   1589     {
   1590       const char *key, *value;
   1591 
   1592       key = (const char *) _dbus_hash_iter_get_string_key (&iter);
   1593       value = (const char *) _dbus_hash_iter_get_value (&iter);
   1594 
   1595       if (!_dbus_string_append_printf (&entry, "%s=%s", key, value))
   1596         break;
   1597 
   1598       if (!_dbus_string_steal_data (&entry, environment + i))
   1599         break;
   1600       i++;
   1601     }
   1602 
   1603   _dbus_string_free (&entry);
   1604 
   1605   if (i != length)
   1606     {
   1607       dbus_free_string_array (environment);
   1608       environment = NULL;
   1609     }
   1610 
   1611   return environment;
   1612 }
   1613 
   1614 dbus_bool_t
   1615 bus_activation_set_environment_variable (BusActivation     *activation,
   1616                                          const char        *key,
   1617                                          const char        *value,
   1618                                          DBusError         *error)
   1619 {
   1620   char        *hash_key;
   1621   char        *hash_value;
   1622   dbus_bool_t  retval;
   1623 
   1624   retval = FALSE;
   1625   hash_key = NULL;
   1626   hash_value = NULL;
   1627   hash_key = _dbus_strdup (key);
   1628 
   1629   if (hash_key == NULL)
   1630     goto out;
   1631 
   1632   hash_value = _dbus_strdup (value);
   1633 
   1634   if (hash_value == NULL)
   1635     goto out;
   1636 
   1637   if (!_dbus_hash_table_insert_string (activation->environment,
   1638                                        hash_key, hash_value))
   1639     goto out;
   1640 
   1641   retval = TRUE;
   1642 out:
   1643   if (retval == FALSE)
   1644     {
   1645       dbus_free (hash_key);
   1646       dbus_free (hash_value);
   1647       BUS_SET_OOM (error);
   1648     }
   1649 
   1650   return retval;
   1651 }
   1652 
   1653 dbus_bool_t
   1654 bus_activation_activate_service (BusActivation  *activation,
   1655                                  DBusConnection *connection,
   1656                                  BusTransaction *transaction,
   1657                                  dbus_bool_t     auto_activation,
   1658                                  DBusMessage    *activation_message,
   1659                                  const char     *service_name,
   1660                                  DBusError      *error)
   1661 {
   1662   BusActivationEntry *entry;
   1663   BusPendingActivation *pending_activation;
   1664   BusPendingActivationEntry *pending_activation_entry;
   1665   DBusMessage *message;
   1666   DBusString service_str;
   1667   const char *servicehelper;
   1668   char **argv;
   1669   char **envp = NULL;
   1670   int argc;
   1671   dbus_bool_t retval;
   1672   DBusHashIter iter;
   1673   dbus_bool_t activated;
   1674   DBusString command;
   1675 
   1676   activated = TRUE;
   1677 
   1678   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   1679 
   1680   if (activation->n_pending_activations >=
   1681       bus_context_get_max_pending_activations (activation->context))
   1682     {
   1683       dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
   1684                       "The maximum number of pending activations has been reached, activation of %s failed",
   1685                       service_name);
   1686       return FALSE;
   1687     }
   1688 
   1689   entry = activation_find_entry (activation, service_name, error);
   1690   if (!entry)
   1691     return FALSE;
   1692 
   1693   /* Bypass the registry lookup if we're auto-activating, bus_dispatch would not
   1694    * call us if the service is already active.
   1695    */
   1696   if (!auto_activation)
   1697     {
   1698       /* Check if the service is active */
   1699       _dbus_string_init_const (&service_str, service_name);
   1700       if (bus_registry_lookup (bus_context_get_registry (activation->context), &service_str) != NULL)
   1701         {
   1702           dbus_uint32_t result;
   1703 
   1704           _dbus_verbose ("Service \"%s\" is already active\n", service_name);
   1705 
   1706           message = dbus_message_new_method_return (activation_message);
   1707 
   1708           if (!message)
   1709             {
   1710               _dbus_verbose ("No memory to create reply to activate message\n");
   1711               BUS_SET_OOM (error);
   1712               return FALSE;
   1713             }
   1714 
   1715           result = DBUS_START_REPLY_ALREADY_RUNNING;
   1716 
   1717           if (!dbus_message_append_args (message,
   1718                                          DBUS_TYPE_UINT32, &result,
   1719                                          DBUS_TYPE_INVALID))
   1720             {
   1721               _dbus_verbose ("No memory to set args of reply to activate message\n");
   1722               BUS_SET_OOM (error);
   1723               dbus_message_unref (message);
   1724               return FALSE;
   1725             }
   1726 
   1727           retval = bus_transaction_send_from_driver (transaction, connection, message);
   1728           dbus_message_unref (message);
   1729           if (!retval)
   1730             {
   1731               _dbus_verbose ("Failed to send reply\n");
   1732               BUS_SET_OOM (error);
   1733             }
   1734 
   1735           return retval;
   1736         }
   1737     }
   1738 
   1739   pending_activation_entry = dbus_new0 (BusPendingActivationEntry, 1);
   1740   if (!pending_activation_entry)
   1741     {
   1742       _dbus_verbose ("Failed to create pending activation entry\n");
   1743       BUS_SET_OOM (error);
   1744       return FALSE;
   1745     }
   1746 
   1747   pending_activation_entry->auto_activation = auto_activation;
   1748 
   1749   pending_activation_entry->activation_message = activation_message;
   1750   dbus_message_ref (activation_message);
   1751   pending_activation_entry->connection = connection;
   1752   dbus_connection_ref (connection);
   1753 
   1754   /* Check if the service is being activated */
   1755   pending_activation = _dbus_hash_table_lookup_string (activation->pending_activations, service_name);
   1756   if (pending_activation)
   1757     {
   1758       if (!_dbus_list_append (&pending_activation->entries, pending_activation_entry))
   1759         {
   1760           _dbus_verbose ("Failed to append a new entry to pending activation\n");
   1761 
   1762           BUS_SET_OOM (error);
   1763           bus_pending_activation_entry_free (pending_activation_entry);
   1764           return FALSE;
   1765         }
   1766 
   1767       pending_activation->n_entries += 1;
   1768       pending_activation->activation->n_pending_activations += 1;
   1769     }
   1770   else
   1771     {
   1772       pending_activation = dbus_new0 (BusPendingActivation, 1);
   1773       if (!pending_activation)
   1774         {
   1775           _dbus_verbose ("Failed to create pending activation\n");
   1776 
   1777           BUS_SET_OOM (error);
   1778           bus_pending_activation_entry_free (pending_activation_entry);
   1779           return FALSE;
   1780         }
   1781 
   1782       pending_activation->activation = activation;
   1783       pending_activation->refcount = 1;
   1784 
   1785       pending_activation->service_name = _dbus_strdup (service_name);
   1786       if (!pending_activation->service_name)
   1787         {
   1788           _dbus_verbose ("Failed to copy service name for pending activation\n");
   1789 
   1790           BUS_SET_OOM (error);
   1791           bus_pending_activation_unref (pending_activation);
   1792           bus_pending_activation_entry_free (pending_activation_entry);
   1793           return FALSE;
   1794         }
   1795 
   1796       pending_activation->exec = _dbus_strdup (entry->exec);
   1797       if (!pending_activation->exec)
   1798         {
   1799           _dbus_verbose ("Failed to copy service exec for pending activation\n");
   1800           BUS_SET_OOM (error);
   1801           bus_pending_activation_unref (pending_activation);
   1802           bus_pending_activation_entry_free (pending_activation_entry);
   1803           return FALSE;
   1804         }
   1805 
   1806       if (entry->systemd_service)
   1807         {
   1808           pending_activation->systemd_service = _dbus_strdup (entry->systemd_service);
   1809           if (!pending_activation->systemd_service)
   1810             {
   1811               _dbus_verbose ("Failed to copy systemd service for pending activation\n");
   1812               BUS_SET_OOM (error);
   1813               bus_pending_activation_unref (pending_activation);
   1814               bus_pending_activation_entry_free (pending_activation_entry);
   1815               return FALSE;
   1816             }
   1817         }
   1818 
   1819       pending_activation->timeout =
   1820         _dbus_timeout_new (bus_context_get_activation_timeout (activation->context),
   1821                            pending_activation_timed_out,
   1822                            pending_activation,
   1823                            NULL);
   1824       if (!pending_activation->timeout)
   1825         {
   1826           _dbus_verbose ("Failed to create timeout for pending activation\n");
   1827 
   1828           BUS_SET_OOM (error);
   1829           bus_pending_activation_unref (pending_activation);
   1830           bus_pending_activation_entry_free (pending_activation_entry);
   1831           return FALSE;
   1832         }
   1833 
   1834       if (!_dbus_loop_add_timeout (bus_context_get_loop (activation->context),
   1835                                    pending_activation->timeout,
   1836                                    handle_timeout_callback,
   1837                                    pending_activation,
   1838                                    NULL))
   1839         {
   1840           _dbus_verbose ("Failed to add timeout for pending activation\n");
   1841 
   1842           BUS_SET_OOM (error);
   1843           bus_pending_activation_unref (pending_activation);
   1844           bus_pending_activation_entry_free (pending_activation_entry);
   1845           return FALSE;
   1846         }
   1847 
   1848       pending_activation->timeout_added = TRUE;
   1849 
   1850       if (!_dbus_list_append (&pending_activation->entries, pending_activation_entry))
   1851         {
   1852           _dbus_verbose ("Failed to add entry to just-created pending activation\n");
   1853 
   1854           BUS_SET_OOM (error);
   1855           bus_pending_activation_unref (pending_activation);
   1856           bus_pending_activation_entry_free (pending_activation_entry);
   1857           return FALSE;
   1858         }
   1859 
   1860       pending_activation->n_entries += 1;
   1861       pending_activation->activation->n_pending_activations += 1;
   1862 
   1863       activated = FALSE;
   1864       _dbus_hash_iter_init (activation->pending_activations, &iter);
   1865       while (_dbus_hash_iter_next (&iter))
   1866         {
   1867           BusPendingActivation *p = _dbus_hash_iter_get_value (&iter);
   1868 
   1869           if (strcmp (p->exec, entry->exec) == 0)
   1870             {
   1871               activated = TRUE;
   1872               break;
   1873             }
   1874         }
   1875 
   1876       if (!_dbus_hash_table_insert_string (activation->pending_activations,
   1877                                            pending_activation->service_name,
   1878                                            pending_activation))
   1879         {
   1880           _dbus_verbose ("Failed to put pending activation in hash table\n");
   1881 
   1882           BUS_SET_OOM (error);
   1883           bus_pending_activation_unref (pending_activation);
   1884           return FALSE;
   1885         }
   1886     }
   1887 
   1888   if (!add_cancel_pending_to_transaction (transaction, pending_activation))
   1889     {
   1890       _dbus_verbose ("Failed to add pending activation cancel hook to transaction\n");
   1891       BUS_SET_OOM (error);
   1892       _dbus_hash_table_remove_string (activation->pending_activations,
   1893                                       pending_activation->service_name);
   1894 
   1895       return FALSE;
   1896     }
   1897 
   1898   if (activated)
   1899     return TRUE;
   1900 
   1901   if (bus_context_get_systemd_activation (activation->context))
   1902     {
   1903       if (strcmp (service_name, "org.freedesktop.systemd1") == 0)
   1904           /* systemd itself is missing apparently. That can happen
   1905              only during early startup. Let's just wait until systemd
   1906              connects to us and do nothing. */
   1907         return TRUE;
   1908 
   1909       if (entry->systemd_service)
   1910         {
   1911           BusTransaction *activation_transaction;
   1912           DBusString service_string;
   1913           BusService *service;
   1914           BusRegistry *registry;
   1915 
   1916           /* OK, we have a systemd service configured for this entry,
   1917              hence let's enqueue an activation request message. This
   1918              is implemented as a directed signal, not a method call,
   1919              for three reasons: 1) we don't expect a response on
   1920              success, where we just expect a name appearing on the
   1921              bus; 2) at this time the systemd service might not yet
   1922              have connected, so we wouldn't know the message serial at
   1923              this point to set up a pending call; 3) it is ugly if the
   1924              bus suddenly becomes the caller of a remote method. */
   1925 
   1926           message = dbus_message_new_signal (DBUS_PATH_DBUS,
   1927                                              "org.freedesktop.systemd1.Activator",
   1928                                              "ActivationRequest");
   1929           if (!message)
   1930             {
   1931               _dbus_verbose ("No memory to create activation message\n");
   1932               BUS_SET_OOM (error);
   1933               return FALSE;
   1934             }
   1935 
   1936           if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS) ||
   1937               !dbus_message_set_destination (message, "org.freedesktop.systemd1") ||
   1938               !dbus_message_append_args (message,
   1939                                          DBUS_TYPE_STRING, &entry->systemd_service,
   1940                                          DBUS_TYPE_INVALID))
   1941             {
   1942               _dbus_verbose ("No memory to set args of activation message\n");
   1943               dbus_message_unref (message);
   1944               BUS_SET_OOM (error);
   1945               return FALSE;
   1946             }
   1947 
   1948           /* Create our transaction */
   1949           activation_transaction = bus_transaction_new (activation->context);
   1950           if (activation_transaction == NULL)
   1951             {
   1952               _dbus_verbose ("No memory to create activation transaction\n");
   1953               dbus_message_unref (message);
   1954               BUS_SET_OOM (error);
   1955               return FALSE;
   1956             }
   1957 
   1958           /* Check whether systemd is already connected */
   1959           registry = bus_connection_get_registry (connection);
   1960           _dbus_string_init_const (&service_string, "org.freedesktop.systemd1");
   1961           service = bus_registry_lookup (registry, &service_string);
   1962 
   1963           if (service != NULL)
   1964             /* Wonderful, systemd is connected, let's just send the msg */
   1965             retval = bus_dispatch_matches (activation_transaction, NULL, bus_service_get_primary_owners_connection (service),
   1966                                            message, error);
   1967           else
   1968             /* systemd is not around, let's "activate" it. */
   1969             retval = bus_activation_activate_service (activation, connection, activation_transaction, TRUE,
   1970                                                       message, "org.freedesktop.systemd1", error);
   1971 
   1972           dbus_message_unref (message);
   1973 
   1974           if (!retval)
   1975             {
   1976               _DBUS_ASSERT_ERROR_IS_SET (error);
   1977               _dbus_verbose ("failed to send activation message: %s\n", error->name);
   1978               bus_transaction_cancel_and_free (activation_transaction);
   1979               return FALSE;
   1980             }
   1981 
   1982           bus_transaction_execute_and_free (activation_transaction);
   1983           return TRUE;
   1984         }
   1985 
   1986       /* OK, we have no configured systemd service, hence let's
   1987          proceed with traditional activation. */
   1988     }
   1989 
   1990   /* use command as system and session different */
   1991   if (!_dbus_string_init (&command))
   1992     {
   1993       BUS_SET_OOM (error);
   1994       return FALSE;
   1995     }
   1996 
   1997   /* does the bus use a helper? */
   1998   servicehelper = bus_context_get_servicehelper (activation->context);
   1999   if (servicehelper != NULL)
   2000     {
   2001       if (entry->user == NULL)
   2002         {
   2003           _dbus_string_free (&command);
   2004           dbus_set_error (error, DBUS_ERROR_SPAWN_FILE_INVALID,
   2005                           "Cannot do system-bus activation with no user\n");
   2006           return FALSE;
   2007         }
   2008 
   2009       /* join the helper path and the service name */
   2010       if (!_dbus_string_append (&command, servicehelper))
   2011         {
   2012           _dbus_string_free (&command);
   2013           BUS_SET_OOM (error);
   2014           return FALSE;
   2015         }
   2016       if (!_dbus_string_append (&command, " "))
   2017         {
   2018           _dbus_string_free (&command);
   2019           BUS_SET_OOM (error);
   2020           return FALSE;
   2021         }
   2022       if (!_dbus_string_append (&command, service_name))
   2023         {
   2024           _dbus_string_free (&command);
   2025           BUS_SET_OOM (error);
   2026           return FALSE;
   2027         }
   2028     }
   2029   else
   2030     {
   2031       /* the bus does not use a helper, so we can append arguments with the exec line */
   2032       if (!_dbus_string_append (&command, entry->exec))
   2033         {
   2034           _dbus_string_free (&command);
   2035           BUS_SET_OOM (error);
   2036           return FALSE;
   2037         }
   2038     }
   2039 
   2040   /* convert command into arguments */
   2041   if (!_dbus_shell_parse_argv (_dbus_string_get_const_data (&command), &argc, &argv, error))
   2042     {
   2043       _dbus_verbose ("Failed to parse command line: %s\n", entry->exec);
   2044       _DBUS_ASSERT_ERROR_IS_SET (error);
   2045 
   2046       _dbus_hash_table_remove_string (activation->pending_activations,
   2047                                       pending_activation->service_name);
   2048 
   2049       _dbus_string_free (&command);
   2050       return FALSE;
   2051     }
   2052   _dbus_string_free (&command);
   2053 
   2054   if (!add_bus_environment (activation, error))
   2055     {
   2056       _DBUS_ASSERT_ERROR_IS_SET (error);
   2057       dbus_free_string_array (argv);
   2058       return FALSE;
   2059     }
   2060 
   2061   envp = bus_activation_get_environment (activation);
   2062 
   2063   if (envp == NULL)
   2064     {
   2065       BUS_SET_OOM (error);
   2066       dbus_free_string_array (argv);
   2067       return FALSE;
   2068     }
   2069 
   2070   _dbus_verbose ("Spawning %s ...\n", argv[0]);
   2071   if (!_dbus_spawn_async_with_babysitter (&pending_activation->babysitter, argv,
   2072                                           envp,
   2073                                           NULL, activation,
   2074                                           error))
   2075     {
   2076       _dbus_verbose ("Failed to spawn child\n");
   2077       _DBUS_ASSERT_ERROR_IS_SET (error);
   2078       dbus_free_string_array (argv);
   2079       dbus_free_string_array (envp);
   2080 
   2081       return FALSE;
   2082     }
   2083 
   2084   dbus_free_string_array (argv);
   2085   envp = NULL;
   2086 
   2087   _dbus_assert (pending_activation->babysitter != NULL);
   2088 
   2089   if (!_dbus_babysitter_set_watch_functions (pending_activation->babysitter,
   2090                                              add_babysitter_watch,
   2091                                              remove_babysitter_watch,
   2092                                              NULL,
   2093                                              pending_activation,
   2094                                              NULL))
   2095     {
   2096       BUS_SET_OOM (error);
   2097       _dbus_verbose ("Failed to set babysitter watch functions\n");
   2098       return FALSE;
   2099     }
   2100 
   2101   return TRUE;
   2102 }
   2103 
   2104 dbus_bool_t
   2105 bus_activation_list_services (BusActivation *activation,
   2106 			      char        ***listp,
   2107 			      int           *array_len)
   2108 {
   2109   int i, j, len;
   2110   char **retval;
   2111   DBusHashIter iter;
   2112 
   2113   len = _dbus_hash_table_get_n_entries (activation->entries);
   2114   retval = dbus_new (char *, len + 1);
   2115 
   2116   if (retval == NULL)
   2117     return FALSE;
   2118 
   2119   _dbus_hash_iter_init (activation->entries, &iter);
   2120   i = 0;
   2121   while (_dbus_hash_iter_next (&iter))
   2122     {
   2123       BusActivationEntry *entry = _dbus_hash_iter_get_value (&iter);
   2124 
   2125       retval[i] = _dbus_strdup (entry->name);
   2126       if (retval[i] == NULL)
   2127 	goto error;
   2128 
   2129       i++;
   2130     }
   2131 
   2132   retval[i] = NULL;
   2133 
   2134   if (array_len)
   2135     *array_len = len;
   2136 
   2137   *listp = retval;
   2138   return TRUE;
   2139 
   2140  error:
   2141   for (j = 0; j < i; j++)
   2142     dbus_free (retval[i]);
   2143   dbus_free (retval);
   2144 
   2145   return FALSE;
   2146 }
   2147 
   2148 dbus_bool_t
   2149 dbus_activation_systemd_failure (BusActivation *activation,
   2150                                  DBusMessage   *message)
   2151 {
   2152   DBusError error;
   2153   const char *code, *str, *unit = NULL;
   2154 
   2155   dbus_error_init(&error);
   2156 
   2157   /* This is called whenever the systemd activator sent us a
   2158      response. We'll invalidate all pending activations that match the
   2159      unit name. */
   2160 
   2161   if (dbus_message_get_args (message, &error,
   2162                              DBUS_TYPE_STRING, &unit,
   2163                              DBUS_TYPE_STRING, &code,
   2164                              DBUS_TYPE_STRING, &str,
   2165                              DBUS_TYPE_INVALID))
   2166     dbus_set_error(&error, code, str);
   2167 
   2168   if (unit)
   2169     {
   2170       DBusHashIter iter;
   2171 
   2172       _dbus_hash_iter_init (activation->pending_activations,
   2173                             &iter);
   2174 
   2175       while (_dbus_hash_iter_next (&iter))
   2176         {
   2177           BusPendingActivation *p = _dbus_hash_iter_get_value (&iter);
   2178 
   2179           if (p->systemd_service && strcmp (p->systemd_service, unit) == 0)
   2180             pending_activation_failed(p, &error);
   2181         }
   2182     }
   2183 
   2184   dbus_error_free(&error);
   2185 
   2186   return TRUE;
   2187 }
   2188 
   2189 #ifdef DBUS_BUILD_TESTS
   2190 
   2191 #include <stdio.h>
   2192 
   2193 #define SERVICE_NAME_1 "MyService1"
   2194 #define SERVICE_NAME_2 "MyService2"
   2195 #define SERVICE_NAME_3 "MyService3"
   2196 
   2197 #define SERVICE_FILE_1 "service-1.service"
   2198 #define SERVICE_FILE_2 "service-2.service"
   2199 #define SERVICE_FILE_3 "service-3.service"
   2200 
   2201 static dbus_bool_t
   2202 test_create_service_file (DBusString *dir,
   2203                           const char *filename,
   2204                           const char *name,
   2205                           const char *exec)
   2206 {
   2207   DBusString  file_name, full_path;
   2208   FILE        *file;
   2209   dbus_bool_t  ret_val;
   2210 
   2211   ret_val = TRUE;
   2212   _dbus_string_init_const (&file_name, filename);
   2213 
   2214   if (!_dbus_string_init (&full_path))
   2215     return FALSE;
   2216 
   2217   if (!_dbus_string_append (&full_path, _dbus_string_get_const_data (dir)) ||
   2218       !_dbus_concat_dir_and_file (&full_path, &file_name))
   2219     {
   2220       ret_val = FALSE;
   2221       goto out;
   2222     }
   2223 
   2224   file = fopen (_dbus_string_get_const_data (&full_path), "w");
   2225   if (!file)
   2226     {
   2227       ret_val = FALSE;
   2228       goto out;
   2229     }
   2230 
   2231   fprintf (file, "[D-BUS Service]\nName=%s\nExec=%s\n", name, exec);
   2232   fclose (file);
   2233 
   2234 out:
   2235   _dbus_string_free (&full_path);
   2236   return ret_val;
   2237 }
   2238 
   2239 static dbus_bool_t
   2240 test_remove_service_file (DBusString *dir, const char *filename)
   2241 {
   2242   DBusString  file_name, full_path;
   2243   dbus_bool_t ret_val;
   2244 
   2245   ret_val = TRUE;
   2246 
   2247   _dbus_string_init_const (&file_name, filename);
   2248 
   2249   if (!_dbus_string_init (&full_path))
   2250     return FALSE;
   2251 
   2252   if (!_dbus_string_append (&full_path, _dbus_string_get_const_data (dir)) ||
   2253       !_dbus_concat_dir_and_file (&full_path, &file_name))
   2254     {
   2255       ret_val = FALSE;
   2256       goto out;
   2257     }
   2258 
   2259   if (!_dbus_delete_file (&full_path, NULL))
   2260     {
   2261       ret_val = FALSE;
   2262       goto out;
   2263     }
   2264 
   2265 out:
   2266   _dbus_string_free (&full_path);
   2267   return ret_val;
   2268 }
   2269 
   2270 static dbus_bool_t
   2271 test_remove_directory (DBusString *dir)
   2272 {
   2273   DBusDirIter *iter;
   2274   DBusString   filename, full_path;
   2275   dbus_bool_t  ret_val;
   2276 
   2277   ret_val = TRUE;
   2278 
   2279   if (!_dbus_string_init (&filename))
   2280     return FALSE;
   2281 
   2282   if (!_dbus_string_init (&full_path))
   2283     {
   2284       _dbus_string_free (&filename);
   2285       return FALSE;
   2286     }
   2287 
   2288   iter = _dbus_directory_open (dir, NULL);
   2289   if (iter == NULL)
   2290     {
   2291       ret_val = FALSE;
   2292       goto out;
   2293     }
   2294 
   2295   while (_dbus_directory_get_next_file (iter, &filename, NULL))
   2296     {
   2297       if (!test_remove_service_file (dir, _dbus_string_get_const_data (&filename)))
   2298         {
   2299           ret_val = FALSE;
   2300           goto out;
   2301         }
   2302     }
   2303   _dbus_directory_close (iter);
   2304 
   2305   if (!_dbus_delete_directory (dir, NULL))
   2306     {
   2307       ret_val = FALSE;
   2308       goto out;
   2309     }
   2310 
   2311 out:
   2312   _dbus_string_free (&filename);
   2313   _dbus_string_free (&full_path);
   2314 
   2315   return ret_val;
   2316 }
   2317 
   2318 static dbus_bool_t
   2319 init_service_reload_test (DBusString *dir)
   2320 {
   2321   DBusStat stat_buf;
   2322 
   2323   if (!_dbus_stat (dir, &stat_buf, NULL))
   2324     {
   2325       if (!_dbus_create_directory (dir, NULL))
   2326         return FALSE;
   2327     }
   2328   else
   2329     {
   2330       if (!test_remove_directory (dir))
   2331         return FALSE;
   2332 
   2333       if (!_dbus_create_directory (dir, NULL))
   2334         return FALSE;
   2335     }
   2336 
   2337   /* Create one initial file */
   2338   if (!test_create_service_file (dir, SERVICE_FILE_1, SERVICE_NAME_1, "exec-1"))
   2339     return FALSE;
   2340 
   2341   return TRUE;
   2342 }
   2343 
   2344 static dbus_bool_t
   2345 cleanup_service_reload_test (DBusString *dir)
   2346 {
   2347   if (!test_remove_directory (dir))
   2348     return FALSE;
   2349 
   2350   return TRUE;
   2351 }
   2352 
   2353 typedef struct
   2354 {
   2355   BusActivation *activation;
   2356   const char    *service_name;
   2357   dbus_bool_t    expecting_find;
   2358 } CheckData;
   2359 
   2360 static dbus_bool_t
   2361 check_func (void *data)
   2362 {
   2363   CheckData          *d;
   2364   BusActivationEntry *entry;
   2365   DBusError           error;
   2366   dbus_bool_t         ret_val;
   2367 
   2368   ret_val = TRUE;
   2369   d = data;
   2370 
   2371   dbus_error_init (&error);
   2372 
   2373   entry = activation_find_entry (d->activation, d->service_name, &error);
   2374   if (entry == NULL)
   2375     {
   2376       if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
   2377         {
   2378           ret_val = TRUE;
   2379         }
   2380       else
   2381         {
   2382           if (d->expecting_find)
   2383             ret_val = FALSE;
   2384         }
   2385 
   2386       dbus_error_free (&error);
   2387     }
   2388   else
   2389     {
   2390       if (!d->expecting_find)
   2391         ret_val = FALSE;
   2392     }
   2393 
   2394   return ret_val;
   2395 }
   2396 
   2397 static dbus_bool_t
   2398 do_test (const char *description, dbus_bool_t oom_test, CheckData *data)
   2399 {
   2400   dbus_bool_t err;
   2401 
   2402   if (oom_test)
   2403     err = !_dbus_test_oom_handling (description, check_func, data);
   2404   else
   2405     err = !check_func (data);
   2406 
   2407   if (err)
   2408     _dbus_assert_not_reached ("Test failed");
   2409 
   2410   return TRUE;
   2411 }
   2412 
   2413 static dbus_bool_t
   2414 do_service_reload_test (DBusString *dir, dbus_bool_t oom_test)
   2415 {
   2416   BusActivation *activation;
   2417   DBusString     address;
   2418   DBusList      *directories;
   2419   CheckData      d;
   2420 
   2421   directories = NULL;
   2422   _dbus_string_init_const (&address, "");
   2423 
   2424   if (!_dbus_list_append (&directories, _dbus_string_get_data (dir)))
   2425     return FALSE;
   2426 
   2427   activation = bus_activation_new (NULL, &address, &directories, NULL);
   2428   if (!activation)
   2429     return FALSE;
   2430 
   2431   d.activation = activation;
   2432 
   2433   /* Check for existing service file */
   2434   d.expecting_find = TRUE;
   2435   d.service_name = SERVICE_NAME_1;
   2436 
   2437   if (!do_test ("Existing service file", oom_test, &d))
   2438     return FALSE;
   2439 
   2440   /* Check for non-existing service file */
   2441   d.expecting_find = FALSE;
   2442   d.service_name = SERVICE_NAME_3;
   2443 
   2444   if (!do_test ("Nonexisting service file", oom_test, &d))
   2445     return FALSE;
   2446 
   2447   /* Check for added service file */
   2448   if (!test_create_service_file (dir, SERVICE_FILE_2, SERVICE_NAME_2, "exec-2"))
   2449     return FALSE;
   2450 
   2451   d.expecting_find = TRUE;
   2452   d.service_name = SERVICE_NAME_2;
   2453 
   2454   if (!do_test ("Added service file", oom_test, &d))
   2455     return FALSE;
   2456 
   2457   /* Check for removed service file */
   2458   if (!test_remove_service_file (dir, SERVICE_FILE_2))
   2459     return FALSE;
   2460 
   2461   d.expecting_find = FALSE;
   2462   d.service_name = SERVICE_FILE_2;
   2463 
   2464   if (!do_test ("Removed service file", oom_test, &d))
   2465     return FALSE;
   2466 
   2467   /* Check for updated service file */
   2468 
   2469   _dbus_sleep_milliseconds (1000); /* Sleep a second to make sure the mtime is updated */
   2470 
   2471   if (!test_create_service_file (dir, SERVICE_FILE_1, SERVICE_NAME_3, "exec-3"))
   2472     return FALSE;
   2473 
   2474   d.expecting_find = TRUE;
   2475   d.service_name = SERVICE_NAME_3;
   2476 
   2477   if (!do_test ("Updated service file, part 1", oom_test, &d))
   2478     return FALSE;
   2479 
   2480   d.expecting_find = FALSE;
   2481   d.service_name = SERVICE_NAME_1;
   2482 
   2483   if (!do_test ("Updated service file, part 2", oom_test, &d))
   2484     return FALSE;
   2485 
   2486   bus_activation_unref (activation);
   2487   _dbus_list_clear (&directories);
   2488 
   2489   return TRUE;
   2490 }
   2491 
   2492 dbus_bool_t
   2493 bus_activation_service_reload_test (const DBusString *test_data_dir)
   2494 {
   2495   DBusString directory;
   2496 
   2497   if (!_dbus_string_init (&directory))
   2498     return FALSE;
   2499 
   2500   if (!_dbus_string_append (&directory, _dbus_get_tmpdir()))
   2501     return FALSE;
   2502 
   2503   if (!_dbus_string_append (&directory, "/dbus-reload-test-") ||
   2504       !_dbus_generate_random_ascii (&directory, 6))
   2505      {
   2506        return FALSE;
   2507      }
   2508 
   2509   /* Do normal tests */
   2510   if (!init_service_reload_test (&directory))
   2511     _dbus_assert_not_reached ("could not initiate service reload test");
   2512 
   2513   if (!do_service_reload_test (&directory, FALSE))
   2514     ; /* Do nothing? */
   2515 
   2516   /* Do OOM tests */
   2517   if (!init_service_reload_test (&directory))
   2518     _dbus_assert_not_reached ("could not initiate service reload test");
   2519 
   2520   if (!do_service_reload_test (&directory, TRUE))
   2521     ; /* Do nothing? */
   2522 
   2523   /* Cleanup test directory */
   2524   if (!cleanup_service_reload_test (&directory))
   2525     return FALSE;
   2526 
   2527   _dbus_string_free (&directory);
   2528 
   2529   return TRUE;
   2530 }
   2531 
   2532 #endif /* DBUS_BUILD_TESTS */
   2533