1*2912Sartem /*************************************************************************** 2*2912Sartem * CVSID: $Id$ 3*2912Sartem * 4*2912Sartem * lshal.c : Show devices managed by HAL 5*2912Sartem * 6*2912Sartem * Copyright (C) 2003 David Zeuthen, <david@fubar.dk> 7*2912Sartem * Copyright (C) 2005 Pierre Ossman, <drzeus@drzeus.cx> 8*2912Sartem * 9*2912Sartem * Licensed under the Academic Free License version 2.1 10*2912Sartem * 11*2912Sartem * This program is free software; you can redistribute it and/or modify 12*2912Sartem * it under the terms of the GNU General Public License as published by 13*2912Sartem * the Free Software Foundation; either version 2 of the License, or 14*2912Sartem * (at your option) any later version. 15*2912Sartem * 16*2912Sartem * This program is distributed in the hope that it will be useful, 17*2912Sartem * but WITHOUT ANY WARRANTY; without even the implied warranty of 18*2912Sartem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19*2912Sartem * GNU General Public License for more details. 20*2912Sartem * 21*2912Sartem * You should have received a copy of the GNU General Public License 22*2912Sartem * along with this program; if not, write to the Free Software 23*2912Sartem * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24*2912Sartem * 25*2912Sartem **************************************************************************/ 26*2912Sartem 27*2912Sartem 28*2912Sartem #ifdef HAVE_CONFIG_H 29*2912Sartem # include <config.h> 30*2912Sartem #endif 31*2912Sartem 32*2912Sartem #include <stdio.h> 33*2912Sartem #include <stdlib.h> 34*2912Sartem #include <string.h> 35*2912Sartem #include <unistd.h> 36*2912Sartem #include <getopt.h> 37*2912Sartem 38*2912Sartem #include <glib.h> 39*2912Sartem #include <dbus/dbus-glib-lowlevel.h> 40*2912Sartem #include <dbus/dbus-glib.h> 41*2912Sartem #include <libhal.h> 42*2912Sartem 43*2912Sartem #ifdef __SUNPRO_C 44*2912Sartem #define __FUNCTION__ __func__ 45*2912Sartem #endif 46*2912Sartem 47*2912Sartem /** 48*2912Sartem * @defgroup HalLsHal List HAL devices 49*2912Sartem * @ingroup HalMisc 50*2912Sartem * 51*2912Sartem * @brief A commandline tool, lshal, for displaying and, optionally, 52*2912Sartem * monitor the devices managed by the HAL daemon. Uses libhal. 53*2912Sartem * 54*2912Sartem * @{ 55*2912Sartem */ 56*2912Sartem 57*2912Sartem /** Macro for terminating the program on an unrecoverable error */ 58*2912Sartem #define DIE(expr) do {printf("*** [DIE] %s:%s():%d : ", __FILE__, __FUNCTION__, __LINE__); printf expr; printf("\n"); exit(1); } while(0) 59*2912Sartem 60*2912Sartem #define UDI_BASE "/org/freedesktop/Hal/devices/" 61*2912Sartem 62*2912Sartem static LibHalContext *hal_ctx; 63*2912Sartem static dbus_bool_t long_list = FALSE; 64*2912Sartem static dbus_bool_t tree_view = FALSE; 65*2912Sartem static dbus_bool_t short_list = FALSE; 66*2912Sartem static char *show_device = NULL; 67*2912Sartem 68*2912Sartem struct Device { 69*2912Sartem char *name; 70*2912Sartem char *parent; 71*2912Sartem }; 72*2912Sartem 73*2912Sartem /** Generate a short name for a device 74*2912Sartem * 75*2912Sartem * @param udi Universal Device Id 76*2912Sartem */ 77*2912Sartem static const char * 78*2912Sartem short_name (const char *udi) 79*2912Sartem { 80*2912Sartem return &udi[sizeof(UDI_BASE) - 1]; 81*2912Sartem } 82*2912Sartem 83*2912Sartem /** Print all properties of a device 84*2912Sartem * 85*2912Sartem * @param udi Universal Device Id 86*2912Sartem */ 87*2912Sartem 88*2912Sartem static void 89*2912Sartem print_props (const char *udi) 90*2912Sartem { 91*2912Sartem DBusError error; 92*2912Sartem LibHalPropertySet *props; 93*2912Sartem LibHalPropertySetIterator it; 94*2912Sartem int type; 95*2912Sartem 96*2912Sartem dbus_error_init (&error); 97*2912Sartem 98*2912Sartem props = libhal_device_get_all_properties (hal_ctx, udi, &error); 99*2912Sartem 100*2912Sartem /* NOTE : This may be NULL if the device was removed 101*2912Sartem * in the daemon; this is because 102*2912Sartem * hal_device_get_all_properties() is a in 103*2912Sartem * essence an IPC call and other stuff may 104*2912Sartem * be happening.. 105*2912Sartem */ 106*2912Sartem if (props == NULL) { 107*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 108*2912Sartem return; 109*2912Sartem } 110*2912Sartem 111*2912Sartem for (libhal_psi_init (&it, props); libhal_psi_has_more (&it); libhal_psi_next (&it)) { 112*2912Sartem type = libhal_psi_get_type (&it); 113*2912Sartem switch (type) { 114*2912Sartem case LIBHAL_PROPERTY_TYPE_STRING: 115*2912Sartem printf (" %s = '%s' (string)\n", 116*2912Sartem libhal_psi_get_key (&it), 117*2912Sartem libhal_psi_get_string (&it)); 118*2912Sartem break; 119*2912Sartem 120*2912Sartem case LIBHAL_PROPERTY_TYPE_INT32: 121*2912Sartem printf (" %s = %d (0x%x) (int)\n", 122*2912Sartem libhal_psi_get_key (&it), 123*2912Sartem libhal_psi_get_int (&it), 124*2912Sartem libhal_psi_get_int (&it)); 125*2912Sartem break; 126*2912Sartem 127*2912Sartem case LIBHAL_PROPERTY_TYPE_UINT64: 128*2912Sartem printf (" %s = %llu (0x%llx) (uint64)\n", 129*2912Sartem libhal_psi_get_key (&it), 130*2912Sartem (long long unsigned int) libhal_psi_get_uint64 (&it), 131*2912Sartem (long long unsigned int) libhal_psi_get_uint64 (&it)); 132*2912Sartem break; 133*2912Sartem 134*2912Sartem case LIBHAL_PROPERTY_TYPE_DOUBLE: 135*2912Sartem printf (" %s = %g (double)\n", 136*2912Sartem libhal_psi_get_key (&it), 137*2912Sartem libhal_psi_get_double (&it)); 138*2912Sartem break; 139*2912Sartem 140*2912Sartem case LIBHAL_PROPERTY_TYPE_BOOLEAN: 141*2912Sartem printf (" %s = %s (bool)\n", 142*2912Sartem libhal_psi_get_key (&it), 143*2912Sartem libhal_psi_get_bool (&it) ? "true" : 144*2912Sartem "false"); 145*2912Sartem break; 146*2912Sartem 147*2912Sartem case LIBHAL_PROPERTY_TYPE_STRLIST: 148*2912Sartem { 149*2912Sartem unsigned int i; 150*2912Sartem char **strlist; 151*2912Sartem 152*2912Sartem printf (" %s = {", libhal_psi_get_key (&it)); 153*2912Sartem 154*2912Sartem strlist = libhal_psi_get_strlist (&it); 155*2912Sartem for (i = 0; strlist[i] != 0; i++) { 156*2912Sartem printf ("'%s'", strlist[i]); 157*2912Sartem if (strlist[i+1] != NULL) 158*2912Sartem printf (", "); 159*2912Sartem } 160*2912Sartem printf ("} (string list)\n"); 161*2912Sartem break; 162*2912Sartem } 163*2912Sartem 164*2912Sartem default: 165*2912Sartem printf ("Unknown type %d=0x%02x\n", type, type); 166*2912Sartem break; 167*2912Sartem } 168*2912Sartem } 169*2912Sartem 170*2912Sartem libhal_free_property_set (props); 171*2912Sartem } 172*2912Sartem 173*2912Sartem /** Dumps information about a single device 174*2912Sartem * 175*2912Sartem * @param udi Universal Device Id 176*2912Sartem */ 177*2912Sartem 178*2912Sartem static void 179*2912Sartem dump_device (const char *udi) 180*2912Sartem { 181*2912Sartem DBusError error; 182*2912Sartem 183*2912Sartem dbus_error_init (&error); 184*2912Sartem 185*2912Sartem if (!libhal_device_exists (hal_ctx, udi, &error)) { 186*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 187*2912Sartem return; 188*2912Sartem } 189*2912Sartem 190*2912Sartem if (long_list) { 191*2912Sartem printf ("udi = '%s'\n", udi); 192*2912Sartem 193*2912Sartem print_props (udi); 194*2912Sartem printf ("\n"); 195*2912Sartem } 196*2912Sartem else 197*2912Sartem printf ("%s\n", short_name (udi)); 198*2912Sartem } 199*2912Sartem 200*2912Sartem /** Dump all children of device 201*2912Sartem * 202*2912Sartem * @param udi Universal Device Id of parent 203*2912Sartem * @param num_devices Total number of devices in device list 204*2912Sartem * @param devices List of devices 205*2912Sartem * @param depth Current recursion depth 206*2912Sartem */ 207*2912Sartem 208*2912Sartem static void 209*2912Sartem dump_children (char *udi, int num_devices, struct Device *devices, int depth) 210*2912Sartem { 211*2912Sartem int i; 212*2912Sartem 213*2912Sartem for (i = 0; i < num_devices; i++) { 214*2912Sartem if (!udi) { 215*2912Sartem if (devices[i].parent) 216*2912Sartem continue; 217*2912Sartem } 218*2912Sartem else { 219*2912Sartem if (!devices[i].parent) 220*2912Sartem continue; 221*2912Sartem if (strcmp (devices[i].parent, udi)) 222*2912Sartem continue; 223*2912Sartem } 224*2912Sartem 225*2912Sartem if (long_list) 226*2912Sartem printf ("udi = '%s'\n", devices[i].name); 227*2912Sartem else { 228*2912Sartem int j; 229*2912Sartem if (tree_view) { 230*2912Sartem for (j = 0;j < depth;j++) 231*2912Sartem printf(" "); 232*2912Sartem } 233*2912Sartem printf ("%s\n", short_name (devices[i].name)); 234*2912Sartem } 235*2912Sartem 236*2912Sartem if (long_list) { 237*2912Sartem print_props (devices[i].name); 238*2912Sartem printf ("\n"); 239*2912Sartem } 240*2912Sartem 241*2912Sartem dump_children(devices[i].name, num_devices, devices, depth + 1); 242*2912Sartem } 243*2912Sartem } 244*2912Sartem 245*2912Sartem /** Dump all devices to stdout 246*2912Sartem * 247*2912Sartem */ 248*2912Sartem static void 249*2912Sartem dump_devices (void) 250*2912Sartem { 251*2912Sartem int i; 252*2912Sartem int num_devices; 253*2912Sartem char **device_names; 254*2912Sartem struct Device *devices; 255*2912Sartem DBusError error; 256*2912Sartem 257*2912Sartem dbus_error_init (&error); 258*2912Sartem 259*2912Sartem device_names = libhal_get_all_devices (hal_ctx, &num_devices, &error); 260*2912Sartem if (device_names == NULL) { 261*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 262*2912Sartem DIE (("Couldn't obtain list of devices\n")); 263*2912Sartem } 264*2912Sartem 265*2912Sartem devices = malloc (sizeof(struct Device) * num_devices); 266*2912Sartem if (!devices) { 267*2912Sartem libhal_free_string_array (device_names); 268*2912Sartem return; 269*2912Sartem } 270*2912Sartem 271*2912Sartem for (i = 0;i < num_devices;i++) { 272*2912Sartem devices[i].name = device_names[i]; 273*2912Sartem devices[i].parent = libhal_device_get_property_string (hal_ctx, 274*2912Sartem device_names[i], "info.parent", &error); 275*2912Sartem 276*2912Sartem if (dbus_error_is_set (&error)) { 277*2912Sartem /* Free the error (which include a dbus_error_init()) 278*2912Sartem This should prevent errors if a call above fails */ 279*2912Sartem dbus_error_free (&error); 280*2912Sartem } 281*2912Sartem } 282*2912Sartem 283*2912Sartem if (long_list) { 284*2912Sartem printf ("\n" 285*2912Sartem "Dumping %d device(s) from the Global Device List:\n" 286*2912Sartem "-------------------------------------------------\n", 287*2912Sartem num_devices); 288*2912Sartem } 289*2912Sartem 290*2912Sartem dump_children(NULL, num_devices, devices, 0); 291*2912Sartem 292*2912Sartem for (i = 0;i < num_devices;i++) { 293*2912Sartem if (devices[i].parent) 294*2912Sartem libhal_free_string (devices[i].parent); 295*2912Sartem } 296*2912Sartem 297*2912Sartem free (devices); 298*2912Sartem libhal_free_string_array (device_names); 299*2912Sartem 300*2912Sartem if (long_list) { 301*2912Sartem printf ("\n" 302*2912Sartem "Dumped %d device(s) from the Global Device List.\n" 303*2912Sartem "------------------------------------------------\n", 304*2912Sartem num_devices); 305*2912Sartem 306*2912Sartem printf ("\n"); 307*2912Sartem } 308*2912Sartem } 309*2912Sartem 310*2912Sartem /** Invoked when a device is added to the Global Device List. Simply prints 311*2912Sartem * a message on stdout. 312*2912Sartem * 313*2912Sartem * @param udi Universal Device Id 314*2912Sartem */ 315*2912Sartem static void 316*2912Sartem device_added (LibHalContext *ctx, 317*2912Sartem const char *udi) 318*2912Sartem { 319*2912Sartem if (show_device && strcmp(show_device, udi)) 320*2912Sartem return; 321*2912Sartem 322*2912Sartem if (long_list) { 323*2912Sartem printf ("*** lshal: device_added, udi='%s'\n", udi); 324*2912Sartem print_props (udi); 325*2912Sartem } else 326*2912Sartem printf ("%s added\n", short_name (udi)); 327*2912Sartem } 328*2912Sartem 329*2912Sartem /** Invoked when a device is removed from the Global Device List. Simply 330*2912Sartem * prints a message on stdout. 331*2912Sartem * 332*2912Sartem * @param udi Universal Device Id 333*2912Sartem */ 334*2912Sartem static void 335*2912Sartem device_removed (LibHalContext *ctx, 336*2912Sartem const char *udi) 337*2912Sartem { 338*2912Sartem if (show_device && strcmp(show_device, udi)) 339*2912Sartem return; 340*2912Sartem 341*2912Sartem if (long_list) 342*2912Sartem printf ("*** lshal: device_removed, udi='%s'\n", udi); 343*2912Sartem else 344*2912Sartem printf ("%s removed\n", short_name (udi)); 345*2912Sartem } 346*2912Sartem 347*2912Sartem /** Invoked when device in the Global Device List acquires a new capability. 348*2912Sartem * Prints the name of the capability to stdout. 349*2912Sartem * 350*2912Sartem * @param udi Universal Device Id 351*2912Sartem * @param capability Name of capability 352*2912Sartem */ 353*2912Sartem static void 354*2912Sartem device_new_capability (LibHalContext *ctx, 355*2912Sartem const char *udi, 356*2912Sartem const char *capability) 357*2912Sartem { 358*2912Sartem if (show_device && strcmp(show_device, udi)) 359*2912Sartem return; 360*2912Sartem 361*2912Sartem if (long_list) { 362*2912Sartem printf ("*** lshal: new_capability, udi='%s'\n", udi); 363*2912Sartem printf ("*** capability: %s\n", capability); 364*2912Sartem } else 365*2912Sartem printf ("%s capability %s added\n", short_name (udi), 366*2912Sartem capability); 367*2912Sartem } 368*2912Sartem 369*2912Sartem /** Invoked when device in the Global Device List loses a capability. 370*2912Sartem * Prints the name of the capability to stdout. 371*2912Sartem * 372*2912Sartem * @param udi Universal Device Id 373*2912Sartem * @param capability Name of capability 374*2912Sartem */ 375*2912Sartem static void 376*2912Sartem device_lost_capability (LibHalContext *ctx, 377*2912Sartem const char *udi, 378*2912Sartem const char *capability) 379*2912Sartem { 380*2912Sartem if (show_device && strcmp(show_device, udi)) 381*2912Sartem return; 382*2912Sartem 383*2912Sartem if (long_list) { 384*2912Sartem printf ("*** lshal: lost_capability, udi='%s'\n", udi); 385*2912Sartem printf ("*** capability: %s\n", capability); 386*2912Sartem } else 387*2912Sartem printf ("%s capability %s lost\n", short_name (udi), 388*2912Sartem capability); 389*2912Sartem } 390*2912Sartem 391*2912Sartem /** Acquires and prints the value of of a property to stdout. 392*2912Sartem * 393*2912Sartem * @param udi Universal Device Id 394*2912Sartem * @param key Key of property 395*2912Sartem */ 396*2912Sartem static void 397*2912Sartem print_property (const char *udi, const char *key) 398*2912Sartem { 399*2912Sartem int type; 400*2912Sartem char *str; 401*2912Sartem DBusError error; 402*2912Sartem 403*2912Sartem dbus_error_init (&error); 404*2912Sartem 405*2912Sartem type = libhal_device_get_property_type (hal_ctx, udi, key, &error); 406*2912Sartem 407*2912Sartem switch (type) { 408*2912Sartem case LIBHAL_PROPERTY_TYPE_STRING: 409*2912Sartem str = libhal_device_get_property_string (hal_ctx, udi, key, &error); 410*2912Sartem printf (long_list?"*** new value: '%s' (string)\n":"'%s'", str); 411*2912Sartem libhal_free_string (str); 412*2912Sartem break; 413*2912Sartem case LIBHAL_PROPERTY_TYPE_INT32: 414*2912Sartem { 415*2912Sartem dbus_int32_t value = libhal_device_get_property_int (hal_ctx, udi, key, &error); 416*2912Sartem printf (long_list?"*** new value: %d (0x%x) (int)\n":"%d (0x%x)", 417*2912Sartem value, value); 418*2912Sartem } 419*2912Sartem break; 420*2912Sartem case LIBHAL_PROPERTY_TYPE_UINT64: 421*2912Sartem { 422*2912Sartem dbus_uint64_t value = libhal_device_get_property_uint64 (hal_ctx, udi, key, &error); 423*2912Sartem printf (long_list?"*** new value: %llu (0x%llx) (uint64)\n":"%llu (0x%llx)", 424*2912Sartem (long long unsigned int) value, (long long unsigned int) value); 425*2912Sartem } 426*2912Sartem break; 427*2912Sartem case LIBHAL_PROPERTY_TYPE_DOUBLE: 428*2912Sartem printf (long_list?"*** new value: %g (double)\n":"%g", 429*2912Sartem libhal_device_get_property_double (hal_ctx, udi, key, &error)); 430*2912Sartem break; 431*2912Sartem case LIBHAL_PROPERTY_TYPE_BOOLEAN: 432*2912Sartem printf (long_list?"*** new value: %s (bool)\n":"%s", 433*2912Sartem libhal_device_get_property_bool (hal_ctx, udi, key, &error) ? "true" : "false"); 434*2912Sartem break; 435*2912Sartem case LIBHAL_PROPERTY_TYPE_STRLIST: 436*2912Sartem { 437*2912Sartem unsigned int i; 438*2912Sartem char **strlist; 439*2912Sartem 440*2912Sartem if (long_list) 441*2912Sartem printf ("*** new value: {"); 442*2912Sartem else 443*2912Sartem printf ("{"); 444*2912Sartem 445*2912Sartem strlist = libhal_device_get_property_strlist (hal_ctx, udi, key, &error); 446*2912Sartem for (i = 0; strlist[i] != 0; i++) { 447*2912Sartem printf ("'%s'", strlist[i]); 448*2912Sartem if (strlist[i+1] != NULL) 449*2912Sartem printf (", "); 450*2912Sartem } 451*2912Sartem if (long_list) 452*2912Sartem printf ("} (string list)\n"); 453*2912Sartem else 454*2912Sartem printf ("}"); 455*2912Sartem libhal_free_string_array (strlist); 456*2912Sartem break; 457*2912Sartem } 458*2912Sartem 459*2912Sartem default: 460*2912Sartem fprintf (stderr, "Unknown type %d='%c'\n", type, type); 461*2912Sartem break; 462*2912Sartem } 463*2912Sartem 464*2912Sartem if (dbus_error_is_set (&error)) 465*2912Sartem dbus_error_free (&error); 466*2912Sartem } 467*2912Sartem 468*2912Sartem /** Invoked when a property of a device in the Global Device List is 469*2912Sartem * changed, and we have we have subscribed to changes for that device. 470*2912Sartem * 471*2912Sartem * @param udi Univerisal Device Id 472*2912Sartem * @param key Key of property 473*2912Sartem */ 474*2912Sartem static void 475*2912Sartem property_modified (LibHalContext *ctx, 476*2912Sartem const char *udi, 477*2912Sartem const char *key, 478*2912Sartem dbus_bool_t is_removed, 479*2912Sartem dbus_bool_t is_added) 480*2912Sartem { 481*2912Sartem if (show_device && strcmp(show_device, udi)) 482*2912Sartem return; 483*2912Sartem 484*2912Sartem if (long_list) { 485*2912Sartem printf ("*** lshal: property_modified, udi=%s, key=%s\n", 486*2912Sartem udi, key); 487*2912Sartem printf (" is_removed=%s, is_added=%s\n", 488*2912Sartem is_removed ? "true" : "false", 489*2912Sartem is_added ? "true" : "false"); 490*2912Sartem if (!is_removed) 491*2912Sartem print_property (udi, key); 492*2912Sartem printf ("\n"); 493*2912Sartem } else { 494*2912Sartem printf ("%s property %s ", short_name (udi), key); 495*2912Sartem if (is_removed) 496*2912Sartem printf ("removed"); 497*2912Sartem else { 498*2912Sartem printf ("= "); 499*2912Sartem print_property (udi, key); 500*2912Sartem 501*2912Sartem if (is_added) 502*2912Sartem printf (" (new)"); 503*2912Sartem } 504*2912Sartem printf ("\n"); 505*2912Sartem } 506*2912Sartem } 507*2912Sartem 508*2912Sartem 509*2912Sartem /** Invoked when a property of a device in the Global Device List is 510*2912Sartem * changed, and we have we have subscribed to changes for that device. 511*2912Sartem * 512*2912Sartem * @param udi Univerisal Device Id 513*2912Sartem * @param condition_name Name of condition 514*2912Sartem * @param message D-BUS message with parameters 515*2912Sartem */ 516*2912Sartem static void 517*2912Sartem device_condition (LibHalContext *ctx, 518*2912Sartem const char *udi, 519*2912Sartem const char *condition_name, 520*2912Sartem const char *condition_details) 521*2912Sartem { 522*2912Sartem if (show_device && strcmp(show_device, udi)) 523*2912Sartem return; 524*2912Sartem 525*2912Sartem if (long_list) { 526*2912Sartem printf ("*** lshal: device_condition, udi=%s\n", udi); 527*2912Sartem printf (" condition_name=%s\n", condition_name); 528*2912Sartem printf (" condition_details=%s\n", condition_details); 529*2912Sartem printf ("\n"); 530*2912Sartem } else { 531*2912Sartem printf ("%s condition %s = %s\n", short_name (udi), 532*2912Sartem condition_name, condition_details); 533*2912Sartem } 534*2912Sartem } 535*2912Sartem 536*2912Sartem 537*2912Sartem /** Print out program usage. 538*2912Sartem * 539*2912Sartem * @param argc Number of arguments given to program 540*2912Sartem * @param argv Arguments given to program 541*2912Sartem */ 542*2912Sartem static void 543*2912Sartem usage (int argc, char *argv[]) 544*2912Sartem { 545*2912Sartem fprintf (stderr, "lshal version " PACKAGE_VERSION "\n"); 546*2912Sartem 547*2912Sartem fprintf (stderr, "\n" "usage : %s [options]\n", argv[0]); 548*2912Sartem fprintf (stderr, 549*2912Sartem "\n" 550*2912Sartem "Options:\n" 551*2912Sartem " -m, --monitor Monitor device list\n" 552*2912Sartem " -s, --short short output (print only nonstatic part of udi)\n" 553*2912Sartem " -l, --long Long output\n" 554*2912Sartem " -t, --tree Tree view\n" 555*2912Sartem " -u, --show <udi> Show only the specified device\n" 556*2912Sartem "\n" 557*2912Sartem " -h, --help Show this information and exit\n" 558*2912Sartem " -V, --version Print version number\n" 559*2912Sartem "\n" 560*2912Sartem "Without any given options lshal will start with option --long." 561*2912Sartem "\n" 562*2912Sartem "Shows all devices and their properties. If the --monitor option is given\n" 563*2912Sartem "then the device list and all devices are monitored for changes.\n" 564*2912Sartem "\n"); 565*2912Sartem } 566*2912Sartem 567*2912Sartem /** Entry point 568*2912Sartem * 569*2912Sartem * @param argc Number of arguments given to program 570*2912Sartem * @param argv Arguments given to program 571*2912Sartem * @return Return code 572*2912Sartem */ 573*2912Sartem int 574*2912Sartem main (int argc, char *argv[]) 575*2912Sartem { 576*2912Sartem DBusError error; 577*2912Sartem dbus_bool_t do_monitor = FALSE; 578*2912Sartem GMainLoop *loop; 579*2912Sartem DBusConnection *conn; 580*2912Sartem 581*2912Sartem if (argc == 1) { 582*2912Sartem /* This is the default case lshal without any options */ 583*2912Sartem long_list = TRUE; 584*2912Sartem } 585*2912Sartem else { 586*2912Sartem static const struct option long_options[] = { 587*2912Sartem {"monitor", no_argument, NULL, 'm'}, 588*2912Sartem {"long", no_argument, NULL, 'l'}, 589*2912Sartem {"short", no_argument, NULL, 's'}, 590*2912Sartem {"tree", no_argument, NULL, 't'}, 591*2912Sartem {"show", required_argument, NULL, 'u'}, 592*2912Sartem {"help", no_argument, NULL, 'h'}, 593*2912Sartem {"usage", no_argument, NULL, 'U'}, 594*2912Sartem {"version", no_argument, NULL, 'V'}, 595*2912Sartem {NULL, 0, NULL, 0} 596*2912Sartem }; 597*2912Sartem 598*2912Sartem while (1) { 599*2912Sartem int c; 600*2912Sartem 601*2912Sartem c = getopt_long (argc, argv, "mlstu:hUV", long_options, NULL); 602*2912Sartem 603*2912Sartem if (c == -1) { 604*2912Sartem /* this should happen e.g. if 'lshal -' and this is incorrect/incomplete option */ 605*2912Sartem if (!do_monitor && !long_list && !short_list && !tree_view && !show_device) { 606*2912Sartem usage (argc, argv); 607*2912Sartem return 1; 608*2912Sartem } 609*2912Sartem 610*2912Sartem break; 611*2912Sartem } 612*2912Sartem 613*2912Sartem switch (c) { 614*2912Sartem case 'm': 615*2912Sartem do_monitor = TRUE; 616*2912Sartem break; 617*2912Sartem 618*2912Sartem case 'l': 619*2912Sartem long_list = TRUE; 620*2912Sartem break; 621*2912Sartem 622*2912Sartem case 's': 623*2912Sartem short_list = TRUE; 624*2912Sartem long_list = FALSE; 625*2912Sartem break; 626*2912Sartem 627*2912Sartem case 't': 628*2912Sartem tree_view = TRUE; 629*2912Sartem break; 630*2912Sartem 631*2912Sartem case 'u': 632*2912Sartem if (strchr(optarg, '/') != NULL) 633*2912Sartem show_device = strdup(optarg); 634*2912Sartem else { 635*2912Sartem show_device = malloc(strlen(UDI_BASE) + strlen(optarg) + 1); 636*2912Sartem memcpy(show_device, UDI_BASE, strlen(UDI_BASE)); 637*2912Sartem memcpy(show_device + strlen(UDI_BASE), optarg, strlen(optarg) + 1); 638*2912Sartem } 639*2912Sartem 640*2912Sartem break; 641*2912Sartem 642*2912Sartem case 'h': 643*2912Sartem case 'U': 644*2912Sartem usage (argc, argv); 645*2912Sartem return 0; 646*2912Sartem 647*2912Sartem case 'V': 648*2912Sartem printf ("lshal version " PACKAGE_VERSION "\n"); 649*2912Sartem return 0; 650*2912Sartem 651*2912Sartem default: 652*2912Sartem usage (argc, argv); 653*2912Sartem return 1; 654*2912Sartem } 655*2912Sartem } 656*2912Sartem } 657*2912Sartem 658*2912Sartem if (do_monitor) 659*2912Sartem loop = g_main_loop_new (NULL, FALSE); 660*2912Sartem else 661*2912Sartem loop = NULL; 662*2912Sartem 663*2912Sartem dbus_error_init (&error); 664*2912Sartem conn = dbus_bus_get (DBUS_BUS_SYSTEM, &error); 665*2912Sartem if (conn == NULL) { 666*2912Sartem fprintf (stderr, "error: dbus_bus_get: %s: %s\n", 667*2912Sartem error.name, error.message); 668*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 669*2912Sartem return 1; 670*2912Sartem } 671*2912Sartem 672*2912Sartem if (do_monitor) 673*2912Sartem dbus_connection_setup_with_g_main (conn, NULL); 674*2912Sartem 675*2912Sartem if ((hal_ctx = libhal_ctx_new ()) == NULL) { 676*2912Sartem fprintf (stderr, "error: libhal_ctx_new\n"); 677*2912Sartem return 1; 678*2912Sartem } 679*2912Sartem if (!libhal_ctx_set_dbus_connection (hal_ctx, conn)) { 680*2912Sartem fprintf (stderr, "error: libhal_ctx_set_dbus_connection: %s: %s\n", 681*2912Sartem error.name, error.message); 682*2912Sartem return 1; 683*2912Sartem } 684*2912Sartem if (!libhal_ctx_init (hal_ctx, &error)) { 685*2912Sartem if (dbus_error_is_set(&error)) { 686*2912Sartem fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message); 687*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 688*2912Sartem } 689*2912Sartem fprintf (stderr, "Could not initialise connection to hald.\n" 690*2912Sartem "Normally this means the HAL daemon (hald) is not running or not ready.\n"); 691*2912Sartem return 1; 692*2912Sartem } 693*2912Sartem 694*2912Sartem libhal_ctx_set_device_added (hal_ctx, device_added); 695*2912Sartem libhal_ctx_set_device_removed (hal_ctx, device_removed); 696*2912Sartem libhal_ctx_set_device_new_capability (hal_ctx, device_new_capability); 697*2912Sartem libhal_ctx_set_device_lost_capability (hal_ctx, device_lost_capability); 698*2912Sartem libhal_ctx_set_device_property_modified (hal_ctx, property_modified); 699*2912Sartem libhal_ctx_set_device_condition (hal_ctx, device_condition); 700*2912Sartem 701*2912Sartem if (show_device) 702*2912Sartem dump_device (show_device); 703*2912Sartem else if (!do_monitor) 704*2912Sartem dump_devices (); 705*2912Sartem 706*2912Sartem /* run the main loop only if we should monitor */ 707*2912Sartem if (do_monitor && loop != NULL) { 708*2912Sartem if( long_list || short_list || tree_view ) 709*2912Sartem dump_devices (); 710*2912Sartem 711*2912Sartem if ( libhal_device_property_watch_all (hal_ctx, &error) == FALSE) { 712*2912Sartem fprintf (stderr, "error: monitoring devicelist - libhal_device_property_watch_all: %s: %s\n", 713*2912Sartem error.name, error.message); 714*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 715*2912Sartem return 1; 716*2912Sartem } 717*2912Sartem printf ("\nStart monitoring devicelist:\n" 718*2912Sartem "-------------------------------------------------\n"); 719*2912Sartem g_main_loop_run (loop); 720*2912Sartem } 721*2912Sartem 722*2912Sartem if ( libhal_ctx_shutdown (hal_ctx, &error) == FALSE) 723*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 724*2912Sartem libhal_ctx_free (hal_ctx); 725*2912Sartem 726*2912Sartem dbus_connection_close (conn); 727*2912Sartem dbus_connection_unref (conn); 728*2912Sartem 729*2912Sartem if (show_device) 730*2912Sartem free(show_device); 731*2912Sartem 732*2912Sartem return 0; 733*2912Sartem } 734*2912Sartem 735*2912Sartem /** 736*2912Sartem * @} 737*2912Sartem */ 738