1*2912Sartem /*************************************************************************** 2*2912Sartem * CVSID: $Id$ 3*2912Sartem * 4*2912Sartem * hald_runner.c - Interface to the hal runner helper daemon 5*2912Sartem * 6*2912Sartem * Copyright (C) 2006 Sjoerd Simons, <sjoerd@luon.net> 7*2912Sartem * 8*2912Sartem * Licensed under the Academic Free License version 2.1 9*2912Sartem * 10*2912Sartem * This program is free software; you can redistribute it and/or modify 11*2912Sartem * it under the terms of the GNU General Public License as published by 12*2912Sartem * the Free Software Foundation; either version 2 of the License, or 13*2912Sartem * (at your option) any later version. 14*2912Sartem * 15*2912Sartem * This program is distributed in the hope that it will be useful, 16*2912Sartem * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*2912Sartem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*2912Sartem * GNU General Public License for more details. 19*2912Sartem * 20*2912Sartem * You should have received a copy of the GNU General Public License 21*2912Sartem * along with this program; if not, write to the Free Software 22*2912Sartem * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23*2912Sartem * 24*2912Sartem **************************************************************************/ 25*2912Sartem 26*2912Sartem #ifdef HAVE_CONFIG_H 27*2912Sartem # include <config.h> 28*2912Sartem #endif 29*2912Sartem 30*2912Sartem #include <sys/utsname.h> 31*2912Sartem #include <stdio.h> 32*2912Sartem 33*2912Sartem #include <glib.h> 34*2912Sartem #include <dbus/dbus.h> 35*2912Sartem #include <dbus/dbus-glib-lowlevel.h> 36*2912Sartem 37*2912Sartem #include "hald.h" 38*2912Sartem #include "util.h" 39*2912Sartem #include "logger.h" 40*2912Sartem #include "hald_dbus.h" 41*2912Sartem #include "hald_runner.h" 42*2912Sartem 43*2912Sartem typedef struct { 44*2912Sartem HalDevice *d; 45*2912Sartem HalRunTerminatedCB cb; 46*2912Sartem gpointer data1; 47*2912Sartem gpointer data2; 48*2912Sartem } HelperData; 49*2912Sartem 50*2912Sartem #define DBUS_SERVER_ADDRESS "unix:tmpdir=" HALD_SOCKET_DIR 51*2912Sartem 52*2912Sartem static DBusConnection *runner_connection = NULL; 53*2912Sartem 54*2912Sartem typedef struct 55*2912Sartem { 56*2912Sartem GPid pid; 57*2912Sartem HalDevice *device; 58*2912Sartem HalRunTerminatedCB cb; 59*2912Sartem gpointer data1; 60*2912Sartem gpointer data2; 61*2912Sartem } RunningProcess; 62*2912Sartem 63*2912Sartem /* mapping from PID to RunningProcess */ 64*2912Sartem static GHashTable *running_processes; 65*2912Sartem 66*2912Sartem static gboolean 67*2912Sartem rprd_foreach (gpointer key, 68*2912Sartem gpointer value, 69*2912Sartem gpointer user_data) 70*2912Sartem { 71*2912Sartem gboolean remove = FALSE; 72*2912Sartem RunningProcess *rp = value; 73*2912Sartem HalDevice *device = user_data; 74*2912Sartem 75*2912Sartem if (rp->device == device) { 76*2912Sartem remove = TRUE; 77*2912Sartem g_free (rp); 78*2912Sartem } 79*2912Sartem 80*2912Sartem return remove; 81*2912Sartem } 82*2912Sartem 83*2912Sartem static void 84*2912Sartem running_processes_remove_device (HalDevice *device) 85*2912Sartem { 86*2912Sartem g_hash_table_foreach_remove (running_processes, rprd_foreach, device); 87*2912Sartem } 88*2912Sartem 89*2912Sartem void 90*2912Sartem runner_device_finalized (HalDevice *device) 91*2912Sartem { 92*2912Sartem running_processes_remove_device (device); 93*2912Sartem } 94*2912Sartem 95*2912Sartem 96*2912Sartem static DBusHandlerResult 97*2912Sartem runner_server_message_handler (DBusConnection *connection, 98*2912Sartem DBusMessage *message, 99*2912Sartem void *user_data) 100*2912Sartem { 101*2912Sartem 102*2912Sartem /*HAL_INFO (("runner_server_message_handler: destination=%s obj_path=%s interface=%s method=%s", 103*2912Sartem dbus_message_get_destination (message), 104*2912Sartem dbus_message_get_path (message), 105*2912Sartem dbus_message_get_interface (message), 106*2912Sartem dbus_message_get_member (message)));*/ 107*2912Sartem if (dbus_message_is_signal (message, 108*2912Sartem "org.freedesktop.HalRunner", 109*2912Sartem "StartedProcessExited")) { 110*2912Sartem dbus_uint64_t dpid; 111*2912Sartem DBusError error; 112*2912Sartem dbus_error_init (&error); 113*2912Sartem if (dbus_message_get_args (message, &error, 114*2912Sartem DBUS_TYPE_INT64, &dpid, 115*2912Sartem DBUS_TYPE_INVALID)) { 116*2912Sartem RunningProcess *rp; 117*2912Sartem GPid pid; 118*2912Sartem 119*2912Sartem pid = (GPid) dpid; 120*2912Sartem 121*2912Sartem /*HAL_INFO (("Previously started process with pid %d exited", pid));*/ 122*2912Sartem rp = g_hash_table_lookup (running_processes, (gpointer) pid); 123*2912Sartem if (rp != NULL) { 124*2912Sartem rp->cb (rp->device, 0, 0, NULL, rp->data1, rp->data2); 125*2912Sartem g_hash_table_remove (running_processes, (gpointer) pid); 126*2912Sartem g_free (rp); 127*2912Sartem } 128*2912Sartem } 129*2912Sartem } 130*2912Sartem return DBUS_HANDLER_RESULT_HANDLED; 131*2912Sartem } 132*2912Sartem 133*2912Sartem static void 134*2912Sartem runner_server_unregister_handler (DBusConnection *connection, void *user_data) 135*2912Sartem { 136*2912Sartem HAL_INFO (("unregistered")); 137*2912Sartem } 138*2912Sartem 139*2912Sartem 140*2912Sartem static void 141*2912Sartem handle_connection(DBusServer *server, 142*2912Sartem DBusConnection *new_connection, 143*2912Sartem void *data) 144*2912Sartem { 145*2912Sartem 146*2912Sartem if (runner_connection == NULL) { 147*2912Sartem DBusObjectPathVTable vtable = { &runner_server_unregister_handler, 148*2912Sartem &runner_server_message_handler, 149*2912Sartem NULL, NULL, NULL, NULL}; 150*2912Sartem 151*2912Sartem runner_connection = new_connection; 152*2912Sartem dbus_connection_ref (new_connection); 153*2912Sartem dbus_connection_setup_with_g_main (new_connection, NULL); 154*2912Sartem 155*2912Sartem dbus_connection_register_fallback (new_connection, 156*2912Sartem "/org/freedesktop", 157*2912Sartem &vtable, 158*2912Sartem NULL); 159*2912Sartem 160*2912Sartem /* dbus_server_unref(server); */ 161*2912Sartem 162*2912Sartem } 163*2912Sartem } 164*2912Sartem 165*2912Sartem static void 166*2912Sartem runner_died(GPid pid, gint status, gpointer data) { 167*2912Sartem g_spawn_close_pid (pid); 168*2912Sartem DIE (("Runner died")); 169*2912Sartem } 170*2912Sartem 171*2912Sartem gboolean 172*2912Sartem hald_runner_start_runner(void) 173*2912Sartem { 174*2912Sartem DBusServer *server = NULL; 175*2912Sartem DBusError err; 176*2912Sartem GError *error = NULL; 177*2912Sartem GPid pid; 178*2912Sartem char *argv[] = { NULL, NULL}; 179*2912Sartem char *env[] = { NULL, NULL, NULL, NULL}; 180*2912Sartem const char *hald_runner_path; 181*2912Sartem char *server_addr; 182*2912Sartem 183*2912Sartem running_processes = g_hash_table_new (g_direct_hash, g_direct_equal); 184*2912Sartem 185*2912Sartem dbus_error_init(&err); 186*2912Sartem server = dbus_server_listen(DBUS_SERVER_ADDRESS, &err); 187*2912Sartem if (server == NULL) { 188*2912Sartem HAL_ERROR (("Cannot create D-BUS server for the runner")); 189*2912Sartem goto error; 190*2912Sartem } 191*2912Sartem 192*2912Sartem dbus_server_setup_with_g_main(server, NULL); 193*2912Sartem dbus_server_set_new_connection_function(server, handle_connection, 194*2912Sartem NULL, NULL); 195*2912Sartem 196*2912Sartem 197*2912Sartem argv[0] = "hald-runner"; 198*2912Sartem server_addr = dbus_server_get_address (server); 199*2912Sartem env[0] = g_strdup_printf("HALD_RUNNER_DBUS_ADDRESS=%s", server_addr); 200*2912Sartem dbus_free (server_addr); 201*2912Sartem hald_runner_path = g_getenv("HALD_RUNNER_PATH"); 202*2912Sartem if (hald_runner_path != NULL) { 203*2912Sartem env[1] = g_strdup_printf ("PATH=%s:" PACKAGE_LIBEXEC_DIR ":" PACKAGE_SCRIPT_DIR ":" PACKAGE_BIN_DIR, hald_runner_path); 204*2912Sartem } else { 205*2912Sartem env[1] = g_strdup_printf ("PATH=" PACKAGE_LIBEXEC_DIR ":" PACKAGE_SCRIPT_DIR ":" PACKAGE_BIN_DIR); 206*2912Sartem } 207*2912Sartem 208*2912Sartem /*env[2] = "DBUS_VERBOSE=1";*/ 209*2912Sartem 210*2912Sartem 211*2912Sartem if (!g_spawn_async(NULL, argv, env, G_SPAWN_DO_NOT_REAP_CHILD|G_SPAWN_SEARCH_PATH, 212*2912Sartem NULL, NULL, &pid, &error)) { 213*2912Sartem HAL_ERROR (("Could not spawn runner : '%s'", error->message)); 214*2912Sartem g_error_free (error); 215*2912Sartem goto error; 216*2912Sartem } 217*2912Sartem g_free(env[0]); 218*2912Sartem g_free(env[1]); 219*2912Sartem 220*2912Sartem HAL_INFO (("Runner has pid %d", pid)); 221*2912Sartem 222*2912Sartem g_child_watch_add(pid, runner_died, NULL); 223*2912Sartem while (runner_connection == NULL) { 224*2912Sartem /* Wait for the runner */ 225*2912Sartem g_main_context_iteration(NULL, TRUE); 226*2912Sartem } 227*2912Sartem return TRUE; 228*2912Sartem 229*2912Sartem error: 230*2912Sartem if (server != NULL) 231*2912Sartem dbus_server_unref(server); 232*2912Sartem return FALSE; 233*2912Sartem } 234*2912Sartem 235*2912Sartem static gboolean 236*2912Sartem add_property_to_msg (HalDevice *device, HalProperty *property, 237*2912Sartem gpointer user_data) 238*2912Sartem { 239*2912Sartem char *prop_upper, *value; 240*2912Sartem char *c; 241*2912Sartem gchar *env; 242*2912Sartem DBusMessageIter *iter = (DBusMessageIter *)user_data; 243*2912Sartem 244*2912Sartem prop_upper = g_ascii_strup (hal_property_get_key (property), -1); 245*2912Sartem 246*2912Sartem /* periods aren't valid in the environment, so replace them with 247*2912Sartem * underscores. */ 248*2912Sartem for (c = prop_upper; *c; c++) { 249*2912Sartem if (*c == '.') 250*2912Sartem *c = '_'; 251*2912Sartem } 252*2912Sartem 253*2912Sartem value = hal_property_to_string (property); 254*2912Sartem env = g_strdup_printf ("HAL_PROP_%s=%s", prop_upper, value); 255*2912Sartem dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &env); 256*2912Sartem 257*2912Sartem g_free (env); 258*2912Sartem g_free (value); 259*2912Sartem g_free (prop_upper); 260*2912Sartem 261*2912Sartem return TRUE; 262*2912Sartem } 263*2912Sartem 264*2912Sartem static void 265*2912Sartem add_env(DBusMessageIter *iter, const gchar *key, const gchar *value) { 266*2912Sartem gchar *env; 267*2912Sartem env = g_strdup_printf ("%s=%s", key, value); 268*2912Sartem dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &env); 269*2912Sartem g_free(env); 270*2912Sartem } 271*2912Sartem 272*2912Sartem static void 273*2912Sartem add_basic_env(DBusMessageIter *iter, const gchar *udi) { 274*2912Sartem struct utsname un; 275*2912Sartem char *server_addr; 276*2912Sartem 277*2912Sartem if (hald_is_verbose) { 278*2912Sartem add_env(iter, "HALD_VERBOSE", "1"); 279*2912Sartem } 280*2912Sartem if (hald_is_initialising) { 281*2912Sartem add_env(iter, "HALD_STARTUP", "1"); 282*2912Sartem } 283*2912Sartem if (hald_use_syslog) { 284*2912Sartem add_env(iter, "HALD_USE_SYSLOG", "1"); 285*2912Sartem } 286*2912Sartem add_env(iter, "UDI", udi); 287*2912Sartem server_addr = hald_dbus_local_server_addr(); 288*2912Sartem add_env(iter, "HALD_DIRECT_ADDR", server_addr); 289*2912Sartem dbus_free (server_addr); 290*2912Sartem #ifdef HAVE_POLKIT 291*2912Sartem add_env(iter, "HAVE_POLKIT", "1"); 292*2912Sartem #endif 293*2912Sartem 294*2912Sartem if (uname(&un) == 0) { 295*2912Sartem char *sysname; 296*2912Sartem 297*2912Sartem sysname = g_ascii_strdown(un.sysname, -1); 298*2912Sartem add_env(iter, "HALD_UNAME_S", sysname); 299*2912Sartem g_free(sysname); 300*2912Sartem } 301*2912Sartem } 302*2912Sartem 303*2912Sartem static void 304*2912Sartem add_extra_env(DBusMessageIter *iter, gchar **env) { 305*2912Sartem int i; 306*2912Sartem if (env != NULL) for (i = 0; env[i] != NULL; i++) { 307*2912Sartem dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &env[i]); 308*2912Sartem } 309*2912Sartem } 310*2912Sartem 311*2912Sartem static gboolean 312*2912Sartem add_command(DBusMessageIter *iter, const gchar *command_line) { 313*2912Sartem gint argc; 314*2912Sartem gint x; 315*2912Sartem char **argv; 316*2912Sartem GError *err = NULL; 317*2912Sartem DBusMessageIter array_iter; 318*2912Sartem 319*2912Sartem if (!g_shell_parse_argv(command_line, &argc, &argv, &err)) { 320*2912Sartem HAL_ERROR (("Error parsing commandline '%s': %s", 321*2912Sartem command_line, err->message)); 322*2912Sartem g_error_free (err); 323*2912Sartem return FALSE; 324*2912Sartem } 325*2912Sartem if (!dbus_message_iter_open_container(iter, 326*2912Sartem DBUS_TYPE_ARRAY, 327*2912Sartem DBUS_TYPE_STRING_AS_STRING, 328*2912Sartem &array_iter)) 329*2912Sartem DIE (("No memory")); 330*2912Sartem for (x = 0 ; argv[x] != NULL; x++) { 331*2912Sartem dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &argv[x]); 332*2912Sartem } 333*2912Sartem dbus_message_iter_close_container(iter, &array_iter); 334*2912Sartem 335*2912Sartem g_strfreev(argv); 336*2912Sartem return TRUE; 337*2912Sartem } 338*2912Sartem 339*2912Sartem static gboolean 340*2912Sartem add_first_part(DBusMessageIter *iter, HalDevice *device, 341*2912Sartem const gchar *command_line, char **extra_env) { 342*2912Sartem DBusMessageIter array_iter; 343*2912Sartem const char *udi; 344*2912Sartem 345*2912Sartem udi = hal_device_get_udi(device); 346*2912Sartem dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &udi); 347*2912Sartem 348*2912Sartem dbus_message_iter_open_container(iter, 349*2912Sartem DBUS_TYPE_ARRAY, 350*2912Sartem DBUS_TYPE_STRING_AS_STRING, 351*2912Sartem &array_iter); 352*2912Sartem hal_device_property_foreach (device, add_property_to_msg, &array_iter); 353*2912Sartem add_basic_env(&array_iter, udi); 354*2912Sartem add_extra_env(&array_iter, extra_env); 355*2912Sartem dbus_message_iter_close_container(iter, &array_iter); 356*2912Sartem 357*2912Sartem if (!add_command(iter, command_line)) { 358*2912Sartem return FALSE; 359*2912Sartem } 360*2912Sartem return TRUE; 361*2912Sartem } 362*2912Sartem 363*2912Sartem /* Start a helper, returns true on a successfull start */ 364*2912Sartem gboolean 365*2912Sartem hald_runner_start (HalDevice *device, const gchar *command_line, char **extra_env, 366*2912Sartem HalRunTerminatedCB cb, gpointer data1, gpointer data2) 367*2912Sartem { 368*2912Sartem DBusMessage *msg, *reply; 369*2912Sartem DBusError err; 370*2912Sartem DBusMessageIter iter; 371*2912Sartem 372*2912Sartem dbus_error_init(&err); 373*2912Sartem msg = dbus_message_new_method_call("org.freedesktop.HalRunner", 374*2912Sartem "/org/freedesktop/HalRunner", 375*2912Sartem "org.freedesktop.HalRunner", 376*2912Sartem "Start"); 377*2912Sartem if (msg == NULL) 378*2912Sartem DIE(("No memory")); 379*2912Sartem dbus_message_iter_init_append(msg, &iter); 380*2912Sartem 381*2912Sartem if (!add_first_part(&iter, device, command_line, extra_env)) 382*2912Sartem goto error; 383*2912Sartem 384*2912Sartem /* Wait for the reply, should be almost instantanious */ 385*2912Sartem reply = 386*2912Sartem dbus_connection_send_with_reply_and_block(runner_connection, 387*2912Sartem msg, -1, &err); 388*2912Sartem if (reply) { 389*2912Sartem gboolean ret = 390*2912Sartem (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN); 391*2912Sartem 392*2912Sartem if (ret) { 393*2912Sartem dbus_int64_t pid_from_runner; 394*2912Sartem if (dbus_message_get_args (reply, &err, 395*2912Sartem DBUS_TYPE_INT64, &pid_from_runner, 396*2912Sartem DBUS_TYPE_INVALID)) { 397*2912Sartem if (cb != NULL) { 398*2912Sartem RunningProcess *rp; 399*2912Sartem rp = g_new0 (RunningProcess, 1); 400*2912Sartem rp->pid = (GPid) pid_from_runner; 401*2912Sartem rp->cb = cb; 402*2912Sartem rp->device = device; 403*2912Sartem rp->data1 = data1; 404*2912Sartem rp->data2 = data2; 405*2912Sartem 406*2912Sartem g_hash_table_insert (running_processes, (gpointer) rp->pid, rp); 407*2912Sartem } 408*2912Sartem } else { 409*2912Sartem HAL_ERROR (("Error extracting out_pid from runner's Start()")); 410*2912Sartem } 411*2912Sartem } 412*2912Sartem 413*2912Sartem dbus_message_unref(reply); 414*2912Sartem dbus_message_unref(msg); 415*2912Sartem return ret; 416*2912Sartem } 417*2912Sartem 418*2912Sartem error: 419*2912Sartem dbus_message_unref(msg); 420*2912Sartem return FALSE; 421*2912Sartem } 422*2912Sartem 423*2912Sartem static void 424*2912Sartem call_notify(DBusPendingCall *pending, void *user_data) 425*2912Sartem { 426*2912Sartem HelperData *hb = (HelperData *)user_data; 427*2912Sartem dbus_uint32_t exitt = HALD_RUN_SUCCESS; 428*2912Sartem dbus_int32_t return_code = 0; 429*2912Sartem DBusMessage *m; 430*2912Sartem GArray *error = NULL; 431*2912Sartem DBusMessageIter iter; 432*2912Sartem 433*2912Sartem error = g_array_new(TRUE, FALSE, sizeof(char *)); 434*2912Sartem 435*2912Sartem m = dbus_pending_call_steal_reply(pending); 436*2912Sartem if (dbus_message_get_type(m) != DBUS_MESSAGE_TYPE_METHOD_RETURN) 437*2912Sartem goto malformed; 438*2912Sartem 439*2912Sartem if (!dbus_message_iter_init(m, &iter) || 440*2912Sartem dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) 441*2912Sartem goto malformed; 442*2912Sartem dbus_message_iter_get_basic(&iter, &exitt); 443*2912Sartem 444*2912Sartem if (!dbus_message_iter_next(&iter) || 445*2912Sartem dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) 446*2912Sartem goto malformed; 447*2912Sartem dbus_message_iter_get_basic(&iter, &return_code); 448*2912Sartem 449*2912Sartem while (dbus_message_iter_next(&iter) && 450*2912Sartem dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) { 451*2912Sartem const char *value; 452*2912Sartem dbus_message_iter_get_basic(&iter, &value); 453*2912Sartem g_array_append_vals(error, &value, 1); 454*2912Sartem } 455*2912Sartem 456*2912Sartem hb->cb(hb->d, exitt, return_code, 457*2912Sartem (gchar **)error->data, hb->data1, hb->data2); 458*2912Sartem 459*2912Sartem g_object_unref (hb->d); 460*2912Sartem 461*2912Sartem dbus_message_unref(m); 462*2912Sartem dbus_pending_call_unref (pending); 463*2912Sartem g_array_free(error, TRUE); 464*2912Sartem 465*2912Sartem return; 466*2912Sartem malformed: 467*2912Sartem /* Send a Fail callback on malformed messages */ 468*2912Sartem HAL_ERROR (("Malformed or unexpected reply message")); 469*2912Sartem hb->cb(hb->d, HALD_RUN_FAILED, return_code, NULL, hb->data1, hb->data2); 470*2912Sartem 471*2912Sartem g_object_unref (hb->d); 472*2912Sartem 473*2912Sartem dbus_message_unref(m); 474*2912Sartem dbus_pending_call_unref (pending); 475*2912Sartem g_array_free(error, TRUE); 476*2912Sartem } 477*2912Sartem 478*2912Sartem /* Run a helper program using the commandline, with input as infomation on 479*2912Sartem * stdin */ 480*2912Sartem void 481*2912Sartem hald_runner_run_method(HalDevice *device, 482*2912Sartem const gchar *command_line, char **extra_env, 483*2912Sartem gchar *input, gboolean error_on_stderr, 484*2912Sartem guint32 timeout, 485*2912Sartem HalRunTerminatedCB cb, 486*2912Sartem gpointer data1, gpointer data2) { 487*2912Sartem DBusMessage *msg; 488*2912Sartem DBusMessageIter iter; 489*2912Sartem DBusPendingCall *call; 490*2912Sartem HelperData *hd = NULL; 491*2912Sartem msg = dbus_message_new_method_call("org.freedesktop.HalRunner", 492*2912Sartem "/org/freedesktop/HalRunner", 493*2912Sartem "org.freedesktop.HalRunner", 494*2912Sartem "Run"); 495*2912Sartem if (msg == NULL) 496*2912Sartem DIE(("No memory")); 497*2912Sartem dbus_message_iter_init_append(msg, &iter); 498*2912Sartem 499*2912Sartem if (!add_first_part(&iter, device, command_line, extra_env)) 500*2912Sartem goto error; 501*2912Sartem 502*2912Sartem dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &input); 503*2912Sartem dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &error_on_stderr); 504*2912Sartem dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &timeout); 505*2912Sartem 506*2912Sartem if (!dbus_connection_send_with_reply(runner_connection, 507*2912Sartem msg, &call, INT_MAX)) 508*2912Sartem DIE (("No memory")); 509*2912Sartem 510*2912Sartem hd = malloc(sizeof(HelperData)); 511*2912Sartem hd->d = device; 512*2912Sartem hd->cb = cb; 513*2912Sartem hd->data1 = data1; 514*2912Sartem hd->data2 = data2; 515*2912Sartem 516*2912Sartem g_object_ref (device); 517*2912Sartem 518*2912Sartem dbus_pending_call_set_notify(call, call_notify, hd, free); 519*2912Sartem dbus_message_unref(msg); 520*2912Sartem return; 521*2912Sartem error: 522*2912Sartem dbus_message_unref(msg); 523*2912Sartem free(hd); 524*2912Sartem cb(device, HALD_RUN_FAILED, 0, NULL, data1, data2); 525*2912Sartem } 526*2912Sartem 527*2912Sartem void 528*2912Sartem hald_runner_run(HalDevice *device, 529*2912Sartem const gchar *command_line, char **extra_env, 530*2912Sartem guint timeout, 531*2912Sartem HalRunTerminatedCB cb, 532*2912Sartem gpointer data1, gpointer data2) { 533*2912Sartem hald_runner_run_method(device, command_line, extra_env, 534*2912Sartem "", FALSE, timeout, cb, data1, data2); 535*2912Sartem } 536*2912Sartem 537*2912Sartem 538*2912Sartem 539*2912Sartem void 540*2912Sartem hald_runner_kill_device(HalDevice *device) { 541*2912Sartem DBusMessage *msg, *reply; 542*2912Sartem DBusError err; 543*2912Sartem DBusMessageIter iter; 544*2912Sartem const char *udi; 545*2912Sartem 546*2912Sartem running_processes_remove_device (device); 547*2912Sartem 548*2912Sartem msg = dbus_message_new_method_call("org.freedesktop.HalRunner", 549*2912Sartem "/org/freedesktop/HalRunner", 550*2912Sartem "org.freedesktop.HalRunner", 551*2912Sartem "Kill"); 552*2912Sartem if (msg == NULL) 553*2912Sartem DIE(("No memory")); 554*2912Sartem dbus_message_iter_init_append(msg, &iter); 555*2912Sartem udi = hal_device_get_udi(device); 556*2912Sartem dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &udi); 557*2912Sartem 558*2912Sartem /* Wait for the reply, should be almost instantanious */ 559*2912Sartem dbus_error_init(&err); 560*2912Sartem reply = 561*2912Sartem dbus_connection_send_with_reply_and_block(runner_connection, msg, -1, &err); 562*2912Sartem if (reply) { 563*2912Sartem dbus_message_unref(reply); 564*2912Sartem } 565*2912Sartem 566*2912Sartem dbus_message_unref(msg); 567*2912Sartem } 568*2912Sartem 569*2912Sartem void 570*2912Sartem hald_runner_kill_all(HalDevice *device) { 571*2912Sartem DBusMessage *msg, *reply; 572*2912Sartem DBusError err; 573*2912Sartem 574*2912Sartem running_processes_remove_device (device); 575*2912Sartem 576*2912Sartem msg = dbus_message_new_method_call("org.freedesktop.HalRunner", 577*2912Sartem "/org/freedesktop/HalRunner", 578*2912Sartem "org.freedesktop.HalRunner", 579*2912Sartem "KillAll"); 580*2912Sartem if (msg == NULL) 581*2912Sartem DIE(("No memory")); 582*2912Sartem 583*2912Sartem /* Wait for the reply, should be almost instantanious */ 584*2912Sartem dbus_error_init(&err); 585*2912Sartem reply = 586*2912Sartem dbus_connection_send_with_reply_and_block(runner_connection, 587*2912Sartem msg, -1, &err); 588*2912Sartem if (reply) { 589*2912Sartem dbus_message_unref(reply); 590*2912Sartem } 591*2912Sartem 592*2912Sartem dbus_message_unref(msg); 593*2912Sartem } 594