1 /***************************************************************************
2  * CVSID: $Id$
3  *
4  * hal_get_property.c : Get property for a device
5  *
6  * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
7  *
8  * Licensed under the Academic Free License version 2.1
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23  *
24  **************************************************************************/
25 
26 
27 #ifdef HAVE_CONFIG_H
28 #  include <config.h>
29 #endif
30 
31 #include <stdio.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <getopt.h>
35 
36 #include <libhal.h>
37 
38 /**
39  * @defgroup HalGetProperty  Get HAL device property
40  * @ingroup HalMisc
41  *
42  * @brief A commandline tool getting a property of a device. Uses libhal
43  *
44  * @{
45  */
46 
47 static LibHalContext *hal_ctx;
48 
49 /** Print out program usage.
50  *
51  *  @param  argc                Number of arguments given to program
52  *  @param  argv                Arguments given to program
53  */
54 static void
55 usage (int argc, char *argv[])
56 {
57 	fprintf (stderr,
58  "\n"
59  "usage : hal-get-property --udi <udi> --key <key> \n"
60  "                        [--hex] [--help] [--verbose] [--version]\n");
61 	fprintf (stderr,
62  "\n"
63  "        --udi            Unique Device Id\n"
64  "        --key            Key of the property to get\n"
65  "        --hex            Show integer values in hex (without leading 0x)\n"
66  "        --verbose        Be verbose\n"
67  "        --version        Show version and exit\n"
68  "        --help           Show this information and exit\n"
69  "\n"
70  "This program retrieves a property from a device. If the property exist\n"
71  "then it is printed on stdout and this program exits with exit code 0.\n"
72  "On error, the program exits with an exit code different from 0\n"
73  "\n");
74 }
75 
76 /** Entry point
77  *
78  *  @param  argc                Number of arguments given to program
79  *  @param  argv                Arguments given to program
80  *  @return                     Return code
81  */
82 int
83 main (int argc, char *argv[])
84 {
85 	char *udi = NULL;
86 	char *key = NULL;
87 	int type;
88 	dbus_bool_t is_hex = FALSE;
89 	dbus_bool_t is_verbose = FALSE;
90 	dbus_bool_t is_version = FALSE;
91 	char *str;
92 	DBusError error;
93 
94 	if (argc <= 1) {
95 		usage (argc, argv);
96 		return 1;
97 	}
98 
99 	while (1) {
100 		int c;
101 		int option_index = 0;
102 		const char *opt;
103 		static struct option long_options[] = {
104 			{"udi", 1, NULL, 0},
105 			{"key", 1, NULL, 0},
106 			{"hex", 0, NULL, 0},
107 			{"verbose", 0, NULL, 0},
108 			{"version", 0, NULL, 0},
109 			{"help", 0, NULL, 0},
110 			{NULL, 0, NULL, 0}
111 		};
112 
113 		c = getopt_long (argc, argv, "",
114 				 long_options, &option_index);
115 		if (c == -1)
116 			break;
117 
118 		switch (c) {
119 		case 0:
120 			opt = long_options[option_index].name;
121 
122 			if (strcmp (opt, "help") == 0) {
123 				usage (argc, argv);
124 				return 0;
125 			} else if (strcmp (opt, "hex") == 0) {
126 				is_hex = TRUE;
127 			} else if (strcmp (opt, "verbose") == 0) {
128 				is_verbose = TRUE;
129 			} else if (strcmp (opt, "version") == 0) {
130 				is_version = TRUE;
131 			} else if (strcmp (opt, "key") == 0) {
132 				key = strdup (optarg);
133 			} else if (strcmp (opt, "udi") == 0) {
134 				udi = strdup (optarg);
135 			}
136 			break;
137 
138 		default:
139 			usage (argc, argv);
140 			return 1;
141 			break;
142 		}
143 	}
144 
145 	if (is_version) {
146 		printf ("hal-get-property " PACKAGE_VERSION "\n");
147 		return 0;
148 	}
149 
150 	if (udi == NULL || key == NULL) {
151 		usage (argc, argv);
152 		return 1;
153 	}
154 
155 	dbus_error_init (&error);
156 	if ((hal_ctx = libhal_ctx_new ()) == NULL) {
157 		fprintf (stderr, "error: libhal_ctx_new\n");
158 		return 1;
159 	}
160 	if (!libhal_ctx_set_dbus_connection (hal_ctx, dbus_bus_get (DBUS_BUS_SYSTEM, &error))) {
161 		fprintf (stderr, "error: libhal_ctx_set_dbus_connection: %s: %s\n", error.name, error.message);
162 		LIBHAL_FREE_DBUS_ERROR (&error);
163 		return 1;
164 	}
165 	if (!libhal_ctx_init (hal_ctx, &error)) {
166 		if (dbus_error_is_set(&error)) {
167 			fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message);
168 			LIBHAL_FREE_DBUS_ERROR (&error);
169 		}
170 		fprintf (stderr, "Could not initialise connection to hald.\n"
171 				 "Normally this means the HAL daemon (hald) is not running or not ready.\n");
172 		return 1;
173 	}
174 
175 	type = libhal_device_get_property_type (hal_ctx, udi, key, &error);
176 	if (type == LIBHAL_PROPERTY_TYPE_INVALID) {
177 		fprintf (stderr, "error: libhal_device_get_property_type: %s: %s\n", error.name, error.message);
178 		LIBHAL_FREE_DBUS_ERROR (&error);
179 		return 1;
180 	}
181 	/* emit the value to stdout */
182 	switch (type) {
183 	case LIBHAL_PROPERTY_TYPE_STRING:
184 		str = libhal_device_get_property_string (hal_ctx, udi, key, &error);
185 		if (is_verbose)
186 			printf ("Type is string\n");
187 		printf ("%s\n", str);
188 		libhal_free_string (str);
189 		break;
190 	case LIBHAL_PROPERTY_TYPE_INT32:
191 		if (is_verbose)
192 			printf ("Type is integer (shown in %s)\n",
193 				(is_hex ? "hexadecimal" : "decimal"));
194 		printf ((is_hex ? "%x\n" : "%d\n"),
195 			libhal_device_get_property_int (hal_ctx, udi, key, &error));
196 		break;
197 	case LIBHAL_PROPERTY_TYPE_UINT64:
198 		if (is_verbose)
199 			printf ("Type is uint64 (shown in %s)\n",
200 				(is_hex ? "hexadecimal" : "decimal"));
201 		printf ((is_hex ? "%llx\n" : "%llu\n"),
202 			(long long unsigned int) libhal_device_get_property_uint64 (hal_ctx, udi, key, &error));
203 		break;
204 	case LIBHAL_PROPERTY_TYPE_DOUBLE:
205 		if (is_verbose)
206 			printf ("Type is double\n");
207 		printf ("%f\n",
208 			libhal_device_get_property_double (hal_ctx, udi, key, &error));
209 		break;
210 	case LIBHAL_PROPERTY_TYPE_BOOLEAN:
211 		if (is_verbose)
212 			printf ("Type is boolean\n");
213 		printf ("%s\n",
214 			libhal_device_get_property_bool (hal_ctx, udi, key, &error) ? "true" : "false");
215 		break;
216 
217 	case LIBHAL_PROPERTY_TYPE_STRLIST:
218 	{
219 		unsigned int i;
220 		char **strlist;
221 
222 		if ((strlist = libhal_device_get_property_strlist (hal_ctx, udi, key, &error)) != NULL) {
223 
224 			for (i = 0; strlist[i] != 0; i++) {
225 				printf ("%s", strlist[i]);
226 				if (strlist[i+1] != NULL)
227 					printf (" ");
228 			}
229 		}
230 		break;
231 	}
232 	default:
233 		printf ("Unknown type %d='%c'\n", type, type);
234 		return 1;
235 		break;
236 	}
237 
238 	if (dbus_error_is_set (&error)) {
239 		fprintf (stderr, "error: %s: %s\n", error.name, error.message);
240 		dbus_error_free (&error);
241 		return 1;
242 	}
243 
244 
245 	return 0;
246 }
247 
248 /**
249  * @}
250  */
251