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