diff options
Diffstat (limited to 'tools/idevicecrashreport.c')
-rw-r--r-- | tools/idevicecrashreport.c | 142 |
1 files changed, 74 insertions, 68 deletions
diff --git a/tools/idevicecrashreport.c b/tools/idevicecrashreport.c index ba54ebc..48bda3a 100644 --- a/tools/idevicecrashreport.c +++ b/tools/idevicecrashreport.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <stdlib.h> | 30 | #include <stdlib.h> |
31 | #include <string.h> | 31 | #include <string.h> |
32 | #include <unistd.h> | 32 | #include <unistd.h> |
33 | #include <getopt.h> | ||
33 | #ifndef WIN32 | 34 | #ifndef WIN32 |
34 | #include <signal.h> | 35 | #include <signal.h> |
35 | #endif | 36 | #endif |
@@ -313,27 +314,27 @@ static int afc_client_copy_and_remove_crash_reports(afc_client_t afc, const char | |||
313 | return res; | 314 | return res; |
314 | } | 315 | } |
315 | 316 | ||
316 | static void print_usage(int argc, char **argv) | 317 | static void print_usage(int argc, char **argv, int is_error) |
317 | { | 318 | { |
318 | char *name = NULL; | 319 | char *name = strrchr(argv[0], '/'); |
319 | 320 | fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] DIRECTORY\n", (name ? name + 1: argv[0])); | |
320 | name = strrchr(argv[0], '/'); | 321 | fprintf(is_error ? stderr : stdout, |
321 | printf("Usage: %s [OPTIONS] DIRECTORY\n", (name ? name + 1: argv[0])); | 322 | "\n" |
322 | printf("\n"); | 323 | "Move crash reports from device to a local DIRECTORY.\n" |
323 | printf("Move crash reports from device to a local DIRECTORY.\n"); | 324 | "\n" |
324 | printf("\n"); | 325 | "OPTIONS:\n" |
325 | printf("OPTIONS:\n"); | 326 | " -u, --udid UDID target specific device by UDID\n" |
326 | printf(" -u, --udid UDID\ttarget specific device by UDID\n"); | 327 | " -n, --network connect to network device\n" |
327 | printf(" -n, --network\t\tconnect to network device\n"); | 328 | " -e, --extract extract raw crash report into separate '.crash' file\n" |
328 | printf(" -e, --extract\t\textract raw crash report into separate '.crash' file\n"); | 329 | " -k, --keep copy but do not remove crash reports from device\n" |
329 | printf(" -k, --keep\t\tcopy but do not remove crash reports from device\n"); | 330 | " -d, --debug enable communication debugging\n" |
330 | printf(" -d, --debug\t\tenable communication debugging\n"); | 331 | " -f, --filter NAME filter crash reports by NAME (case sensitive)\n" |
331 | printf(" -f, --filter NAME\tfilter crash reports by NAME (case sensitive)\n"); | 332 | " -h, --help prints usage information\n" |
332 | printf(" -h, --help\t\tprints usage information\n"); | 333 | " -v, --version prints version information\n" |
333 | printf(" -v, --version\t\tprints version information\n"); | 334 | "\n" |
334 | printf("\n"); | 335 | "Homepage: <" PACKAGE_URL ">\n" |
335 | printf("Homepage: <" PACKAGE_URL ">\n"); | 336 | "Bug Reports: <" PACKAGE_BUGREPORT ">\n" |
336 | printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); | 337 | ); |
337 | } | 338 | } |
338 | 339 | ||
339 | int main(int argc, char* argv[]) | 340 | int main(int argc, char* argv[]) |
@@ -346,79 +347,84 @@ int main(int argc, char* argv[]) | |||
346 | lockdownd_error_t lockdownd_error = LOCKDOWN_E_SUCCESS; | 347 | lockdownd_error_t lockdownd_error = LOCKDOWN_E_SUCCESS; |
347 | afc_error_t afc_error = AFC_E_SUCCESS; | 348 | afc_error_t afc_error = AFC_E_SUCCESS; |
348 | 349 | ||
349 | int i; | ||
350 | const char* udid = NULL; | 350 | const char* udid = NULL; |
351 | int use_network = 0; | 351 | int use_network = 0; |
352 | const char* filename_filter = NULL; | 352 | const char* filename_filter = NULL; |
353 | 353 | ||
354 | int c = 0; | ||
355 | const struct option longopts[] = { | ||
356 | { "debug", no_argument, NULL, 'd' }, | ||
357 | { "help", no_argument, NULL, 'h' }, | ||
358 | { "udid", required_argument, NULL, 'u' }, | ||
359 | { "network", no_argument, NULL, 'n' }, | ||
360 | { "version", no_argument, NULL, 'v' }, | ||
361 | { "filter", required_argument, NULL, 'f' }, | ||
362 | { "extract", no_argument, NULL, 'e' }, | ||
363 | { "keep", no_argument, NULL, 'k' }, | ||
364 | { NULL, 0, NULL, 0} | ||
365 | }; | ||
366 | |||
354 | #ifndef WIN32 | 367 | #ifndef WIN32 |
355 | signal(SIGPIPE, SIG_IGN); | 368 | signal(SIGPIPE, SIG_IGN); |
356 | #endif | 369 | #endif |
370 | |||
357 | /* parse cmdline args */ | 371 | /* parse cmdline args */ |
358 | for (i = 1; i < argc; i++) { | 372 | while ((c = getopt_long(argc, argv, "dhu:nvf:ek", longopts, NULL)) != -1) { |
359 | if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { | 373 | switch (c) { |
374 | case 'd': | ||
360 | idevice_set_debug_level(1); | 375 | idevice_set_debug_level(1); |
361 | continue; | 376 | break; |
362 | } | 377 | case 'u': |
363 | else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { | 378 | if (!*optarg) { |
364 | i++; | 379 | fprintf(stderr, "ERROR: UDID argument must not be empty!\n"); |
365 | if (!argv[i] || !*argv[i]) { | 380 | print_usage(argc, argv, 1); |
366 | print_usage(argc, argv); | 381 | return 2; |
367 | return 0; | ||
368 | } | 382 | } |
369 | udid = argv[i]; | 383 | udid = optarg; |
370 | continue; | 384 | break; |
371 | } | 385 | case 'n': |
372 | else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) { | ||
373 | use_network = 1; | 386 | use_network = 1; |
374 | continue; | 387 | break; |
375 | } | 388 | case 'h': |
376 | else if (!strcmp(argv[i], "-f") || !strcmp(argv[i], "--filter")) { | 389 | print_usage(argc, argv, 0); |
377 | i++; | ||
378 | if (!argv[i] || !*argv[i]) { | ||
379 | print_usage(argc, argv); | ||
380 | return 0; | ||
381 | } | ||
382 | filename_filter = argv[i]; | ||
383 | continue; | ||
384 | } | ||
385 | else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { | ||
386 | print_usage(argc, argv); | ||
387 | return 0; | 390 | return 0; |
388 | } | 391 | case 'v': |
389 | else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { | ||
390 | printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); | 392 | printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); |
391 | return 0; | 393 | return 0; |
392 | } | 394 | case 'f': |
393 | else if (!strcmp(argv[i], "-e") || !strcmp(argv[i], "--extract")) { | 395 | if (!*optarg) { |
396 | fprintf(stderr, "ERROR: filter argument must not be empty!\n"); | ||
397 | print_usage(argc, argv, 1); | ||
398 | return 2; | ||
399 | } | ||
400 | filename_filter = optarg; | ||
401 | break; | ||
402 | case 'e': | ||
394 | extract_raw_crash_reports = 1; | 403 | extract_raw_crash_reports = 1; |
395 | continue; | 404 | break; |
396 | } | 405 | case 'k': |
397 | else if (!strcmp(argv[i], "-k") || !strcmp(argv[i], "--keep")) { | ||
398 | keep_crash_reports = 1; | 406 | keep_crash_reports = 1; |
399 | continue; | 407 | break; |
400 | } | 408 | default: |
401 | else if (target_directory == NULL) { | 409 | print_usage(argc, argv, 1); |
402 | target_directory = argv[i]; | 410 | return 2; |
403 | continue; | ||
404 | } | ||
405 | else { | ||
406 | print_usage(argc, argv); | ||
407 | return 0; | ||
408 | } | 411 | } |
409 | } | 412 | } |
413 | argc -= optind; | ||
414 | argv += optind; | ||
410 | 415 | ||
411 | /* ensure a target directory was supplied */ | 416 | /* ensure a target directory was supplied */ |
412 | if (!target_directory) { | 417 | if (!argv[0]) { |
413 | print_usage(argc, argv); | 418 | fprintf(stderr, "ERROR: missing target directory.\n"); |
414 | return 0; | 419 | print_usage(argc+optind, argv-optind, 1); |
420 | return 2; | ||
415 | } | 421 | } |
422 | target_directory = argv[0]; | ||
416 | 423 | ||
417 | /* check if target directory exists */ | 424 | /* check if target directory exists */ |
418 | if (!file_exists(target_directory)) { | 425 | if (!file_exists(target_directory)) { |
419 | fprintf(stderr, "ERROR: Directory '%s' does not exist.\n", target_directory); | 426 | fprintf(stderr, "ERROR: Directory '%s' does not exist.\n", target_directory); |
420 | print_usage(argc, argv); | 427 | return 1; |
421 | return 0; | ||
422 | } | 428 | } |
423 | 429 | ||
424 | device_error = idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX); | 430 | device_error = idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX); |