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
usage(int argc,char * argv[])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
main(int argc,char * argv[])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 	dbus_bool_t udi_exists = FALSE;
92 	char *str;
93 	DBusError error;
94 
95 	if (argc <= 1) {
96 		usage (argc, argv);
97 		return 1;
98 	}
99 
100 	while (1) {
101 		int c;
102 		int option_index = 0;
103 		const char *opt;
104 		static struct option long_options[] = {
105 			{"udi", 1, NULL, 0},
106 			{"key", 1, NULL, 0},
107 			{"hex", 0, NULL, 0},
108 			{"verbose", 0, NULL, 0},
109 			{"version", 0, NULL, 0},
110 			{"help", 0, NULL, 0},
111 			{NULL, 0, NULL, 0}
112 		};
113 
114 		c = getopt_long (argc, argv, "",
115 				 long_options, &option_index);
116 		if (c == -1)
117 			break;
118 
119 		switch (c) {
120 		case 0:
121 			opt = long_options[option_index].name;
122 
123 			if (strcmp (opt, "help") == 0) {
124 				usage (argc, argv);
125 				return 0;
126 			} else if (strcmp (opt, "hex") == 0) {
127 				is_hex = TRUE;
128 			} else if (strcmp (opt, "verbose") == 0) {
129 				is_verbose = TRUE;
130 			} else if (strcmp (opt, "version") == 0) {
131 				is_version = TRUE;
132 			} else if (strcmp (opt, "key") == 0) {
133 				key = strdup (optarg);
134 			} else if (strcmp (opt, "udi") == 0) {
135 				udi = strdup (optarg);
136 			}
137 			break;
138 
139 		default:
140 			usage (argc, argv);
141 			return 1;
142 			break;
143 		}
144 	}
145 
146 	if (is_version) {
147 		printf ("hal-get-property " PACKAGE_VERSION "\n");
148 		return 0;
149 	}
150 
151 	if (udi == NULL || key == NULL) {
152 		usage (argc, argv);
153 		return 1;
154 	}
155 
156 	dbus_error_init (&error);
157 	if ((hal_ctx = libhal_ctx_new ()) == NULL) {
158 		fprintf (stderr, "error: libhal_ctx_new\n");
159 		return 1;
160 	}
161 	if (!libhal_ctx_set_dbus_connection (hal_ctx, dbus_bus_get (DBUS_BUS_SYSTEM, &error))) {
162 		fprintf (stderr, "error: libhal_ctx_set_dbus_connection: %s: %s\n", error.name, error.message);
163 		LIBHAL_FREE_DBUS_ERROR (&error);
164 		return 1;
165 	}
166 	if (!libhal_ctx_init (hal_ctx, &error)) {
167 		if (dbus_error_is_set(&error)) {
168 			fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message);
169 			dbus_error_free (&error);
170 		}
171 		fprintf (stderr, "Could not initialise connection to hald.\n"
172 				 "Normally this means the HAL daemon (hald) is not running or not ready.\n");
173 		return 1;
174 	}
175 
176         /* check UDI exists */
177 	udi_exists = libhal_device_exists (hal_ctx, udi, &error);
178 	if (!udi_exists) {
179 		fprintf (stderr, "error: UDI %s does not exist\n", udi);
180 		return 1;
181 	}
182         if (dbus_error_is_set(&error)) {
183 		fprintf (stderr, "error: libhal_device_exists: %s: %s\n", error.name, error.message);
184 		dbus_error_free (&error);
185 		return 1;
186 	}
187 
188 
189 	type = libhal_device_get_property_type (hal_ctx, udi, key, &error);
190 	if (type == LIBHAL_PROPERTY_TYPE_INVALID) {
191 		if (dbus_error_is_set(&error)) {
192 		        fprintf (stderr, "error: libhal_device_get_property_type: %s: %s\n", error.name, error.message);
193 			dbus_error_free (&error);
194 		} else {
195 		        fprintf (stderr, "error: libhal_device_get_property_type: invalid params.\n");
196 		}
197 		return 1;
198 	}
199 	/* emit the value to stdout */
200 	switch (type) {
201 	case LIBHAL_PROPERTY_TYPE_STRING:
202 		str = libhal_device_get_property_string (hal_ctx, udi, key, &error);
203 		if (is_verbose)
204 			printf ("Type is string\n");
205 		printf ("%s\n", str);
206 		libhal_free_string (str);
207 		break;
208 	case LIBHAL_PROPERTY_TYPE_INT32:
209 		if (is_verbose)
210 			printf ("Type is integer (shown in %s)\n",
211 				(is_hex ? "hexadecimal" : "decimal"));
212 		printf ((is_hex ? "%x\n" : "%d\n"),
213 			libhal_device_get_property_int (hal_ctx, udi, key, &error));
214 		break;
215 	case LIBHAL_PROPERTY_TYPE_UINT64:
216 		if (is_verbose)
217 			printf ("Type is uint64 (shown in %s)\n",
218 				(is_hex ? "hexadecimal" : "decimal"));
219 		printf ((is_hex ? "%llx\n" : "%llu\n"),
220 			(long long unsigned int) libhal_device_get_property_uint64 (hal_ctx, udi, key, &error));
221 		break;
222 	case LIBHAL_PROPERTY_TYPE_DOUBLE:
223 		if (is_verbose)
224 			printf ("Type is double\n");
225 		printf ("%f\n",
226 			libhal_device_get_property_double (hal_ctx, udi, key, &error));
227 		break;
228 	case LIBHAL_PROPERTY_TYPE_BOOLEAN:
229 		if (is_verbose)
230 			printf ("Type is boolean\n");
231 		printf ("%s\n",
232 			libhal_device_get_property_bool (hal_ctx, udi, key, &error) ? "true" : "false");
233 		break;
234 
235 	case LIBHAL_PROPERTY_TYPE_STRLIST:
236 	{
237 		unsigned int i;
238 		char **strlist;
239 
240 		if ((strlist = libhal_device_get_property_strlist (hal_ctx, udi, key, &error)) != NULL) {
241 
242 			for (i = 0; strlist[i] != 0; i++) {
243 				printf ("%s", strlist[i]);
244 				if (strlist[i+1] != NULL)
245 					printf (" ");
246 			}
247 		}
248 		break;
249 	}
250 	default:
251 		printf ("Unknown type %d='%c'\n", type, type);
252 		return 1;
253 		break;
254 	}
255 
256 	if (dbus_error_is_set (&error)) {
257 		fprintf (stderr, "error: %s: %s\n", error.name, error.message);
258 		dbus_error_free (&error);
259 		return 1;
260 	}
261 
262 
263 	return 0;
264 }
265 
266 /**
267  * @}
268  */
269