summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2022-03-29 13:22:57 +0200
committerGravatar Nikias Bassen2022-03-29 13:22:57 +0200
commit25ca67d92589f9fec15c1c7d2f1f692ac748e547 (patch)
tree71d27c5fac83dc00a9273362f710a42b518499bd /tools
parent09b0cd30bf808aef08f9d2afd8e74e8aacf80688 (diff)
downloadlibimobiledevice-25ca67d92589f9fec15c1c7d2f1f692ac748e547.tar.gz
libimobiledevice-25ca67d92589f9fec15c1c7d2f1f692ac748e547.tar.bz2
idevicedebug: Use getopt for option parsing
Diffstat (limited to 'tools')
-rw-r--r--tools/idevicedebug.c156
1 files changed, 89 insertions, 67 deletions
diff --git a/tools/idevicedebug.c b/tools/idevicedebug.c
index aa7a400..53e84b7 100644
--- a/tools/idevicedebug.c
+++ b/tools/idevicedebug.c
@@ -32,6 +32,7 @@
32#include <time.h> 32#include <time.h>
33#include <unistd.h> 33#include <unistd.h>
34#include <libgen.h> 34#include <libgen.h>
35#include <getopt.h>
35 36
36#ifdef WIN32 37#ifdef WIN32
37#include <windows.h> 38#include <windows.h>
@@ -173,28 +174,30 @@ static debugserver_error_t debugserver_client_handle_response(debugserver_client
173 return dres; 174 return dres;
174} 175}
175 176
176static void print_usage(int argc, char **argv) 177static void print_usage(int argc, char **argv, int is_error)
177{ 178{
178 char *name = NULL; 179 char *name = NULL;
179 name = strrchr(argv[0], '/'); 180 name = strrchr(argv[0], '/');
180 printf("Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0])); 181 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0]));
181 printf("\n"); 182 fprintf(is_error ? stderr : stdout,
182 printf("Interact with the debugserver service of a device.\n"); 183 "\n" \
183 printf("\n"); 184 "Interact with the debugserver service of a device.\n" \
184 printf("Where COMMAND is one of:\n"); 185 "\n" \
185 printf(" run BUNDLEID [ARGS...]\trun app with BUNDLEID and optional ARGS on device.\n"); 186 "Where COMMAND is one of:\n" \
186 printf("\n"); 187 " run BUNDLEID [ARGS...]\trun app with BUNDLEID and optional ARGS on device.\n" \
187 printf("The following OPTIONS are accepted:\n"); 188 "\n" \
188 printf(" -u, --udid UDID\ttarget specific device by UDID\n"); 189 "The following OPTIONS are accepted:\n" \
189 printf(" -n, --network\t\tconnect to network device\n"); 190 " -u, --udid UDID\ttarget specific device by UDID\n" \
190 printf(" --detach\t\tdetach from app after launch, keeping it running\n"); 191 " -n, --network\t\tconnect to network device\n" \
191 printf(" -e, --env NAME=VALUE\tset environment variable NAME to VALUE\n"); 192 " --detach\t\tdetach from app after launch, keeping it running\n" \
192 printf(" -d, --debug\t\tenable communication debugging\n"); 193 " -e, --env NAME=VALUE\tset environment variable NAME to VALUE\n" \
193 printf(" -h, --help\t\tprints usage information\n"); 194 " -d, --debug\t\tenable communication debugging\n" \
194 printf(" -v, --version\t\tprints version information\n"); 195 " -h, --help\t\tprints usage information\n" \
195 printf("\n"); 196 " -v, --version\t\tprints version information\n" \
196 printf("Homepage: <" PACKAGE_URL ">\n"); 197 "\n" \
197 printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); 198 "Homepage: <" PACKAGE_URL ">\n" \
199 "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
200 );
198} 201}
199 202
200int main(int argc, char *argv[]) 203int main(int argc, char *argv[])
@@ -220,6 +223,18 @@ int main(int argc, char *argv[])
220 debugserver_command_t command = NULL; 223 debugserver_command_t command = NULL;
221 debugserver_error_t dres = DEBUGSERVER_E_UNKNOWN_ERROR; 224 debugserver_error_t dres = DEBUGSERVER_E_UNKNOWN_ERROR;
222 225
226 int c = 0;
227 const struct option longopts[] = {
228 { "debug", no_argument, NULL, 'd' },
229 { "help", no_argument, NULL, 'h' },
230 { "udid", required_argument, NULL, 'u' },
231 { "network", no_argument, NULL, 'n' },
232 { "detach", no_argument, NULL, 1 },
233 { "env", required_argument, NULL, 'e' },
234 { "version", no_argument, NULL, 'v' },
235 { NULL, 0, NULL, 0 }
236 };
237
223 /* map signals */ 238 /* map signals */
224 signal(SIGINT, on_signal); 239 signal(SIGINT, on_signal);
225 signal(SIGTERM, on_signal); 240 signal(SIGTERM, on_signal);
@@ -228,32 +243,31 @@ int main(int argc, char *argv[])
228 signal(SIGPIPE, SIG_IGN); 243 signal(SIGPIPE, SIG_IGN);
229#endif 244#endif
230 245
231 /* parse command line arguments */ 246 while ((c = getopt_long(argc, argv, "dhu:ne:v", longopts, NULL)) != -1) {
232 for (i = 1; i < argc; i++) { 247 switch (c) {
233 if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { 248 case 'd':
234 debug_level++; 249 debug_level++;
235 idevice_set_debug_level(debug_level); 250 idevice_set_debug_level(debug_level);
236 continue; 251 break;
237 } else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { 252 case 'u':
238 i++; 253 if (!*optarg) {
239 if (!argv[i] || !*argv[i]) { 254 fprintf(stderr, "ERROR: UDID must not be empty!\n");
240 print_usage(argc, argv); 255 print_usage(argc, argv, 1);
241 res = 0; 256 return 2;
242 goto cleanup;
243 } 257 }
244 udid = argv[i]; 258 udid = optarg;
245 continue; 259 break;
246 } else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) { 260 case 'n':
247 use_network = 1; 261 use_network = 1;
248 continue; 262 break;
249 } else if (!strcmp(argv[i], "--detach")) { 263 case 1:
250 detach_after_start = 1; 264 detach_after_start = 1;
251 continue; 265 break;
252 } else if (!strcmp(argv[i], "-e") || !strcmp(argv[i], "--env")) { 266 case 'e':
253 i++; 267 if (!*optarg || strchr(optarg, '=') == NULL) {
254 if (!argv[i] || (strlen(argv[i]) <= 1) || strchr(argv[i], '=') == NULL) { 268 fprintf(stderr, "ERROR: environment variables need to be specified as -e KEY=VALUE\n");
255 print_usage(argc, argv); 269 print_usage(argc, argv, 1);
256 res = 0; 270 res = 2;
257 goto cleanup; 271 goto cleanup;
258 } 272 }
259 /* add environment variable */ 273 /* add environment variable */
@@ -261,50 +275,58 @@ int main(int argc, char *argv[])
261 newlist = malloc((environment_count + 1) * sizeof(char*)); 275 newlist = malloc((environment_count + 1) * sizeof(char*));
262 else 276 else
263 newlist = realloc(environment, (environment_count + 1) * sizeof(char*)); 277 newlist = realloc(environment, (environment_count + 1) * sizeof(char*));
264 newlist[environment_count++] = strdup(argv[i]); 278 newlist[environment_count++] = strdup(optarg);
265 environment = newlist; 279 environment = newlist;
266 continue; 280 break;
267 } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { 281 case 'h':
268 print_usage(argc, argv); 282 print_usage(argc, argv, 0);
269 res = 0; 283 res = 0;
270 goto cleanup; 284 goto cleanup;
271 } else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { 285 break;
286 case 'v':
272 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); 287 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
273 res = 0; 288 res = 0;
274 goto cleanup; 289 goto cleanup;
275 } else if (!strcmp(argv[i], "run")) {
276 cmd = CMD_RUN;
277
278 i++;
279 if (!argv[i]) {
280 /* make sure at least the bundle identifier was provided */
281 printf("Please supply the bundle identifier of the app to run.\n");
282 print_usage(argc, argv);
283 res = 0;
284 goto cleanup;
285 }
286 /* read bundle identifier */
287 bundle_identifier = argv[i];
288 break; 290 break;
289 } else {
290 print_usage(argc, argv);
291 res = 0;
292 goto cleanup;
293 } 291 }
294 } 292 }
295 293
296 if (environment) { 294 argc -= optind;
297 newlist = realloc(environment, (environment_count + 1) * sizeof(char*)); 295 argv += optind;
298 newlist[environment_count] = NULL; 296
299 environment = newlist; 297 if (argc < 1) {
298 fprintf(stderr, "ERROR: Missing command.\n");
299 print_usage(argc+optind, argv-optind, 1);
300 }
301
302 if (!strcmp(argv[0], "run")) {
303 cmd = CMD_RUN;
304 if (argc < 2) {
305 /* make sure at least the bundle identifier was provided */
306 fprintf(stderr, "ERROR: Please supply the bundle identifier of the app to run.\n");
307 print_usage(argc+optind, argv-optind, 1);
308 res = 2;
309 goto cleanup;
310 }
311 /* read bundle identifier */
312 bundle_identifier = argv[1];
313 i = 1;
300 } 314 }
301 315
302 /* verify options */ 316 /* verify options */
303 if (cmd == CMD_NONE) { 317 if (cmd == CMD_NONE) {
304 print_usage(argc, argv); 318 fprintf(stderr, "ERROR: Unsupported command specified.\n");
319 print_usage(argc+optind, argv-optind, 1);
320 res = 2;
305 goto cleanup; 321 goto cleanup;
306 } 322 }
307 323
324 if (environment) {
325 newlist = realloc(environment, (environment_count + 1) * sizeof(char*));
326 newlist[environment_count] = NULL;
327 environment = newlist;
328 }
329
308 /* connect to the device */ 330 /* connect to the device */
309 ret = idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX); 331 ret = idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX);
310 if (ret != IDEVICE_E_SUCCESS) { 332 if (ret != IDEVICE_E_SUCCESS) {