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