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 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 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