summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2022-04-30 13:31:20 +0200
committerGravatar Nikias Bassen2022-04-30 13:31:20 +0200
commit6cb13f9e6d3939930aecf91d8e23d1896a3b92e5 (patch)
tree371e4676ac914d9eef6bb4cfc0b5b6dc6f27da4f
parent3b5cad28fabb236e05b8fff82fab5098127aa2bb (diff)
downloadlibimobiledevice-6cb13f9e6d3939930aecf91d8e23d1896a3b92e5.tar.gz
libimobiledevice-6cb13f9e6d3939930aecf91d8e23d1896a3b92e5.tar.bz2
tools: Use getopt for option parsing in all tools
-rw-r--r--docs/idevicebackup.12
-rw-r--r--docs/idevicebackup2.12
-rw-r--r--tools/idevice_id.c27
-rw-r--r--tools/idevicebackup.c152
-rw-r--r--tools/idevicebackup2.c423
-rw-r--r--tools/idevicecrashreport.c142
-rw-r--r--tools/idevicedate.c133
-rw-r--r--tools/idevicedebug.c39
-rw-r--r--tools/idevicedebugserverproxy.c105
-rw-r--r--tools/idevicediagnostics.c235
-rw-r--r--tools/ideviceenterrecovery.c71
-rw-r--r--tools/ideviceimagemounter.c46
-rw-r--r--tools/ideviceinfo.c29
-rw-r--r--tools/idevicename.c41
-rw-r--r--tools/idevicenotificationproxy.c180
-rw-r--r--tools/idevicepair.c92
-rw-r--r--tools/ideviceprovision.c240
-rw-r--r--tools/idevicescreenshot.c228
-rw-r--r--tools/idevicesetlocation.c19
-rw-r--r--tools/idevicesyslog.c57
20 files changed, 1182 insertions, 1081 deletions
diff --git a/docs/idevicebackup.1 b/docs/idevicebackup.1
index 3a40f5f..6f2a8f9 100644
--- a/docs/idevicebackup.1
+++ b/docs/idevicebackup.1
@@ -7,7 +7,7 @@ idevicebackup \- Create or restore backup for devices.
7 7
8.SH DESCRIPTION 8.SH DESCRIPTION
9 9
10Create or restore backup from the current or specified directory. 10Create or restore backup in/from the specified directory.
11 11
12\f[B]NOTE\f[]: This tool is outdated. See idevicebackup2(1) for an updated tool. 12\f[B]NOTE\f[]: This tool is outdated. See idevicebackup2(1) for an updated tool.
13 13
diff --git a/docs/idevicebackup2.1 b/docs/idevicebackup2.1
index 74d1c68..abbe38a 100644
--- a/docs/idevicebackup2.1
+++ b/docs/idevicebackup2.1
@@ -7,7 +7,7 @@ idevicebackup2 \- Create or restore backups for devices running iOS 4 or later.
7 7
8.SH DESCRIPTION 8.SH DESCRIPTION
9 9
10Create or restore backup from the current or specified directory. 10Create or restore backup in/from the specified directory.
11 11
12.SH OPTIONS 12.SH OPTIONS
13.TP 13.TP
diff --git a/tools/idevice_id.c b/tools/idevice_id.c
index 98fd22d..540a6f2 100644
--- a/tools/idevice_id.c
+++ b/tools/idevice_id.c
@@ -38,24 +38,23 @@
38 38
39static void print_usage(int argc, char **argv, int is_error) 39static void print_usage(int argc, char **argv, int is_error)
40{ 40{
41 char *name = NULL; 41 char *name = strrchr(argv[0], '/');
42 name = strrchr(argv[0], '/');
43 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] [UDID]\n", (name ? name + 1: argv[0])); 42 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] [UDID]\n", (name ? name + 1: argv[0]));
44 fprintf(is_error ? stderr : stdout, 43 fprintf(is_error ? stderr : stdout,
44 "\n"
45 "List attached devices or print device name of given device.\n"
45 "\n" \ 46 "\n" \
46 "List attached devices or print device name of given device.\n" \ 47 " If UDID is given, the name of the connected device with that UDID"
48 " will be retrieved.\n"
47 "\n" \ 49 "\n" \
48 " If UDID is given, the name of the connected device with that UDID" \ 50 "OPTIONS:\n"
49 " will be retrieved.\n" \ 51 " -l, --list list UDIDs of all devices attached via USB\n"
50 "\n" \ 52 " -n, --network list UDIDs of all devices available via network\n"
51 "OPTIONS:\n" \ 53 " -d, --debug enable communication debugging\n"
52 " -l, --list list UDIDs of all devices attached via USB\n" \ 54 " -h, --help prints usage information\n"
53 " -n, --network list UDIDs of all devices available via network\n" \ 55 " -v, --version prints version information\n"
54 " -d, --debug enable communication debugging\n" \ 56 "\n"
55 " -h, --help prints usage information\n" \ 57 "Homepage: <" PACKAGE_URL ">\n"
56 " -v, --version prints version information\n" \
57 "\n" \
58 "Homepage: <" PACKAGE_URL ">\n" \
59 "Bug Reports: <" PACKAGE_BUGREPORT ">\n" 58 "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
60 ); 59 );
61} 60}
diff --git a/tools/idevicebackup.c b/tools/idevicebackup.c
index 1e512d8..0affd7a 100644
--- a/tools/idevicebackup.c
+++ b/tools/idevicebackup.c
@@ -31,6 +31,7 @@
31#include <errno.h> 31#include <errno.h>
32#include <stdlib.h> 32#include <stdlib.h>
33#include <signal.h> 33#include <signal.h>
34#include <getopt.h>
34#if defined(HAVE_OPENSSL) 35#if defined(HAVE_OPENSSL)
35#include <openssl/sha.h> 36#include <openssl/sha.h>
36#elif defined(HAVE_GNUTLS) 37#elif defined(HAVE_GNUTLS)
@@ -647,27 +648,28 @@ static void clean_exit(int sig)
647 quit_flag++; 648 quit_flag++;
648} 649}
649 650
650static void print_usage(int argc, char **argv) 651static void print_usage(int argc, char **argv, int is_error)
651{ 652{
652 char *name = NULL; 653 char *name = strrchr(argv[0], '/');
653 name = strrchr(argv[0], '/'); 654 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] CMD DIRECTORY\n", (name ? name + 1: argv[0]));
654 printf("Usage: %s [OPTIONS] CMD [DIRECTORY]\n", (name ? name + 1: argv[0])); 655 fprintf(is_error ? stderr : stdout,
655 printf("\n"); 656 "\n"
656 printf("Create or restore backup from the current or specified directory.\n"); 657 "Create or restore backup in/from the specified directory.\n"
657 printf("\n"); 658 "\n"
658 printf("CMD:\n"); 659 "CMD:\n"
659 printf(" backup\tSaves a device backup into DIRECTORY\n"); 660 " backup Saves a device backup into DIRECTORY\n"
660 printf(" restore\tRestores a device backup from DIRECTORY.\n"); 661 " restore Restores a device backup from DIRECTORY.\n"
661 printf("\n"); 662 "\n"
662 printf("OPTIONS:\n"); 663 "OPTIONS:\n"
663 printf(" -u, --udid UDID\ttarget specific device by UDID\n"); 664 " -u, --udid UDID target specific device by UDID\n"
664 printf(" -n, --network\t\tconnect to network device\n"); 665 " -n, --network connect to network device\n"
665 printf(" -d, --debug\t\tenable communication debugging\n"); 666 " -d, --debug enable communication debugging\n"
666 printf(" -h, --help\t\tprints usage information\n"); 667 " -h, --help prints usage information\n"
667 printf(" -v, --version\t\tprints version information\n"); 668 " -v, --version prints version information\n"
668 printf("\n"); 669 "\n"
669 printf("Homepage: <" PACKAGE_URL ">\n"); 670 "Homepage: <" PACKAGE_URL ">\n"
670 printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); 671 "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
672 );
671} 673}
672 674
673int main(int argc, char *argv[]) 675int main(int argc, char *argv[])
@@ -691,7 +693,15 @@ int main(int argc, char *argv[])
691 uint64_t length = 0; 693 uint64_t length = 0;
692 uint64_t backup_total_size = 0; 694 uint64_t backup_total_size = 0;
693 enum device_link_file_status_t file_status = DEVICE_LINK_FILE_STATUS_NONE; 695 enum device_link_file_status_t file_status = DEVICE_LINK_FILE_STATUS_NONE;
694 uint64_t c = 0; 696 int c = 0;
697 const struct option longopts[] = {
698 { "debug", no_argument, NULL, 'd' },
699 { "help", no_argument, NULL, 'h' },
700 { "udid", required_argument, NULL, 'u' },
701 { "network", no_argument, NULL, 'n' },
702 { "version", no_argument, NULL, 'v' },
703 { NULL, 0, NULL, 0}
704 };
695 705
696 /* we need to exit cleanly on running backups and restores or we cause havok */ 706 /* we need to exit cleanly on running backups and restores or we cause havok */
697 signal(SIGINT, clean_exit); 707 signal(SIGINT, clean_exit);
@@ -702,59 +712,58 @@ int main(int argc, char *argv[])
702#endif 712#endif
703 713
704 /* parse cmdline args */ 714 /* parse cmdline args */
705 for (i = 1; i < argc; i++) { 715 while ((c = getopt_long(argc, argv, "dhu:nv", longopts, NULL)) != -1) {
706 if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { 716 switch (c) {
717 case 'd':
707 idevice_set_debug_level(1); 718 idevice_set_debug_level(1);
708 continue; 719 break;
709 } 720 case 'u':
710 else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { 721 if (!*optarg) {
711 i++; 722 fprintf(stderr, "ERROR: UDID must not be empty!\n");
712 if (!argv[i] || !*argv[i]) { 723 print_usage(argc, argv, 1);
713 print_usage(argc, argv); 724 return 2;
714 return 0;
715 } 725 }
716 udid = strdup(argv[i]); 726 udid = strdup(optarg);
717 continue; 727 break;
718 } 728 case 'n':
719 else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) {
720 use_network = 1; 729 use_network = 1;
721 continue; 730 break;
722 } 731 case 'h':
723 else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { 732 print_usage(argc, argv, 0);
724 print_usage(argc, argv);
725 return 0; 733 return 0;
726 } 734 case 'v':
727 else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
728 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); 735 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
729 return 0; 736 return 0;
730 } 737 default:
731 else if (!strcmp(argv[i], "backup")) { 738 print_usage(argc, argv, 1);
732 cmd = CMD_BACKUP; 739 return 2;
733 }
734 else if (!strcmp(argv[i], "restore")) {
735 cmd = CMD_RESTORE;
736 }
737 else if (backup_directory == NULL) {
738 backup_directory = argv[i];
739 }
740 else {
741 print_usage(argc, argv);
742 return 0;
743 } 740 }
744 } 741 }
742 argc -= optind;
743 argv += optind;
745 744
746 /* verify options */ 745 if (argc < 1) {
747 if (cmd == -1) { 746 fprintf(stderr, "ERROR: Missing command.\n");
748 printf("No command specified.\n"); 747 print_usage(argc+optind, argv-optind, 1);
749 print_usage(argc, argv); 748 return 2;
750 return -1;
751 } 749 }
752 750
753 if (backup_directory == NULL) { 751 if (!strcmp(argv[0], "backup")) {
754 printf("No target backup directory specified.\n"); 752 cmd = CMD_BACKUP;
755 print_usage(argc, argv); 753 } else if (!strcmp(argv[0], "restore")) {
756 return -1; 754 cmd = CMD_RESTORE;
755 } else {
756 fprintf(stderr, "ERROR: Invalid command '%s'.\n", argv[0]);
757 print_usage(argc+optind, argv-optind, 1);
758 return 2;
759 }
760
761 if (argc < 2) {
762 fprintf(stderr, "No target backup directory specified.\n");
763 print_usage(argc+optind, argv-optind, 1);
764 return 2;
757 } 765 }
766 backup_directory = argv[1];
758 767
759 /* verify if passed backup directory exists */ 768 /* verify if passed backup directory exists */
760 if (stat(backup_directory, &st) != 0) { 769 if (stat(backup_directory, &st) != 0) {
@@ -784,9 +793,14 @@ int main(int argc, char *argv[])
784 return -1; 793 return -1;
785 } 794 }
786 795
796 if (!udid) {
797 idevice_get_udid(device, &udid);
798 }
799
787 if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new_with_handshake(device, &client, TOOL_NAME))) { 800 if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new_with_handshake(device, &client, TOOL_NAME))) {
788 printf("ERROR: Could not connect to lockdownd, error code %d\n", ldret); 801 printf("ERROR: Could not connect to lockdownd, error code %d\n", ldret);
789 idevice_free(device); 802 idevice_free(device);
803 free(udid);
790 return -1; 804 return -1;
791 } 805 }
792 806
@@ -806,6 +820,7 @@ int main(int argc, char *argv[])
806 printf("ERROR: This tool is only compatible with iOS 3 or below. For newer iOS versions please use the idevicebackup2 tool.\n"); 820 printf("ERROR: This tool is only compatible with iOS 3 or below. For newer iOS versions please use the idevicebackup2 tool.\n");
807 lockdownd_client_free(client); 821 lockdownd_client_free(client);
808 idevice_free(device); 822 idevice_free(device);
823 free(udid);
809 return -1; 824 return -1;
810 } 825 }
811 } 826 }
@@ -851,7 +866,7 @@ int main(int argc, char *argv[])
851 ldret = lockdownd_start_service(client, MOBILEBACKUP_SERVICE_NAME, &service); 866 ldret = lockdownd_start_service(client, MOBILEBACKUP_SERVICE_NAME, &service);
852 if ((ldret == LOCKDOWN_E_SUCCESS) && service && service->port) { 867 if ((ldret == LOCKDOWN_E_SUCCESS) && service && service->port) {
853 printf("Started \"%s\" service on port %d.\n", MOBILEBACKUP_SERVICE_NAME, service->port); 868 printf("Started \"%s\" service on port %d.\n", MOBILEBACKUP_SERVICE_NAME, service->port);
854 mobilebackup_client_new(device, service, &mobilebackup); 869 printf("%d\n", mobilebackup_client_new(device, service, &mobilebackup));
855 870
856 if (service) { 871 if (service) {
857 lockdownd_service_descriptor_free(service); 872 lockdownd_service_descriptor_free(service);
@@ -993,7 +1008,7 @@ int main(int argc, char *argv[])
993 } else if (err == MOBILEBACKUP_E_REPLY_NOT_OK) { 1008 } else if (err == MOBILEBACKUP_E_REPLY_NOT_OK) {
994 printf("ERROR: Could not start backup process: device refused to start the backup process.\n"); 1009 printf("ERROR: Could not start backup process: device refused to start the backup process.\n");
995 } else { 1010 } else {
996 printf("ERROR: Could not start backup process: unspecified error occurred\n"); 1011 printf("ERROR: Could not start backup process: unspecified error occurred (%d)\n", err);
997 } 1012 }
998 break; 1013 break;
999 } 1014 }
@@ -1015,6 +1030,7 @@ int main(int argc, char *argv[])
1015 char *format_size = NULL; 1030 char *format_size = NULL;
1016 int is_manifest = 0; 1031 int is_manifest = 0;
1017 uint8_t b = 0; 1032 uint8_t b = 0;
1033 uint64_t u64val = 0;
1018 1034
1019 /* process series of DLSendFile messages */ 1035 /* process series of DLSendFile messages */
1020 do { 1036 do {
@@ -1046,8 +1062,8 @@ int main(int argc, char *argv[])
1046 1062
1047 /* check DLFileStatusKey (codes: 1 = Hunk, 2 = Last Hunk) */ 1063 /* check DLFileStatusKey (codes: 1 = Hunk, 2 = Last Hunk) */
1048 node = plist_dict_get_item(node_tmp, "DLFileStatusKey"); 1064 node = plist_dict_get_item(node_tmp, "DLFileStatusKey");
1049 plist_get_uint_val(node, &c); 1065 plist_get_uint_val(node, &u64val);
1050 file_status = c; 1066 file_status = u64val;
1051 1067
1052 /* get source filename */ 1068 /* get source filename */
1053 node = plist_dict_get_item(node_tmp, "BackupManifestKey"); 1069 node = plist_dict_get_item(node_tmp, "BackupManifestKey");
@@ -1610,9 +1626,7 @@ files_out:
1610 1626
1611 idevice_free(device); 1627 idevice_free(device);
1612 1628
1613 if (udid) { 1629 free(udid);
1614 free(udid);
1615 }
1616 1630
1617 return 0; 1631 return 0;
1618} 1632}
diff --git a/tools/idevicebackup2.c b/tools/idevicebackup2.c
index 2170f98..d1ef0d6 100644
--- a/tools/idevicebackup2.c
+++ b/tools/idevicebackup2.c
@@ -36,6 +36,7 @@
36#include <libgen.h> 36#include <libgen.h>
37#include <ctype.h> 37#include <ctype.h>
38#include <time.h> 38#include <time.h>
39#include <getopt.h>
39 40
40#include <libimobiledevice/libimobiledevice.h> 41#include <libimobiledevice/libimobiledevice.h>
41#include <libimobiledevice/lockdown.h> 42#include <libimobiledevice/lockdown.h>
@@ -1415,47 +1416,48 @@ static void clean_exit(int sig)
1415 quit_flag++; 1416 quit_flag++;
1416} 1417}
1417 1418
1418static void print_usage(int argc, char **argv) 1419static void print_usage(int argc, char **argv, int is_error)
1419{ 1420{
1420 char *name = NULL; 1421 char *name = strrchr(argv[0], '/');
1421 name = strrchr(argv[0], '/'); 1422 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] CMD [CMDOPTIONS] DIRECTORY\n", (name ? name + 1: argv[0]));
1422 printf("Usage: %s [OPTIONS] CMD [CMDOPTIONS] DIRECTORY\n", (name ? name + 1: argv[0])); 1423 fprintf(is_error ? stderr : stdout,
1423 printf("\n"); 1424 "\n"
1424 printf("Create or restore backup from the current or specified directory.\n"); 1425 "Create or restore backup in/from the specified directory.\n"
1425 printf("\n"); 1426 "\n"
1426 printf("CMD:\n"); 1427 "CMD:\n"
1427 printf(" backup\tcreate backup for the device\n"); 1428 " backup create backup for the device\n"
1428 printf(" --full\t\tforce full backup from device.\n"); 1429 " --full force full backup from device.\n"
1429 printf(" restore\trestore last backup to the device\n"); 1430 " restore restore last backup to the device\n"
1430 printf(" --system\t\trestore system files, too.\n"); 1431 " --system restore system files, too.\n"
1431 printf(" --no-reboot\t\tdo NOT reboot the device when done (default: yes).\n"); 1432 " --no-reboot do NOT reboot the device when done (default: yes).\n"
1432 printf(" --copy\t\tcreate a copy of backup folder before restoring.\n"); 1433 " --copy create a copy of backup folder before restoring.\n"
1433 printf(" --settings\t\trestore device settings from the backup.\n"); 1434 " --settings restore device settings from the backup.\n"
1434 printf(" --remove\t\tremove items which are not being restored\n"); 1435 " --remove remove items which are not being restored\n"
1435 printf(" --skip-apps\t\tdo not trigger re-installation of apps after restore\n"); 1436 " --skip-apps do not trigger re-installation of apps after restore\n"
1436 printf(" --password PWD\tsupply the password for the encrypted source backup\n"); 1437 " --password PWD supply the password for the encrypted source backup\n"
1437 printf(" info\t\tshow details about last completed backup of device\n"); 1438 " info show details about last completed backup of device\n"
1438 printf(" list\t\tlist files of last completed backup in CSV format\n"); 1439 " list list files of last completed backup in CSV format\n"
1439 printf(" unback\tunpack a completed backup in DIRECTORY/_unback_/\n"); 1440 " unback unpack a completed backup in DIRECTORY/_unback_/\n"
1440 printf(" encryption on|off [PWD]\tenable or disable backup encryption\n"); 1441 " encryption on|off [PWD] enable or disable backup encryption\n"
1441 printf(" changepw [OLD NEW] change backup password on target device\n"); 1442 " changepw [OLD NEW] change backup password on target device\n"
1442 printf(" cloud on|off\tenable or disable cloud use (requires iCloud account)\n"); 1443 " cloud on|off enable or disable cloud use (requires iCloud account)\n"
1443 printf("\n"); 1444 "\n"
1444 printf("NOTE: Passwords will be requested in interactive mode (-i) if omitted, or can\n"); 1445 "NOTE: Passwords will be requested in interactive mode (-i) if omitted, or can\n"
1445 printf("be passed via environment variable BACKUP_PASSWORD/BACKUP_PASSWORD_NEW.\n"); 1446 "be passed via environment variable BACKUP_PASSWORD/BACKUP_PASSWORD_NEW.\n"
1446 printf("See man page for further details.\n"); 1447 "See man page for further details.\n"
1447 printf("\n"); 1448 "\n"
1448 printf("OPTIONS:\n"); 1449 "OPTIONS:\n"
1449 printf(" -u, --udid UDID\ttarget specific device by UDID\n"); 1450 " -u, --udid UDID target specific device by UDID\n"
1450 printf(" -s, --source UDID\tuse backup data from device specified by UDID\n"); 1451 " -s, --source UDID use backup data from device specified by UDID\n"
1451 printf(" -n, --network\t\tconnect to network device\n"); 1452 " -n, --network connect to network device\n"
1452 printf(" -i, --interactive\trequest passwords interactively\n"); 1453 " -i, --interactive request passwords interactively\n"
1453 printf(" -d, --debug\t\tenable communication debugging\n"); 1454 " -d, --debug enable communication debugging\n"
1454 printf(" -h, --help\t\tprints usage information\n"); 1455 " -h, --help prints usage information\n"
1455 printf(" -v, --version\t\tprints version information\n"); 1456 " -v, --version prints version information\n"
1456 printf("\n"); 1457 "\n"
1457 printf("Homepage: <" PACKAGE_URL ">\n"); 1458 "Homepage: <" PACKAGE_URL ">\n"
1458 printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); 1459 "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
1460 );
1459} 1461}
1460 1462
1461#define DEVICE_VERSION(maj, min, patch) ((((maj) & 0xFF) << 16) | (((min) & 0xFF) << 8) | ((patch) & 0xFF)) 1463#define DEVICE_VERSION(maj, min, patch) ((((maj) & 0xFF) << 16) | (((min) & 0xFF) << 8) | ((patch) & 0xFF))
@@ -1464,7 +1466,7 @@ int main(int argc, char *argv[])
1464{ 1466{
1465 idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; 1467 idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
1466 lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR; 1468 lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR;
1467 int i; 1469 int i = 0;
1468 char* udid = NULL; 1470 char* udid = NULL;
1469 char* source_udid = NULL; 1471 char* source_udid = NULL;
1470 int use_network = 0; 1472 int use_network = 0;
@@ -1490,6 +1492,38 @@ int main(int argc, char *argv[])
1490 mobilebackup2_error_t err; 1492 mobilebackup2_error_t err;
1491 uint64_t lockfile = 0; 1493 uint64_t lockfile = 0;
1492 1494
1495#define OPT_SYSTEM 1
1496#define OPT_REBOOT 2
1497#define OPT_NO_REBOOT 3
1498#define OPT_COPY 4
1499#define OPT_SETTINGS 5
1500#define OPT_REMOVE 6
1501#define OPT_SKIP_APPS 7
1502#define OPT_PASSWORD 8
1503#define OPT_FULL 9
1504
1505 int c = 0;
1506 const struct option longopts[] = {
1507 { "debug", no_argument, NULL, 'd' },
1508 { "help", no_argument, NULL, 'h' },
1509 { "udid", required_argument, NULL, 'u' },
1510 { "source", required_argument, NULL, 's' },
1511 { "interactive", no_argument, NULL, 'i' },
1512 { "network", no_argument, NULL, 'n' },
1513 { "version", no_argument, NULL, 'v' },
1514 // command options:
1515 { "system", no_argument, NULL, OPT_SYSTEM },
1516 { "reboot", no_argument, NULL, OPT_REBOOT },
1517 { "no-reboot", no_argument, NULL, OPT_NO_REBOOT },
1518 { "copy", no_argument, NULL, OPT_COPY },
1519 { "settings", no_argument, NULL, OPT_SETTINGS },
1520 { "remove", no_argument, NULL, OPT_REMOVE },
1521 { "skip-apps", no_argument, NULL, OPT_SKIP_APPS },
1522 { "password", no_argument, NULL, OPT_PASSWORD },
1523 { "full", no_argument, NULL, OPT_FULL },
1524 { NULL, 0, NULL, 0}
1525 };
1526
1493 /* we need to exit cleanly on running backups and restores or we cause havok */ 1527 /* we need to exit cleanly on running backups and restores or we cause havok */
1494 signal(SIGINT, clean_exit); 1528 signal(SIGINT, clean_exit);
1495 signal(SIGTERM, clean_exit); 1529 signal(SIGTERM, clean_exit);
@@ -1499,201 +1533,192 @@ int main(int argc, char *argv[])
1499#endif 1533#endif
1500 1534
1501 /* parse cmdline args */ 1535 /* parse cmdline args */
1502 for (i = 1; i < argc; i++) { 1536 while ((c = getopt_long(argc, argv, "dhu:s:inv", longopts, NULL)) != -1) {
1503 if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { 1537 switch (c) {
1538 case 'd':
1504 idevice_set_debug_level(1); 1539 idevice_set_debug_level(1);
1505 continue; 1540 break;
1506 } 1541 case 'u':
1507 else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { 1542 if (!*optarg) {
1508 i++; 1543 fprintf(stderr, "ERROR: UDID argument must not be empty!\n");
1509 if (!argv[i] || !*argv[i]) { 1544 print_usage(argc, argv, 1);
1510 print_usage(argc, argv); 1545 return 2;
1511 return -1;
1512 } 1546 }
1513 udid = strdup(argv[i]); 1547 udid = strdup(optarg);
1514 continue; 1548 break;
1515 } 1549 case 's':
1516 else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--source")) { 1550 if (!*optarg) {
1517 i++; 1551 fprintf(stderr, "ERROR: SOURCE argument must not be empty!\n");
1518 if (!argv[i] || !*argv[i]) { 1552 print_usage(argc, argv, 1);
1519 print_usage(argc, argv); 1553 return 2;
1520 return -1;
1521 } 1554 }
1522 source_udid = strdup(argv[i]); 1555 source_udid = strdup(optarg);
1523 continue; 1556 case 'i':
1524 }
1525 else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) {
1526 use_network = 1;
1527 continue;
1528 }
1529 else if (!strcmp(argv[i], "-i") || !strcmp(argv[i], "--interactive")) {
1530 interactive_mode = 1; 1557 interactive_mode = 1;
1531 continue; 1558 break;
1532 } 1559 case 'n':
1533 else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { 1560 use_network = 1;
1534 print_usage(argc, argv); 1561 break;
1562 case 'h':
1563 print_usage(argc, argv, 0);
1535 return 0; 1564 return 0;
1536 } 1565 case 'v':
1537 else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
1538 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); 1566 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
1539 return 0; 1567 return 0;
1540 } 1568 case OPT_SYSTEM:
1541 else if (!strcmp(argv[i], "backup")) {
1542 cmd = CMD_BACKUP;
1543 }
1544 else if (!strcmp(argv[i], "restore")) {
1545 cmd = CMD_RESTORE;
1546 }
1547 else if (!strcmp(argv[i], "--system")) {
1548 cmd_flags |= CMD_FLAG_RESTORE_SYSTEM_FILES; 1569 cmd_flags |= CMD_FLAG_RESTORE_SYSTEM_FILES;
1549 } 1570 break;
1550 else if (!strcmp(argv[i], "--reboot")) { 1571 case OPT_REBOOT:
1551 cmd_flags &= ~CMD_FLAG_RESTORE_NO_REBOOT; 1572 cmd_flags &= ~CMD_FLAG_RESTORE_NO_REBOOT;
1552 } 1573 break;
1553 else if (!strcmp(argv[i], "--no-reboot")) { 1574 case OPT_NO_REBOOT:
1554 cmd_flags |= CMD_FLAG_RESTORE_NO_REBOOT; 1575 cmd_flags |= CMD_FLAG_RESTORE_NO_REBOOT;
1555 } 1576 break;
1556 else if (!strcmp(argv[i], "--copy")) { 1577 case OPT_COPY:
1557 cmd_flags |= CMD_FLAG_RESTORE_COPY_BACKUP; 1578 cmd_flags |= CMD_FLAG_RESTORE_COPY_BACKUP;
1558 } 1579 break;
1559 else if (!strcmp(argv[i], "--settings")) { 1580 case OPT_SETTINGS:
1560 cmd_flags |= CMD_FLAG_RESTORE_SETTINGS; 1581 cmd_flags |= CMD_FLAG_RESTORE_SETTINGS;
1561 } 1582 break;
1562 else if (!strcmp(argv[i], "--remove")) { 1583 case OPT_REMOVE:
1563 cmd_flags |= CMD_FLAG_RESTORE_REMOVE_ITEMS; 1584 cmd_flags |= CMD_FLAG_RESTORE_REMOVE_ITEMS;
1564 } 1585 break;
1565 else if (!strcmp(argv[i], "--skip-apps")) { 1586 case OPT_SKIP_APPS:
1566 cmd_flags |= CMD_FLAG_RESTORE_SKIP_APPS; 1587 cmd_flags |= CMD_FLAG_RESTORE_SKIP_APPS;
1567 } 1588 break;
1568 else if (!strcmp(argv[i], "--password")) { 1589 case OPT_PASSWORD:
1569 i++; 1590 free(backup_password);
1570 if (!argv[i]) { 1591 backup_password = strdup(optarg);
1571 print_usage(argc, argv); 1592 break;
1572 return -1; 1593 case OPT_FULL:
1573 }
1574 if (backup_password)
1575 free(backup_password);
1576 backup_password = strdup(argv[i]);
1577 continue;
1578 }
1579 else if (!strcmp(argv[i], "cloud")) {
1580 cmd = CMD_CLOUD;
1581 i++;
1582 if (!argv[i]) {
1583 printf("No argument given for cloud command; requires either 'on' or 'off'.\n");
1584 print_usage(argc, argv);
1585 return -1;
1586 }
1587 if (!strcmp(argv[i], "on")) {
1588 cmd_flags |= CMD_FLAG_CLOUD_ENABLE;
1589 } else if (!strcmp(argv[i], "off")) {
1590 cmd_flags |= CMD_FLAG_CLOUD_DISABLE;
1591 } else {
1592 printf("Invalid argument '%s' for cloud command; must be either 'on' or 'off'.\n", argv[i]);
1593 }
1594 continue;
1595 }
1596 else if (!strcmp(argv[i], "--full")) {
1597 cmd_flags |= CMD_FLAG_FORCE_FULL_BACKUP; 1594 cmd_flags |= CMD_FLAG_FORCE_FULL_BACKUP;
1595 default:
1596 print_usage(argc, argv, 1);
1597 return 2;
1598 } 1598 }
1599 else if (!strcmp(argv[i], "info")) { 1599 }
1600 cmd = CMD_INFO; 1600 argc -= optind;
1601 verbose = 0; 1601 argv += optind;
1602 } 1602
1603 else if (!strcmp(argv[i], "list")) { 1603 if (!argv[0]) {
1604 cmd = CMD_LIST; 1604 fprintf(stderr, "ERROR: No command specified.\n");
1605 verbose = 0; 1605 print_usage(argc+optind, argv-optind, 1);
1606 return 2;
1607 }
1608
1609 if (!strcmp(argv[0], "backup")) {
1610 cmd = CMD_BACKUP;
1611 i = 1;
1612 }
1613 else if (!strcmp(argv[0], "restore")) {
1614 cmd = CMD_RESTORE;
1615 i = 1;
1616 }
1617 else if (!strcmp(argv[0], "cloud")) {
1618 cmd = CMD_CLOUD;
1619 i = 1;
1620 if (!argv[i]) {
1621 fprintf(stderr, "ERROR: No argument given for cloud command; requires either 'on' or 'off'.\n");
1622 print_usage(argc+optind, argv-optind, 1);
1623 return 2;
1606 } 1624 }
1607 else if (!strcmp(argv[i], "unback")) { 1625 if (!strcmp(argv[i], "on")) {
1608 cmd = CMD_UNBACK; 1626 cmd_flags |= CMD_FLAG_CLOUD_ENABLE;
1627 } else if (!strcmp(argv[i], "off")) {
1628 cmd_flags |= CMD_FLAG_CLOUD_DISABLE;
1629 } else {
1630 fprintf(stderr, "ERROR: Invalid argument '%s' for cloud command; must be either 'on' or 'off'.\n", argv[i]);
1631 print_usage(argc+optind, argv-optind, 1);
1632 return 2;
1633 }
1634 }
1635 else if (!strcmp(argv[0], "info")) {
1636 cmd = CMD_INFO;
1637 verbose = 0;
1638 }
1639 else if (!strcmp(argv[0], "list")) {
1640 cmd = CMD_LIST;
1641 verbose = 0;
1642 }
1643 else if (!strcmp(argv[0], "unback")) {
1644 cmd = CMD_UNBACK;
1645 }
1646 else if (!strcmp(argv[0], "encryption")) {
1647 cmd = CMD_CHANGEPW;
1648 i = 1;
1649 if (!argv[i]) {
1650 fprintf(stderr, "ERROR: No argument given for encryption command; requires either 'on' or 'off'.\n");
1651 print_usage(argc+optind, argv-optind, 1);
1652 return 2;
1653 }
1654 if (!strcmp(argv[i], "on")) {
1655 cmd_flags |= CMD_FLAG_ENCRYPTION_ENABLE;
1656 } else if (!strcmp(argv[i], "off")) {
1657 cmd_flags |= CMD_FLAG_ENCRYPTION_DISABLE;
1658 } else {
1659 fprintf(stderr, "ERROR: Invalid argument '%s' for encryption command; must be either 'on' or 'off'.\n", argv[i]);
1660 print_usage(argc+optind, argv-optind, 1);
1661 return 2;
1609 } 1662 }
1610 else if (!strcmp(argv[i], "encryption")) { 1663 // check if a password was given on the command line
1611 cmd = CMD_CHANGEPW; 1664 free(newpw);
1612 i++; 1665 newpw = NULL;
1613 if (!argv[i]) { 1666 free(backup_password);
1614 printf("No argument given for encryption command; requires either 'on' or 'off'.\n"); 1667 backup_password = NULL;
1615 print_usage(argc, argv); 1668 i++;
1616 return -1; 1669 if (argv[i]) {
1617 } 1670 if (cmd_flags & CMD_FLAG_ENCRYPTION_ENABLE) {
1618 if (!strcmp(argv[i], "on")) { 1671 newpw = strdup(argv[i]);
1619 cmd_flags |= CMD_FLAG_ENCRYPTION_ENABLE; 1672 } else if (cmd_flags & CMD_FLAG_ENCRYPTION_DISABLE) {
1620 } else if (!strcmp(argv[i], "off")) { 1673 backup_password = strdup(argv[i]);
1621 cmd_flags |= CMD_FLAG_ENCRYPTION_DISABLE;
1622 } else {
1623 printf("Invalid argument '%s' for encryption command; must be either 'on' or 'off'.\n", argv[i]);
1624 }
1625 // check if a password was given on the command line
1626 if (newpw) {
1627 free(newpw);
1628 newpw = NULL;
1629 }
1630 if (backup_password) {
1631 free(backup_password);
1632 backup_password = NULL;
1633 }
1634 i++;
1635 if (argv[i]) {
1636 if (cmd_flags & CMD_FLAG_ENCRYPTION_ENABLE) {
1637 newpw = strdup(argv[i]);
1638 } else if (cmd_flags & CMD_FLAG_ENCRYPTION_DISABLE) {
1639 backup_password = strdup(argv[i]);
1640 }
1641 } 1674 }
1642 continue;
1643 } 1675 }
1644 else if (!strcmp(argv[i], "changepw")) { 1676 }
1645 cmd = CMD_CHANGEPW; 1677 else if (!strcmp(argv[0], "changepw")) {
1646 cmd_flags |= CMD_FLAG_ENCRYPTION_CHANGEPW; 1678 cmd = CMD_CHANGEPW;
1647 // check if passwords were given on command line 1679 cmd_flags |= CMD_FLAG_ENCRYPTION_CHANGEPW;
1648 if (newpw) { 1680 // check if passwords were given on command line
1649 free(newpw); 1681 free(newpw);
1650 newpw = NULL; 1682 newpw = NULL;
1651 } 1683 free(backup_password);
1652 if (backup_password) { 1684 backup_password = NULL;
1653 free(backup_password); 1685 i = 1;
1654 backup_password = NULL; 1686 if (argv[i]) {
1655 } 1687 backup_password = strdup(argv[i]);
1656 i++; 1688 i++;
1657 if (argv[i]) { 1689 if (!argv[i]) {
1658 backup_password = strdup(argv[i]); 1690 fprintf(stderr, "ERROR: Old and new passwords have to be passed as arguments for the changepw command\n");
1659 i++; 1691 print_usage(argc+optind, argv-optind, 1);
1660 if (!argv[i]) { 1692 return 2;
1661 printf("Old and new passwords have to be passed as arguments for the changepw command\n");
1662 print_usage(argc, argv);
1663 return -1;
1664 }
1665 newpw = strdup(argv[i]);
1666 } 1693 }
1667 continue; 1694 newpw = strdup(argv[i]);
1668 }
1669 else if (backup_directory == NULL) {
1670 backup_directory = argv[i];
1671 }
1672 else {
1673 print_usage(argc, argv);
1674 return -1;
1675 } 1695 }
1676 } 1696 }
1677 1697
1698 i++;
1699 if (argv[i]) {
1700 backup_directory = argv[i];
1701 }
1702
1678 /* verify options */ 1703 /* verify options */
1679 if (cmd == -1) { 1704 if (cmd == -1) {
1680 printf("No command specified.\n"); 1705 fprintf(stderr, "ERROR: Unsupported command '%s'.\n", argv[0]);
1681 print_usage(argc, argv); 1706 print_usage(argc+optind, argv-optind, 1);
1682 return -1; 1707 return 2;
1683 } 1708 }
1684 1709
1685 if (cmd == CMD_CHANGEPW || cmd == CMD_CLOUD) { 1710 if (cmd == CMD_CHANGEPW || cmd == CMD_CLOUD) {
1686 backup_directory = (char*)".this_folder_is_not_present_on_purpose"; 1711 backup_directory = (char*)".this_folder_is_not_present_on_purpose";
1687 } else { 1712 } else {
1688 if (backup_directory == NULL) { 1713 if (backup_directory == NULL) {
1689 printf("No target backup directory specified.\n"); 1714 fprintf(stderr, "ERROR: No target backup directory specified.\n");
1690 print_usage(argc, argv); 1715 print_usage(argc+optind, argv-optind, 1);
1691 return -1; 1716 return 2;
1692 } 1717 }
1693 1718
1694 /* verify if passed backup directory exists */ 1719 /* verify if passed backup directory exists */
1695 if (stat(backup_directory, &st) != 0) { 1720 if (stat(backup_directory, &st) != 0) {
1696 printf("ERROR: Backup directory \"%s\" does not exist!\n", backup_directory); 1721 fprintf(stderr, "ERROR: Backup directory \"%s\" does not exist!\n", backup_directory);
1697 return -1; 1722 return -1;
1698 } 1723 }
1699 } 1724 }
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
316static void print_usage(int argc, char **argv) 317static 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
339int main(int argc, char* argv[]) 340int 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);
diff --git a/tools/idevicedate.c b/tools/idevicedate.c
index 505ed30..d05f63e 100644
--- a/tools/idevicedate.c
+++ b/tools/idevicedate.c
@@ -28,6 +28,7 @@
28#include <stdio.h> 28#include <stdio.h>
29#include <stdlib.h> 29#include <stdlib.h>
30#include <string.h> 30#include <string.h>
31#include <getopt.h>
31#include <time.h> 32#include <time.h>
32#if HAVE_LANGINFO_CODESET 33#if HAVE_LANGINFO_CODESET
33#include <langinfo.h> 34#include <langinfo.h>
@@ -49,29 +50,29 @@
49#endif 50#endif
50#endif 51#endif
51 52
52static void print_usage(int argc, char **argv) 53static void print_usage(int argc, char **argv, int is_error)
53{ 54{
54 char *name = NULL; 55 char *name = strrchr(argv[0], '/');
55 56 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0]));
56 name = strrchr(argv[0], '/'); 57 fprintf(is_error ? stderr : stdout,
57 printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); 58 "\n"
58 printf("\n"); 59 "Display the current date or set it on a device.\n"
59 printf("Display the current date or set it on a device.\n"); 60 "\n"
60 printf("\n"); 61 "NOTE: Setting the time on iOS 6 and later is only supported\n"
61 printf("NOTE: Setting the time on iOS 6 and later is only supported\n"); 62 " in the setup wizard screens before device activation.\n"
62 printf(" in the setup wizard screens before device activation.\n"); 63 "\n"
63 printf("\n"); 64 "OPTIONS:\n"
64 printf("OPTIONS:\n"); 65 " -u, --udid UDID target specific device by UDID\n"
65 printf(" -u, --udid UDID\ttarget specific device by UDID\n"); 66 " -n, --network connect to network device\n"
66 printf(" -n, --network\t\tconnect to network device\n"); 67 " -s, --set TIMESTAMP set UTC time described by TIMESTAMP\n"
67 printf(" -s, --set TIMESTAMP\tset UTC time described by TIMESTAMP\n"); 68 " -c, --sync set time of device to current system time\n"
68 printf(" -c, --sync\t\tset time of device to current system time\n"); 69 " -d, --debug enable communication debugging\n"
69 printf(" -d, --debug\t\tenable communication debugging\n"); 70 " -h, --help prints usage information\n"
70 printf(" -h, --help\t\tprints usage information\n"); 71 " -v, --version prints version information\n"
71 printf(" -v, --version\t\tprints version information\n"); 72 "\n"
72 printf("\n"); 73 "Homepage: <" PACKAGE_URL ">\n"
73 printf("Homepage: <" PACKAGE_URL ">\n"); 74 "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
74 printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); 75 );
75} 76}
76 77
77int main(int argc, char *argv[]) 78int main(int argc, char *argv[])
@@ -80,7 +81,6 @@ int main(int argc, char *argv[])
80 lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR; 81 lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR;
81 idevice_t device = NULL; 82 idevice_t device = NULL;
82 idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; 83 idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
83 int i;
84 const char* udid = NULL; 84 const char* udid = NULL;
85 int use_network = 0; 85 int use_network = 0;
86 time_t setdate = 0; 86 time_t setdate = 0;
@@ -92,65 +92,72 @@ int main(int argc, char *argv[])
92 char buffer[80]; 92 char buffer[80];
93 int result = 0; 93 int result = 0;
94 94
95 int c = 0;
96 const struct option longopts[] = {
97 { "debug", no_argument, NULL, 'd' },
98 { "help", no_argument, NULL, 'h' },
99 { "udid", required_argument, NULL, 'u' },
100 { "network", no_argument, NULL, 'n' },
101 { "version", no_argument, NULL, 'v' },
102 { "set", required_argument, NULL, 's' },
103 { "sync", no_argument, NULL, 'c' },
104 { NULL, 0, NULL, 0}
105 };
106
95#ifndef WIN32 107#ifndef WIN32
96 signal(SIGPIPE, SIG_IGN); 108 signal(SIGPIPE, SIG_IGN);
97#endif 109#endif
98 /* parse cmdline args */ 110 /* parse cmdline args */
99 for (i = 1; i < argc; i++) { 111 while ((c = getopt_long(argc, argv, "dhu:nvs:c", longopts, NULL)) != -1) {
100 if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { 112 switch (c) {
113 case 'd':
101 idevice_set_debug_level(1); 114 idevice_set_debug_level(1);
102 continue; 115 break;
103 } 116 case 'u':
104 else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { 117 if (!*optarg) {
105 i++; 118 fprintf(stderr, "ERROR: UDID argument must not be empty!\n");
106 if (!argv[i] || !*argv[i]) { 119 print_usage(argc, argv, 1);
107 print_usage(argc, argv); 120 return 2;
108 return 0;
109 } 121 }
110 udid = argv[i]; 122 udid = optarg;
111 continue; 123 break;
112 } 124 case 'n':
113 else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) {
114 use_network = 1; 125 use_network = 1;
115 continue; 126 break;
116 } 127 case 'h':
117 else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--set")) { 128 print_usage(argc, argv, 0);
118 i++; 129 return 0;
119 if (!argv[i] || (strlen(argv[i]) <= 1)) { 130 case 'v':
120 print_usage(argc, argv); 131 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
121 return 0; 132 return 0;
133 case 's':
134 if (!*optarg) {
135 fprintf(stderr, "ERROR: set argument must not be empty!\n");
136 print_usage(argc, argv, 1);
137 return 2;
122 } 138 }
123 setdate = atoi(argv[i]); 139 setdate = atoi(optarg);
124 if (setdate == 0) { 140 if (setdate == 0) {
125 printf("ERROR: Invalid timestamp value.\n"); 141 fprintf(stderr, "ERROR: Invalid timestamp value.\n");
126 print_usage(argc, argv); 142 print_usage(argc, argv, 1);
127 return 0; 143 return 0;
128 } 144 }
129 continue; 145 break;
130 } 146 case 'c':
131 else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--sync")) {
132 i++;
133 /* get current time */ 147 /* get current time */
134 setdate = time(NULL); 148 setdate = time(NULL);
135 /* convert it to local time which sets timezone/daylight variables */ 149 /* convert it to local time which sets timezone/daylight variables */
136 tmp = localtime(&setdate); 150 tmp = localtime(&setdate);
137 /* recalculate to make it UTC */ 151 /* recalculate to make it UTC */
138 setdate = mktime(tmp); 152 setdate = mktime(tmp);
139 continue; 153 break;
140 } 154 default:
141 else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { 155 print_usage(argc, argv, 1);
142 print_usage(argc, argv); 156 return 2;
143 return 0;
144 }
145 else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
146 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
147 return 0;
148 }
149 else {
150 print_usage(argc, argv);
151 return 0;
152 } 157 }
153 } 158 }
159 argc -= optind;
160 argv += optind;
154 161
155 ret = idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX); 162 ret = idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX);
156 if (ret != IDEVICE_E_SUCCESS) { 163 if (ret != IDEVICE_E_SUCCESS) {
diff --git a/tools/idevicedebug.c b/tools/idevicedebug.c
index 01551a2..fbb6c3e 100644
--- a/tools/idevicedebug.c
+++ b/tools/idevicedebug.c
@@ -177,27 +177,26 @@ static debugserver_error_t debugserver_client_handle_response(debugserver_client
177 177
178static void print_usage(int argc, char **argv, int is_error) 178static void print_usage(int argc, char **argv, int is_error)
179{ 179{
180 char *name = NULL; 180 char *name = strrchr(argv[0], '/');
181 name = strrchr(argv[0], '/');
182 fprintf(is_error ? stderr : stdout, "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]));
183 fprintf(is_error ? stderr : stdout, 182 fprintf(is_error ? stderr : stdout,
184 "\n" \ 183 "\n"
185 "Interact with the debugserver service of a device.\n" \ 184 "Interact with the debugserver service of a device.\n"
186 "\n" \ 185 "\n"
187 "Where COMMAND is one of:\n" \ 186 "Where COMMAND is one of:\n"
188 " run BUNDLEID [ARGS...]\trun app with BUNDLEID and optional ARGS on device.\n" \ 187 " run BUNDLEID [ARGS...] run app with BUNDLEID and optional ARGS on device.\n"
189 " kill BUNDLEID\tkill app with BUNDLEID\n" \ 188 " kill BUNDLEID kill app with BUNDLEID\n"
190 "\n" \ 189 "\n"
191 "The following OPTIONS are accepted:\n" \ 190 "The following OPTIONS are accepted:\n"
192 " -u, --udid UDID\ttarget specific device by UDID\n" \ 191 " -u, --udid UDID target specific device by UDID\n"
193 " -n, --network\t\tconnect to network device\n" \ 192 " -n, --network connect to network device\n"
194 " --detach\t\tdetach from app after launch, keeping it running\n" \ 193 " --detach detach from app after launch, keeping it running\n"
195 " -e, --env NAME=VALUE\tset environment variable NAME to VALUE\n" \ 194 " -e, --env NAME=VALUE set environment variable NAME to VALUE\n"
196 " -d, --debug\t\tenable communication debugging\n" \ 195 " -d, --debug enable communication debugging\n"
197 " -h, --help\t\tprints usage information\n" \ 196 " -h, --help prints usage information\n"
198 " -v, --version\t\tprints version information\n" \ 197 " -v, --version prints version information\n"
199 "\n" \ 198 "\n"
200 "Homepage: <" PACKAGE_URL ">\n" \ 199 "Homepage: <" PACKAGE_URL ">\n"
201 "Bug Reports: <" PACKAGE_BUGREPORT ">\n" 200 "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
202 ); 201 );
203} 202}
@@ -294,13 +293,13 @@ int main(int argc, char *argv[])
294 break; 293 break;
295 } 294 }
296 } 295 }
297
298 argc -= optind; 296 argc -= optind;
299 argv += optind; 297 argv += optind;
300 298
301 if (argc < 1) { 299 if (argc < 1) {
302 fprintf(stderr, "ERROR: Missing command.\n"); 300 fprintf(stderr, "ERROR: Missing command.\n");
303 print_usage(argc+optind, argv-optind, 1); 301 print_usage(argc+optind, argv-optind, 1);
302 return 2;
304 } 303 }
305 304
306 if (!strcmp(argv[0], "run")) { 305 if (!strcmp(argv[0], "run")) {
diff --git a/tools/idevicedebugserverproxy.c b/tools/idevicedebugserverproxy.c
index 79c2d38..8a3b4ff 100644
--- a/tools/idevicedebugserverproxy.c
+++ b/tools/idevicedebugserverproxy.c
@@ -29,6 +29,7 @@
29#include <stdio.h> 29#include <stdio.h>
30#include <stdlib.h> 30#include <stdlib.h>
31#include <string.h> 31#include <string.h>
32#include <getopt.h>
32#include <errno.h> 33#include <errno.h>
33#include <signal.h> 34#include <signal.h>
34#ifdef WIN32 35#ifdef WIN32
@@ -75,26 +76,26 @@ static void clean_exit(int sig)
75 quit_flag++; 76 quit_flag++;
76} 77}
77 78
78static void print_usage(int argc, char **argv) 79static void print_usage(int argc, char **argv, int is_error)
79{ 80{
80 char *name = NULL; 81 char *name = strrchr(argv[0], '/');
81 82 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] [PORT]\n", (name ? name + 1: argv[0]));
82 name = strrchr(argv[0], '/'); 83 fprintf(is_error ? stderr : stdout,
83 printf("Usage: %s [OPTIONS] [PORT]\n", (name ? name + 1: argv[0])); 84 "\n"
84 printf("\n"); 85 "Proxy debugserver connection from device to a local socket at PORT.\n"
85 printf("Proxy debugserver connection from device to a local socket at PORT.\n"); 86 "If PORT is omitted, the next available port will be used and printed\n"
86 printf("If PORT is omitted, the next available port will be used and printed\n"); 87 "to stdout.\n"
87 printf("to stdout.\n"); 88 "\n"
88 printf("\n"); 89 "OPTIONS:\n"
89 printf("OPTIONS:\n"); 90 " -u, --udid UDID target specific device by UDID\n"
90 printf(" -u, --udid UDID\ttarget specific device by UDID\n"); 91 " -n, --network connect to network device\n"
91 printf(" -n, --network\t\tconnect to network device\n"); 92 " -d, --debug enable communication debugging\n"
92 printf(" -d, --debug\t\tenable communication debugging\n"); 93 " -h, --help prints usage information\n"
93 printf(" -h, --help\t\tprints usage information\n"); 94 " -v, --version prints version information\n"
94 printf(" -v, --version\t\tprints version information\n"); 95 "\n"
95 printf("\n"); 96 "Homepage: <" PACKAGE_URL ">\n"
96 printf("Homepage: <" PACKAGE_URL ">\n"); 97 "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
97 printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); 98 );
98} 99}
99 100
100static void* connection_handler(void* data) 101static void* connection_handler(void* data)
@@ -182,7 +183,15 @@ int main(int argc, char *argv[])
182 uint16_t local_port = 0; 183 uint16_t local_port = 0;
183 int server_fd; 184 int server_fd;
184 int result = EXIT_SUCCESS; 185 int result = EXIT_SUCCESS;
185 int i; 186 int c = 0;
187 const struct option longopts[] = {
188 { "debug", no_argument, NULL, 'd' },
189 { "help", no_argument, NULL, 'h' },
190 { "udid", required_argument, NULL, 'u' },
191 { "network", no_argument, NULL, 'n' },
192 { "version", no_argument, NULL, 'v' },
193 { NULL, 0, NULL, 0}
194 };
186 195
187#ifndef WIN32 196#ifndef WIN32
188 struct sigaction sa; 197 struct sigaction sa;
@@ -207,43 +216,41 @@ int main(int argc, char *argv[])
207#endif 216#endif
208 217
209 /* parse cmdline arguments */ 218 /* parse cmdline arguments */
210 for (i = 1; i < argc; i++) { 219 while ((c = getopt_long(argc, argv, "dhu:nv", longopts, NULL)) != -1) {
211 if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { 220 switch (c) {
221 case 'd':
212 debug_mode = 1; 222 debug_mode = 1;
213 idevice_set_debug_level(1); 223 idevice_set_debug_level(1);
214 socket_set_verbose(3); 224 socket_set_verbose(3);
215 continue; 225 break;
216 } 226 case 'u':
217 else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { 227 if (!*optarg) {
218 i++; 228 fprintf(stderr, "ERROR: UDID argument must not be empty!\n");
219 if (!argv[i] || !*argv[i]) { 229 print_usage(argc, argv, 1);
220 print_usage(argc, argv); 230 return 2;
221 return 0;
222 } 231 }
223 udid = argv[i]; 232 udid = optarg;
224 continue; 233 break;
225 } 234 case 'n':
226 else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) {
227 use_network = 1; 235 use_network = 1;
228 continue; 236 break;
229 } 237 case 'h':
230 else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { 238 print_usage(argc, argv, 0);
231 print_usage(argc, argv); 239 return 0;
232 return EXIT_SUCCESS; 240 case 'v':
233 }
234 else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
235 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); 241 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
236 return EXIT_SUCCESS; 242 return 0;
237 } 243 default:
238 else if (atoi(argv[i]) > 0) { 244 print_usage(argc, argv, 1);
239 local_port = atoi(argv[i]); 245 return 2;
240 continue;
241 }
242 else {
243 print_usage(argc, argv);
244 return EXIT_SUCCESS;
245 } 246 }
246 } 247 }
248 argc -= optind;
249 argv += optind;
250
251 if (argv[0] && (atoi(argv[0]) > 0)) {
252 local_port = atoi(argv[0]);
253 }
247 254
248 /* start services and connect to device */ 255 /* start services and connect to device */
249 ret = idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX); 256 ret = idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX);
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
62void print_usage(int argc, char **argv); 63static 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
64int main(int argc, char **argv) 92int 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
329void 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}
diff --git a/tools/ideviceenterrecovery.c b/tools/ideviceenterrecovery.c
index 0cc9936..29cc5c9 100644
--- a/tools/ideviceenterrecovery.c
+++ b/tools/ideviceenterrecovery.c
@@ -27,8 +27,9 @@
27 27
28#include <stdio.h> 28#include <stdio.h>
29#include <string.h> 29#include <string.h>
30#include <errno.h>
31#include <stdlib.h> 30#include <stdlib.h>
31#include <getopt.h>
32#include <errno.h>
32#ifndef WIN32 33#ifndef WIN32
33#include <signal.h> 34#include <signal.h>
34#endif 35#endif
@@ -36,22 +37,22 @@
36#include <libimobiledevice/libimobiledevice.h> 37#include <libimobiledevice/libimobiledevice.h>
37#include <libimobiledevice/lockdown.h> 38#include <libimobiledevice/lockdown.h>
38 39
39static void print_usage(int argc, char **argv) 40static void print_usage(int argc, char **argv, int is_error)
40{ 41{
41 char *name = NULL; 42 char *name = strrchr(argv[0], '/');
42 43 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] UDID\n", (name ? name + 1: argv[0]));
43 name = strrchr(argv[0], '/'); 44 fprintf(is_error ? stderr : stdout,
44 printf("Usage: %s [OPTIONS] UDID\n", (name ? name + 1: argv[0])); 45 "\n"
45 printf("\n"); 46 "Makes a device with the supplied UDID enter recovery mode immediately.\n"
46 printf("Makes a device with the supplied UDID enter recovery mode immediately.\n"); 47 "\n"
47 printf("\n"); 48 "OPTIONS:\n"
48 printf("OPTIONS:\n"); 49 " -d, --debug enable communication debugging\n"
49 printf(" -d, --debug\t\tenable communication debugging\n"); 50 " -h, --help prints usage information\n"
50 printf(" -h, --help\t\tprints usage information\n"); 51 " -v, --version prints version information\n"
51 printf(" -v, --version\t\tprints version information\n"); 52 "\n"
52 printf("\n"); 53 "Homepage: <" PACKAGE_URL ">\n"
53 printf("Homepage: <" PACKAGE_URL ">\n"); 54 "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
54 printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); 55 );
55} 56}
56 57
57int main(int argc, char *argv[]) 58int main(int argc, char *argv[])
@@ -60,34 +61,44 @@ int main(int argc, char *argv[])
60 lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR; 61 lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR;
61 idevice_t device = NULL; 62 idevice_t device = NULL;
62 idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; 63 idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
63 int i;
64 const char* udid = NULL; 64 const char* udid = NULL;
65 int c = 0;
66 const struct option longopts[] = {
67 { "debug", no_argument, NULL, 'd' },
68 { "help", no_argument, NULL, 'h' },
69 { "version", no_argument, NULL, 'v' },
70 { NULL, 0, NULL, 0}
71 };
65 72
66#ifndef WIN32 73#ifndef WIN32
67 signal(SIGPIPE, SIG_IGN); 74 signal(SIGPIPE, SIG_IGN);
68#endif 75#endif
69 /* parse cmdline args */ 76 /* parse cmdline args */
70 for (i = 1; i < argc; i++) { 77 while ((c = getopt_long(argc, argv, "dhv", longopts, NULL)) != -1) {
71 if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { 78 switch (c) {
79 case 'd':
72 idevice_set_debug_level(1); 80 idevice_set_debug_level(1);
73 continue; 81 break;
74 } 82 case 'h':
75 else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { 83 print_usage(argc, argv, 0);
76 print_usage(argc, argv);
77 return 0; 84 return 0;
78 } 85 case 'v':
79 else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
80 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); 86 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
81 return 0; 87 return 0;
88 default:
89 print_usage(argc, argv, 1);
90 return 2;
82 } 91 }
83 } 92 }
93 argc -= optind;
94 argv += optind;
84 95
85 i--; 96 if (!argv[0]) {
86 if (argc < 2 || !argv[i] || !*argv[i]) { 97 fprintf(stderr, "ERROR: No UDID specified\n");
87 print_usage(argc, argv); 98 print_usage(argc+optind, argv-optind, 1);
88 return 0; 99 return 2;
89 } 100 }
90 udid = argv[i]; 101 udid = argv[0];
91 102
92 ret = idevice_new(&device, udid); 103 ret = idevice_new(&device, udid);
93 if (ret != IDEVICE_E_SUCCESS) { 104 if (ret != IDEVICE_E_SUCCESS) {
diff --git a/tools/ideviceimagemounter.c b/tools/ideviceimagemounter.c
index 37c2154..b854d5d 100644
--- a/tools/ideviceimagemounter.c
+++ b/tools/ideviceimagemounter.c
@@ -62,27 +62,27 @@ typedef enum {
62 DISK_IMAGE_UPLOAD_TYPE_UPLOAD_IMAGE 62 DISK_IMAGE_UPLOAD_TYPE_UPLOAD_IMAGE
63} disk_image_upload_type_t; 63} disk_image_upload_type_t;
64 64
65static void print_usage(int argc, char **argv) 65static void print_usage(int argc, char **argv, int is_error)
66{ 66{
67 char *name = NULL; 67 char *name = strrchr(argv[0], '/');
68 68 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] IMAGE_FILE IMAGE_SIGNATURE_FILE\n", (name ? name + 1: argv[0]));
69 name = strrchr(argv[0], '/'); 69 fprintf(is_error ? stderr : stdout,
70 printf("Usage: %s [OPTIONS] IMAGE_FILE IMAGE_SIGNATURE_FILE\n", (name ? name + 1: argv[0])); 70 "\n"
71 printf("\n"); 71 "Mounts the specified disk image on the device.\n"
72 printf("Mounts the specified disk image on the device.\n"); 72 "\n"
73 printf("\n"); 73 "OPTIONS:\n"
74 printf("OPTIONS:\n"); 74 " -u, --udid UDID target specific device by UDID\n"
75 printf(" -u, --udid UDID\ttarget specific device by UDID\n"); 75 " -n, --network connect to network device\n"
76 printf(" -n, --network\t\tconnect to network device\n"); 76 " -l, --list List mount information\n"
77 printf(" -l, --list\t\tList mount information\n"); 77 " -t, --imagetype TYPE Image type to use, default is 'Developer'\n"
78 printf(" -t, --imagetype\tImage type to use, default is 'Developer'\n"); 78 " -x, --xml Use XML output\n"
79 printf(" -x, --xml\t\tUse XML output\n"); 79 " -d, --debug enable communication debugging\n"
80 printf(" -d, --debug\t\tenable communication debugging\n"); 80 " -h, --help prints usage information\n"
81 printf(" -h, --help\t\tprints usage information\n"); 81 " -v, --version prints version information\n"
82 printf(" -v, --version\t\tprints version information\n"); 82 "\n"
83 printf("\n"); 83 "Homepage: <" PACKAGE_URL ">\n"
84 printf("Homepage: <" PACKAGE_URL ">\n"); 84 "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
85 printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); 85 );
86} 86}
87 87
88static void parse_opts(int argc, char **argv) 88static void parse_opts(int argc, char **argv)
@@ -108,12 +108,12 @@ static void parse_opts(int argc, char **argv)
108 108
109 switch (c) { 109 switch (c) {
110 case 'h': 110 case 'h':
111 print_usage(argc, argv); 111 print_usage(argc, argv, 0);
112 exit(0); 112 exit(0);
113 case 'u': 113 case 'u':
114 if (!*optarg) { 114 if (!*optarg) {
115 fprintf(stderr, "ERROR: UDID must not be empty!\n"); 115 fprintf(stderr, "ERROR: UDID must not be empty!\n");
116 print_usage(argc, argv); 116 print_usage(argc, argv, 1);
117 exit(2); 117 exit(2);
118 } 118 }
119 udid = optarg; 119 udid = optarg;
@@ -137,7 +137,7 @@ static void parse_opts(int argc, char **argv)
137 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); 137 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
138 exit(0); 138 exit(0);
139 default: 139 default:
140 print_usage(argc, argv); 140 print_usage(argc, argv, 1);
141 exit(2); 141 exit(2);
142 } 142 }
143 } 143 }
diff --git a/tools/ideviceinfo.c b/tools/ideviceinfo.c
index f80b678..ead3fa6 100644
--- a/tools/ideviceinfo.c
+++ b/tools/ideviceinfo.c
@@ -93,23 +93,22 @@ static int is_domain_known(const char *domain)
93static void print_usage(int argc, char **argv, int is_error) 93static void print_usage(int argc, char **argv, int is_error)
94{ 94{
95 int i = 0; 95 int i = 0;
96 char *name = NULL; 96 char *name = strrchr(argv[0], '/');
97 name = strrchr(argv[0], '/');
98 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); 97 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0]));
99 fprintf(is_error ? stderr : stdout, 98 fprintf(is_error ? stderr : stdout,
100 "\n" \ 99 "\n"
101 "Show information about a connected device.\n" \ 100 "Show information about a connected device.\n"
102 "\n" \ 101 "\n"
103 "OPTIONS:\n" \ 102 "OPTIONS:\n"
104 " -u, --udid UDID target specific device by UDID\n" \ 103 " -u, --udid UDID target specific device by UDID\n"
105 " -n, --network connect to network device\n" \ 104 " -n, --network connect to network device\n"
106 " -s, --simple use a simple connection to avoid auto-pairing with the device\n" \ 105 " -s, --simple use simple connection to avoid auto-pairing with device\n"
107 " -q, --domain NAME set domain of query to NAME. Default: None\n" \ 106 " -q, --domain NAME set domain of query to NAME. Default: None\n" \
108 " -k, --key NAME only query key specified by NAME. Default: All keys.\n" \ 107 " -k, --key NAME only query key specified by NAME. Default: All keys.\n" \
109 " -x, --xml output information as xml plist instead of key/value pairs\n" \ 108 " -x, --xml output information in XML property list format\n" \
110 " -h, --help prints usage information\n" \ 109 " -h, --help prints usage information\n" \
111 " -d, --debug enable communication debugging\n" \ 110 " -d, --debug enable communication debugging\n" \
112 " -v, --version prints version information\n" \ 111 " -v, --version prints version information\n" \
113 "\n" 112 "\n"
114 ); 113 );
115 fprintf(is_error ? stderr : stdout, "Known domains are:\n\n"); 114 fprintf(is_error ? stderr : stdout, "Known domains are:\n\n");
diff --git a/tools/idevicename.c b/tools/idevicename.c
index 97bf2d4..69b76f6 100644
--- a/tools/idevicename.c
+++ b/tools/idevicename.c
@@ -37,21 +37,24 @@
37#include <libimobiledevice/libimobiledevice.h> 37#include <libimobiledevice/libimobiledevice.h>
38#include <libimobiledevice/lockdown.h> 38#include <libimobiledevice/lockdown.h>
39 39
40static void print_usage(void) 40static void print_usage(int argc, char** argv, int is_error)
41{ 41{
42 printf("Usage: idevicename [OPTIONS] [NAME]\n"); 42 char *name = strrchr(argv[0], '/');
43 printf("\n"); 43 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] [NAME]\n", (name ? name + 1: argv[0]));
44 printf("Display the device name or set it to NAME if specified.\n"); 44 fprintf(is_error ? stderr : stdout,
45 printf("\n"); 45 "\n"
46 printf("OPTIONS:\n"); 46 "Display the device name or set it to NAME if specified.\n"
47 printf(" -u, --udid UDID\ttarget specific device by UDID\n"); 47 "\n"
48 printf(" -n, --network\t\tconnect to network device\n"); 48 "OPTIONS:\n"
49 printf(" -d, --debug\t\tenable communication debugging\n"); 49 " -u, --udid UDID target specific device by UDID\n"
50 printf(" -h, --help\t\tprint usage information\n"); 50 " -n, --network connect to network device\n"
51 printf(" -v, --version\t\tprint version information\n"); 51 " -d, --debug enable communication debugging\n"
52 printf("\n"); 52 " -h, --help print usage information\n"
53 printf("Homepage: <" PACKAGE_URL ">\n"); 53 " -v, --version print version information\n"
54 printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); 54 "\n"
55 "Homepage: <" PACKAGE_URL ">\n"
56 "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
57 );
55} 58}
56 59
57int main(int argc, char** argv) 60int main(int argc, char** argv)
@@ -78,7 +81,7 @@ int main(int argc, char** argv)
78 case 'u': 81 case 'u':
79 if (!*optarg) { 82 if (!*optarg) {
80 fprintf(stderr, "ERROR: UDID must not be empty!\n"); 83 fprintf(stderr, "ERROR: UDID must not be empty!\n");
81 print_usage(); 84 print_usage(argc, argv, 1);
82 exit(2); 85 exit(2);
83 } 86 }
84 udid = optarg; 87 udid = optarg;
@@ -87,7 +90,7 @@ int main(int argc, char** argv)
87 use_network = 1; 90 use_network = 1;
88 break; 91 break;
89 case 'h': 92 case 'h':
90 print_usage(); 93 print_usage(argc, argv, 0);
91 return 0; 94 return 0;
92 case 'd': 95 case 'd':
93 idevice_set_debug_level(1); 96 idevice_set_debug_level(1);
@@ -96,7 +99,7 @@ int main(int argc, char** argv)
96 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); 99 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
97 return 0; 100 return 0;
98 default: 101 default:
99 print_usage(); 102 print_usage(argc, argv, 1);
100 return 2; 103 return 2;
101 } 104 }
102 } 105 }
@@ -105,8 +108,8 @@ int main(int argc, char** argv)
105 argv += optind; 108 argv += optind;
106 109
107 if (argc > 1) { 110 if (argc > 1) {
108 print_usage(); 111 print_usage(argc, argv, 1);
109 return -1; 112 return 2;
110 } 113 }
111 114
112 idevice_t device = NULL; 115 idevice_t device = NULL;
diff --git a/tools/idevicenotificationproxy.c b/tools/idevicenotificationproxy.c
index 00bcba8..d1e25c1 100644
--- a/tools/idevicenotificationproxy.c
+++ b/tools/idevicenotificationproxy.c
@@ -27,9 +27,10 @@
27 27
28#include <stdio.h> 28#include <stdio.h>
29#include <string.h> 29#include <string.h>
30#include <stdlib.h>
31#include <getopt.h>
30#include <errno.h> 32#include <errno.h>
31#include <signal.h> 33#include <signal.h>
32#include <stdlib.h>
33 34
34#ifdef WIN32 35#ifdef WIN32
35#include <windows.h> 36#include <windows.h>
@@ -59,28 +60,29 @@ static void clean_exit(int sig)
59 quit_flag++; 60 quit_flag++;
60} 61}
61 62
62static void print_usage(int argc, char **argv) 63static void print_usage(int argc, char **argv, int is_error)
63{ 64{
64 char *name = NULL; 65 char *name = strrchr(argv[0], '/');
65 66 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0]));
66 name = strrchr(argv[0], '/'); 67 fprintf(is_error ? stderr : stdout,
67 printf("Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0])); 68 "\n"
68 printf("\n"); 69 "Post or observe notifications on a device.\n"
69 printf("Post or observe notifications on a device.\n"); 70 "\n"
70 printf("\n"); 71 "Where COMMAND is one of:\n"
71 printf("Where COMMAND is one of:\n"); 72 " post ID [...] post notification IDs to device and exit\n"
72 printf(" post ID [...]\t\tpost notification IDs to device and exit\n"); 73 " observe ID [...] observe notification IDs in foreground until CTRL+C\n"
73 printf(" observe ID [...]\tobserve notification IDs in the foreground until CTRL+C or signal is received\n"); 74 " or signal is received\n"
74 printf("\n"); 75 "\n"
75 printf("The following OPTIONS are accepted:\n"); 76 "The following OPTIONS are accepted:\n"
76 printf(" -u, --udid UDID\ttarget specific device by UDID\n"); 77 " -u, --udid UDID target specific device by UDID\n"
77 printf(" -n, --network\t\tconnect to network device\n"); 78 " -n, --network connect to network device\n"
78 printf(" -d, --debug\t\tenable communication debugging\n"); 79 " -d, --debug enable communication debugging\n"
79 printf(" -h, --help\t\tprints usage information\n"); 80 " -h, --help prints usage information\n"
80 printf(" -v, --version\t\tprints version information\n"); 81 " -v, --version prints version information\n"
81 printf("\n"); 82 "\n"
82 printf("Homepage: <" PACKAGE_URL ">\n"); 83 "Homepage: <" PACKAGE_URL ">\n"
83 printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); 84 "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
85 );
84} 86}
85 87
86static void notify_cb(const char *notification, void *user_data) 88static void notify_cb(const char *notification, void *user_data)
@@ -97,7 +99,7 @@ int main(int argc, char *argv[])
97 np_client_t gnp = NULL; 99 np_client_t gnp = NULL;
98 100
99 int result = -1; 101 int result = -1;
100 int i; 102 int i = 0;
101 const char* udid = NULL; 103 const char* udid = NULL;
102 int use_network = 0; 104 int use_network = 0;
103 int cmd = CMD_NONE; 105 int cmd = CMD_NONE;
@@ -107,6 +109,16 @@ int main(int argc, char *argv[])
107 char **nspec = NULL; 109 char **nspec = NULL;
108 char **nspectmp = NULL; 110 char **nspectmp = NULL;
109 111
112 int c = 0;
113 const struct option longopts[] = {
114 { "debug", no_argument, NULL, 'd' },
115 { "help", no_argument, NULL, 'h' },
116 { "udid", required_argument, NULL, 'u' },
117 { "network", no_argument, NULL, 'n' },
118 { "version", no_argument, NULL, 'v' },
119 { NULL, 0, NULL, 0}
120 };
121
110 signal(SIGINT, clean_exit); 122 signal(SIGINT, clean_exit);
111 signal(SIGTERM, clean_exit); 123 signal(SIGTERM, clean_exit);
112#ifndef WIN32 124#ifndef WIN32
@@ -115,80 +127,82 @@ int main(int argc, char *argv[])
115#endif 127#endif
116 128
117 /* parse cmdline args */ 129 /* parse cmdline args */
118 for (i = 1; i < argc; i++) { 130 while ((c = getopt_long(argc, argv, "dhu:nv", longopts, NULL)) != -1) {
119 if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { 131 switch (c) {
132 case 'd':
120 idevice_set_debug_level(1); 133 idevice_set_debug_level(1);
121 continue; 134 break;
122 } 135 case 'u':
123 else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { 136 if (!*optarg) {
124 i++; 137 fprintf(stderr, "ERROR: UDID argument must not be empty!\n");
125 if (!argv[i] || !*argv[i]) { 138 print_usage(argc, argv, 1);
126 print_usage(argc, argv); 139 return 2;
127 result = 0;
128 goto cleanup;
129 } 140 }
130 udid = argv[i]; 141 udid = optarg;
131 continue; 142 break;
132 } 143 case 'n':
133 else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
134 print_usage(argc, argv);
135 result = 0;
136 goto cleanup;
137 }
138 else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) {
139 use_network = 1; 144 use_network = 1;
140 continue; 145 break;
141 } 146 case 'h':
142 else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { 147 print_usage(argc, argv, 0);
148 return 0;
149 case 'v':
143 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); 150 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
144 result = 0; 151 return 0;
145 goto cleanup; 152 default:
153 print_usage(argc, argv, 1);
154 return 2;
146 } 155 }
147 else if (!strcmp(argv[i], "post") || !strcmp(argv[i], "observe")) { 156 }
148 cmd = CMD_POST; 157 argc -= optind;
149 if (!strcmp(argv[i], "observe")) { 158 argv += optind;
150 cmd = CMD_OBSERVE;
151 }
152
153 i++;
154 159
155 if (!argv[i] || argv[i] == NULL || (!strncmp(argv[i], "-", 1))) { 160 if (!argv[i]) {
156 printf("Please supply a valid notification identifier.\n"); 161 fprintf(stderr, "ERROR: Missing command\n");
157 print_usage(argc, argv); 162 print_usage(argc+optind, argv-optind, 1);
158 goto cleanup; 163 return 2;
159 } 164 }
160 165
161 count = 0; 166 if (!strcmp(argv[i], "post")) {
162 nspec = malloc(sizeof(char*) * (count+1)); 167 cmd = CMD_POST;
163 168 } else if (!strcmp(argv[i], "observe")) {
164 while(1) { 169 cmd = CMD_OBSERVE;
165 if (argv[i] && (strlen(argv[i]) >= 2) && (strncmp(argv[i], "-", 1) != 0)) { 170 }
166 nspectmp = realloc(nspec, sizeof(char*) * (count+1));
167 nspectmp[count] = strdup(argv[i]);
168 nspec = nspectmp;
169 count = count+1;
170 i++;
171 } else {
172 i--;
173 break;
174 }
175 }
176 171
177 nspectmp = realloc(nspec, sizeof(char*) * (count+1)); 172 if (cmd == CMD_POST || cmd == CMD_OBSERVE) {
178 nspectmp[count] = NULL; 173 i++;
179 nspec = nspectmp; 174 if (!argv[i]) {
180 continue; 175 fprintf(stderr, "ERROR: Please supply a valid notification identifier.\n");
176 print_usage(argc+optind, argv-optind, 1);
177 return 2;
181 } 178 }
182 else { 179
183 print_usage(argc, argv); 180 count = 0;
184 return 0; 181 nspec = malloc(sizeof(char*) * (count+1));
182
183 while(1) {
184 if (argv[i] && (strlen(argv[i]) >= 2) && (strncmp(argv[i], "-", 1) != 0)) {
185 nspectmp = realloc(nspec, sizeof(char*) * (count+1));
186 nspectmp[count] = strdup(argv[i]);
187 nspec = nspectmp;
188 count = count+1;
189 i++;
190 } else {
191 i--;
192 break;
193 }
185 } 194 }
195
196 nspectmp = realloc(nspec, sizeof(char*) * (count+1));
197 nspectmp[count] = NULL;
198 nspec = nspectmp;
186 } 199 }
187 200
188 /* verify options */ 201 /* verify options */
189 if (cmd == CMD_NONE) { 202 if (cmd == CMD_NONE) {
190 print_usage(argc, argv); 203 fprintf(stderr, "ERROR: Unsupported command '%s'\n", argv[0]);
191 goto cleanup; 204 print_usage(argc+optind, argv-optind, 1);
205 return 2;
192 } 206 }
193 207
194 if (IDEVICE_E_SUCCESS != idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX)) { 208 if (IDEVICE_E_SUCCESS != idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX)) {
diff --git a/tools/idevicepair.c b/tools/idevicepair.c
index f42f498..dda02ec 100644
--- a/tools/idevicepair.c
+++ b/tools/idevicepair.c
@@ -144,42 +144,50 @@ static void print_error_message(lockdownd_error_t err)
144 } 144 }
145} 145}
146 146
147static void print_usage(int argc, char **argv) 147static void print_usage(int argc, char **argv, int is_error)
148{ 148{
149 char *name = NULL; 149 char *name = strrchr(argv[0], '/');
150 150 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0]));
151 name = strrchr(argv[0], '/'); 151 fprintf(is_error ? stderr : stdout,
152 printf("Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0])); 152 "\n"
153 printf("\n"); 153 "Manage host pairings with devices and usbmuxd.\n"
154 printf("Manage host pairings with devices and usbmuxd.\n"); 154 "\n"
155 printf("\n"); 155 "Where COMMAND is one of:\n"
156 printf("Where COMMAND is one of:\n"); 156 " systembuid print the system buid of the usbmuxd host\n"
157 printf(" systembuid print the system buid of the usbmuxd host\n"); 157 " hostid print the host id for target device\n"
158 printf(" hostid print the host id for target device\n"); 158 " pair pair device with this host\n"
159 printf(" pair pair device with this host\n"); 159 " validate validate if device is paired with this host\n"
160 printf(" validate validate if device is paired with this host\n"); 160 " unpair unpair device with this host\n"
161 printf(" unpair unpair device with this host\n"); 161 " list list devices paired with this host\n"
162 printf(" list list devices paired with this host\n"); 162 "\n"
163 printf("\n"); 163 "The following OPTIONS are accepted:\n"
164 printf("The following OPTIONS are accepted:\n"); 164 " -u, --udid UDID target specific device by UDID\n"
165 printf(" -u, --udid UDID target specific device by UDID\n"); 165 );
166#ifdef HAVE_WIRELESS_PAIRING 166#ifdef HAVE_WIRELESS_PAIRING
167 printf(" -w, --wireless perform wireless pairing (see NOTE)\n"); 167 fprintf(is_error ? stderr : stdout,
168 printf(" -n, --network connect to network device (see NOTE)\n"); 168 " -w, --wireless perform wireless pairing (see NOTE)\n"
169 " -n, --network connect to network device (see NOTE)\n"
170 );
169#endif 171#endif
170 printf(" -d, --debug enable communication debugging\n"); 172 fprintf(is_error ? stderr : stdout,
171 printf(" -h, --help prints usage information\n"); 173 " -d, --debug enable communication debugging\n"
172 printf(" -v, --version prints version information\n"); 174 " -h, --help prints usage information\n"
175 " -v, --version prints version information\n"
176 );
173#ifdef HAVE_WIRELESS_PAIRING 177#ifdef HAVE_WIRELESS_PAIRING
174 printf("\n"); 178 fprintf(is_error ? stderr : stdout,
175 printf("NOTE: Pairing over network (wireless pairing) is only supported by Apple TV\n"); 179 "\n"
176 printf("devices. To perform a wireless pairing, you need to use the -w command line\n"); 180 "NOTE: Pairing over network (wireless pairing) is only supported by Apple TV\n"
177 printf("switch. Make sure to put the device into pairing mode first by opening\n"); 181 "devices. To perform a wireless pairing, you need to use the -w command line\n"
178 printf("Settings > Remotes and Devices > Remote App and Devices.\n"); 182 "switch. Make sure to put the device into pairing mode first by opening\n"
183 "Settings > Remotes and Devices > Remote App and Devices.\n"
184 );
179#endif 185#endif
180 printf("\n"); 186 fprintf(is_error ? stderr : stdout,
181 printf("Homepage: <" PACKAGE_URL ">\n"); 187 "\n"
182 printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); 188 "Homepage: <" PACKAGE_URL ">\n"
189 "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
190 );
183} 191}
184 192
185int main(int argc, char **argv) 193int main(int argc, char **argv)
@@ -223,12 +231,12 @@ int main(int argc, char **argv)
223 while ((c = getopt_long(argc, argv, SHORT_OPTIONS, longopts, NULL)) != -1) { 231 while ((c = getopt_long(argc, argv, SHORT_OPTIONS, longopts, NULL)) != -1) {
224 switch (c) { 232 switch (c) {
225 case 'h': 233 case 'h':
226 print_usage(argc, argv); 234 print_usage(argc, argv, 0);
227 exit(EXIT_SUCCESS); 235 exit(EXIT_SUCCESS);
228 case 'u': 236 case 'u':
229 if (!*optarg) { 237 if (!*optarg) {
230 fprintf(stderr, "ERROR: UDID must not be empty!\n"); 238 fprintf(stderr, "ERROR: UDID must not be empty!\n");
231 print_usage(argc, argv); 239 print_usage(argc, argv, 1);
232 result = EXIT_FAILURE; 240 result = EXIT_FAILURE;
233 goto leave; 241 goto leave;
234 } 242 }
@@ -280,7 +288,7 @@ int main(int argc, char **argv)
280 result = EXIT_SUCCESS; 288 result = EXIT_SUCCESS;
281 goto leave; 289 goto leave;
282 default: 290 default:
283 print_usage(argc, argv); 291 print_usage(argc, argv, 1);
284 result = EXIT_FAILURE; 292 result = EXIT_FAILURE;
285 goto leave; 293 goto leave;
286 } 294 }
@@ -291,15 +299,15 @@ int main(int argc, char **argv)
291#endif 299#endif
292 300
293 if ((argc - optind) < 1) { 301 if ((argc - optind) < 1) {
294 printf("ERROR: You need to specify a COMMAND!\n"); 302 fprintf(stderr, "ERROR: You need to specify a COMMAND!\n");
295 print_usage(argc, argv); 303 print_usage(argc, argv, 1);
296 result = EXIT_FAILURE; 304 result = EXIT_FAILURE;
297 goto leave; 305 goto leave;
298 } 306 }
299 307
300 if (wireless_pairing && use_network) { 308 if (wireless_pairing && use_network) {
301 printf("ERROR: You cannot use -w and -n together.\n"); 309 fprintf(stderr, "ERROR: You cannot use -w and -n together.\n");
302 print_usage(argc, argv); 310 print_usage(argc, argv, 1);
303 result = EXIT_FAILURE; 311 result = EXIT_FAILURE;
304 goto leave; 312 goto leave;
305 } 313 }
@@ -319,16 +327,16 @@ int main(int argc, char **argv)
319 } else if (!strcmp(cmd, "systembuid")) { 327 } else if (!strcmp(cmd, "systembuid")) {
320 op = OP_SYSTEMBUID; 328 op = OP_SYSTEMBUID;
321 } else { 329 } else {
322 printf("ERROR: Invalid command '%s' specified\n", cmd); 330 fprintf(stderr, "ERROR: Invalid command '%s' specified\n", cmd);
323 print_usage(argc, argv); 331 print_usage(argc, argv, 1);
324 result = EXIT_FAILURE; 332 result = EXIT_FAILURE;
325 goto leave; 333 goto leave;
326 } 334 }
327 335
328 if (wireless_pairing) { 336 if (wireless_pairing) {
329 if (op == OP_VALIDATE || op == OP_UNPAIR) { 337 if (op == OP_VALIDATE || op == OP_UNPAIR) {
330 printf("ERROR: Command '%s' is not supported with -w\n", cmd); 338 fprintf(stderr, "ERROR: Command '%s' is not supported with -w\n", cmd);
331 print_usage(argc, argv); 339 print_usage(argc, argv, 1);
332 result = EXIT_FAILURE; 340 result = EXIT_FAILURE;
333 goto leave; 341 goto leave;
334 } 342 }
diff --git a/tools/ideviceprovision.c b/tools/ideviceprovision.c
index 754b84d..981a7ee 100644
--- a/tools/ideviceprovision.c
+++ b/tools/ideviceprovision.c
@@ -29,6 +29,7 @@
29#include <stdio.h> 29#include <stdio.h>
30#include <stdlib.h> 30#include <stdlib.h>
31#include <string.h> 31#include <string.h>
32#include <getopt.h>
32#include <sys/stat.h> 33#include <sys/stat.h>
33#include <errno.h> 34#include <errno.h>
34#ifndef WIN32 35#ifndef WIN32
@@ -46,40 +47,40 @@
46#include <libimobiledevice/misagent.h> 47#include <libimobiledevice/misagent.h>
47#include <libimobiledevice-glue/utils.h> 48#include <libimobiledevice-glue/utils.h>
48 49
49static void print_usage(int argc, char **argv) 50static void print_usage(int argc, char **argv, int is_error)
50{ 51{
51 char *name = NULL; 52 char *name = strrchr(argv[0], '/');
52 53 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0]));
53 name = strrchr(argv[0], '/'); 54 fprintf(is_error ? stderr : stdout,
54 printf("Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0])); 55 "\n"
55 printf("\n"); 56 "Manage provisioning profiles on a device.\n"
56 printf("Manage provisioning profiles on a device.\n"); 57 "\n"
57 printf("\n"); 58 "Where COMMAND is one of:\n"
58 printf("Where COMMAND is one of:\n"); 59 " install FILE Installs the provisioning profile specified by FILE.\n"
59 printf(" install FILE\tInstalls the provisioning profile specified by FILE.\n"); 60 " A valid .mobileprovision file is expected.\n"
60 printf(" \tA valid .mobileprovision file is expected.\n"); 61 " list Get a list of all provisioning profiles on the device.\n"
61 printf(" list\t\tGet a list of all provisioning profiles on the device.\n"); 62 " copy PATH Retrieves all provisioning profiles from the device and\n"
62 printf(" copy PATH\tRetrieves all provisioning profiles from the device and\n"); 63 " stores them into the existing directory specified by PATH.\n"
63 printf(" \tstores them into the existing directory specified by PATH.\n"); 64 " The files will be stored as UUID.mobileprovision\n"
64 printf(" \tThe files will be stored as UUID.mobileprovision\n"); 65 " copy UUID PATH Retrieves the provisioning profile identified by UUID\n"
65 printf(" copy UUID PATH Retrieves the provisioning profile identified by UUID\n"); 66 " from the device and stores it into the existing directory\n"
66 printf(" \tfrom the device and stores it into the existing directory\n"); 67 " specified by PATH. The file will be stored as UUID.mobileprovision.\n"
67 printf(" \tspecified by PATH. The file will be stored as UUID.mobileprovision.\n"); 68 " remove UUID Removes the provisioning profile identified by UUID.\n"
68 printf(" remove UUID\tRemoves the provisioning profile identified by UUID.\n"); 69 " remove-all Removes all installed provisioning profiles.\n"
69 printf(" remove-all\tRemoves all installed provisioning profiles.\n"); 70 " dump FILE Prints detailed information about the provisioning profile\n"
70 printf(" dump FILE\tPrints detailed information about the provisioning profile\n"); 71 " specified by FILE.\n"
71 printf(" \tspecified by FILE.\n"); 72 "\n"
72 printf("\n"); 73 "The following OPTIONS are accepted:\n"
73 printf("The following OPTIONS are accepted:\n"); 74 " -u, --udid UDID target specific device by UDID\n"
74 printf(" -u, --udid UDID target specific device by UDID\n"); 75 " -n, --network connect to network device\n"
75 printf(" -n, --network connect to network device\n"); 76 " -x, --xml print XML output when using the 'dump' command\n"
76 printf(" -x, --xml print XML output when using the 'dump' command\n"); 77 " -d, --debug enable communication debugging\n"
77 printf(" -d, --debug enable communication debugging\n"); 78 " -h, --help prints usage information\n"
78 printf(" -h, --help prints usage information\n"); 79 " -v, --version prints version information\n"
79 printf(" -v, --version prints version information\n"); 80 "\n"
80 printf("\n"); 81 "Homepage: <" PACKAGE_URL ">\n"
81 printf("Homepage: <" PACKAGE_URL ">\n"); 82 "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
82 printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); 83 );
83} 84}
84 85
85enum { 86enum {
@@ -302,102 +303,115 @@ int main(int argc, char *argv[])
302 const char* param = NULL; 303 const char* param = NULL;
303 const char* param2 = NULL; 304 const char* param2 = NULL;
304 int use_network = 0; 305 int use_network = 0;
306 int c = 0;
307 const struct option longopts[] = {
308 { "debug", no_argument, NULL, 'd' },
309 { "help", no_argument, NULL, 'h' },
310 { "udid", required_argument, NULL, 'u' },
311 { "network", no_argument, NULL, 'n' },
312 { "version", no_argument, NULL, 'v' },
313 { "xml", no_argument, NULL, 'x' },
314 { NULL, 0, NULL, 0}
315 };
305 316
306#ifndef WIN32 317#ifndef WIN32
307 signal(SIGPIPE, SIG_IGN); 318 signal(SIGPIPE, SIG_IGN);
308#endif 319#endif
309 /* parse cmdline args */ 320 /* parse cmdline args */
310 for (i = 1; i < argc; i++) { 321 while ((c = getopt_long(argc, argv, "dhu:nvx", longopts, NULL)) != -1) {
311 if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { 322 switch (c) {
323 case 'd':
312 idevice_set_debug_level(1); 324 idevice_set_debug_level(1);
313 continue; 325 break;
314 } 326 case 'u':
315 else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { 327 if (!*optarg) {
316 i++; 328 fprintf(stderr, "ERROR: UDID argument must not be empty!\n");
317 if (!argv[i] || !*argv[i]) { 329 print_usage(argc, argv, 1);
318 print_usage(argc, argv); 330 return 2;
319 return 0;
320 } 331 }
321 udid = argv[i]; 332 udid = optarg;
322 continue; 333 break;
323 } 334 case 'n':
324 else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) {
325 use_network = 1; 335 use_network = 1;
326 continue; 336 break;
327 } 337 case 'h':
328 else if (!strcmp(argv[i], "install")) { 338 print_usage(argc, argv, 0);
329 i++; 339 return 0;
330 if (!argv[i] || (strlen(argv[i]) < 1)) { 340 case 'v':
331 print_usage(argc, argv); 341 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
332 return 0; 342 return 0;
333 } 343 case 'x':
334 param = argv[i]; 344 output_xml = 1;
335 op = OP_INSTALL; 345 break;
336 continue; 346 default:
337 } 347 print_usage(argc, argv, 1);
338 else if (!strcmp(argv[i], "list")) { 348 return 2;
339 op = OP_LIST;
340 }
341 else if (!strcmp(argv[i], "copy")) {
342 i++;
343 if (!argv[i] || (strlen(argv[i]) < 1)) {
344 print_usage(argc, argv);
345 return 0;
346 }
347 param = argv[i];
348 op = OP_COPY;
349 i++;
350 if (argv[i] && (strlen(argv[i]) > 0)) {
351 param2 = argv[i];
352 }
353 continue;
354 }
355 else if (!strcmp(argv[i], "remove")) {
356 i++;
357 if (!argv[i] || (strlen(argv[i]) < 1)) {
358 print_usage(argc, argv);
359 return 0;
360 }
361 param = argv[i];
362 op = OP_REMOVE;
363 continue;
364 }
365 else if (!strcmp(argv[i], "remove-all")) {
366 i++;
367 op = OP_REMOVE;
368 continue;
369 } 349 }
370 else if (!strcmp(argv[i], "dump")) { 350 }
371 i++; 351 argc -= optind;
372 if (!argv[i] || (strlen(argv[i]) < 1)) { 352 argv += optind;
373 print_usage(argc, argv); 353
374 return 0; 354 if (!argv[0]) {
375 } 355 fprintf(stderr, "ERROR: Missing command.\n");
376 param = argv[i]; 356 print_usage(argc+optind, argv-optind, 1);
377 op = OP_DUMP; 357 return 2;
378 continue; 358 }
359
360 i = 0;
361 if (!strcmp(argv[i], "install")) {
362 op = OP_INSTALL;
363 i++;
364 if (!argv[i] || !*argv[i]) {
365 fprintf(stderr, "Missing argument for 'install' command.\n");
366 print_usage(argc+optind, argv-optind, 1);
367 return 2;
379 } 368 }
380 else if (!strcmp(argv[i], "-x") || !strcmp(argv[i], "--xml")) { 369 param = argv[i];
381 output_xml = 1; 370 }
382 continue; 371 else if (!strcmp(argv[i], "list")) {
372 op = OP_LIST;
373 }
374 else if (!strcmp(argv[i], "copy")) {
375 op = OP_COPY;
376 i++;
377 if (!argv[i] || !*argv[i]) {
378 fprintf(stderr, "Missing argument for 'copy' command.\n");
379 print_usage(argc+optind, argv-optind, 1);
380 return 2;
383 } 381 }
384 else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { 382 param = argv[i];
385 print_usage(argc, argv); 383 i++;
386 return 0; 384 if (argv[i] && (strlen(argv[i]) > 0)) {
385 param2 = argv[i];
387 } 386 }
388 else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { 387 }
389 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); 388 else if (!strcmp(argv[i], "remove")) {
390 return 0; 389 op = OP_REMOVE;
390 i++;
391 if (!argv[i] || !*argv[i]) {
392 fprintf(stderr, "Missing argument for 'remove' command.\n");
393 print_usage(argc+optind, argv-optind, 1);
394 return 2;
391 } 395 }
392 else { 396 param = argv[i];
393 print_usage(argc, argv); 397 }
394 return 0; 398 else if (!strcmp(argv[i], "remove-all")) {
399 op = OP_REMOVE;
400 }
401 else if (!strcmp(argv[i], "dump")) {
402 op = OP_DUMP;
403 i++;
404 if (!argv[i] || !*argv[i]) {
405 fprintf(stderr, "Missing argument for 'remove' command.\n");
406 print_usage(argc+optind, argv-optind, 1);
407 return 2;
395 } 408 }
409 param = argv[i];
396 } 410 }
397
398 if ((op == -1) || (op >= NUM_OPS)) { 411 if ((op == -1) || (op >= NUM_OPS)) {
399 print_usage(argc, argv); 412 fprintf(stderr, "ERROR: Unsupported command '%s'\n", argv[i]);
400 return 0; 413 print_usage(argc+optind, argv-optind, 1);
414 return 2;
401 } 415 }
402 416
403 if (op == OP_DUMP) { 417 if (op == OP_DUMP) {
diff --git a/tools/idevicescreenshot.c b/tools/idevicescreenshot.c
index 9b1ffa3..0e694c7 100644
--- a/tools/idevicescreenshot.c
+++ b/tools/idevicescreenshot.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#include <unistd.h> 34#include <unistd.h>
@@ -39,8 +40,86 @@
39#include <libimobiledevice/lockdown.h> 40#include <libimobiledevice/lockdown.h>
40#include <libimobiledevice/screenshotr.h> 41#include <libimobiledevice/screenshotr.h>
41 42
42void get_image_filename(char *imgdata, char **filename); 43static void get_image_filename(char *imgdata, char **filename)
43void print_usage(int argc, char **argv); 44{
45 // If the provided filename already has an extension, use it as is.
46 if (*filename) {
47 char *last_dot = strrchr(*filename, '.');
48 if (last_dot && !strchr(last_dot, '/')) {
49 return;
50 }
51 }
52
53 // Find the appropriate file extension for the filename.
54 const char *fileext = NULL;
55 if (memcmp(imgdata, "\x89PNG", 4) == 0) {
56 fileext = ".png";
57 } else if (memcmp(imgdata, "MM\x00*", 4) == 0) {
58 fileext = ".tiff";
59 } else {
60 printf("WARNING: screenshot data has unexpected image format.\n");
61 fileext = ".dat";
62 }
63
64 // If a filename without an extension is provided, append the extension.
65 // Otherwise, generate a filename based on the current time.
66 char *basename = NULL;
67 if (*filename) {
68 basename = (char*)malloc(strlen(*filename) + 1);
69 strcpy(basename, *filename);
70 free(*filename);
71 *filename = NULL;
72 } else {
73 time_t now = time(NULL);
74 basename = (char*)malloc(32);
75 strftime(basename, 31, "screenshot-%Y-%m-%d-%H-%M-%S", gmtime(&now));
76 }
77
78 // Ensure the filename is unique on disk.
79 char *unique_filename = (char*)malloc(strlen(basename) + strlen(fileext) + 7);
80 sprintf(unique_filename, "%s%s", basename, fileext);
81 int i;
82 for (i = 2; i < (1 << 16); i++) {
83 if (access(unique_filename, F_OK) == -1) {
84 *filename = unique_filename;
85 break;
86 }
87 sprintf(unique_filename, "%s-%d%s", basename, i, fileext);
88 }
89 if (!*filename) {
90 free(unique_filename);
91 }
92 free(basename);
93}
94
95static void print_usage(int argc, char **argv, int is_error)
96{
97 char *name = strrchr(argv[0], '/');
98 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] [FILE]\n", (name ? name + 1: argv[0]));
99 fprintf(is_error ? stderr : stdout,
100 "\n"
101 "Gets a screenshot from a connected device.\n"
102 "\n"
103 "The image is in PNG format for iOS 9+ and otherwise in TIFF format.\n"
104 "The screenshot is saved as an image with the given FILE name.\n"
105 "If FILE has no extension, FILE will be a prefix of the saved filename.\n"
106 "If FILE is not specified, \"screenshot-DATE\", will be used as a prefix\n"
107 "of the filename, e.g.:\n"
108 " ./screenshot-2013-12-31-23-59-59.tiff\n"
109 "\n"
110 "NOTE: A mounted developer disk image is required on the device, otherwise\n"
111 "the screenshotr service is not available.\n"
112 "\n"
113 " -u, --udid UDID target specific device by UDID\n"
114 " -n, --network connect to network device\n"
115 " -d, --debug enable communication debugging\n"
116 " -h, --help prints usage information\n"
117 " -v, --version prints version information\n"
118 "\n"
119 "Homepage: <" PACKAGE_URL ">\n"
120 "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
121 );
122}
44 123
45int main(int argc, char **argv) 124int main(int argc, char **argv)
46{ 125{
@@ -50,50 +129,58 @@ int main(int argc, char **argv)
50 screenshotr_client_t shotr = NULL; 129 screenshotr_client_t shotr = NULL;
51 lockdownd_service_descriptor_t service = NULL; 130 lockdownd_service_descriptor_t service = NULL;
52 int result = -1; 131 int result = -1;
53 int i;
54 const char *udid = NULL; 132 const char *udid = NULL;
55 int use_network = 0; 133 int use_network = 0;
56 char *filename = NULL; 134 char *filename = NULL;
135 int c = 0;
136 const struct option longopts[] = {
137 { "debug", no_argument, NULL, 'd' },
138 { "help", no_argument, NULL, 'h' },
139 { "udid", required_argument, NULL, 'u' },
140 { "network", no_argument, NULL, 'n' },
141 { "version", no_argument, NULL, 'v' },
142 { NULL, 0, NULL, 0}
143 };
57 144
58#ifndef WIN32 145#ifndef WIN32
59 signal(SIGPIPE, SIG_IGN); 146 signal(SIGPIPE, SIG_IGN);
60#endif 147#endif
61 /* parse cmdline args */ 148 /* parse cmdline args */
62 for (i = 1; i < argc; i++) { 149
63 if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { 150 /* parse cmdline arguments */
151 while ((c = getopt_long(argc, argv, "dhu:nv", longopts, NULL)) != -1) {
152 switch (c) {
153 case 'd':
64 idevice_set_debug_level(1); 154 idevice_set_debug_level(1);
65 continue; 155 break;
66 } 156 case 'u':
67 else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { 157 if (!*optarg) {
68 i++; 158 fprintf(stderr, "ERROR: UDID argument must not be empty!\n");
69 if (!argv[i] || !*argv[i]) { 159 print_usage(argc, argv, 1);
70 print_usage(argc, argv); 160 return 2;
71 return 0;
72 } 161 }
73 udid = argv[i]; 162 udid = optarg;
74 continue; 163 break;
75 } 164 case 'n':
76 else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) {
77 use_network = 1; 165 use_network = 1;
78 continue; 166 break;
79 } 167 case 'h':
80 else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { 168 print_usage(argc, argv, 0);
81 print_usage(argc, argv);
82 return 0; 169 return 0;
83 } 170 case 'v':
84 else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
85 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); 171 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
86 return 0; 172 return 0;
87 } 173 default:
88 else if (argv[i][0] != '-' && !filename) { 174 print_usage(argc, argv, 1);
89 filename = strdup(argv[i]); 175 return 2;
90 continue;
91 }
92 else {
93 print_usage(argc, argv);
94 return 0;
95 } 176 }
96 } 177 }
178 argc -= optind;
179 argv += optind;
180
181 if (argv[0]) {
182 filename = strdup(argv[0]);
183 }
97 184
98 if (IDEVICE_E_SUCCESS != idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX)) { 185 if (IDEVICE_E_SUCCESS != idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX)) {
99 if (udid) { 186 if (udid) {
@@ -153,84 +240,3 @@ int main(int argc, char **argv)
153 240
154 return result; 241 return result;
155} 242}
156
157void get_image_filename(char *imgdata, char **filename)
158{
159 // If the provided filename already has an extension, use it as is.
160 if (*filename) {
161 char *last_dot = strrchr(*filename, '.');
162 if (last_dot && !strchr(last_dot, '/')) {
163 return;
164 }
165 }
166
167 // Find the appropriate file extension for the filename.
168 const char *fileext = NULL;
169 if (memcmp(imgdata, "\x89PNG", 4) == 0) {
170 fileext = ".png";
171 } else if (memcmp(imgdata, "MM\x00*", 4) == 0) {
172 fileext = ".tiff";
173 } else {
174 printf("WARNING: screenshot data has unexpected image format.\n");
175 fileext = ".dat";
176 }
177
178 // If a filename without an extension is provided, append the extension.
179 // Otherwise, generate a filename based on the current time.
180 char *basename = NULL;
181 if (*filename) {
182 basename = (char*)malloc(strlen(*filename) + 1);
183 strcpy(basename, *filename);
184 free(*filename);
185 *filename = NULL;
186 } else {
187 time_t now = time(NULL);
188 basename = (char*)malloc(32);
189 strftime(basename, 31, "screenshot-%Y-%m-%d-%H-%M-%S", gmtime(&now));
190 }
191
192 // Ensure the filename is unique on disk.
193 char *unique_filename = (char*)malloc(strlen(basename) + strlen(fileext) + 7);
194 sprintf(unique_filename, "%s%s", basename, fileext);
195 int i;
196 for (i = 2; i < (1 << 16); i++) {
197 if (access(unique_filename, F_OK) == -1) {
198 *filename = unique_filename;
199 break;
200 }
201 sprintf(unique_filename, "%s-%d%s", basename, i, fileext);
202 }
203 if (!*filename) {
204 free(unique_filename);
205 }
206 free(basename);
207}
208
209void print_usage(int argc, char **argv)
210{
211 char *name = NULL;
212
213 name = strrchr(argv[0], '/');
214 printf("Usage: %s [OPTIONS] [FILE]\n", (name ? name + 1: argv[0]));
215 printf("\n");
216 printf("Gets a screenshot from a connected device.\n");
217 printf("\n");
218 printf("The image is in PNG format for iOS 9+ and otherwise in TIFF format.\n");
219 printf("The screenshot is saved as an image with the given FILE name.\n");
220 printf("If FILE has no extension, FILE will be a prefix of the saved filename.\n");
221 printf("If FILE is not specified, \"screenshot-DATE\", will be used as a prefix\n");
222 printf("of the filename, e.g.:\n");
223 printf(" ./screenshot-2013-12-31-23-59-59.tiff\n");
224 printf("\n");
225 printf("NOTE: A mounted developer disk image is required on the device, otherwise\n");
226 printf("the screenshotr service is not available.\n");
227 printf("\n");
228 printf(" -u, --udid UDID\ttarget specific device by UDID\n");
229 printf(" -n, --network\t\tconnect to network device\n");
230 printf(" -d, --debug\t\tenable communication debugging\n");
231 printf(" -h, --help\t\tprints usage information\n");
232 printf(" -v, --version\t\tprints version information\n");
233 printf("\n");
234 printf("Homepage: <" PACKAGE_URL ">\n");
235 printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n");
236}
diff --git a/tools/idevicesetlocation.c b/tools/idevicesetlocation.c
index 6237a1a..69fbaf5 100644
--- a/tools/idevicesetlocation.c
+++ b/tools/idevicesetlocation.c
@@ -51,15 +51,16 @@ static void print_usage(int argc, char **argv, int is_error)
51 51
52 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] -- <LAT> <LONG>\n", bname); 52 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] -- <LAT> <LONG>\n", bname);
53 fprintf(is_error ? stderr : stdout, " %s [OPTIONS] reset\n", bname); 53 fprintf(is_error ? stderr : stdout, " %s [OPTIONS] reset\n", bname);
54 fprintf(is_error ? stderr : stdout, "\n" \ 54 fprintf(is_error ? stderr : stdout,
55 "OPTIONS:\n" \ 55 "\n"
56 " -u, --udid UDID target specific device by UDID\n" \ 56 "OPTIONS:\n"
57 " -n, --network connect to network device\n" \ 57 " -u, --udid UDID target specific device by UDID\n"
58 " -d, --debug enable communication debugging\n" \ 58 " -n, --network connect to network device\n"
59 " -h, --help prints usage information\n" \ 59 " -d, --debug enable communication debugging\n"
60 " -v, --version prints version information\n" \ 60 " -h, --help prints usage information\n"
61 "\n" \ 61 " -v, --version prints version information\n"
62 "Homepage: <" PACKAGE_URL ">\n" \ 62 "\n"
63 "Homepage: <" PACKAGE_URL ">\n"
63 "Bug Reports: <" PACKAGE_BUGREPORT ">\n" 64 "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
64 ); 65 );
65} 66}
diff --git a/tools/idevicesyslog.c b/tools/idevicesyslog.c
index 44dd5ba..2a72d72 100644
--- a/tools/idevicesyslog.c
+++ b/tools/idevicesyslog.c
@@ -466,37 +466,36 @@ static void clean_exit(int sig)
466 466
467static void print_usage(int argc, char **argv, int is_error) 467static void print_usage(int argc, char **argv, int is_error)
468{ 468{
469 char *name = NULL; 469 char *name = strrchr(argv[0], '/');
470 name = strrchr(argv[0], '/');
471 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); 470 fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0]));
472 fprintf(is_error ? stderr : stdout, 471 fprintf(is_error ? stderr : stdout,
473 "\n" \ 472 "\n"
474 "Relay syslog of a connected device.\n" \ 473 "Relay syslog of a connected device.\n"
475 "\n" \ 474 "\n"
476 "OPTIONS:\n" \ 475 "OPTIONS:\n"
477 " -u, --udid UDID target specific device by UDID\n" \ 476 " -u, --udid UDID target specific device by UDID\n"
478 " -n, --network connect to network device\n" \ 477 " -n, --network connect to network device\n"
479 " -x, --exit exit when device disconnects\n" \ 478 " -x, --exit exit when device disconnects\n"
480 " -h, --help prints usage information\n" \ 479 " -h, --help prints usage information\n"
481 " -d, --debug enable communication debugging\n" \ 480 " -d, --debug enable communication debugging\n"
482 " -v, --version prints version information\n" \ 481 " -v, --version prints version information\n"
483 " --no-colors disable colored output\n" \ 482 " --no-colors disable colored output\n"
484 "\n" \ 483 "\n"
485 "FILTER OPTIONS:\n" \ 484 "FILTER OPTIONS:\n"
486 " -m, --match STRING only print messages that contain STRING\n" \ 485 " -m, --match STRING only print messages that contain STRING\n"
487 " -t, --trigger STRING start logging when matching STRING\n" \ 486 " -t, --trigger STRING start logging when matching STRING\n"
488 " -T, --untrigger STRING stop logging when matching STRING\n" \ 487 " -T, --untrigger STRING stop logging when matching STRING\n"
489 " -p, --process PROCESS only print messages from matching process(es)\n" \ 488 " -p, --process PROCESS only print messages from matching process(es)\n"
490 " -e, --exclude PROCESS print all messages except matching process(es)\n" \ 489 " -e, --exclude PROCESS print all messages except matching process(es)\n"
491 " PROCESS is a process name or multiple process names\n" \ 490 " PROCESS is a process name or multiple process names\n"
492 " separated by \"|\".\n" \ 491 " separated by \"|\".\n"
493 " -q, --quiet set a filter to exclude common noisy processes\n" \ 492 " -q, --quiet set a filter to exclude common noisy processes\n"
494 " --quiet-list prints the list of processes for --quiet and exits\n" \ 493 " --quiet-list prints the list of processes for --quiet and exits\n"
495 " -k, --kernel only print kernel messages\n" \ 494 " -k, --kernel only print kernel messages\n"
496 " -K, --no-kernel suppress kernel messages\n" \ 495 " -K, --no-kernel suppress kernel messages\n"
497 "\n" \ 496 "\n"
498 "For filter examples consult idevicesyslog(1) man page.\n" \ 497 "For filter examples consult idevicesyslog(1) man page.\n"
499 "\n" \ 498 "\n"
500 "Homepage: <" PACKAGE_URL ">\n" 499 "Homepage: <" PACKAGE_URL ">\n"
501 "Bug Reports: <" PACKAGE_BUGREPORT ">\n" 500 "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
502 ); 501 );