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