1*2912Sartem /*************************************************************************** 2*2912Sartem * CVSID: $Id$ 3*2912Sartem * 4*2912Sartem * hal_set_property.c : Set property for a device 5*2912Sartem * 6*2912Sartem * Copyright (C) 2003 David Zeuthen, <david@fubar.dk> 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 27*2912Sartem #ifdef HAVE_CONFIG_H 28*2912Sartem # include <config.h> 29*2912Sartem #endif 30*2912Sartem 31*2912Sartem #include <stdio.h> 32*2912Sartem #include <stdlib.h> 33*2912Sartem #include <string.h> 34*2912Sartem #include <unistd.h> 35*2912Sartem #include <getopt.h> 36*2912Sartem 37*2912Sartem #include <libhal.h> 38*2912Sartem 39*2912Sartem static LibHalContext *hal_ctx; 40*2912Sartem 41*2912Sartem enum property_op { 42*2912Sartem PROP_INT, 43*2912Sartem PROP_UINT64, 44*2912Sartem PROP_STRING, 45*2912Sartem PROP_DOUBLE, 46*2912Sartem PROP_BOOL, 47*2912Sartem PROP_STRLIST_PRE, 48*2912Sartem PROP_STRLIST_POST, 49*2912Sartem PROP_STRLIST_REM, 50*2912Sartem PROP_INVALID 51*2912Sartem }; 52*2912Sartem 53*2912Sartem /** 54*2912Sartem * @defgroup HalSetProperty Set HAL device property 55*2912Sartem * @ingroup HalMisc 56*2912Sartem * 57*2912Sartem * @brief A commandline tool setting a property of a device. Uses libhal 58*2912Sartem * 59*2912Sartem * @{ 60*2912Sartem */ 61*2912Sartem 62*2912Sartem /** Print out program usage. 63*2912Sartem * 64*2912Sartem * @param argc Number of arguments given to program 65*2912Sartem * @param argv Arguments given to program 66*2912Sartem */ 67*2912Sartem static void 68*2912Sartem usage (int argc, char *argv[]) 69*2912Sartem { 70*2912Sartem fprintf (stderr, 71*2912Sartem "\n" 72*2912Sartem "usage : hal-set-property --udi <udi> --key <key>\n" 73*2912Sartem " (--int <value> | --string <value> | --bool <value> |\n" 74*2912Sartem " --strlist-pre <value> | --strlist-post <value> |\n" 75*2912Sartem " --strlist-rem <value> | --double <value> | --remove)\n" 76*2912Sartem " [--help] [--version]\n"); 77*2912Sartem fprintf (stderr, 78*2912Sartem "\n" " --udi Unique Device Id\n" 79*2912Sartem " --key Key of the property to set\n" 80*2912Sartem " --int Set value to an integer. Accepts decimal and " 81*2912Sartem " hexadecimal prefixed with 0x or x\n" 82*2912Sartem " --uint64 Set value to an integer. Accepts decimal and " 83*2912Sartem " hexadecimal prefixed with 0x or x\n" 84*2912Sartem " --string Set value to a string\n" 85*2912Sartem " --double Set value to a floating point number\n" 86*2912Sartem " --bool Set value to a boolean, ie. true or false\n" 87*2912Sartem " --strlist-pre Prepend a string to a list\n" 88*2912Sartem " --strlist-post Append a string to a list\n" 89*2912Sartem " --strlist-rem Remove a string from a list\n" 90*2912Sartem " --remove Indicates that the property should be removed\n" 91*2912Sartem " --version Show version and exit\n" 92*2912Sartem " --help Show this information and exit\n" 93*2912Sartem "\n" 94*2912Sartem "This program attempts to set property for a device. Note that, due to\n" 95*2912Sartem "security considerations, it may not be possible to set a property; on\n" 96*2912Sartem "success this program exits with exit code 0. On error, the program exits\n" 97*2912Sartem "with an exit code different from 0\n" "\n"); 98*2912Sartem } 99*2912Sartem 100*2912Sartem /** Entry point 101*2912Sartem * 102*2912Sartem * @param argc Number of arguments given to program 103*2912Sartem * @param argv Arguments given to program 104*2912Sartem * @return Return code 105*2912Sartem */ 106*2912Sartem int 107*2912Sartem main (int argc, char *argv[]) 108*2912Sartem { 109*2912Sartem dbus_bool_t rc = 0; 110*2912Sartem char *udi = NULL; 111*2912Sartem char *key = NULL; 112*2912Sartem char *str_value = NULL; 113*2912Sartem dbus_int32_t int_value = 0; 114*2912Sartem dbus_uint64_t uint64_value = 0; 115*2912Sartem double double_value = 0.0f; 116*2912Sartem dbus_bool_t bool_value = TRUE; 117*2912Sartem dbus_bool_t remove = FALSE; 118*2912Sartem dbus_bool_t is_version = FALSE; 119*2912Sartem int type = PROP_INVALID; 120*2912Sartem DBusError error; 121*2912Sartem 122*2912Sartem if (argc <= 1) { 123*2912Sartem usage (argc, argv); 124*2912Sartem return 1; 125*2912Sartem } 126*2912Sartem 127*2912Sartem while (1) { 128*2912Sartem int c; 129*2912Sartem int option_index = 0; 130*2912Sartem const char *opt; 131*2912Sartem static struct option long_options[] = { 132*2912Sartem {"udi", 1, NULL, 0}, 133*2912Sartem {"key", 1, NULL, 0}, 134*2912Sartem {"int", 1, NULL, 0}, 135*2912Sartem {"uint64", 1, NULL, 0}, 136*2912Sartem {"string", 1, NULL, 0}, 137*2912Sartem {"double", 1, NULL, 0}, 138*2912Sartem {"bool", 1, NULL, 0}, 139*2912Sartem {"strlist-pre", 1, NULL, 0}, 140*2912Sartem {"strlist-post", 1, NULL, 0}, 141*2912Sartem {"strlist-rem", 1, NULL, 0}, 142*2912Sartem {"remove", 0, NULL, 0}, 143*2912Sartem {"version", 0, NULL, 0}, 144*2912Sartem {"help", 0, NULL, 0}, 145*2912Sartem {NULL, 0, NULL, 0} 146*2912Sartem }; 147*2912Sartem 148*2912Sartem c = getopt_long (argc, argv, "", 149*2912Sartem long_options, &option_index); 150*2912Sartem if (c == -1) 151*2912Sartem break; 152*2912Sartem 153*2912Sartem switch (c) { 154*2912Sartem case 0: 155*2912Sartem opt = long_options[option_index].name; 156*2912Sartem 157*2912Sartem if (strcmp (opt, "help") == 0) { 158*2912Sartem usage (argc, argv); 159*2912Sartem return 0; 160*2912Sartem } else if (strcmp (opt, "key") == 0) { 161*2912Sartem key = strdup (optarg); 162*2912Sartem } else if (strcmp (opt, "string") == 0) { 163*2912Sartem str_value = strdup (optarg); 164*2912Sartem type = PROP_STRING; 165*2912Sartem } else if (strcmp (opt, "int") == 0) { 166*2912Sartem int_value = strtol (optarg, NULL, 0); 167*2912Sartem type = PROP_INT; 168*2912Sartem } else if (strcmp (opt, "uint64") == 0) { 169*2912Sartem uint64_value = strtoull (optarg, NULL, 0); 170*2912Sartem type = PROP_UINT64; 171*2912Sartem } else if (strcmp (opt, "double") == 0) { 172*2912Sartem double_value = (double) atof (optarg); 173*2912Sartem type = PROP_DOUBLE; 174*2912Sartem } else if (strcmp (opt, "bool") == 0) { 175*2912Sartem if (strcmp (optarg, "true") == 0) 176*2912Sartem bool_value = TRUE; 177*2912Sartem else if (strcmp (optarg, "false") == 0) 178*2912Sartem bool_value = FALSE; 179*2912Sartem else { 180*2912Sartem usage (argc, argv); 181*2912Sartem return 1; 182*2912Sartem } 183*2912Sartem type = PROP_BOOL; 184*2912Sartem } else if (strcmp (opt, "strlist-pre") == 0) { 185*2912Sartem str_value = strdup (optarg); 186*2912Sartem type = PROP_STRLIST_PRE; 187*2912Sartem } else if (strcmp (opt, "strlist-post") == 0) { 188*2912Sartem str_value = strdup (optarg); 189*2912Sartem type = PROP_STRLIST_POST; 190*2912Sartem } else if (strcmp (opt, "strlist-rem") == 0) { 191*2912Sartem str_value = strdup (optarg); 192*2912Sartem type = PROP_STRLIST_REM; 193*2912Sartem } else if (strcmp (opt, "remove") == 0) { 194*2912Sartem remove = TRUE; 195*2912Sartem } else if (strcmp (opt, "udi") == 0) { 196*2912Sartem udi = strdup (optarg); 197*2912Sartem } else if (strcmp (opt, "version") == 0) { 198*2912Sartem is_version = TRUE; 199*2912Sartem } 200*2912Sartem break; 201*2912Sartem 202*2912Sartem default: 203*2912Sartem usage (argc, argv); 204*2912Sartem return 1; 205*2912Sartem break; 206*2912Sartem } 207*2912Sartem } 208*2912Sartem 209*2912Sartem if (is_version) { 210*2912Sartem printf ("hal-set-property " PACKAGE_VERSION "\n"); 211*2912Sartem return 0; 212*2912Sartem } 213*2912Sartem 214*2912Sartem /* must have at least one, but not neither or both */ 215*2912Sartem if ((remove && type != PROP_INVALID) || ((!remove) && type == PROP_INVALID)) { 216*2912Sartem usage (argc, argv); 217*2912Sartem return 1; 218*2912Sartem } 219*2912Sartem 220*2912Sartem fprintf (stderr, "\n"); 221*2912Sartem 222*2912Sartem dbus_error_init (&error); 223*2912Sartem if ((hal_ctx = libhal_ctx_new ()) == NULL) { 224*2912Sartem fprintf (stderr, "error: libhal_ctx_new\n"); 225*2912Sartem return 1; 226*2912Sartem } 227*2912Sartem if (!libhal_ctx_set_dbus_connection (hal_ctx, dbus_bus_get (DBUS_BUS_SYSTEM, &error))) { 228*2912Sartem fprintf (stderr, "error: libhal_ctx_set_dbus_connection: %s: %s\n", error.name, error.message); 229*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 230*2912Sartem return 1; 231*2912Sartem } 232*2912Sartem if (!libhal_ctx_init (hal_ctx, &error)) { 233*2912Sartem if (dbus_error_is_set(&error)) { 234*2912Sartem fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message); 235*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 236*2912Sartem } 237*2912Sartem fprintf (stderr, "Could not initialise connection to hald.\n" 238*2912Sartem "Normally this means the HAL daemon (hald) is not running or not ready.\n"); 239*2912Sartem return 1; 240*2912Sartem } 241*2912Sartem 242*2912Sartem if (remove) { 243*2912Sartem rc = libhal_device_remove_property (hal_ctx, udi, key, &error); 244*2912Sartem if (!rc) { 245*2912Sartem fprintf (stderr, "error: libhal_device_remove_property: %s: %s\n", error.name, error.message); 246*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 247*2912Sartem return 1; 248*2912Sartem } 249*2912Sartem } else { 250*2912Sartem switch (type) { 251*2912Sartem case PROP_STRING: 252*2912Sartem rc = libhal_device_set_property_string (hal_ctx, udi, key, str_value, &error); 253*2912Sartem break; 254*2912Sartem case PROP_INT: 255*2912Sartem rc = libhal_device_set_property_int (hal_ctx, udi, key, int_value, &error); 256*2912Sartem break; 257*2912Sartem case PROP_UINT64: 258*2912Sartem rc = libhal_device_set_property_uint64 (hal_ctx, udi, key, uint64_value, &error); 259*2912Sartem break; 260*2912Sartem case PROP_DOUBLE: 261*2912Sartem rc = libhal_device_set_property_double (hal_ctx, udi, key, double_value, &error); 262*2912Sartem break; 263*2912Sartem case PROP_BOOL: 264*2912Sartem rc = libhal_device_set_property_bool (hal_ctx, udi, key, bool_value, &error); 265*2912Sartem break; 266*2912Sartem case PROP_STRLIST_PRE: 267*2912Sartem rc = libhal_device_property_strlist_prepend (hal_ctx, udi, key, str_value, &error); 268*2912Sartem break; 269*2912Sartem case PROP_STRLIST_POST: 270*2912Sartem rc = libhal_device_property_strlist_append (hal_ctx, udi, key, str_value, &error); 271*2912Sartem break; 272*2912Sartem case PROP_STRLIST_REM: 273*2912Sartem rc = libhal_device_property_strlist_remove (hal_ctx, udi, key, str_value, &error); 274*2912Sartem break; 275*2912Sartem } 276*2912Sartem if (!rc) { 277*2912Sartem fprintf (stderr, "error: libhal_device_set_property: %s: %s\n", error.name, error.message); 278*2912Sartem dbus_error_free (&error); 279*2912Sartem return 1; 280*2912Sartem } 281*2912Sartem } 282*2912Sartem 283*2912Sartem return rc ? 0 : 1; 284*2912Sartem } 285*2912Sartem 286*2912Sartem /** 287*2912Sartem * @} 288*2912Sartem */ 289