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