xref: /onnv-gate/usr/src/cmd/hal/hald-runner/main.c (revision 3168:18866604610a)
12912Sartem /***************************************************************************
22912Sartem  * CVSID: $Id$
32912Sartem  *
42912Sartem  * main.c - Main dbus interface of the hald runner
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 #include <stdio.h>
262912Sartem #include <stdlib.h>
272912Sartem #define DBUS_API_SUBJECT_TO_CHANGE
282912Sartem #include <dbus/dbus-glib-lowlevel.h>
292912Sartem 
302912Sartem #include <glib.h>
312912Sartem #include "utils.h"
322912Sartem #include "runner.h"
332912Sartem 
342912Sartem static gboolean
parse_first_part(run_request * r,DBusMessage * msg,DBusMessageIter * iter)352912Sartem parse_first_part(run_request *r, DBusMessage *msg, DBusMessageIter *iter)
362912Sartem {
372912Sartem 	DBusMessageIter sub_iter;
382912Sartem 	char *tmpstr;
392912Sartem 
402912Sartem 	/* First should be the device UDI */
412912Sartem 	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING)
422912Sartem 		goto malformed;
432912Sartem 	dbus_message_iter_get_basic(iter, &tmpstr);
442912Sartem 	r->udi = g_strdup(tmpstr);
452912Sartem 
462912Sartem 	/* Then the environment array */
472912Sartem 	if (!dbus_message_iter_next(iter) || dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
482912Sartem 		goto malformed;
492912Sartem 	dbus_message_iter_recurse(iter, &sub_iter);
502912Sartem 	/* Add default path for the programs we start */
512912Sartem 	tmpstr = g_strdup_printf("PATH=/sbin:/usr/sbin:/bin:/usr/bin:%s", getenv("PATH"));
522912Sartem 	r->environment = get_string_array(&sub_iter, tmpstr);
532912Sartem 
542912Sartem 	/* Then argv */
552912Sartem 	if (!dbus_message_iter_next(iter) || dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
562912Sartem 		goto malformed;
572912Sartem 	dbus_message_iter_recurse(iter, &sub_iter);
582912Sartem 	r->argv = get_string_array(&sub_iter, NULL);
592912Sartem 
602912Sartem 	return TRUE;
612912Sartem 
622912Sartem malformed:
632912Sartem 	return FALSE;
642912Sartem }
652912Sartem 
662912Sartem static void
handle_run(DBusConnection * con,DBusMessage * msg)672912Sartem handle_run(DBusConnection *con, DBusMessage *msg)
682912Sartem {
692912Sartem 	DBusMessage *reply;
702912Sartem 	DBusMessageIter iter;
712912Sartem 	run_request *r;
722912Sartem 	char *tmpstr;
732912Sartem 
742912Sartem 	r = new_run_request();
752912Sartem 	g_assert(dbus_message_iter_init(msg, &iter));
762912Sartem 
772912Sartem 	if (!parse_first_part(r, msg, &iter))
782912Sartem 		goto malformed;
792912Sartem 
802912Sartem 	/* Next a string of what should be written to stdin */
812912Sartem 	if (!dbus_message_iter_next(&iter) || dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
822912Sartem 		goto malformed;
832912Sartem 	dbus_message_iter_get_basic(&iter, &tmpstr);
842912Sartem 	r->input = g_strdup(tmpstr);
852912Sartem 
862912Sartem 	/* Then an bool to indicate if we should grab stderr */
872912Sartem 	if (!dbus_message_iter_next(&iter) || dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
882912Sartem 		goto malformed;
892912Sartem 	dbus_message_iter_get_basic(&iter, &(r->error_on_stderr));
902912Sartem 
912912Sartem 	/* Then an uint32 timeout for it */
922912Sartem 	if (!dbus_message_iter_next(&iter) || dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
932912Sartem 		goto malformed;
942912Sartem 	dbus_message_iter_get_basic(&iter, &(r->timeout));
952912Sartem 
962912Sartem 	/* let run_request_run handle the reply */
972912Sartem 	run_request_run(r, con, msg, NULL);
982912Sartem 	return;
992912Sartem 
1002912Sartem malformed:
1012912Sartem 	del_run_request(r);
1022912Sartem 	reply = dbus_message_new_error(msg, "org.freedesktop.HalRunner.Malformed",
1032912Sartem 				       "Malformed run request");
1042912Sartem 	dbus_connection_send(con, reply, NULL);
1052912Sartem 	dbus_message_unref(reply);
1062912Sartem }
1072912Sartem 
1082912Sartem static void
handle_start(DBusConnection * con,DBusMessage * msg)1092912Sartem handle_start(DBusConnection *con, DBusMessage *msg)
1102912Sartem {
1112912Sartem 	DBusMessage *reply;
1122912Sartem 	DBusMessageIter iter;
1132912Sartem 	run_request *r;
1142912Sartem 	GPid pid;
115*3168Sartem 	dbus_int64_t pid64;
1162912Sartem 
1172912Sartem 	r = new_run_request();
1182912Sartem 	g_assert(dbus_message_iter_init(msg, &iter));
1192912Sartem 
1202912Sartem 	if (!dbus_message_iter_init(msg, &iter) || !parse_first_part(r, msg, &iter))
1212912Sartem 		goto malformed;
1222912Sartem 
1232912Sartem 	if (run_request_run(r, con, NULL, &pid)) {
124*3168Sartem 		pid64 = pid;
1252912Sartem 		reply = dbus_message_new_method_return(msg);
1262912Sartem 		dbus_message_append_args (reply,
127*3168Sartem 					  DBUS_TYPE_INT64, &pid64,
1282912Sartem 					  DBUS_TYPE_INVALID);
1292912Sartem 
1302912Sartem 	} else {
1312912Sartem 		reply = dbus_message_new_error(msg, "org.freedesktop.HalRunner.Failed",
1322912Sartem 					       "Start request failed");
1332912Sartem 	}
1342912Sartem 	dbus_connection_send(con, reply, NULL);
1352912Sartem 	dbus_message_unref(reply);
1362912Sartem 	return ;
1372912Sartem malformed:
1382912Sartem 	del_run_request(r);
1392912Sartem 	reply = dbus_message_new_error(msg, "org.freedesktop.HalRunner.Malformed",
1402912Sartem 				       "Malformed start request");
1412912Sartem 	dbus_connection_send(con, reply, NULL);
1422912Sartem 	dbus_message_unref(reply);
1432912Sartem }
1442912Sartem 
1452912Sartem static void
handle_kill(DBusConnection * con,DBusMessage * msg)1462912Sartem handle_kill(DBusConnection *con, DBusMessage *msg)
1472912Sartem {
1482912Sartem 	DBusError error;
1492912Sartem 	DBusMessage *reply = NULL;
1502912Sartem 	char *udi;
1512912Sartem 
1522912Sartem 	dbus_error_init (&error);
1532912Sartem 	if (!dbus_message_get_args(msg, &error,
1542912Sartem 				   DBUS_TYPE_STRING, &udi,
1552912Sartem 				   DBUS_TYPE_INVALID)) {
1562912Sartem 		reply = dbus_message_new_error (msg, "org.freedesktop.HalRunner.Malformed",
1572912Sartem 						"Malformed kill message");
1582912Sartem 		g_assert(reply);
1592912Sartem 		dbus_connection_send (con, reply, NULL);
1602912Sartem 		dbus_message_unref(reply);
1612912Sartem 		return;
1622912Sartem 	}
1632912Sartem 	run_kill_udi(udi);
1642912Sartem 
1652912Sartem 	/* always successfull */
1662912Sartem 	reply = dbus_message_new_method_return(msg);
1672912Sartem 	dbus_connection_send(con, reply, NULL);
1682912Sartem 	dbus_message_unref(reply);
1692912Sartem }
1702912Sartem 
1712912Sartem static DBusHandlerResult
filter(DBusConnection * con,DBusMessage * msg,void * user_data)1722912Sartem filter(DBusConnection *con, DBusMessage *msg, void *user_data)
1732912Sartem {
1742912Sartem 	DBusMessage *reply;
1752912Sartem 
1762912Sartem 	if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "Run")) {
1772912Sartem 		handle_run(con, msg);
1782912Sartem 		return DBUS_HANDLER_RESULT_HANDLED;
1792912Sartem 	} else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "Start")) {
1802912Sartem 		handle_start(con, msg);
1812912Sartem 		return DBUS_HANDLER_RESULT_HANDLED;
1822912Sartem 	} else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "Kill")) {
1832912Sartem 		handle_kill(con, msg);
1842912Sartem 		return DBUS_HANDLER_RESULT_HANDLED;
1852912Sartem 	} else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "KillAll")) {
1862912Sartem 		run_kill_all();
1872912Sartem 		/* alwasy successfull */
1882912Sartem 		reply = dbus_message_new_method_return(msg);
1892912Sartem 		dbus_connection_send(con, reply, NULL);
1902912Sartem 		dbus_message_unref(reply);
1912912Sartem 		return DBUS_HANDLER_RESULT_HANDLED;
1922912Sartem 	}
1932912Sartem 	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1942912Sartem }
1952912Sartem 
1962912Sartem int
main(int argc,char ** argv)1972912Sartem main(int argc, char **argv)
1982912Sartem {
1992912Sartem 	DBusConnection *c;
2002912Sartem 	DBusError error;
2012912Sartem 	GMainLoop *loop;
2022912Sartem 	char *dbus_address;
2032912Sartem 
2042912Sartem 	run_init();
2052912Sartem 	dbus_error_init(&error);
2062912Sartem 	dbus_address = getenv("HALD_RUNNER_DBUS_ADDRESS");
2072912Sartem 	g_assert(dbus_address != NULL);
2082912Sartem 
2092912Sartem 	fprintf(stderr, "Runner started - allowed paths are '%s'\n", getenv("PATH"));
2102912Sartem 
2112912Sartem 	c = dbus_connection_open(dbus_address, &error);
2122912Sartem 	if (c == NULL)
2132912Sartem 		goto error;
2142912Sartem 
2152912Sartem 	loop = g_main_loop_new(NULL, FALSE);
2162912Sartem 
2172912Sartem 	dbus_connection_setup_with_g_main(c, NULL);
2182912Sartem 	dbus_connection_set_exit_on_disconnect(c, TRUE);
2192912Sartem 	dbus_connection_add_filter(c, filter, NULL, NULL);
2202912Sartem 
2212912Sartem 	g_main_loop_run(loop);
2222912Sartem 
2232912Sartem error:
2242912Sartem 	fprintf(stderr,"An error has occured: %s\n", error.message);
2252912Sartem 	return -1;
2262912Sartem }
227