18c2aff776a775d34a4c9893a4c72e0434d68e36artem/***************************************************************************
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * CVSID: $Id$
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * lshal.c : Show devices managed by HAL
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Copyright (C) 2005 Pierre Ossman, <drzeus@drzeus.cx>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Licensed under the Academic Free License version 2.1
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * This program is free software; you can redistribute it and/or modify
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * it under the terms of the GNU General Public License as published by
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * the Free Software Foundation; either version 2 of the License, or
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * (at your option) any later version.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * This program is distributed in the hope that it will be useful,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * but WITHOUT ANY WARRANTY; without even the implied warranty of
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * GNU General Public License for more details.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * You should have received a copy of the GNU General Public License
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * along with this program; if not, write to the Free Software
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18c2aff776a775d34a4c9893a4c72e0434d68e36artem **************************************************************************/
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @defgroup HalLsHal List HAL devices
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @ingroup HalMisc
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @brief A commandline tool, lshal, for displaying and, optionally,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * monitor the devices managed by the HAL daemon. Uses libhal.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Macro for terminating the program on an unrecoverable error */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#define DIE(expr) do {printf("*** [DIE] %s:%s():%d : ", __FILE__, __FUNCTION__, __LINE__); printf expr; printf("\n"); exit(1); } while(0)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Generate a short name for a device
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param udi Universal Device Id
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic const char *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Print all properties of a device
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param udi Universal Device Id
18c2aff776a775d34a4c9893a4c72e0434d68e36artem props = libhal_device_get_all_properties (hal_ctx, udi, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* NOTE : This may be NULL if the device was removed
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * in the daemon; this is because
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * hal_device_get_all_properties() is a in
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * essence an IPC call and other stuff may
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * be happening..
18c2aff776a775d34a4c9893a4c72e0434d68e36artem for (libhal_psi_init (&it, props); libhal_psi_has_more (&it); libhal_psi_next (&it)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (long long unsigned int) libhal_psi_get_uint64 (&it));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unsigned int i;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem for (i = 0; strlist[i] != 0; i++) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Dumps information about a single device
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param udi Universal Device Id
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Dump all children of device
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param udi Universal Device Id of parent
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param num_devices Total number of devices in device list
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param devices List of devices
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param depth Current recursion depth
18c2aff776a775d34a4c9893a4c72e0434d68e36artemdump_children (char *udi, int num_devices, struct Device *devices, int depth)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem for (i = 0; i < num_devices; i++) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem for (j = 0;j < depth;j++)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dump_children(devices[i].name, num_devices, devices, depth + 1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Dump all devices to stdout
18c2aff776a775d34a4c9893a4c72e0434d68e36artem device_names = libhal_get_all_devices (hal_ctx, &num_devices, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem devices = malloc (sizeof(struct Device) * num_devices);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem for (i = 0;i < num_devices;i++) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem devices[i].parent = libhal_device_get_property_string (hal_ctx,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Free the error (which include a dbus_error_init())
18c2aff776a775d34a4c9893a4c72e0434d68e36artem This should prevent errors if a call above fails */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "Dumping %d device(s) from the Global Device List:\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "-------------------------------------------------\n",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem for (i = 0;i < num_devices;i++) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "Dumped %d device(s) from the Global Device List.\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "------------------------------------------------\n",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Invoked when a device is added to the Global Device List. Simply prints
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * a message on stdout.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param udi Universal Device Id
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *udi)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Invoked when a device is removed from the Global Device List. Simply
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * prints a message on stdout.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param udi Universal Device Id
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *udi)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("*** lshal: device_removed, udi='%s'\n", udi);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Invoked when device in the Global Device List acquires a new capability.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Prints the name of the capability to stdout.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param udi Universal Device Id
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param capability Name of capability
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *udi,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *capability)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("*** lshal: new_capability, udi='%s'\n", udi);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Invoked when device in the Global Device List loses a capability.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Prints the name of the capability to stdout.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param udi Universal Device Id
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param capability Name of capability
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *udi,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *capability)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("*** lshal: lost_capability, udi='%s'\n", udi);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Acquires and prints the value of of a property to stdout.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param udi Universal Device Id
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param key Key of property
18c2aff776a775d34a4c9893a4c72e0434d68e36artem type = libhal_device_get_property_type (hal_ctx, udi, key, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem str = libhal_device_get_property_string (hal_ctx, udi, key, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf (long_list?"*** new value: '%s' (string)\n":"'%s'", str);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dbus_int32_t value = libhal_device_get_property_int (hal_ctx, udi, key, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf (long_list?"*** new value: %d (0x%x) (int)\n":"%d (0x%x)",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dbus_uint64_t value = libhal_device_get_property_uint64 (hal_ctx, udi, key, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf (long_list?"*** new value: %llu (0x%llx) (uint64)\n":"%llu (0x%llx)",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (long long unsigned int) value, (long long unsigned int) value);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf (long_list?"*** new value: %g (double)\n":"%g",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_device_get_property_double (hal_ctx, udi, key, &error));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_device_get_property_bool (hal_ctx, udi, key, &error) ? "true" : "false");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unsigned int i;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem strlist = libhal_device_get_property_strlist (hal_ctx, udi, key, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem for (i = 0; strlist[i] != 0; i++) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "Unknown type %d='%c'\n", type, type);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Invoked when a property of a device in the Global Device List is
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * changed, and we have we have subscribed to changes for that device.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param udi Univerisal Device Id
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param key Key of property
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *udi,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *key,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("*** lshal: property_modified, udi=%s, key=%s\n",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Invoked when a property of a device in the Global Device List is
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * changed, and we have we have subscribed to changes for that device.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param udi Univerisal Device Id
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param condition_name Name of condition
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param message D-BUS message with parameters
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *udi,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("*** lshal: device_condition, udi=%s\n", udi);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf (" condition_details=%s\n", condition_details);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Print out program usage.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param argc Number of arguments given to program
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param argv Arguments given to program
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "lshal version " PACKAGE_VERSION "\n");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "\n" "usage : %s [options]\n", argv[0]);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "Options:\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem " -m, --monitor Monitor device list\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem " -s, --short short output (print only nonstatic part of udi)\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem " -l, --long Long output\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem " -t, --tree Tree view\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem " -u, --show <udi> Show only the specified device\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem " -h, --help Show this information and exit\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem " -V, --version Print version number\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "Without any given options lshal will start with option --long."
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "Shows all devices and their properties. If the --monitor option is given\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "then the device list and all devices are monitored for changes.\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Entry point
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param argc Number of arguments given to program
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param argv Arguments given to program
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @return Return code
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* This is the default case lshal without any options */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem while (1) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem c = getopt_long (argc, argv, "mlstu:hUV", long_options, NULL);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (c == -1) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* this should happen e.g. if 'lshal -' and this is incorrect/incomplete option */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (!do_monitor && !long_list && !short_list && !tree_view && !show_device) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem switch (c) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem show_device = malloc(strlen(UDI_BASE) + strlen(optarg) + 1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem memcpy(show_device + strlen(UDI_BASE), optarg, strlen(optarg) + 1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (!libhal_ctx_set_dbus_connection (hal_ctx, conn)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "error: libhal_ctx_set_dbus_connection: %s: %s\n",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "Could not initialise connection to hald.\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "Normally this means the HAL daemon (hald) is not running or not ready.\n");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_ctx_set_device_removed (hal_ctx, device_removed);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_ctx_set_device_new_capability (hal_ctx, device_new_capability);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_ctx_set_device_lost_capability (hal_ctx, device_lost_capability);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_ctx_set_device_property_modified (hal_ctx, property_modified);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_ctx_set_device_condition (hal_ctx, device_condition);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* run the main loop only if we should monitor */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ( libhal_device_property_watch_all (hal_ctx, &error) == FALSE) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "error: monitoring devicelist - libhal_device_property_watch_all: %s: %s\n",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "-------------------------------------------------\n");