summaryrefslogtreecommitdiffstats
path: root/tools/ideviceinfo.c
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2010-01-28 22:18:41 +0100
committerGravatar Martin Szulecki2010-01-29 02:16:00 +0100
commit96101a1231a4ddfeb40fd738a24e108a3a904048 (patch)
tree65a8f54354d9acbbba93dac2c8602d07e469482c /tools/ideviceinfo.c
parent45b88ae3956de089fdc35605910f1359a1d3961c (diff)
downloadlibimobiledevice-96101a1231a4ddfeb40fd738a24e108a3a904048.tar.gz
libimobiledevice-96101a1231a4ddfeb40fd738a24e108a3a904048.tar.bz2
Global renames due to project rename to libimobiledevice
Diffstat (limited to 'tools/ideviceinfo.c')
-rw-r--r--tools/ideviceinfo.c336
1 files changed, 336 insertions, 0 deletions
diff --git a/tools/ideviceinfo.c b/tools/ideviceinfo.c
new file mode 100644
index 0000000..9183d92
--- /dev/null
+++ b/tools/ideviceinfo.c
@@ -0,0 +1,336 @@
1/*
2 * ideviceinfo.c
3 * Simple utility to show information about an attached device
4 *
5 * Copyright (c) 2009 Martin Szulecki All Rights Reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include <stdio.h>
23#include <string.h>
24#include <errno.h>
25#include <stdlib.h>
26#include <glib.h>
27
28#include <libimobiledevice/libimobiledevice.h>
29#include <libimobiledevice/lockdown.h>
30
31#define FORMAT_KEY_VALUE 1
32#define FORMAT_XML 2
33
34static const char *domains[] = {
35 "com.apple.disk_usage",
36 "com.apple.mobile.battery",
37/* FIXME: For some reason lockdownd segfaults on this, works sometimes though
38 "com.apple.mobile.debug",. */
39 "com.apple.xcode.developerdomain",
40 "com.apple.international",
41 "com.apple.mobile.data_sync",
42 "com.apple.mobile.tethered_sync",
43 "com.apple.mobile.mobile_application_usage",
44 "com.apple.mobile.backup",
45 "com.apple.mobile.nikita",
46 "com.apple.mobile.restriction",
47 "com.apple.mobile.user_preferences",
48 "com.apple.mobile.sync_data_class",
49 "com.apple.mobile.software_behavior",
50 "com.apple.mobile.iTunes.SQLMusicLibraryPostProcessCommands",
51 "com.apple.mobile.iTunes.accessories",
52 "com.apple.fairplay",
53 "com.apple.iTunes",
54 "com.apple.mobile.iTunes.store",
55 "com.apple.mobile.iTunes",
56 NULL
57};
58
59static int indent_level = 0;
60
61static int is_domain_known(char *domain)
62{
63 int i = 0;
64 while (domains[i] != NULL) {
65 if (strstr(domain, domains[i++])) {
66 return 1;
67 }
68 }
69 return 0;
70}
71
72static void plist_node_to_string(plist_t node);
73
74static void plist_array_to_string(plist_t node)
75{
76 /* iterate over items */
77 int i, count;
78 plist_t subnode = NULL;
79
80 count = plist_array_get_size(node);
81
82 for (i = 0; i < count; i++) {
83 subnode = plist_array_get_item(node, i);
84 printf("%*s", indent_level, "");
85 printf("%d: ", i);
86 plist_node_to_string(subnode);
87 }
88}
89
90static void plist_dict_to_string(plist_t node)
91{
92 /* iterate over key/value pairs */
93 plist_dict_iter it = NULL;
94
95 char* key = NULL;
96 plist_t subnode = NULL;
97 plist_dict_new_iter(node, &it);
98 plist_dict_next_item(node, it, &key, &subnode);
99 while (subnode)
100 {
101 printf("%*s", indent_level, "");
102 printf("%s", key);
103 if (plist_get_node_type(subnode) == PLIST_ARRAY)
104 printf("[%d]: ", plist_array_get_size(subnode));
105 else
106 printf(": ");
107 free(key);
108 key = NULL;
109 plist_node_to_string(subnode);
110 plist_dict_next_item(node, it, &key, &subnode);
111 }
112 free(it);
113}
114
115static void plist_node_to_string(plist_t node)
116{
117 char *s = NULL;
118 char *data = NULL;
119 double d;
120 uint8_t b;
121 uint64_t u = 0;
122 GTimeVal tv = { 0, 0 };
123
124 plist_type t;
125
126 if (!node)
127 return;
128
129 t = plist_get_node_type(node);
130
131 switch (t) {
132 case PLIST_BOOLEAN:
133 plist_get_bool_val(node, &b);
134 printf("%s\n", (b ? "true" : "false"));
135 break;
136
137 case PLIST_UINT:
138 plist_get_uint_val(node, &u);
139 printf("%llu\n", (long long)u);
140 break;
141
142 case PLIST_REAL:
143 plist_get_real_val(node, &d);
144 printf("%f\n", d);
145 break;
146
147 case PLIST_STRING:
148 plist_get_string_val(node, &s);
149 printf("%s\n", s);
150 free(s);
151 break;
152
153 case PLIST_KEY:
154 plist_get_key_val(node, &s);
155 printf("%s: ", s);
156 free(s);
157 break;
158
159 case PLIST_DATA:
160 plist_get_data_val(node, &data, &u);
161 s = g_base64_encode((guchar *)data, u);
162 free(data);
163 printf("%s\n", s);
164 g_free(s);
165 break;
166
167 case PLIST_DATE:
168 plist_get_date_val(node, (int32_t*)&tv.tv_sec, (int32_t*)&tv.tv_usec);
169 s = g_time_val_to_iso8601(&tv);
170 printf("%s\n", s);
171 free(s);
172 break;
173
174 case PLIST_ARRAY:
175 printf("\n");
176 indent_level++;
177 plist_array_to_string(node);
178 indent_level--;
179 break;
180
181 case PLIST_DICT:
182 printf("\n");
183 indent_level++;
184 plist_dict_to_string(node);
185 indent_level--;
186 break;
187
188 default:
189 break;
190 }
191}
192
193static void print_usage(int argc, char **argv)
194{
195 int i = 0;
196 char *name = NULL;
197
198 name = strrchr(argv[0], '/');
199 printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0]));
200 printf("Show information about a connected iPhone/iPod Touch.\n\n");
201 printf(" -d, --debug\t\tenable communication debugging\n");
202 printf(" -u, --uuid UUID\ttarget specific device by its 40-digit device UUID\n");
203 printf(" -q, --domain NAME\tset domain of query to NAME. Default: None\n");
204 printf(" -k, --key NAME\tonly query key specified by NAME. Default: All keys.\n");
205 printf(" -x, --xml\t\toutput information as xml plist instead of key/value pairs\n");
206 printf(" -h, --help\t\tprints usage information\n");
207 printf("\n");
208 printf(" Known domains are:\n\n");
209 while (domains[i] != NULL) {
210 printf(" %s\n", domains[i++]);
211 }
212 printf("\n");
213}
214
215int main(int argc, char *argv[])
216{
217 lockdownd_client_t client = NULL;
218 idevice_t phone = NULL;
219 idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
220 int i;
221 int format = FORMAT_KEY_VALUE;
222 char uuid[41];
223 char *domain = NULL;
224 char *key = NULL;
225 char *xml_doc = NULL;
226 uint32_t xml_length;
227 plist_t node = NULL;
228 plist_type node_type;
229 uuid[0] = 0;
230
231 /* parse cmdline args */
232 for (i = 1; i < argc; i++) {
233 if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) {
234 idevice_set_debug_level(1);
235 continue;
236 }
237 else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--uuid")) {
238 i++;
239 if (!argv[i] || (strlen(argv[i]) != 40)) {
240 print_usage(argc, argv);
241 return 0;
242 }
243 strcpy(uuid, argv[i]);
244 continue;
245 }
246 else if (!strcmp(argv[i], "-q") || !strcmp(argv[i], "--domain")) {
247 i++;
248 if (!argv[i] || (strlen(argv[i]) < 4)) {
249 print_usage(argc, argv);
250 return 0;
251 }
252 if (!is_domain_known(argv[i])) {
253 fprintf(stderr, "WARNING: Sending query with unknown domain \"%s\".\n", argv[i]);
254 }
255 domain = strdup(argv[i]);
256 continue;
257 }
258 else if (!strcmp(argv[i], "-k") || !strcmp(argv[i], "--key")) {
259 i++;
260 if (!argv[i] || (strlen(argv[i]) <= 1)) {
261 print_usage(argc, argv);
262 return 0;
263 }
264 key = strdup(argv[i]);
265 continue;
266 }
267 else if (!strcmp(argv[i], "-x") || !strcmp(argv[i], "--xml")) {
268 format = FORMAT_XML;
269 continue;
270 }
271 else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
272 print_usage(argc, argv);
273 return 0;
274 }
275 else {
276 print_usage(argc, argv);
277 return 0;
278 }
279 }
280
281 if (uuid[0] != 0) {
282 ret = idevice_new(&phone, uuid);
283 if (ret != IDEVICE_E_SUCCESS) {
284 printf("No device found with uuid %s, is it plugged in?\n", uuid);
285 return -1;
286 }
287 }
288 else
289 {
290 ret = idevice_new(&phone, NULL);
291 if (ret != IDEVICE_E_SUCCESS) {
292 printf("No device found, is it plugged in?\n");
293 return -1;
294 }
295 }
296
297 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "ideviceinfo")) {
298 idevice_free(phone);
299 return -1;
300 }
301
302 /* run query and output information */
303 if(lockdownd_get_value(client, domain, key, &node) == LOCKDOWN_E_SUCCESS) {
304 if (node) {
305 switch (format) {
306 case FORMAT_XML:
307 plist_to_xml(node, &xml_doc, &xml_length);
308 printf("%s", xml_doc);
309 free(xml_doc);
310 break;
311 case FORMAT_KEY_VALUE:
312 node_type = plist_get_node_type(node);
313 if (node_type == PLIST_DICT) {
314 plist_dict_to_string(node);
315 } else if (node_type == PLIST_ARRAY) {
316 plist_array_to_string(node);
317 break;
318 }
319 default:
320 if (key != NULL)
321 plist_node_to_string(node);
322 break;
323 }
324 plist_free(node);
325 node = NULL;
326 }
327 }
328
329 if (domain != NULL)
330 free(domain);
331 lockdownd_client_free(client);
332 idevice_free(phone);
333
334 return 0;
335}
336