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 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 842912Sartem running_processes_remove_device (HalDevice *device) 852912Sartem { 862912Sartem g_hash_table_foreach_remove (running_processes, rprd_foreach, device); 872912Sartem } 882912Sartem 892912Sartem void 902912Sartem runner_device_finalized (HalDevice *device) 912912Sartem { 922912Sartem running_processes_remove_device (device); 932912Sartem } 942912Sartem 952912Sartem 962912Sartem static DBusHandlerResult 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 1342912Sartem runner_server_unregister_handler (DBusConnection *connection, void *user_data) 1352912Sartem { 1362912Sartem HAL_INFO (("unregistered")); 1372912Sartem } 1382912Sartem 1392912Sartem 1402912Sartem static void 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 1662912Sartem runner_died(GPid pid, gint status, gpointer data) { 1672912Sartem g_spawn_close_pid (pid); 1682912Sartem DIE (("Runner died")); 1692912Sartem } 1702912Sartem 1712912Sartem gboolean 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 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 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 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 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 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 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 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 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 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 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 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 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