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