diff options
Diffstat (limited to 'bus/activation.c')
-rw-r--r-- | bus/activation.c | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/bus/activation.c b/bus/activation.c new file mode 100644 index 00000000..7f7dd438 --- /dev/null +++ b/bus/activation.c @@ -0,0 +1,216 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* activation.c Activation of services + * + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 1.2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include "activation.h" +#include "desktop-file.h" +#include "utils.h" +#include <dbus/dbus-internals.h> +#include <dbus/dbus-hash.h> +#include <sys/types.h> +#include <dirent.h> +#include <errno.h> + +#define DBUS_SERVICE_SECTION "D-BUS Service" +#define DBUS_SERVICE_NAME "Name" +#define DBUS_SERVICE_EXEC "Exec" + +static DBusHashTable *activation_entries = NULL; + +typedef struct +{ + char *name; + char *exec; +} BusActivationEntry; + +static void +bus_activation_entry_free (BusActivationEntry *entry) +{ + if (!entry) + return; + + dbus_free (entry->name); + dbus_free (entry->exec); +} + +static dbus_bool_t +add_desktop_file_entry (BusDesktopFile *desktop_file) +{ + char *name, *exec; + BusActivationEntry *entry; + + if (!bus_desktop_file_get_string (desktop_file, + DBUS_SERVICE_SECTION, + DBUS_SERVICE_NAME, + &name)) + { + _dbus_verbose ("No \""DBUS_SERVICE_NAME"\" key in .service file\n"); + return FALSE; + } + + if (!bus_desktop_file_get_string (desktop_file, + DBUS_SERVICE_SECTION, + DBUS_SERVICE_EXEC, + &exec)) + { + _dbus_verbose ("No \""DBUS_SERVICE_EXEC"\" key in .service file\n"); + + dbus_free (name); + return FALSE; + } + + if (_dbus_hash_table_lookup_string (activation_entries, name)) + { + _dbus_verbose ("Service %s already exists in activation entry list\n", name); + dbus_free (name); + dbus_free (exec); + + return FALSE; + } + + BUS_HANDLE_OOM (entry = dbus_malloc0 (sizeof (BusActivationEntry))); + entry->name = name; + entry->exec = exec; + + BUS_HANDLE_OOM (_dbus_hash_table_insert_string (activation_entries, entry->name, entry)); + + _dbus_verbose ("Added \"%s\" to list of services\n", entry->name); + + return TRUE; +} + +static void +load_directory (const char *directory) +{ + DBusDirIter *iter; + DBusString dir, filename; + DBusResultCode result; + + _dbus_string_init_const (&dir, directory); + + iter = _dbus_directory_open (&dir, &result); + if (iter == NULL) + { + _dbus_verbose ("Failed to open directory %s: &s\n", directory, + result); + return; + } + + BUS_HANDLE_OOM (_dbus_string_init (&filename, _DBUS_INT_MAX)); + + /* Now read the files */ + while (_dbus_directory_get_next_file (iter, &filename, &result)) + { + DBusString full_path; + BusDesktopFile *desktop_file; + DBusError error; + + if (!_dbus_string_ends_with_c_str (&filename, ".service")) + { + const char *filename_c; + _dbus_string_get_const_data (&filename, &filename_c); + _dbus_verbose ("Skipping non-.service file %s\n", + filename_c); + continue; + } + + BUS_HANDLE_OOM (_dbus_string_init (&full_path, _DBUS_INT_MAX)); + BUS_HANDLE_OOM (_dbus_string_append (&full_path, directory)); + + BUS_HANDLE_OOM (_dbus_concat_dir_and_file (&full_path, &filename)); + + desktop_file = bus_desktop_file_load (&full_path, &error); + + if (!desktop_file) + { + const char *full_path_c; + + _dbus_string_get_const_data (&full_path, &full_path_c); + + _dbus_verbose ("Could not load %s: %s\n", full_path_c, + error.message); + dbus_error_free (&error); + _dbus_string_free (&full_path); + continue; + } + + if (!add_desktop_file_entry (desktop_file)) + { + const char *full_path_c; + + _dbus_string_get_const_data (&full_path, &full_path_c); + + _dbus_verbose ("Could not add %s to activation entry list.\n", full_path_c); + } + + bus_desktop_file_free (desktop_file); + _dbus_string_free (&full_path); + } + +#if 0 + while ((directory_entry = readdir (directory_handle))) + { + DBusString path, filename; + BusDesktopFile *desktop_file; + DBusError error; + const char *filename_c; + + + _dbus_string_init_const (&filename, directory_entry->d_name); + + + _dbus_string_get_const_data (&path, &filename_c); + + if (!desktop_file) + { + _dbus_verbose ("Could not load %s: %s\n", filename_c, + error.message); + dbus_error_free (&error); + _dbus_string_free (&path); + continue; + } + + if (!add_desktop_file_entry (desktop_file)) + { + _dbus_verbose ("Could not add %s to activation entry list.\n", filename_c); + } + } +#endif +} + + +void +bus_activation_init (const char **directories) +{ + int i; + + BUS_HANDLE_OOM (activation_entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, + (DBusFreeFunction)bus_activation_entry_free)); + + i = 0; + + /* Load service files */ + while (directories[i] != NULL) + { + load_directory (directories[i]); + i++; + } +} |