12912Sartem /***************************************************************************
22912Sartem * CVSID: $Id$
32912Sartem *
42912Sartem * hald_runner.c - Interface to the hal runner helper daemon
52912Sartem *
62912Sartem * Copyright (C) 2006 Sjoerd Simons, <sjoerd@luon.net>
72912Sartem *
82912Sartem * Licensed under the Academic Free License version 2.1
92912Sartem *
102912Sartem * This program is free software; you can redistribute it and/or modify
112912Sartem * it under the terms of the GNU General Public License as published by
122912Sartem * the Free Software Foundation; either version 2 of the License, or
132912Sartem * (at your option) any later version.
142912Sartem *
152912Sartem * This program is distributed in the hope that it will be useful,
162912Sartem * but WITHOUT ANY WARRANTY; without even the implied warranty of
172912Sartem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
182912Sartem * GNU General Public License for more details.
192912Sartem *
202912Sartem * You should have received a copy of the GNU General Public License
212912Sartem * along with this program; if not, write to the Free Software
222912Sartem * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
232912Sartem *
242912Sartem **************************************************************************/
252912Sartem
262912Sartem #ifdef HAVE_CONFIG_H
272912Sartem # include <config.h>
282912Sartem #endif
292912Sartem
302912Sartem #include <sys/utsname.h>
312912Sartem #include <stdio.h>
322912Sartem
332912Sartem #include <glib.h>
342912Sartem #include <dbus/dbus.h>
352912Sartem #include <dbus/dbus-glib-lowlevel.h>
362912Sartem
372912Sartem #include "hald.h"
382912Sartem #include "util.h"
392912Sartem #include "logger.h"
402912Sartem #include "hald_dbus.h"
412912Sartem #include "hald_runner.h"
422912Sartem
432912Sartem typedef struct {
442912Sartem HalDevice *d;
452912Sartem HalRunTerminatedCB cb;
462912Sartem gpointer data1;
472912Sartem gpointer data2;
482912Sartem } HelperData;
492912Sartem
502912Sartem #define DBUS_SERVER_ADDRESS "unix:tmpdir=" HALD_SOCKET_DIR
512912Sartem
522912Sartem static DBusConnection *runner_connection = NULL;
532912Sartem
542912Sartem typedef struct
552912Sartem {
562912Sartem GPid pid;
572912Sartem HalDevice *device;
582912Sartem HalRunTerminatedCB cb;
592912Sartem gpointer data1;
602912Sartem gpointer data2;
612912Sartem } RunningProcess;
622912Sartem
632912Sartem /* mapping from PID to RunningProcess */
642912Sartem static GHashTable *running_processes;
652912Sartem
662912Sartem static gboolean
rprd_foreach(gpointer key,gpointer value,gpointer user_data)672912Sartem rprd_foreach (gpointer key,
682912Sartem gpointer value,
692912Sartem gpointer user_data)
702912Sartem {
712912Sartem gboolean remove = FALSE;
722912Sartem RunningProcess *rp = value;
732912Sartem HalDevice *device = user_data;
742912Sartem
752912Sartem if (rp->device == device) {
762912Sartem remove = TRUE;
772912Sartem g_free (rp);
782912Sartem }
792912Sartem
802912Sartem return remove;
812912Sartem }
822912Sartem
832912Sartem static void
running_processes_remove_device(HalDevice * device)842912Sartem running_processes_remove_device (HalDevice *device)
852912Sartem {
862912Sartem g_hash_table_foreach_remove (running_processes, rprd_foreach, device);
872912Sartem }
882912Sartem
892912Sartem void
runner_device_finalized(HalDevice * device)902912Sartem runner_device_finalized (HalDevice *device)
912912Sartem {
922912Sartem running_processes_remove_device (device);
932912Sartem }
942912Sartem
952912Sartem
962912Sartem static DBusHandlerResult
runner_server_message_handler(DBusConnection * connection,DBusMessage * message,void * user_data)972912Sartem runner_server_message_handler (DBusConnection *connection,
982912Sartem DBusMessage *message,
992912Sartem void *user_data)
1002912Sartem {
1012912Sartem
1022912Sartem /*HAL_INFO (("runner_server_message_handler: destination=%s obj_path=%s interface=%s method=%s",
1032912Sartem dbus_message_get_destination (message),
1042912Sartem dbus_message_get_path (message),
1052912Sartem dbus_message_get_interface (message),
1062912Sartem dbus_message_get_member (message)));*/
1072912Sartem if (dbus_message_is_signal (message,
1082912Sartem "org.freedesktop.HalRunner",
1092912Sartem "StartedProcessExited")) {
1102912Sartem dbus_uint64_t dpid;
1112912Sartem DBusError error;
1122912Sartem dbus_error_init (&error);
1132912Sartem if (dbus_message_get_args (message, &error,
1142912Sartem DBUS_TYPE_INT64, &dpid,
1152912Sartem DBUS_TYPE_INVALID)) {
1162912Sartem RunningProcess *rp;
1172912Sartem GPid pid;
1182912Sartem
1192912Sartem pid = (GPid) dpid;
1202912Sartem
1212912Sartem /*HAL_INFO (("Previously started process with pid %d exited", pid));*/
1222912Sartem rp = g_hash_table_lookup (running_processes, (gpointer) pid);
1232912Sartem if (rp != NULL) {
1242912Sartem rp->cb (rp->device, 0, 0, NULL, rp->data1, rp->data2);
1252912Sartem g_hash_table_remove (running_processes, (gpointer) pid);
1262912Sartem g_free (rp);
1272912Sartem }
1282912Sartem }
1292912Sartem }
1302912Sartem return DBUS_HANDLER_RESULT_HANDLED;
1312912Sartem }
1322912Sartem
1332912Sartem static void
runner_server_unregister_handler(DBusConnection * connection,void * user_data)1342912Sartem runner_server_unregister_handler (DBusConnection *connection, void *user_data)
1352912Sartem {
1362912Sartem HAL_INFO (("unregistered"));
1372912Sartem }
1382912Sartem
1392912Sartem
1402912Sartem static void
handle_connection(DBusServer * server,DBusConnection * new_connection,void * data)1412912Sartem handle_connection(DBusServer *server,
1422912Sartem DBusConnection *new_connection,
1432912Sartem void *data)
1442912Sartem {
1452912Sartem
1462912Sartem if (runner_connection == NULL) {
1472912Sartem DBusObjectPathVTable vtable = { &runner_server_unregister_handler,
1482912Sartem &runner_server_message_handler,
1492912Sartem NULL, NULL, NULL, NULL};
1502912Sartem
1512912Sartem runner_connection = new_connection;
1522912Sartem dbus_connection_ref (new_connection);
1532912Sartem dbus_connection_setup_with_g_main (new_connection, NULL);
1542912Sartem
1552912Sartem dbus_connection_register_fallback (new_connection,
1562912Sartem "/org/freedesktop",
1572912Sartem &vtable,
1582912Sartem NULL);
1592912Sartem
1602912Sartem /* dbus_server_unref(server); */
1612912Sartem
1622912Sartem }
1632912Sartem }
1642912Sartem
1652912Sartem static void
runner_died(GPid pid,gint status,gpointer data)1662912Sartem runner_died(GPid pid, gint status, gpointer data) {
1672912Sartem g_spawn_close_pid (pid);
1682912Sartem DIE (("Runner died"));
1692912Sartem }
1702912Sartem
1712912Sartem gboolean
hald_runner_start_runner(void)1722912Sartem hald_runner_start_runner(void)
1732912Sartem {
1742912Sartem DBusServer *server = NULL;
1752912Sartem DBusError err;
1762912Sartem GError *error = NULL;
1772912Sartem GPid pid;
1782912Sartem char *argv[] = { NULL, NULL};
1792912Sartem char *env[] = { NULL, NULL, NULL, NULL};
1802912Sartem const char *hald_runner_path;
1812912Sartem char *server_addr;
1822912Sartem
1832912Sartem running_processes = g_hash_table_new (g_direct_hash, g_direct_equal);
1842912Sartem
1852912Sartem dbus_error_init(&err);
1862912Sartem server = dbus_server_listen(DBUS_SERVER_ADDRESS, &err);
1872912Sartem if (server == NULL) {
1882912Sartem HAL_ERROR (("Cannot create D-BUS server for the runner"));
1892912Sartem goto error;
1902912Sartem }
1912912Sartem
1922912Sartem dbus_server_setup_with_g_main(server, NULL);
1932912Sartem dbus_server_set_new_connection_function(server, handle_connection,
1942912Sartem NULL, NULL);
1952912Sartem
1962912Sartem
1972912Sartem argv[0] = "hald-runner";
1982912Sartem server_addr = dbus_server_get_address (server);
1992912Sartem env[0] = g_strdup_printf("HALD_RUNNER_DBUS_ADDRESS=%s", server_addr);
2002912Sartem dbus_free (server_addr);
2012912Sartem hald_runner_path = g_getenv("HALD_RUNNER_PATH");
2022912Sartem if (hald_runner_path != NULL) {
2032912Sartem env[1] = g_strdup_printf ("PATH=%s:" PACKAGE_LIBEXEC_DIR ":" PACKAGE_SCRIPT_DIR ":" PACKAGE_BIN_DIR, hald_runner_path);
2042912Sartem } else {
2052912Sartem env[1] = g_strdup_printf ("PATH=" PACKAGE_LIBEXEC_DIR ":" PACKAGE_SCRIPT_DIR ":" PACKAGE_BIN_DIR);
2062912Sartem }
2072912Sartem
2082912Sartem /*env[2] = "DBUS_VERBOSE=1";*/
2092912Sartem
2102912Sartem
2112912Sartem if (!g_spawn_async(NULL, argv, env, G_SPAWN_DO_NOT_REAP_CHILD|G_SPAWN_SEARCH_PATH,
2122912Sartem NULL, NULL, &pid, &error)) {
2132912Sartem HAL_ERROR (("Could not spawn runner : '%s'", error->message));
2142912Sartem g_error_free (error);
2152912Sartem goto error;
2162912Sartem }
2172912Sartem g_free(env[0]);
2182912Sartem g_free(env[1]);
2192912Sartem
2202912Sartem HAL_INFO (("Runner has pid %d", pid));
2212912Sartem
2222912Sartem g_child_watch_add(pid, runner_died, NULL);
2232912Sartem while (runner_connection == NULL) {
2242912Sartem /* Wait for the runner */
2252912Sartem g_main_context_iteration(NULL, TRUE);
2262912Sartem }
2272912Sartem return TRUE;
2282912Sartem
2292912Sartem error:
2302912Sartem if (server != NULL)
2312912Sartem dbus_server_unref(server);
2322912Sartem return FALSE;
2332912Sartem }
2342912Sartem
2352912Sartem static gboolean
add_property_to_msg(HalDevice * device,HalProperty * property,gpointer user_data)2362912Sartem add_property_to_msg (HalDevice *device, HalProperty *property,
2372912Sartem gpointer user_data)
2382912Sartem {
2392912Sartem char *prop_upper, *value;
2402912Sartem char *c;
2412912Sartem gchar *env;
2422912Sartem DBusMessageIter *iter = (DBusMessageIter *)user_data;
2432912Sartem
2442912Sartem prop_upper = g_ascii_strup (hal_property_get_key (property), -1);
2452912Sartem
2462912Sartem /* periods aren't valid in the environment, so replace them with
2472912Sartem * underscores. */
2482912Sartem for (c = prop_upper; *c; c++) {
2492912Sartem if (*c == '.')
2502912Sartem *c = '_';
2512912Sartem }
2522912Sartem
2532912Sartem value = hal_property_to_string (property);
2542912Sartem env = g_strdup_printf ("HAL_PROP_%s=%s", prop_upper, value);
2552912Sartem dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &env);
2562912Sartem
2572912Sartem g_free (env);
2582912Sartem g_free (value);
2592912Sartem g_free (prop_upper);
2602912Sartem
2612912Sartem return TRUE;
2622912Sartem }
2632912Sartem
2642912Sartem static void
add_env(DBusMessageIter * iter,const gchar * key,const gchar * value)2652912Sartem add_env(DBusMessageIter *iter, const gchar *key, const gchar *value) {
2662912Sartem gchar *env;
2672912Sartem env = g_strdup_printf ("%s=%s", key, value);
2682912Sartem dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &env);
2692912Sartem g_free(env);
2702912Sartem }
2712912Sartem
2722912Sartem static void
add_basic_env(DBusMessageIter * iter,const gchar * udi)2732912Sartem add_basic_env(DBusMessageIter *iter, const gchar *udi) {
2742912Sartem struct utsname un;
2752912Sartem char *server_addr;
2762912Sartem
2772912Sartem if (hald_is_verbose) {
2782912Sartem add_env(iter, "HALD_VERBOSE", "1");
2792912Sartem }
2802912Sartem if (hald_is_initialising) {
2812912Sartem add_env(iter, "HALD_STARTUP", "1");
2822912Sartem }
2832912Sartem if (hald_use_syslog) {
2842912Sartem add_env(iter, "HALD_USE_SYSLOG", "1");
2852912Sartem }
2862912Sartem add_env(iter, "UDI", udi);
2872912Sartem server_addr = hald_dbus_local_server_addr();
2882912Sartem add_env(iter, "HALD_DIRECT_ADDR", server_addr);
2892912Sartem dbus_free (server_addr);
2902912Sartem #ifdef HAVE_POLKIT
2912912Sartem add_env(iter, "HAVE_POLKIT", "1");
2922912Sartem #endif
2932912Sartem
2946573Sphitran if (uname(&un) >= 0) {
2952912Sartem char *sysname;
2962912Sartem
2972912Sartem sysname = g_ascii_strdown(un.sysname, -1);
2982912Sartem add_env(iter, "HALD_UNAME_S", sysname);
2992912Sartem g_free(sysname);
3002912Sartem }
3012912Sartem }
3022912Sartem
3032912Sartem static void
add_extra_env(DBusMessageIter * iter,gchar ** env)3042912Sartem add_extra_env(DBusMessageIter *iter, gchar **env) {
3052912Sartem int i;
3062912Sartem if (env != NULL) for (i = 0; env[i] != NULL; i++) {
3072912Sartem dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &env[i]);
3082912Sartem }
3092912Sartem }
3102912Sartem
3112912Sartem static gboolean
add_command(DBusMessageIter * iter,const gchar * command_line)3122912Sartem add_command(DBusMessageIter *iter, const gchar *command_line) {
3132912Sartem gint argc;
3142912Sartem gint x;
3152912Sartem char **argv;
3162912Sartem GError *err = NULL;
3172912Sartem DBusMessageIter array_iter;
3182912Sartem
3192912Sartem if (!g_shell_parse_argv(command_line, &argc, &argv, &err)) {
3202912Sartem HAL_ERROR (("Error parsing commandline '%s': %s",
3212912Sartem command_line, err->message));
3222912Sartem g_error_free (err);
3232912Sartem return FALSE;
3242912Sartem }
3252912Sartem if (!dbus_message_iter_open_container(iter,
3262912Sartem DBUS_TYPE_ARRAY,
3272912Sartem DBUS_TYPE_STRING_AS_STRING,
3282912Sartem &array_iter))
3292912Sartem DIE (("No memory"));
3302912Sartem for (x = 0 ; argv[x] != NULL; x++) {
3312912Sartem dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &argv[x]);
3322912Sartem }
3332912Sartem dbus_message_iter_close_container(iter, &array_iter);
3342912Sartem
3352912Sartem g_strfreev(argv);
3362912Sartem return TRUE;
3372912Sartem }
3382912Sartem
3392912Sartem static gboolean
add_first_part(DBusMessageIter * iter,HalDevice * device,const gchar * command_line,char ** extra_env)3402912Sartem add_first_part(DBusMessageIter *iter, HalDevice *device,
3412912Sartem const gchar *command_line, char **extra_env) {
3422912Sartem DBusMessageIter array_iter;
3432912Sartem const char *udi;
3442912Sartem
3452912Sartem udi = hal_device_get_udi(device);
3462912Sartem dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &udi);
3472912Sartem
3482912Sartem dbus_message_iter_open_container(iter,
3492912Sartem DBUS_TYPE_ARRAY,
3502912Sartem DBUS_TYPE_STRING_AS_STRING,
3512912Sartem &array_iter);
3522912Sartem hal_device_property_foreach (device, add_property_to_msg, &array_iter);
3532912Sartem add_basic_env(&array_iter, udi);
3542912Sartem add_extra_env(&array_iter, extra_env);
3552912Sartem dbus_message_iter_close_container(iter, &array_iter);
3562912Sartem
3572912Sartem if (!add_command(iter, command_line)) {
3582912Sartem return FALSE;
3592912Sartem }
3602912Sartem return TRUE;
3612912Sartem }
3622912Sartem
3632912Sartem /* Start a helper, returns true on a successfull start */
3642912Sartem gboolean
hald_runner_start(HalDevice * device,const gchar * command_line,char ** extra_env,HalRunTerminatedCB cb,gpointer data1,gpointer data2)3652912Sartem hald_runner_start (HalDevice *device, const gchar *command_line, char **extra_env,
3662912Sartem HalRunTerminatedCB cb, gpointer data1, gpointer data2)
3672912Sartem {
3682912Sartem DBusMessage *msg, *reply;
3692912Sartem DBusError err;
3702912Sartem DBusMessageIter iter;
3712912Sartem
3722912Sartem dbus_error_init(&err);
3732912Sartem msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
3742912Sartem "/org/freedesktop/HalRunner",
3752912Sartem "org.freedesktop.HalRunner",
3762912Sartem "Start");
3772912Sartem if (msg == NULL)
3782912Sartem DIE(("No memory"));
3792912Sartem dbus_message_iter_init_append(msg, &iter);
3802912Sartem
3812912Sartem if (!add_first_part(&iter, device, command_line, extra_env))
3822912Sartem goto error;
3832912Sartem
3842912Sartem /* Wait for the reply, should be almost instantanious */
3852912Sartem reply =
3862912Sartem dbus_connection_send_with_reply_and_block(runner_connection,
3872912Sartem msg, -1, &err);
3882912Sartem if (reply) {
3892912Sartem gboolean ret =
3902912Sartem (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN);
3912912Sartem
3922912Sartem if (ret) {
3932912Sartem dbus_int64_t pid_from_runner;
3942912Sartem if (dbus_message_get_args (reply, &err,
3952912Sartem DBUS_TYPE_INT64, &pid_from_runner,
3962912Sartem DBUS_TYPE_INVALID)) {
3972912Sartem if (cb != NULL) {
3982912Sartem RunningProcess *rp;
3992912Sartem rp = g_new0 (RunningProcess, 1);
4002912Sartem rp->pid = (GPid) pid_from_runner;
4012912Sartem rp->cb = cb;
4022912Sartem rp->device = device;
4032912Sartem rp->data1 = data1;
4042912Sartem rp->data2 = data2;
4052912Sartem
4062912Sartem g_hash_table_insert (running_processes, (gpointer) rp->pid, rp);
4072912Sartem }
4082912Sartem } else {
4092912Sartem HAL_ERROR (("Error extracting out_pid from runner's Start()"));
4102912Sartem }
4112912Sartem }
4122912Sartem
4132912Sartem dbus_message_unref(reply);
4142912Sartem dbus_message_unref(msg);
4152912Sartem return ret;
4162912Sartem }
4172912Sartem
4182912Sartem error:
4192912Sartem dbus_message_unref(msg);
4202912Sartem return FALSE;
4212912Sartem }
4222912Sartem
4232912Sartem static void
call_notify(DBusPendingCall * pending,void * user_data)4242912Sartem call_notify(DBusPendingCall *pending, void *user_data)
4252912Sartem {
4262912Sartem HelperData *hb = (HelperData *)user_data;
4272912Sartem dbus_uint32_t exitt = HALD_RUN_SUCCESS;
4282912Sartem dbus_int32_t return_code = 0;
4292912Sartem DBusMessage *m;
4302912Sartem GArray *error = NULL;
4312912Sartem DBusMessageIter iter;
4322912Sartem
4332912Sartem error = g_array_new(TRUE, FALSE, sizeof(char *));
4342912Sartem
4352912Sartem m = dbus_pending_call_steal_reply(pending);
4362912Sartem if (dbus_message_get_type(m) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
4372912Sartem goto malformed;
4382912Sartem
4392912Sartem if (!dbus_message_iter_init(m, &iter) ||
4402912Sartem dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
4412912Sartem goto malformed;
4422912Sartem dbus_message_iter_get_basic(&iter, &exitt);
4432912Sartem
4442912Sartem if (!dbus_message_iter_next(&iter) ||
4452912Sartem dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32)
4462912Sartem goto malformed;
4472912Sartem dbus_message_iter_get_basic(&iter, &return_code);
4482912Sartem
4492912Sartem while (dbus_message_iter_next(&iter) &&
4502912Sartem dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) {
4512912Sartem const char *value;
4522912Sartem dbus_message_iter_get_basic(&iter, &value);
4532912Sartem g_array_append_vals(error, &value, 1);
4542912Sartem }
4552912Sartem
4562912Sartem hb->cb(hb->d, exitt, return_code,
4572912Sartem (gchar **)error->data, hb->data1, hb->data2);
4582912Sartem
4592912Sartem g_object_unref (hb->d);
4602912Sartem
4612912Sartem dbus_message_unref(m);
4622912Sartem dbus_pending_call_unref (pending);
4632912Sartem g_array_free(error, TRUE);
4642912Sartem
4652912Sartem return;
4662912Sartem malformed:
4672912Sartem /* Send a Fail callback on malformed messages */
4682912Sartem HAL_ERROR (("Malformed or unexpected reply message"));
4692912Sartem hb->cb(hb->d, HALD_RUN_FAILED, return_code, NULL, hb->data1, hb->data2);
4702912Sartem
4712912Sartem g_object_unref (hb->d);
4722912Sartem
4732912Sartem dbus_message_unref(m);
4742912Sartem dbus_pending_call_unref (pending);
4752912Sartem g_array_free(error, TRUE);
4762912Sartem }
4772912Sartem
4782912Sartem /* Run a helper program using the commandline, with input as infomation on
4792912Sartem * stdin */
4802912Sartem void
hald_runner_run_method(HalDevice * device,const gchar * command_line,char ** extra_env,gchar * input,gboolean error_on_stderr,guint32 timeout,HalRunTerminatedCB cb,gpointer data1,gpointer data2)4812912Sartem hald_runner_run_method(HalDevice *device,
4822912Sartem const gchar *command_line, char **extra_env,
4832912Sartem gchar *input, gboolean error_on_stderr,
4842912Sartem guint32 timeout,
4852912Sartem HalRunTerminatedCB cb,
4862912Sartem gpointer data1, gpointer data2) {
4872912Sartem DBusMessage *msg;
4882912Sartem DBusMessageIter iter;
4892912Sartem DBusPendingCall *call;
4902912Sartem HelperData *hd = NULL;
4912912Sartem msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
4922912Sartem "/org/freedesktop/HalRunner",
4932912Sartem "org.freedesktop.HalRunner",
4942912Sartem "Run");
4952912Sartem if (msg == NULL)
4962912Sartem DIE(("No memory"));
4972912Sartem dbus_message_iter_init_append(msg, &iter);
4982912Sartem
4992912Sartem if (!add_first_part(&iter, device, command_line, extra_env))
5002912Sartem goto error;
5012912Sartem
5022912Sartem dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &input);
5032912Sartem dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &error_on_stderr);
5042912Sartem dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &timeout);
5052912Sartem
5062912Sartem if (!dbus_connection_send_with_reply(runner_connection,
5072912Sartem msg, &call, INT_MAX))
5082912Sartem DIE (("No memory"));
5092912Sartem
51010658SXiao-Lin.Zhang@Sun.COM /* the connection was disconnected */
51110658SXiao-Lin.Zhang@Sun.COM if (call == NULL)
51210658SXiao-Lin.Zhang@Sun.COM goto error;
51310658SXiao-Lin.Zhang@Sun.COM
5142912Sartem hd = malloc(sizeof(HelperData));
5152912Sartem hd->d = device;
5162912Sartem hd->cb = cb;
5172912Sartem hd->data1 = data1;
5182912Sartem hd->data2 = data2;
5192912Sartem
5202912Sartem g_object_ref (device);
5212912Sartem
5222912Sartem dbus_pending_call_set_notify(call, call_notify, hd, free);
5232912Sartem dbus_message_unref(msg);
5242912Sartem return;
5252912Sartem error:
5262912Sartem dbus_message_unref(msg);
5272912Sartem free(hd);
5282912Sartem cb(device, HALD_RUN_FAILED, 0, NULL, data1, data2);
5292912Sartem }
5302912Sartem
5312912Sartem void
hald_runner_run(HalDevice * device,const gchar * command_line,char ** extra_env,guint timeout,HalRunTerminatedCB cb,gpointer data1,gpointer data2)5322912Sartem hald_runner_run(HalDevice *device,
5332912Sartem const gchar *command_line, char **extra_env,
5342912Sartem guint timeout,
5352912Sartem HalRunTerminatedCB cb,
5362912Sartem gpointer data1, gpointer data2) {
5372912Sartem hald_runner_run_method(device, command_line, extra_env,
5382912Sartem "", FALSE, timeout, cb, data1, data2);
5392912Sartem }
5402912Sartem
5412912Sartem
5422912Sartem
5432912Sartem void
hald_runner_kill_device(HalDevice * device)5442912Sartem hald_runner_kill_device(HalDevice *device) {
5452912Sartem DBusMessage *msg, *reply;
5462912Sartem DBusError err;
5472912Sartem DBusMessageIter iter;
5482912Sartem const char *udi;
5492912Sartem
5502912Sartem running_processes_remove_device (device);
5512912Sartem
5522912Sartem msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
5532912Sartem "/org/freedesktop/HalRunner",
5542912Sartem "org.freedesktop.HalRunner",
5552912Sartem "Kill");
5562912Sartem if (msg == NULL)
5572912Sartem DIE(("No memory"));
5582912Sartem dbus_message_iter_init_append(msg, &iter);
5592912Sartem udi = hal_device_get_udi(device);
5602912Sartem dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &udi);
5612912Sartem
5622912Sartem /* Wait for the reply, should be almost instantanious */
5632912Sartem dbus_error_init(&err);
5642912Sartem reply =
5652912Sartem dbus_connection_send_with_reply_and_block(runner_connection, msg, -1, &err);
5662912Sartem if (reply) {
5672912Sartem dbus_message_unref(reply);
5682912Sartem }
5692912Sartem
5702912Sartem dbus_message_unref(msg);
5712912Sartem }
5722912Sartem
5732912Sartem void
hald_runner_kill_all(HalDevice * device)5742912Sartem hald_runner_kill_all(HalDevice *device) {
5752912Sartem DBusMessage *msg, *reply;
5762912Sartem DBusError err;
577*12395SLin.Guo@Sun.COM
578*12395SLin.Guo@Sun.COM /* hald_runner has not yet started, just return */
579*12395SLin.Guo@Sun.COM if (runner_connection == NULL) {
580*12395SLin.Guo@Sun.COM return;
581*12395SLin.Guo@Sun.COM }
5822912Sartem
5832912Sartem running_processes_remove_device (device);
5842912Sartem
5852912Sartem msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
5862912Sartem "/org/freedesktop/HalRunner",
5872912Sartem "org.freedesktop.HalRunner",
5882912Sartem "KillAll");
5892912Sartem if (msg == NULL)
5902912Sartem DIE(("No memory"));
5912912Sartem
5922912Sartem /* Wait for the reply, should be almost instantanious */
5932912Sartem dbus_error_init(&err);
5942912Sartem reply =
5952912Sartem dbus_connection_send_with_reply_and_block(runner_connection,
5962912Sartem msg, -1, &err);
5972912Sartem if (reply) {
5982912Sartem dbus_message_unref(reply);
5992912Sartem }
6002912Sartem
6012912Sartem dbus_message_unref(msg);
6022912Sartem }
603