diff options
Diffstat (limited to 'tools/idevicediagnostics.c')
-rw-r--r-- | tools/idevicediagnostics.c | 235 |
1 files changed, 112 insertions, 123 deletions
diff --git a/tools/idevicediagnostics.c b/tools/idevicediagnostics.c index 66ed589..e699bc4 100644 --- a/tools/idevicediagnostics.c +++ b/tools/idevicediagnostics.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <stdio.h> | 28 | #include <stdio.h> |
29 | #include <string.h> | 29 | #include <string.h> |
30 | #include <stdlib.h> | 30 | #include <stdlib.h> |
31 | #include <getopt.h> | ||
31 | #include <errno.h> | 32 | #include <errno.h> |
32 | #include <time.h> | 33 | #include <time.h> |
33 | #ifndef WIN32 | 34 | #ifndef WIN32 |
@@ -59,7 +60,34 @@ static void print_xml(plist_t node) | |||
59 | } | 60 | } |
60 | } | 61 | } |
61 | 62 | ||
62 | void print_usage(int argc, char **argv); | 63 | static void print_usage(int argc, char **argv, int is_error) |
64 | { | ||
65 | char *name = strrchr(argv[0], '/'); | ||
66 | fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0])); | ||
67 | fprintf(is_error ? stderr : stdout, | ||
68 | "\n" | ||
69 | "Use diagnostics interface of a device running iOS 4 or later.\n" | ||
70 | "\n" | ||
71 | "Where COMMAND is one of:\n" | ||
72 | " diagnostics [TYPE] print diagnostics information from device by TYPE (All, WiFi, GasGauge, NAND)\n" | ||
73 | " mobilegestalt KEY [...] print mobilegestalt keys passed as arguments separated by a space.\n" | ||
74 | " ioreg [PLANE] print IORegistry of device, optionally by PLANE (IODeviceTree, IOPower, IOService) (iOS 5+ only)\n" | ||
75 | " ioregentry [KEY] print IORegistry entry of device (AppleARMPMUCharger, ASPStorage, ...) (iOS 5+ only)\n" | ||
76 | " shutdown shutdown device\n" | ||
77 | " restart restart device\n" | ||
78 | " sleep put device into sleep mode (disconnects from host)\n" | ||
79 | "\n" | ||
80 | "The following OPTIONS are accepted:\n" | ||
81 | " -u, --udid UDID target specific device by UDID\n" | ||
82 | " -n, --network connect to network device\n" | ||
83 | " -d, --debug enable communication debugging\n" | ||
84 | " -h, --help prints usage information\n" | ||
85 | " -v, --version prints version information\n" | ||
86 | "\n" | ||
87 | "Homepage: <" PACKAGE_URL ">\n" | ||
88 | "Bug Reports: <" PACKAGE_BUGREPORT ">\n" | ||
89 | ); | ||
90 | } | ||
63 | 91 | ||
64 | int main(int argc, char **argv) | 92 | int main(int argc, char **argv) |
65 | { | 93 | { |
@@ -69,130 +97,119 @@ int main(int argc, char **argv) | |||
69 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; | 97 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
70 | lockdownd_service_descriptor_t service = NULL; | 98 | lockdownd_service_descriptor_t service = NULL; |
71 | int result = EXIT_FAILURE; | 99 | int result = EXIT_FAILURE; |
72 | int i; | ||
73 | const char *udid = NULL; | 100 | const char *udid = NULL; |
74 | int use_network = 0; | 101 | int use_network = 0; |
75 | int cmd = CMD_NONE; | 102 | int cmd = CMD_NONE; |
76 | char* cmd_arg = NULL; | 103 | char* cmd_arg = NULL; |
77 | plist_t node = NULL; | 104 | plist_t node = NULL; |
78 | plist_t keys = NULL; | 105 | plist_t keys = NULL; |
106 | int c = 0; | ||
107 | const struct option longopts[] = { | ||
108 | { "debug", no_argument, NULL, 'd' }, | ||
109 | { "help", no_argument, NULL, 'h' }, | ||
110 | { "udid", required_argument, NULL, 'u' }, | ||
111 | { "network", no_argument, NULL, 'n' }, | ||
112 | { "version", no_argument, NULL, 'v' }, | ||
113 | { NULL, 0, NULL, 0} | ||
114 | }; | ||
79 | 115 | ||
80 | #ifndef WIN32 | 116 | #ifndef WIN32 |
81 | signal(SIGPIPE, SIG_IGN); | 117 | signal(SIGPIPE, SIG_IGN); |
82 | #endif | 118 | #endif |
83 | /* parse cmdline args */ | 119 | /* parse cmdline args */ |
84 | for (i = 1; i < argc; i++) { | 120 | while ((c = getopt_long(argc, argv, "dhu:nv", longopts, NULL)) != -1) { |
85 | if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { | 121 | switch (c) { |
122 | case 'd': | ||
86 | idevice_set_debug_level(1); | 123 | idevice_set_debug_level(1); |
87 | continue; | 124 | break; |
88 | } | 125 | case 'u': |
89 | else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { | 126 | if (!*optarg) { |
90 | i++; | 127 | fprintf(stderr, "ERROR: UDID argument must not be empty!\n"); |
91 | if (!argv[i] || !*argv[i]) { | 128 | print_usage(argc, argv, 1); |
92 | print_usage(argc, argv); | 129 | return 2; |
93 | result = EXIT_SUCCESS; | ||
94 | goto cleanup; | ||
95 | } | 130 | } |
96 | udid = argv[i]; | 131 | udid = optarg; |
97 | continue; | 132 | break; |
98 | } | 133 | case 'n': |
99 | else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) { | ||
100 | use_network = 1; | 134 | use_network = 1; |
101 | continue; | 135 | break; |
102 | } | 136 | case 'h': |
103 | else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { | 137 | print_usage(argc, argv, 0); |
104 | print_usage(argc, argv); | 138 | return 0; |
105 | result = EXIT_SUCCESS; | 139 | case 'v': |
106 | goto cleanup; | ||
107 | } | ||
108 | else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { | ||
109 | printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); | 140 | printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); |
110 | result = EXIT_SUCCESS; | 141 | return 0; |
111 | goto cleanup; | 142 | default: |
143 | print_usage(argc, argv, 1); | ||
144 | return 2; | ||
112 | } | 145 | } |
113 | else if (!strcmp(argv[i], "sleep")) { | 146 | } |
114 | cmd = CMD_SLEEP; | 147 | argc -= optind; |
115 | } | 148 | argv += optind; |
116 | else if (!strcmp(argv[i], "restart")) { | ||
117 | cmd = CMD_RESTART; | ||
118 | } | ||
119 | else if (!strcmp(argv[i], "shutdown")) { | ||
120 | cmd = CMD_SHUTDOWN; | ||
121 | } | ||
122 | else if (!strcmp(argv[i], "diagnostics")) { | ||
123 | cmd = CMD_DIAGNOSTICS; | ||
124 | /* read type */ | ||
125 | i++; | ||
126 | if (!argv[i] || ((strcmp(argv[i], "All") != 0) && (strcmp(argv[i], "WiFi") != 0) && (strcmp(argv[i], "GasGauge") != 0) && (strcmp(argv[i], "NAND") != 0) && (strcmp(argv[i], "HDMI") != 0))) { | ||
127 | if (argv[i] == NULL) { | ||
128 | cmd_arg = strdup("All"); | ||
129 | continue; | ||
130 | } | ||
131 | 149 | ||
132 | if (!strncmp(argv[i], "-", 1)) { | 150 | if (!argv[0]) { |
133 | cmd_arg = strdup("All"); | 151 | fprintf(stderr, "ERROR: No command specified\n"); |
134 | i--; | 152 | print_usage(argc+optind, argv-optind, 1); |
135 | continue; | 153 | return 2; |
136 | } | 154 | } |
137 | 155 | ||
138 | printf("ERROR: Unknown TYPE %s\n", argv[i]); | 156 | if (!strcmp(argv[0], "sleep")) { |
139 | print_usage(argc, argv); | 157 | cmd = CMD_SLEEP; |
158 | } | ||
159 | else if (!strcmp(argv[0], "restart")) { | ||
160 | cmd = CMD_RESTART; | ||
161 | } | ||
162 | else if (!strcmp(argv[0], "shutdown")) { | ||
163 | cmd = CMD_SHUTDOWN; | ||
164 | } | ||
165 | else if (!strcmp(argv[0], "diagnostics")) { | ||
166 | cmd = CMD_DIAGNOSTICS; | ||
167 | /* read type */ | ||
168 | if (!argv[1] || ((strcmp(argv[1], "All") != 0) && (strcmp(argv[1], "WiFi") != 0) && (strcmp(argv[1], "GasGauge") != 0) && (strcmp(argv[1], "NAND") != 0) && (strcmp(argv[1], "HDMI") != 0))) { | ||
169 | if (argv[1] == NULL) { | ||
170 | cmd_arg = strdup("All"); | ||
171 | } else { | ||
172 | fprintf(stderr, "ERROR: Unknown TYPE %s\n", argv[1]); | ||
173 | print_usage(argc+optind, argv-optind, 1); | ||
140 | goto cleanup; | 174 | goto cleanup; |
141 | } | 175 | } |
142 | |||
143 | cmd_arg = strdup(argv[i]); | ||
144 | continue; | ||
145 | } | 176 | } |
146 | else if (!strcmp(argv[i], "mobilegestalt")) { | 177 | cmd_arg = strdup(argv[1]); |
147 | cmd = CMD_MOBILEGESTALT; | 178 | } |
148 | /* read keys */ | 179 | else if (!strcmp(argv[0], "mobilegestalt")) { |
149 | i++; | 180 | cmd = CMD_MOBILEGESTALT; |
150 | 181 | /* read keys */ | |
151 | if (!argv[i] || argv[i] == NULL || (!strncmp(argv[i], "-", 1))) { | 182 | if (!argv[1] || !*argv[1]) { |
152 | printf("ERROR: Please supply the key to query.\n"); | 183 | fprintf(stderr, "ERROR: Please supply the key to query.\n"); |
153 | print_usage(argc, argv); | 184 | print_usage(argc, argv, 1); |
154 | goto cleanup; | 185 | goto cleanup; |
155 | } | ||
156 | |||
157 | keys = plist_new_array(); | ||
158 | while(1) { | ||
159 | if (argv[i] && (strlen(argv[i]) >= 2) && (strncmp(argv[i], "-", 1) != 0)) { | ||
160 | plist_array_append_item(keys, plist_new_string(argv[i])); | ||
161 | i++; | ||
162 | } else { | ||
163 | i--; | ||
164 | break; | ||
165 | } | ||
166 | } | ||
167 | continue; | ||
168 | } | 186 | } |
169 | else if (!strcmp(argv[i], "ioreg")) { | 187 | int i = 1; |
170 | cmd = CMD_IOREGISTRY; | 188 | keys = plist_new_array(); |
171 | /* read plane */ | 189 | while (argv[i] && *argv[i]) { |
190 | plist_array_append_item(keys, plist_new_string(argv[i])); | ||
172 | i++; | 191 | i++; |
173 | if (argv[i]) { | ||
174 | cmd_arg = strdup(argv[i]); | ||
175 | } | ||
176 | continue; | ||
177 | } | 192 | } |
178 | else if (!strcmp(argv[i], "ioregentry")) { | 193 | } |
179 | cmd = CMD_IOREGISTRY_ENTRY; | 194 | else if (!strcmp(argv[0], "ioreg")) { |
180 | /* read key */ | 195 | cmd = CMD_IOREGISTRY; |
181 | i++; | 196 | /* read plane */ |
182 | if (argv[i]) { | 197 | if (argv[1]) { |
183 | cmd_arg = strdup(argv[i]); | 198 | cmd_arg = strdup(argv[1]); |
184 | } | ||
185 | continue; | ||
186 | } | 199 | } |
187 | else { | 200 | } |
188 | print_usage(argc, argv); | 201 | else if (!strcmp(argv[0], "ioregentry")) { |
189 | return EXIT_SUCCESS; | 202 | cmd = CMD_IOREGISTRY_ENTRY; |
203 | /* read key */ | ||
204 | if (argv[1]) { | ||
205 | cmd_arg = strdup(argv[1]); | ||
190 | } | 206 | } |
191 | } | 207 | } |
192 | 208 | ||
193 | /* verify options */ | 209 | /* verify options */ |
194 | if (cmd == CMD_NONE) { | 210 | if (cmd == CMD_NONE) { |
195 | print_usage(argc, argv); | 211 | fprintf(stderr, "ERROR: Unsupported command '%s'\n", argv[0]); |
212 | print_usage(argc+optind, argv-optind, 1); | ||
196 | goto cleanup; | 213 | goto cleanup; |
197 | } | 214 | } |
198 | 215 | ||
@@ -325,31 +342,3 @@ cleanup: | |||
325 | } | 342 | } |
326 | return result; | 343 | return result; |
327 | } | 344 | } |
328 | |||
329 | void print_usage(int argc, char **argv) | ||
330 | { | ||
331 | char *name = NULL; | ||
332 | name = strrchr(argv[0], '/'); | ||
333 | printf("Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0])); | ||
334 | printf("\n"); | ||
335 | printf("Use diagnostics interface of a device running iOS 4 or later.\n"); | ||
336 | printf("\n"); | ||
337 | printf("Where COMMAND is one of:\n"); | ||
338 | printf(" diagnostics [TYPE]\t\tprint diagnostics information from device by TYPE (All, WiFi, GasGauge, NAND)\n"); | ||
339 | printf(" mobilegestalt KEY [...]\tprint mobilegestalt keys passed as arguments separated by a space.\n"); | ||
340 | printf(" ioreg [PLANE]\t\t\tprint IORegistry of device, optionally by PLANE (IODeviceTree, IOPower, IOService) (iOS 5+ only)\n"); | ||
341 | printf(" ioregentry [KEY]\t\tprint IORegistry entry of device (AppleARMPMUCharger, ASPStorage, ...) (iOS 5+ only)\n"); | ||
342 | printf(" shutdown\t\t\tshutdown device\n"); | ||
343 | printf(" restart\t\t\trestart device\n"); | ||
344 | printf(" sleep\t\t\t\tput device into sleep mode (disconnects from host)\n"); | ||
345 | printf("\n"); | ||
346 | printf("The following OPTIONS are accepted:\n"); | ||
347 | printf(" -u, --udid UDID\ttarget specific device by UDID\n"); | ||
348 | printf(" -n, --network\t\tconnect to network device\n"); | ||
349 | printf(" -d, --debug\t\tenable communication debugging\n"); | ||
350 | printf(" -h, --help\t\tprints usage information\n"); | ||
351 | printf(" -v, --version\t\tprints version information\n"); | ||
352 | printf("\n"); | ||
353 | printf("Homepage: <" PACKAGE_URL ">\n"); | ||
354 | printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); | ||
355 | } | ||