xref: /onnv-gate/usr/src/cmd/hal/tools/hal_set_property.c (revision 9823:d1a95ad35c68)
12912Sartem /***************************************************************************
22912Sartem  * CVSID: $Id$
32912Sartem  *
42912Sartem  * hal_set_property.c : Set property for a device
52912Sartem  *
62912Sartem  * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
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 
272912Sartem #ifdef HAVE_CONFIG_H
282912Sartem #  include <config.h>
292912Sartem #endif
302912Sartem 
312912Sartem #include <stdio.h>
322912Sartem #include <stdlib.h>
332912Sartem #include <string.h>
342912Sartem #include <unistd.h>
352912Sartem #include <getopt.h>
362912Sartem 
372912Sartem #include <libhal.h>
382912Sartem 
392912Sartem static LibHalContext *hal_ctx;
402912Sartem 
412912Sartem enum property_op {
422912Sartem 	PROP_INT,
432912Sartem 	PROP_UINT64,
442912Sartem 	PROP_STRING,
452912Sartem 	PROP_DOUBLE,
462912Sartem 	PROP_BOOL,
472912Sartem 	PROP_STRLIST_PRE,
482912Sartem 	PROP_STRLIST_POST,
492912Sartem 	PROP_STRLIST_REM,
502912Sartem 	PROP_INVALID
512912Sartem };
522912Sartem 
532912Sartem /**
542912Sartem  * @defgroup HalSetProperty  Set HAL device property
552912Sartem  * @ingroup HalMisc
562912Sartem  *
572912Sartem  * @brief A commandline tool setting a property of a device. Uses libhal
582912Sartem  *
592912Sartem  * @{
602912Sartem  */
612912Sartem 
622912Sartem /** Print out program usage.
632912Sartem  *
642912Sartem  *  @param  argc                Number of arguments given to program
652912Sartem  *  @param  argv                Arguments given to program
662912Sartem  */
672912Sartem static void
usage(int argc,char * argv[])682912Sartem usage (int argc, char *argv[])
692912Sartem {
702912Sartem 	fprintf (stderr,
712912Sartem  "\n"
722912Sartem  "usage : hal-set-property --udi <udi> --key <key>\n"
732912Sartem  "           (--int <value> | --string <value> | --bool <value> |\n"
742912Sartem  "            --strlist-pre <value> | --strlist-post <value> |\n"
752912Sartem  "            --strlist-rem <value> | --double <value> | --remove)\n"
762912Sartem  "           [--help] [--version]\n");
772912Sartem 	fprintf (stderr,
782912Sartem  "\n" "        --udi            Unique Device Id\n"
792912Sartem  "        --key            Key of the property to set\n"
802912Sartem  "        --int            Set value to an integer. Accepts decimal and "
812912Sartem  "                         hexadecimal prefixed with 0x or x\n"
822912Sartem  "        --uint64         Set value to an integer. Accepts decimal and "
832912Sartem  "                         hexadecimal prefixed with 0x or x\n"
842912Sartem  "        --string         Set value to a string\n"
852912Sartem  "        --double         Set value to a floating point number\n"
862912Sartem  "        --bool           Set value to a boolean, ie. true or false\n"
872912Sartem  "        --strlist-pre    Prepend a string to a list\n"
882912Sartem  "        --strlist-post   Append a string to a list\n"
892912Sartem  "        --strlist-rem    Remove a string from a list\n"
902912Sartem  "        --remove         Indicates that the property should be removed\n"
912912Sartem  "        --version        Show version and exit\n"
922912Sartem  "        --help           Show this information and exit\n"
932912Sartem  "\n"
942912Sartem  "This program attempts to set property for a device. Note that, due to\n"
952912Sartem  "security considerations, it may not be possible to set a property; on\n"
962912Sartem  "success this program exits with exit code 0. On error, the program exits\n"
972912Sartem  "with an exit code different from 0\n" "\n");
982912Sartem }
992912Sartem 
1002912Sartem /** Entry point
1012912Sartem  *
1022912Sartem  *  @param  argc                Number of arguments given to program
1032912Sartem  *  @param  argv                Arguments given to program
1042912Sartem  *  @return                     Return code
1052912Sartem  */
1062912Sartem int
main(int argc,char * argv[])1072912Sartem main (int argc, char *argv[])
1082912Sartem {
1092912Sartem 	dbus_bool_t rc = 0;
1102912Sartem 	char *udi = NULL;
1112912Sartem 	char *key = NULL;
1122912Sartem 	char *str_value = NULL;
1132912Sartem 	dbus_int32_t int_value = 0;
1142912Sartem 	dbus_uint64_t uint64_value = 0;
1152912Sartem 	double double_value = 0.0f;
1162912Sartem 	dbus_bool_t bool_value = TRUE;
1172912Sartem 	dbus_bool_t remove = FALSE;
1182912Sartem 	dbus_bool_t is_version = FALSE;
119*9823SLin.Guo@Sun.COM 	dbus_bool_t udi_exists = FALSE;
1202912Sartem 	int type = PROP_INVALID;
1212912Sartem 	DBusError error;
1222912Sartem 
1232912Sartem 	if (argc <= 1) {
1242912Sartem 		usage (argc, argv);
1252912Sartem 		return 1;
1262912Sartem 	}
1272912Sartem 
1282912Sartem 	while (1) {
1292912Sartem 		int c;
1302912Sartem 		int option_index = 0;
1312912Sartem 		const char *opt;
1322912Sartem 		static struct option long_options[] = {
1332912Sartem 			{"udi", 1, NULL, 0},
1342912Sartem 			{"key", 1, NULL, 0},
1352912Sartem 			{"int", 1, NULL, 0},
1362912Sartem 			{"uint64", 1, NULL, 0},
1372912Sartem 			{"string", 1, NULL, 0},
1382912Sartem 			{"double", 1, NULL, 0},
1392912Sartem 			{"bool", 1, NULL, 0},
1402912Sartem 			{"strlist-pre", 1, NULL, 0},
1412912Sartem 			{"strlist-post", 1, NULL, 0},
1422912Sartem 			{"strlist-rem", 1, NULL, 0},
1432912Sartem 			{"remove", 0, NULL, 0},
1442912Sartem 			{"version", 0, NULL, 0},
1452912Sartem 			{"help", 0, NULL, 0},
1462912Sartem 			{NULL, 0, NULL, 0}
1472912Sartem 		};
1482912Sartem 
1492912Sartem 		c = getopt_long (argc, argv, "",
1502912Sartem 				 long_options, &option_index);
1512912Sartem 		if (c == -1)
1522912Sartem 			break;
1532912Sartem 
1542912Sartem 		switch (c) {
1552912Sartem 		case 0:
1562912Sartem 			opt = long_options[option_index].name;
1572912Sartem 
1582912Sartem 			if (strcmp (opt, "help") == 0) {
1592912Sartem 				usage (argc, argv);
1602912Sartem 				return 0;
1612912Sartem 			} else if (strcmp (opt, "key") == 0) {
1622912Sartem 				key = strdup (optarg);
1632912Sartem 			} else if (strcmp (opt, "string") == 0) {
1642912Sartem 				str_value = strdup (optarg);
1652912Sartem 				type = PROP_STRING;
1662912Sartem 			} else if (strcmp (opt, "int") == 0) {
1672912Sartem 				int_value = strtol (optarg, NULL, 0);
1682912Sartem 				type = PROP_INT;
1692912Sartem 			} else if (strcmp (opt, "uint64") == 0) {
1702912Sartem 				uint64_value = strtoull (optarg, NULL, 0);
1712912Sartem 				type = PROP_UINT64;
1722912Sartem 			} else if (strcmp (opt, "double") == 0) {
1732912Sartem 				double_value = (double) atof (optarg);
1742912Sartem 				type = PROP_DOUBLE;
1752912Sartem 			} else if (strcmp (opt, "bool") == 0) {
1762912Sartem 				if (strcmp (optarg, "true") == 0)
1772912Sartem 					bool_value = TRUE;
1782912Sartem 				else if (strcmp (optarg, "false") == 0)
1792912Sartem 					bool_value = FALSE;
1802912Sartem 				else {
1812912Sartem 					usage (argc, argv);
1822912Sartem 					return 1;
1832912Sartem 				}
1842912Sartem 				type = PROP_BOOL;
1852912Sartem 			} else if (strcmp (opt, "strlist-pre") == 0) {
1862912Sartem 				str_value = strdup (optarg);
1872912Sartem 				type = PROP_STRLIST_PRE;
1882912Sartem 			} else if (strcmp (opt, "strlist-post") == 0) {
1892912Sartem 				str_value = strdup (optarg);
1902912Sartem 				type = PROP_STRLIST_POST;
1912912Sartem 			} else if (strcmp (opt, "strlist-rem") == 0) {
1922912Sartem 				str_value = strdup (optarg);
1932912Sartem 				type = PROP_STRLIST_REM;
1942912Sartem 			} else if (strcmp (opt, "remove") == 0) {
1952912Sartem 				remove = TRUE;
1962912Sartem 			} else if (strcmp (opt, "udi") == 0) {
1972912Sartem 				udi = strdup (optarg);
1982912Sartem 			} else if (strcmp (opt, "version") == 0) {
1992912Sartem 				is_version = TRUE;
2002912Sartem 			}
2012912Sartem 			break;
2022912Sartem 
2032912Sartem 		default:
2042912Sartem 			usage (argc, argv);
2052912Sartem 			return 1;
2062912Sartem 			break;
2072912Sartem 		}
2082912Sartem 	}
2092912Sartem 
2102912Sartem 	if (is_version) {
2112912Sartem 		printf ("hal-set-property " PACKAGE_VERSION "\n");
2122912Sartem 		return 0;
2132912Sartem 	}
2142912Sartem 
2152912Sartem 	/* must have at least one, but not neither or both */
2162912Sartem 	if ((remove && type != PROP_INVALID) || ((!remove) && type == PROP_INVALID)) {
2172912Sartem 		usage (argc, argv);
2182912Sartem 		return 1;
2192912Sartem 	}
2202912Sartem 
2212912Sartem 	fprintf (stderr, "\n");
2222912Sartem 
2232912Sartem 	dbus_error_init (&error);
2242912Sartem 	if ((hal_ctx = libhal_ctx_new ()) == NULL) {
2252912Sartem 		fprintf (stderr, "error: libhal_ctx_new\n");
2262912Sartem 		return 1;
2272912Sartem 	}
2282912Sartem 	if (!libhal_ctx_set_dbus_connection (hal_ctx, dbus_bus_get (DBUS_BUS_SYSTEM, &error))) {
2292912Sartem 		fprintf (stderr, "error: libhal_ctx_set_dbus_connection: %s: %s\n", error.name, error.message);
2302912Sartem 		LIBHAL_FREE_DBUS_ERROR (&error);
2312912Sartem 		return 1;
2322912Sartem 	}
2332912Sartem 	if (!libhal_ctx_init (hal_ctx, &error)) {
2342912Sartem 		if (dbus_error_is_set(&error)) {
2352912Sartem 			fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message);
2362912Sartem 			LIBHAL_FREE_DBUS_ERROR (&error);
2372912Sartem 		}
2382912Sartem 		fprintf (stderr, "Could not initialise connection to hald.\n"
2392912Sartem 				 "Normally this means the HAL daemon (hald) is not running or not ready.\n");
2402912Sartem 		return 1;
2412912Sartem 	}
2422912Sartem 
243*9823SLin.Guo@Sun.COM 	 /* check UDI exists */
244*9823SLin.Guo@Sun.COM 	udi_exists = libhal_device_exists (hal_ctx, udi, &error);
245*9823SLin.Guo@Sun.COM 	if (!udi_exists) {
246*9823SLin.Guo@Sun.COM 		fprintf (stderr, "error: UDI %s does not exist\n", udi);
247*9823SLin.Guo@Sun.COM 		return 1;
248*9823SLin.Guo@Sun.COM 	}
249*9823SLin.Guo@Sun.COM 	if (dbus_error_is_set(&error)) {
250*9823SLin.Guo@Sun.COM 		fprintf (stderr, "error: libhal_device_exists: %s: %s\n", error.name, error.message);
251*9823SLin.Guo@Sun.COM 		dbus_error_free (&error);
252*9823SLin.Guo@Sun.COM 		return 1;
253*9823SLin.Guo@Sun.COM 	}
254*9823SLin.Guo@Sun.COM 
2552912Sartem 	if (remove) {
2562912Sartem 		rc = libhal_device_remove_property (hal_ctx, udi, key, &error);
2572912Sartem 		if (!rc) {
258*9823SLin.Guo@Sun.COM 			if (dbus_error_is_set(&error)) {
259*9823SLin.Guo@Sun.COM 			        fprintf (stderr, "error: libhal_device_remove_property: %s: %s\n", error.name, error.message);
260*9823SLin.Guo@Sun.COM 				dbus_error_free (&error);
261*9823SLin.Guo@Sun.COM 			} else {
262*9823SLin.Guo@Sun.COM 				fprintf (stderr, "error: libhal_device_remove_property: invalid params.\n");
263*9823SLin.Guo@Sun.COM 			}
2642912Sartem 			return 1;
2652912Sartem 		}
2662912Sartem 	} else {
2672912Sartem 		switch (type) {
2682912Sartem 		case PROP_STRING:
2692912Sartem 			rc = libhal_device_set_property_string (hal_ctx, udi, key, str_value, &error);
2702912Sartem 			break;
2712912Sartem 		case PROP_INT:
2722912Sartem 			rc = libhal_device_set_property_int (hal_ctx, udi, key, int_value, &error);
2732912Sartem 			break;
2742912Sartem 		case PROP_UINT64:
2752912Sartem 			rc = libhal_device_set_property_uint64 (hal_ctx, udi, key, uint64_value, &error);
2762912Sartem 			break;
2772912Sartem 		case PROP_DOUBLE:
2782912Sartem 			rc = libhal_device_set_property_double (hal_ctx, udi, key, double_value, &error);
2792912Sartem 			break;
2802912Sartem 		case PROP_BOOL:
2812912Sartem 			rc = libhal_device_set_property_bool (hal_ctx, udi, key, bool_value, &error);
2822912Sartem 			break;
2832912Sartem 		case PROP_STRLIST_PRE:
2842912Sartem 			rc = libhal_device_property_strlist_prepend (hal_ctx, udi, key, str_value, &error);
2852912Sartem 			break;
2862912Sartem 		case PROP_STRLIST_POST:
2872912Sartem 			rc = libhal_device_property_strlist_append (hal_ctx, udi, key, str_value, &error);
2882912Sartem 			break;
2892912Sartem 		case PROP_STRLIST_REM:
2902912Sartem 			rc = libhal_device_property_strlist_remove (hal_ctx, udi, key, str_value, &error);
2912912Sartem 			break;
2922912Sartem 		}
2932912Sartem 		if (!rc) {
294*9823SLin.Guo@Sun.COM 			if (dbus_error_is_set(&error)) {
295*9823SLin.Guo@Sun.COM 			        fprintf (stderr, "error: libhal_device_set_property: %s: %s\n", error.name, error.message);
296*9823SLin.Guo@Sun.COM 				dbus_error_free (&error);
297*9823SLin.Guo@Sun.COM 			} else {
298*9823SLin.Guo@Sun.COM 				fprintf (stderr, "error: libhal_device_set_property: invalid params.\n");
299*9823SLin.Guo@Sun.COM 			}
3002912Sartem 			return 1;
3012912Sartem 		}
3022912Sartem 	}
3032912Sartem 
3042912Sartem 	return rc ? 0 : 1;
3052912Sartem }
3062912Sartem 
3072912Sartem /**
3082912Sartem  * @}
3092912Sartem  */
310