1 /*
2  * idevice_id.c
3  * Prints device name or a list of attached devices
4  *
5  * Copyright (C) 2010-2018 Nikias Bassen <nikias@gmx.li>
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 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 
26 #define TOOL_NAME "idevice_id"
27 
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <getopt.h>
32 #include <libimobiledevice/libimobiledevice.h>
33 #include <libimobiledevice/lockdown.h>
34 
35 #define MODE_NONE 0
36 #define MODE_SHOW_ID 1
37 #define MODE_LIST_DEVICES 2
38 
print_usage(int argc,char ** argv,int is_error)39 static void print_usage(int argc, char **argv, int is_error)
40 {
41 	char *name = NULL;
42 	name = strrchr(argv[0], '/');
43 	fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] [UDID]\n", (name ? name + 1: argv[0]));
44 	fprintf(is_error ? stderr : stdout,
45 		"\n" \
46 		"List attached devices or print device name of given device.\n" \
47 		"\n" \
48 		"  If UDID is given, the name of the connected device with that UDID" \
49 		"  will be retrieved.\n" \
50 		"\n" \
51 		"OPTIONS:\n" \
52 		"  -l, --list      list UDIDs of all devices attached via USB\n" \
53 		"  -n, --network   list UDIDs of all devices available via network\n" \
54 		"  -d, --debug     enable communication debugging\n" \
55 		"  -h, --help      prints usage information\n" \
56 		"  -v, --version   prints version information\n" \
57 		"\n" \
58 		"Homepage:    <" PACKAGE_URL ">\n" \
59 		"Bug Reports: <" PACKAGE_BUGREPORT ">\n"
60 	);
61 }
62 
main(int argc,char ** argv)63 int main(int argc, char **argv)
64 {
65 	idevice_t device = NULL;
66 	lockdownd_client_t client = NULL;
67 	idevice_info_t *dev_list = NULL;
68 	char *device_name = NULL;
69 	int ret = 0;
70 	int i;
71 	int mode = MODE_LIST_DEVICES;
72 	int include_usb = 0;
73 	int include_network = 0;
74 	const char* udid = NULL;
75 
76 	int c = 0;
77 	const struct option longopts[] = {
78 		{ "debug", no_argument, NULL, 'd' },
79 		{ "help",  no_argument, NULL, 'h' },
80 		{ "list",  no_argument, NULL, 'l' },
81 		{ "network", no_argument, NULL, 'n' },
82 		{ "version", no_argument, NULL, 'v' },
83 		{ NULL, 0, NULL, 0}
84 	};
85 
86 	while ((c = getopt_long(argc, argv, "dhlnv", longopts, NULL)) != -1) {
87 		switch (c) {
88 		case 'd':
89 			idevice_set_debug_level(1);
90 			break;
91 		case 'h':
92 			print_usage(argc, argv, 0);
93 			exit(EXIT_SUCCESS);
94 		case 'l':
95 			mode = MODE_LIST_DEVICES;
96 			include_usb = 1;
97 			break;
98 		case 'n':
99 			mode = MODE_LIST_DEVICES;
100 			include_network = 1;
101 			break;
102 		case 'v':
103 			printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
104 			return 0;
105 		default:
106 			print_usage(argc, argv, 1);
107 			exit(EXIT_FAILURE);
108 		}
109 	}
110 	argc -= optind;
111 	argv += optind;
112 
113 	if (argc == 1) {
114 		mode = MODE_SHOW_ID;
115 	} else if (argc == 0 && optind == 1) {
116 		include_usb = 1;
117 		include_network = 1;
118 	}
119 	udid = argv[0];
120 
121 	switch (mode) {
122 	case MODE_SHOW_ID:
123 		idevice_new_with_options(&device, udid, IDEVICE_LOOKUP_USBMUX | IDEVICE_LOOKUP_NETWORK);
124 		if (!device) {
125 			fprintf(stderr, "ERROR: No device with UDID %s attached.\n", udid);
126 			return -2;
127 		}
128 
129 		if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(device, &client, TOOL_NAME)) {
130 			idevice_free(device);
131 			fprintf(stderr, "ERROR: Connecting to device failed!\n");
132 			return -2;
133 		}
134 
135 		if ((LOCKDOWN_E_SUCCESS != lockdownd_get_device_name(client, &device_name)) || !device_name) {
136 			fprintf(stderr, "ERROR: Could not get device name!\n");
137 			ret = -2;
138 		}
139 
140 		lockdownd_client_free(client);
141 		idevice_free(device);
142 
143 		if (ret == 0) {
144 			printf("%s\n", device_name);
145 		}
146 
147 		if (device_name) {
148 			free(device_name);
149 		}
150 		break;
151 
152 	case MODE_LIST_DEVICES:
153 	default:
154 		if (idevice_get_device_list_extended(&dev_list, &i) < 0) {
155 			fprintf(stderr, "ERROR: Unable to retrieve device list!\n");
156 			return -1;
157 		}
158 		for (i = 0; dev_list[i] != NULL; i++) {
159 			if (dev_list[i]->conn_type == CONNECTION_USBMUXD && !include_usb) continue;
160 			if (dev_list[i]->conn_type == CONNECTION_NETWORK && !include_network) continue;
161 			printf("%s", dev_list[i]->udid);
162 			if (include_usb && include_network) {
163 				if (dev_list[i]->conn_type == CONNECTION_NETWORK) {
164 					printf(" (Network)");
165 				} else {
166 					printf(" (USB)");
167 				}
168 			}
169 			printf("\n");
170 		}
171 		idevice_device_list_extended_free(dev_list);
172 		break;
173 	}
174 	return ret;
175 }
176