diff options
author | Nikias Bassen | 2022-04-30 13:31:20 +0200 |
---|---|---|
committer | Nikias Bassen | 2022-04-30 13:31:20 +0200 |
commit | 6cb13f9e6d3939930aecf91d8e23d1896a3b92e5 (patch) | |
tree | 371e4676ac914d9eef6bb4cfc0b5b6dc6f27da4f /tools | |
parent | 3b5cad28fabb236e05b8fff82fab5098127aa2bb (diff) | |
download | libimobiledevice-6cb13f9e6d3939930aecf91d8e23d1896a3b92e5.tar.gz libimobiledevice-6cb13f9e6d3939930aecf91d8e23d1896a3b92e5.tar.bz2 |
tools: Use getopt for option parsing in all tools
Diffstat (limited to 'tools')
-rw-r--r-- | tools/idevice_id.c | 27 | ||||
-rw-r--r-- | tools/idevicebackup.c | 152 | ||||
-rw-r--r-- | tools/idevicebackup2.c | 423 | ||||
-rw-r--r-- | tools/idevicecrashreport.c | 142 | ||||
-rw-r--r-- | tools/idevicedate.c | 133 | ||||
-rw-r--r-- | tools/idevicedebug.c | 39 | ||||
-rw-r--r-- | tools/idevicedebugserverproxy.c | 105 | ||||
-rw-r--r-- | tools/idevicediagnostics.c | 235 | ||||
-rw-r--r-- | tools/ideviceenterrecovery.c | 71 | ||||
-rw-r--r-- | tools/ideviceimagemounter.c | 46 | ||||
-rw-r--r-- | tools/ideviceinfo.c | 29 | ||||
-rw-r--r-- | tools/idevicename.c | 41 | ||||
-rw-r--r-- | tools/idevicenotificationproxy.c | 180 | ||||
-rw-r--r-- | tools/idevicepair.c | 92 | ||||
-rw-r--r-- | tools/ideviceprovision.c | 240 | ||||
-rw-r--r-- | tools/idevicescreenshot.c | 228 | ||||
-rw-r--r-- | tools/idevicesetlocation.c | 19 | ||||
-rw-r--r-- | tools/idevicesyslog.c | 57 |
18 files changed, 1180 insertions, 1079 deletions
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 @@ static void print_usage(int argc, char **argv, int is_error) { - char *name = NULL; - name = strrchr(argv[0], '/'); + char *name = strrchr(argv[0], '/'); fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] [UDID]\n", (name ? name + 1: argv[0])); fprintf(is_error ? stderr : stdout, + "\n" + "List attached devices or print device name of given device.\n" "\n" \ - "List attached devices or print device name of given device.\n" \ + " If UDID is given, the name of the connected device with that UDID" + " will be retrieved.\n" "\n" \ - " If UDID is given, the name of the connected device with that UDID" \ - " will be retrieved.\n" \ - "\n" \ - "OPTIONS:\n" \ - " -l, --list list UDIDs of all devices attached via USB\n" \ - " -n, --network list UDIDs of all devices available via network\n" \ - " -d, --debug enable communication debugging\n" \ - " -h, --help prints usage information\n" \ - " -v, --version prints version information\n" \ - "\n" \ - "Homepage: <" PACKAGE_URL ">\n" \ + "OPTIONS:\n" + " -l, --list list UDIDs of all devices attached via USB\n" + " -n, --network list UDIDs of all devices available via network\n" + " -d, --debug enable communication debugging\n" + " -h, --help prints usage information\n" + " -v, --version prints version information\n" + "\n" + "Homepage: <" PACKAGE_URL ">\n" "Bug Reports: <" PACKAGE_BUGREPORT ">\n" ); } 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 @@ #include <errno.h> #include <stdlib.h> #include <signal.h> +#include <getopt.h> #if defined(HAVE_OPENSSL) #include <openssl/sha.h> #elif defined(HAVE_GNUTLS) @@ -647,27 +648,28 @@ static void clean_exit(int sig) quit_flag++; } -static void print_usage(int argc, char **argv) +static void print_usage(int argc, char **argv, int is_error) { - char *name = NULL; - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS] CMD [DIRECTORY]\n", (name ? name + 1: argv[0])); - printf("\n"); - printf("Create or restore backup from the current or specified directory.\n"); - printf("\n"); - printf("CMD:\n"); - printf(" backup\tSaves a device backup into DIRECTORY\n"); - printf(" restore\tRestores a device backup from DIRECTORY.\n"); - printf("\n"); - printf("OPTIONS:\n"); - printf(" -u, --udid UDID\ttarget specific device by UDID\n"); - printf(" -n, --network\t\tconnect to network device\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf(" -v, --version\t\tprints version information\n"); - printf("\n"); - printf("Homepage: <" PACKAGE_URL ">\n"); - printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); + char *name = strrchr(argv[0], '/'); + fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] CMD DIRECTORY\n", (name ? name + 1: argv[0])); + fprintf(is_error ? stderr : stdout, + "\n" + "Create or restore backup in/from the specified directory.\n" + "\n" + "CMD:\n" + " backup Saves a device backup into DIRECTORY\n" + " restore Restores a device backup from DIRECTORY.\n" + "\n" + "OPTIONS:\n" + " -u, --udid UDID target specific device by UDID\n" + " -n, --network connect to network device\n" + " -d, --debug enable communication debugging\n" + " -h, --help prints usage information\n" + " -v, --version prints version information\n" + "\n" + "Homepage: <" PACKAGE_URL ">\n" + "Bug Reports: <" PACKAGE_BUGREPORT ">\n" + ); } int main(int argc, char *argv[]) @@ -691,7 +693,15 @@ int main(int argc, char *argv[]) uint64_t length = 0; uint64_t backup_total_size = 0; enum device_link_file_status_t file_status = DEVICE_LINK_FILE_STATUS_NONE; - uint64_t c = 0; + int c = 0; + const struct option longopts[] = { + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "udid", required_argument, NULL, 'u' }, + { "network", no_argument, NULL, 'n' }, + { "version", no_argument, NULL, 'v' }, + { NULL, 0, NULL, 0} + }; /* we need to exit cleanly on running backups and restores or we cause havok */ signal(SIGINT, clean_exit); @@ -702,59 +712,58 @@ int main(int argc, char *argv[]) #endif /* parse cmdline args */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + while ((c = getopt_long(argc, argv, "dhu:nv", longopts, NULL)) != -1) { + switch (c) { + case 'd': idevice_set_debug_level(1); - continue; - } - else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { - i++; - if (!argv[i] || !*argv[i]) { - print_usage(argc, argv); - return 0; + break; + case 'u': + if (!*optarg) { + fprintf(stderr, "ERROR: UDID must not be empty!\n"); + print_usage(argc, argv, 1); + return 2; } - udid = strdup(argv[i]); - continue; - } - else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) { + udid = strdup(optarg); + break; + case 'n': use_network = 1; - continue; - } - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); + break; + case 'h': + print_usage(argc, argv, 0); return 0; - } - else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { + case 'v': printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); return 0; - } - else if (!strcmp(argv[i], "backup")) { - cmd = CMD_BACKUP; - } - else if (!strcmp(argv[i], "restore")) { - cmd = CMD_RESTORE; - } - else if (backup_directory == NULL) { - backup_directory = argv[i]; - } - else { - print_usage(argc, argv); - return 0; + default: + print_usage(argc, argv, 1); + return 2; } } + argc -= optind; + argv += optind; - /* verify options */ - if (cmd == -1) { - printf("No command specified.\n"); - print_usage(argc, argv); - return -1; + if (argc < 1) { + fprintf(stderr, "ERROR: Missing command.\n"); + print_usage(argc+optind, argv-optind, 1); + return 2; } - if (backup_directory == NULL) { - printf("No target backup directory specified.\n"); - print_usage(argc, argv); - return -1; + if (!strcmp(argv[0], "backup")) { + cmd = CMD_BACKUP; + } else if (!strcmp(argv[0], "restore")) { + cmd = CMD_RESTORE; + } else { + fprintf(stderr, "ERROR: Invalid command '%s'.\n", argv[0]); + print_usage(argc+optind, argv-optind, 1); + return 2; + } + + if (argc < 2) { + fprintf(stderr, "No target backup directory specified.\n"); + print_usage(argc+optind, argv-optind, 1); + return 2; } + backup_directory = argv[1]; /* verify if passed backup directory exists */ if (stat(backup_directory, &st) != 0) { @@ -784,9 +793,14 @@ int main(int argc, char *argv[]) return -1; } + if (!udid) { + idevice_get_udid(device, &udid); + } + if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new_with_handshake(device, &client, TOOL_NAME))) { printf("ERROR: Could not connect to lockdownd, error code %d\n", ldret); idevice_free(device); + free(udid); return -1; } @@ -806,6 +820,7 @@ int main(int argc, char *argv[]) printf("ERROR: This tool is only compatible with iOS 3 or below. For newer iOS versions please use the idevicebackup2 tool.\n"); lockdownd_client_free(client); idevice_free(device); + free(udid); return -1; } } @@ -851,7 +866,7 @@ int main(int argc, char *argv[]) ldret = lockdownd_start_service(client, MOBILEBACKUP_SERVICE_NAME, &service); if ((ldret == LOCKDOWN_E_SUCCESS) && service && service->port) { printf("Started \"%s\" service on port %d.\n", MOBILEBACKUP_SERVICE_NAME, service->port); - mobilebackup_client_new(device, service, &mobilebackup); + printf("%d\n", mobilebackup_client_new(device, service, &mobilebackup)); if (service) { lockdownd_service_descriptor_free(service); @@ -993,7 +1008,7 @@ int main(int argc, char *argv[]) } else if (err == MOBILEBACKUP_E_REPLY_NOT_OK) { printf("ERROR: Could not start backup process: device refused to start the backup process.\n"); } else { - printf("ERROR: Could not start backup process: unspecified error occurred\n"); + printf("ERROR: Could not start backup process: unspecified error occurred (%d)\n", err); } break; } @@ -1015,6 +1030,7 @@ int main(int argc, char *argv[]) char *format_size = NULL; int is_manifest = 0; uint8_t b = 0; + uint64_t u64val = 0; /* process series of DLSendFile messages */ do { @@ -1046,8 +1062,8 @@ int main(int argc, char *argv[]) /* check DLFileStatusKey (codes: 1 = Hunk, 2 = Last Hunk) */ node = plist_dict_get_item(node_tmp, "DLFileStatusKey"); - plist_get_uint_val(node, &c); - file_status = c; + plist_get_uint_val(node, &u64val); + file_status = u64val; /* get source filename */ node = plist_dict_get_item(node_tmp, "BackupManifestKey"); @@ -1610,9 +1626,7 @@ files_out: idevice_free(device); - if (udid) { - free(udid); - } + free(udid); return 0; } 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 @@ #include <libgen.h> #include <ctype.h> #include <time.h> +#include <getopt.h> #include <libimobiledevice/libimobiledevice.h> #include <libimobiledevice/lockdown.h> @@ -1415,47 +1416,48 @@ static void clean_exit(int sig) quit_flag++; } -static void print_usage(int argc, char **argv) +static void print_usage(int argc, char **argv, int is_error) { - char *name = NULL; - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS] CMD [CMDOPTIONS] DIRECTORY\n", (name ? name + 1: argv[0])); - printf("\n"); - printf("Create or restore backup from the current or specified directory.\n"); - printf("\n"); - printf("CMD:\n"); - printf(" backup\tcreate backup for the device\n"); - printf(" --full\t\tforce full backup from device.\n"); - printf(" restore\trestore last backup to the device\n"); - printf(" --system\t\trestore system files, too.\n"); - printf(" --no-reboot\t\tdo NOT reboot the device when done (default: yes).\n"); - printf(" --copy\t\tcreate a copy of backup folder before restoring.\n"); - printf(" --settings\t\trestore device settings from the backup.\n"); - printf(" --remove\t\tremove items which are not being restored\n"); - printf(" --skip-apps\t\tdo not trigger re-installation of apps after restore\n"); - printf(" --password PWD\tsupply the password for the encrypted source backup\n"); - printf(" info\t\tshow details about last completed backup of device\n"); - printf(" list\t\tlist files of last completed backup in CSV format\n"); - printf(" unback\tunpack a completed backup in DIRECTORY/_unback_/\n"); - printf(" encryption on|off [PWD]\tenable or disable backup encryption\n"); - printf(" changepw [OLD NEW] change backup password on target device\n"); - printf(" cloud on|off\tenable or disable cloud use (requires iCloud account)\n"); - printf("\n"); - printf("NOTE: Passwords will be requested in interactive mode (-i) if omitted, or can\n"); - printf("be passed via environment variable BACKUP_PASSWORD/BACKUP_PASSWORD_NEW.\n"); - printf("See man page for further details.\n"); - printf("\n"); - printf("OPTIONS:\n"); - printf(" -u, --udid UDID\ttarget specific device by UDID\n"); - printf(" -s, --source UDID\tuse backup data from device specified by UDID\n"); - printf(" -n, --network\t\tconnect to network device\n"); - printf(" -i, --interactive\trequest passwords interactively\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf(" -v, --version\t\tprints version information\n"); - printf("\n"); - printf("Homepage: <" PACKAGE_URL ">\n"); - printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); + char *name = strrchr(argv[0], '/'); + fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] CMD [CMDOPTIONS] DIRECTORY\n", (name ? name + 1: argv[0])); + fprintf(is_error ? stderr : stdout, + "\n" + "Create or restore backup in/from the specified directory.\n" + "\n" + "CMD:\n" + " backup create backup for the device\n" + " --full force full backup from device.\n" + " restore restore last backup to the device\n" + " --system restore system files, too.\n" + " --no-reboot do NOT reboot the device when done (default: yes).\n" + " --copy create a copy of backup folder before restoring.\n" + " --settings restore device settings from the backup.\n" + " --remove remove items which are not being restored\n" + " --skip-apps do not trigger re-installation of apps after restore\n" + " --password PWD supply the password for the encrypted source backup\n" + " info show details about last completed backup of device\n" + " list list files of last completed backup in CSV format\n" + " unback unpack a completed backup in DIRECTORY/_unback_/\n" + " encryption on|off [PWD] enable or disable backup encryption\n" + " changepw [OLD NEW] change backup password on target device\n" + " cloud on|off enable or disable cloud use (requires iCloud account)\n" + "\n" + "NOTE: Passwords will be requested in interactive mode (-i) if omitted, or can\n" + "be passed via environment variable BACKUP_PASSWORD/BACKUP_PASSWORD_NEW.\n" + "See man page for further details.\n" + "\n" + "OPTIONS:\n" + " -u, --udid UDID target specific device by UDID\n" + " -s, --source UDID use backup data from device specified by UDID\n" + " -n, --network connect to network device\n" + " -i, --interactive request passwords interactively\n" + " -d, --debug enable communication debugging\n" + " -h, --help prints usage information\n" + " -v, --version prints version information\n" + "\n" + "Homepage: <" PACKAGE_URL ">\n" + "Bug Reports: <" PACKAGE_BUGREPORT ">\n" + ); } #define DEVICE_VERSION(maj, min, patch) ((((maj) & 0xFF) << 16) | (((min) & 0xFF) << 8) | ((patch) & 0xFF)) @@ -1464,7 +1466,7 @@ int main(int argc, char *argv[]) { idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR; - int i; + int i = 0; char* udid = NULL; char* source_udid = NULL; int use_network = 0; @@ -1490,6 +1492,38 @@ int main(int argc, char *argv[]) mobilebackup2_error_t err; uint64_t lockfile = 0; +#define OPT_SYSTEM 1 +#define OPT_REBOOT 2 +#define OPT_NO_REBOOT 3 +#define OPT_COPY 4 +#define OPT_SETTINGS 5 +#define OPT_REMOVE 6 +#define OPT_SKIP_APPS 7 +#define OPT_PASSWORD 8 +#define OPT_FULL 9 + + int c = 0; + const struct option longopts[] = { + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "udid", required_argument, NULL, 'u' }, + { "source", required_argument, NULL, 's' }, + { "interactive", no_argument, NULL, 'i' }, + { "network", no_argument, NULL, 'n' }, + { "version", no_argument, NULL, 'v' }, + // command options: + { "system", no_argument, NULL, OPT_SYSTEM }, + { "reboot", no_argument, NULL, OPT_REBOOT }, + { "no-reboot", no_argument, NULL, OPT_NO_REBOOT }, + { "copy", no_argument, NULL, OPT_COPY }, + { "settings", no_argument, NULL, OPT_SETTINGS }, + { "remove", no_argument, NULL, OPT_REMOVE }, + { "skip-apps", no_argument, NULL, OPT_SKIP_APPS }, + { "password", no_argument, NULL, OPT_PASSWORD }, + { "full", no_argument, NULL, OPT_FULL }, + { NULL, 0, NULL, 0} + }; + /* we need to exit cleanly on running backups and restores or we cause havok */ signal(SIGINT, clean_exit); signal(SIGTERM, clean_exit); @@ -1499,201 +1533,192 @@ int main(int argc, char *argv[]) #endif /* parse cmdline args */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + while ((c = getopt_long(argc, argv, "dhu:s:inv", longopts, NULL)) != -1) { + switch (c) { + case 'd': idevice_set_debug_level(1); - continue; - } - else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { - i++; - if (!argv[i] || !*argv[i]) { - print_usage(argc, argv); - return -1; + break; + case 'u': + if (!*optarg) { + fprintf(stderr, "ERROR: UDID argument must not be empty!\n"); + print_usage(argc, argv, 1); + return 2; } - udid = strdup(argv[i]); - continue; - } - else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--source")) { - i++; - if (!argv[i] || !*argv[i]) { - print_usage(argc, argv); - return -1; + udid = strdup(optarg); + break; + case 's': + if (!*optarg) { + fprintf(stderr, "ERROR: SOURCE argument must not be empty!\n"); + print_usage(argc, argv, 1); + return 2; } - source_udid = strdup(argv[i]); - continue; - } - else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) { - use_network = 1; - continue; - } - else if (!strcmp(argv[i], "-i") || !strcmp(argv[i], "--interactive")) { + source_udid = strdup(optarg); + case 'i': interactive_mode = 1; - continue; - } - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); + break; + case 'n': + use_network = 1; + break; + case 'h': + print_usage(argc, argv, 0); return 0; - } - else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { + case 'v': printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); return 0; - } - else if (!strcmp(argv[i], "backup")) { - cmd = CMD_BACKUP; - } - else if (!strcmp(argv[i], "restore")) { - cmd = CMD_RESTORE; - } - else if (!strcmp(argv[i], "--system")) { + case OPT_SYSTEM: cmd_flags |= CMD_FLAG_RESTORE_SYSTEM_FILES; - } - else if (!strcmp(argv[i], "--reboot")) { + break; + case OPT_REBOOT: cmd_flags &= ~CMD_FLAG_RESTORE_NO_REBOOT; - } - else if (!strcmp(argv[i], "--no-reboot")) { + break; + case OPT_NO_REBOOT: cmd_flags |= CMD_FLAG_RESTORE_NO_REBOOT; - } - else if (!strcmp(argv[i], "--copy")) { + break; + case OPT_COPY: cmd_flags |= CMD_FLAG_RESTORE_COPY_BACKUP; - } - else if (!strcmp(argv[i], "--settings")) { + break; + case OPT_SETTINGS: cmd_flags |= CMD_FLAG_RESTORE_SETTINGS; - } - else if (!strcmp(argv[i], "--remove")) { + break; + case OPT_REMOVE: cmd_flags |= CMD_FLAG_RESTORE_REMOVE_ITEMS; - } - else if (!strcmp(argv[i], "--skip-apps")) { + break; + case OPT_SKIP_APPS: cmd_flags |= CMD_FLAG_RESTORE_SKIP_APPS; - } - else if (!strcmp(argv[i], "--password")) { - i++; - if (!argv[i]) { - print_usage(argc, argv); - return -1; - } - if (backup_password) - free(backup_password); - backup_password = strdup(argv[i]); - continue; - } - else if (!strcmp(argv[i], "cloud")) { - cmd = CMD_CLOUD; - i++; - if (!argv[i]) { - printf("No argument given for cloud command; requires either 'on' or 'off'.\n"); - print_usage(argc, argv); - return -1; - } - if (!strcmp(argv[i], "on")) { - cmd_flags |= CMD_FLAG_CLOUD_ENABLE; - } else if (!strcmp(argv[i], "off")) { - cmd_flags |= CMD_FLAG_CLOUD_DISABLE; - } else { - printf("Invalid argument '%s' for cloud command; must be either 'on' or 'off'.\n", argv[i]); - } - continue; - } - else if (!strcmp(argv[i], "--full")) { + break; + case OPT_PASSWORD: + free(backup_password); + backup_password = strdup(optarg); + break; + case OPT_FULL: cmd_flags |= CMD_FLAG_FORCE_FULL_BACKUP; + default: + print_usage(argc, argv, 1); + return 2; } - else if (!strcmp(argv[i], "info")) { - cmd = CMD_INFO; - verbose = 0; - } - else if (!strcmp(argv[i], "list")) { - cmd = CMD_LIST; - verbose = 0; + } + argc -= optind; + argv += optind; + + if (!argv[0]) { + fprintf(stderr, "ERROR: No command specified.\n"); + print_usage(argc+optind, argv-optind, 1); + return 2; + } + + if (!strcmp(argv[0], "backup")) { + cmd = CMD_BACKUP; + i = 1; + } + else if (!strcmp(argv[0], "restore")) { + cmd = CMD_RESTORE; + i = 1; + } + else if (!strcmp(argv[0], "cloud")) { + cmd = CMD_CLOUD; + i = 1; + if (!argv[i]) { + fprintf(stderr, "ERROR: No argument given for cloud command; requires either 'on' or 'off'.\n"); + print_usage(argc+optind, argv-optind, 1); + return 2; } - else if (!strcmp(argv[i], "unback")) { - cmd = CMD_UNBACK; + if (!strcmp(argv[i], "on")) { + cmd_flags |= CMD_FLAG_CLOUD_ENABLE; + } else if (!strcmp(argv[i], "off")) { + cmd_flags |= CMD_FLAG_CLOUD_DISABLE; + } else { + fprintf(stderr, "ERROR: Invalid argument '%s' for cloud command; must be either 'on' or 'off'.\n", argv[i]); + print_usage(argc+optind, argv-optind, 1); + return 2; + } + } + else if (!strcmp(argv[0], "info")) { + cmd = CMD_INFO; + verbose = 0; + } + else if (!strcmp(argv[0], "list")) { + cmd = CMD_LIST; + verbose = 0; + } + else if (!strcmp(argv[0], "unback")) { + cmd = CMD_UNBACK; + } + else if (!strcmp(argv[0], "encryption")) { + cmd = CMD_CHANGEPW; + i = 1; + if (!argv[i]) { + fprintf(stderr, "ERROR: No argument given for encryption command; requires either 'on' or 'off'.\n"); + print_usage(argc+optind, argv-optind, 1); + return 2; + } + if (!strcmp(argv[i], "on")) { + cmd_flags |= CMD_FLAG_ENCRYPTION_ENABLE; + } else if (!strcmp(argv[i], "off")) { + cmd_flags |= CMD_FLAG_ENCRYPTION_DISABLE; + } else { + fprintf(stderr, "ERROR: Invalid argument '%s' for encryption command; must be either 'on' or 'off'.\n", argv[i]); + print_usage(argc+optind, argv-optind, 1); + return 2; } - else if (!strcmp(argv[i], "encryption")) { - cmd = CMD_CHANGEPW; - i++; - if (!argv[i]) { - printf("No argument given for encryption command; requires either 'on' or 'off'.\n"); - print_usage(argc, argv); - return -1; - } - if (!strcmp(argv[i], "on")) { - cmd_flags |= CMD_FLAG_ENCRYPTION_ENABLE; - } else if (!strcmp(argv[i], "off")) { - cmd_flags |= CMD_FLAG_ENCRYPTION_DISABLE; - } else { - printf("Invalid argument '%s' for encryption command; must be either 'on' or 'off'.\n", argv[i]); - } - // check if a password was given on the command line - if (newpw) { - free(newpw); - newpw = NULL; - } - if (backup_password) { - free(backup_password); - backup_password = NULL; - } - i++; - if (argv[i]) { - if (cmd_flags & CMD_FLAG_ENCRYPTION_ENABLE) { - newpw = strdup(argv[i]); - } else if (cmd_flags & CMD_FLAG_ENCRYPTION_DISABLE) { - backup_password = strdup(argv[i]); - } + // check if a password was given on the command line + free(newpw); + newpw = NULL; + free(backup_password); + backup_password = NULL; + i++; + if (argv[i]) { + if (cmd_flags & CMD_FLAG_ENCRYPTION_ENABLE) { + newpw = strdup(argv[i]); + } else if (cmd_flags & CMD_FLAG_ENCRYPTION_DISABLE) { + backup_password = strdup(argv[i]); } - continue; } - else if (!strcmp(argv[i], "changepw")) { - cmd = CMD_CHANGEPW; - cmd_flags |= CMD_FLAG_ENCRYPTION_CHANGEPW; - // check if passwords were given on command line - if (newpw) { - free(newpw); - newpw = NULL; - } - if (backup_password) { - free(backup_password); - backup_password = NULL; - } + } + else if (!strcmp(argv[0], "changepw")) { + cmd = CMD_CHANGEPW; + cmd_flags |= CMD_FLAG_ENCRYPTION_CHANGEPW; + // check if passwords were given on command line + free(newpw); + newpw = NULL; + free(backup_password); + backup_password = NULL; + i = 1; + if (argv[i]) { + backup_password = strdup(argv[i]); i++; - if (argv[i]) { - backup_password = strdup(argv[i]); - i++; - if (!argv[i]) { - printf("Old and new passwords have to be passed as arguments for the changepw command\n"); - print_usage(argc, argv); - return -1; - } - newpw = strdup(argv[i]); + if (!argv[i]) { + fprintf(stderr, "ERROR: Old and new passwords have to be passed as arguments for the changepw command\n"); + print_usage(argc+optind, argv-optind, 1); + return 2; } - continue; - } - else if (backup_directory == NULL) { - backup_directory = argv[i]; - } - else { - print_usage(argc, argv); - return -1; + newpw = strdup(argv[i]); } } + i++; + if (argv[i]) { + backup_directory = argv[i]; + } + /* verify options */ if (cmd == -1) { - printf("No command specified.\n"); - print_usage(argc, argv); - return -1; + fprintf(stderr, "ERROR: Unsupported command '%s'.\n", argv[0]); + print_usage(argc+optind, argv-optind, 1); + return 2; } if (cmd == CMD_CHANGEPW || cmd == CMD_CLOUD) { backup_directory = (char*)".this_folder_is_not_present_on_purpose"; } else { if (backup_directory == NULL) { - printf("No target backup directory specified.\n"); - print_usage(argc, argv); - return -1; + fprintf(stderr, "ERROR: No target backup directory specified.\n"); + print_usage(argc+optind, argv-optind, 1); + return 2; } /* verify if passed backup directory exists */ if (stat(backup_directory, &st) != 0) { - printf("ERROR: Backup directory \"%s\" does not exist!\n", backup_directory); + fprintf(stderr, "ERROR: Backup directory \"%s\" does not exist!\n", backup_directory); return -1; } } 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 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <getopt.h> #ifndef WIN32 #include <signal.h> #endif @@ -313,27 +314,27 @@ static int afc_client_copy_and_remove_crash_reports(afc_client_t afc, const char return res; } -static void print_usage(int argc, char **argv) +static void print_usage(int argc, char **argv, int is_error) { - char *name = NULL; - - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS] DIRECTORY\n", (name ? name + 1: argv[0])); - printf("\n"); - printf("Move crash reports from device to a local DIRECTORY.\n"); - printf("\n"); - printf("OPTIONS:\n"); - printf(" -u, --udid UDID\ttarget specific device by UDID\n"); - printf(" -n, --network\t\tconnect to network device\n"); - printf(" -e, --extract\t\textract raw crash report into separate '.crash' file\n"); - printf(" -k, --keep\t\tcopy but do not remove crash reports from device\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -f, --filter NAME\tfilter crash reports by NAME (case sensitive)\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf(" -v, --version\t\tprints version information\n"); - printf("\n"); - printf("Homepage: <" PACKAGE_URL ">\n"); - printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); + char *name = strrchr(argv[0], '/'); + fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] DIRECTORY\n", (name ? name + 1: argv[0])); + fprintf(is_error ? stderr : stdout, + "\n" + "Move crash reports from device to a local DIRECTORY.\n" + "\n" + "OPTIONS:\n" + " -u, --udid UDID target specific device by UDID\n" + " -n, --network connect to network device\n" + " -e, --extract extract raw crash report into separate '.crash' file\n" + " -k, --keep copy but do not remove crash reports from device\n" + " -d, --debug enable communication debugging\n" + " -f, --filter NAME filter crash reports by NAME (case sensitive)\n" + " -h, --help prints usage information\n" + " -v, --version prints version information\n" + "\n" + "Homepage: <" PACKAGE_URL ">\n" + "Bug Reports: <" PACKAGE_BUGREPORT ">\n" + ); } int main(int argc, char* argv[]) @@ -346,79 +347,84 @@ int main(int argc, char* argv[]) lockdownd_error_t lockdownd_error = LOCKDOWN_E_SUCCESS; afc_error_t afc_error = AFC_E_SUCCESS; - int i; const char* udid = NULL; int use_network = 0; const char* filename_filter = NULL; + int c = 0; + const struct option longopts[] = { + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "udid", required_argument, NULL, 'u' }, + { "network", no_argument, NULL, 'n' }, + { "version", no_argument, NULL, 'v' }, + { "filter", required_argument, NULL, 'f' }, + { "extract", no_argument, NULL, 'e' }, + { "keep", no_argument, NULL, 'k' }, + { NULL, 0, NULL, 0} + }; + #ifndef WIN32 signal(SIGPIPE, SIG_IGN); #endif + /* parse cmdline args */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + while ((c = getopt_long(argc, argv, "dhu:nvf:ek", longopts, NULL)) != -1) { + switch (c) { + case 'd': idevice_set_debug_level(1); - continue; - } - else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { - i++; - if (!argv[i] || !*argv[i]) { - print_usage(argc, argv); - return 0; + break; + case 'u': + if (!*optarg) { + fprintf(stderr, "ERROR: UDID argument must not be empty!\n"); + print_usage(argc, argv, 1); + return 2; } - udid = argv[i]; - continue; - } - else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) { + udid = optarg; + break; + case 'n': use_network = 1; - continue; - } - else if (!strcmp(argv[i], "-f") || !strcmp(argv[i], "--filter")) { - i++; - if (!argv[i] || !*argv[i]) { - print_usage(argc, argv); - return 0; - } - filename_filter = argv[i]; - continue; - } - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); + break; + case 'h': + print_usage(argc, argv, 0); return 0; - } - else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { + case 'v': printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); return 0; - } - else if (!strcmp(argv[i], "-e") || !strcmp(argv[i], "--extract")) { + case 'f': + if (!*optarg) { + fprintf(stderr, "ERROR: filter argument must not be empty!\n"); + print_usage(argc, argv, 1); + return 2; + } + filename_filter = optarg; + break; + case 'e': extract_raw_crash_reports = 1; - continue; - } - else if (!strcmp(argv[i], "-k") || !strcmp(argv[i], "--keep")) { + break; + case 'k': keep_crash_reports = 1; - continue; - } - else if (target_directory == NULL) { - target_directory = argv[i]; - continue; - } - else { - print_usage(argc, argv); - return 0; + break; + default: + print_usage(argc, argv, 1); + return 2; } } + argc -= optind; + argv += optind; /* ensure a target directory was supplied */ - if (!target_directory) { - print_usage(argc, argv); - return 0; + if (!argv[0]) { + fprintf(stderr, "ERROR: missing target directory.\n"); + print_usage(argc+optind, argv-optind, 1); + return 2; } + target_directory = argv[0]; /* check if target directory exists */ if (!file_exists(target_directory)) { fprintf(stderr, "ERROR: Directory '%s' does not exist.\n", target_directory); - print_usage(argc, argv); - return 0; + return 1; } 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 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <getopt.h> #include <time.h> #if HAVE_LANGINFO_CODESET #include <langinfo.h> @@ -49,29 +50,29 @@ #endif #endif -static void print_usage(int argc, char **argv) +static void print_usage(int argc, char **argv, int is_error) { - char *name = NULL; - - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); - printf("\n"); - printf("Display the current date or set it on a device.\n"); - printf("\n"); - printf("NOTE: Setting the time on iOS 6 and later is only supported\n"); - printf(" in the setup wizard screens before device activation.\n"); - printf("\n"); - printf("OPTIONS:\n"); - printf(" -u, --udid UDID\ttarget specific device by UDID\n"); - printf(" -n, --network\t\tconnect to network device\n"); - printf(" -s, --set TIMESTAMP\tset UTC time described by TIMESTAMP\n"); - printf(" -c, --sync\t\tset time of device to current system time\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf(" -v, --version\t\tprints version information\n"); - printf("\n"); - printf("Homepage: <" PACKAGE_URL ">\n"); - printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); + char *name = strrchr(argv[0], '/'); + fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); + fprintf(is_error ? stderr : stdout, + "\n" + "Display the current date or set it on a device.\n" + "\n" + "NOTE: Setting the time on iOS 6 and later is only supported\n" + " in the setup wizard screens before device activation.\n" + "\n" + "OPTIONS:\n" + " -u, --udid UDID target specific device by UDID\n" + " -n, --network connect to network device\n" + " -s, --set TIMESTAMP set UTC time described by TIMESTAMP\n" + " -c, --sync set time of device to current system time\n" + " -d, --debug enable communication debugging\n" + " -h, --help prints usage information\n" + " -v, --version prints version information\n" + "\n" + "Homepage: <" PACKAGE_URL ">\n" + "Bug Reports: <" PACKAGE_BUGREPORT ">\n" + ); } int main(int argc, char *argv[]) @@ -80,7 +81,6 @@ int main(int argc, char *argv[]) lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR; idevice_t device = NULL; idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; - int i; const char* udid = NULL; int use_network = 0; time_t setdate = 0; @@ -92,65 +92,72 @@ int main(int argc, char *argv[]) char buffer[80]; int result = 0; + int c = 0; + const struct option longopts[] = { + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "udid", required_argument, NULL, 'u' }, + { "network", no_argument, NULL, 'n' }, + { "version", no_argument, NULL, 'v' }, + { "set", required_argument, NULL, 's' }, + { "sync", no_argument, NULL, 'c' }, + { NULL, 0, NULL, 0} + }; + #ifndef WIN32 signal(SIGPIPE, SIG_IGN); #endif /* parse cmdline args */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + while ((c = getopt_long(argc, argv, "dhu:nvs:c", longopts, NULL)) != -1) { + switch (c) { + case 'd': idevice_set_debug_level(1); - continue; - } - else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { - i++; - if (!argv[i] || !*argv[i]) { - print_usage(argc, argv); - return 0; + break; + case 'u': + if (!*optarg) { + fprintf(stderr, "ERROR: UDID argument must not be empty!\n"); + print_usage(argc, argv, 1); + return 2; } - udid = argv[i]; - continue; - } - else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) { + udid = optarg; + break; + case 'n': use_network = 1; - continue; - } - else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--set")) { - i++; - if (!argv[i] || (strlen(argv[i]) <= 1)) { - print_usage(argc, argv); - return 0; + break; + case 'h': + print_usage(argc, argv, 0); + return 0; + case 'v': + printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); + return 0; + case 's': + if (!*optarg) { + fprintf(stderr, "ERROR: set argument must not be empty!\n"); + print_usage(argc, argv, 1); + return 2; } - setdate = atoi(argv[i]); + setdate = atoi(optarg); if (setdate == 0) { - printf("ERROR: Invalid timestamp value.\n"); - print_usage(argc, argv); + fprintf(stderr, "ERROR: Invalid timestamp value.\n"); + print_usage(argc, argv, 1); return 0; } - continue; - } - else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--sync")) { - i++; + break; + case 'c': /* get current time */ setdate = time(NULL); /* convert it to local time which sets timezone/daylight variables */ tmp = localtime(&setdate); /* recalculate to make it UTC */ setdate = mktime(tmp); - continue; - } - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); - return 0; - } - else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { - printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); - return 0; - } - else { - print_usage(argc, argv); - return 0; + break; + default: + print_usage(argc, argv, 1); + return 2; } } + argc -= optind; + argv += optind; ret = idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX); 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 static void print_usage(int argc, char **argv, int is_error) { - char *name = NULL; - name = strrchr(argv[0], '/'); + char *name = strrchr(argv[0], '/'); fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0])); fprintf(is_error ? stderr : stdout, - "\n" \ - "Interact with the debugserver service of a device.\n" \ - "\n" \ - "Where COMMAND is one of:\n" \ - " run BUNDLEID [ARGS...]\trun app with BUNDLEID and optional ARGS on device.\n" \ - " kill BUNDLEID\tkill app with BUNDLEID\n" \ - "\n" \ - "The following OPTIONS are accepted:\n" \ - " -u, --udid UDID\ttarget specific device by UDID\n" \ - " -n, --network\t\tconnect to network device\n" \ - " --detach\t\tdetach from app after launch, keeping it running\n" \ - " -e, --env NAME=VALUE\tset environment variable NAME to VALUE\n" \ - " -d, --debug\t\tenable communication debugging\n" \ - " -h, --help\t\tprints usage information\n" \ - " -v, --version\t\tprints version information\n" \ - "\n" \ - "Homepage: <" PACKAGE_URL ">\n" \ + "\n" + "Interact with the debugserver service of a device.\n" + "\n" + "Where COMMAND is one of:\n" + " run BUNDLEID [ARGS...] run app with BUNDLEID and optional ARGS on device.\n" + " kill BUNDLEID kill app with BUNDLEID\n" + "\n" + "The following OPTIONS are accepted:\n" + " -u, --udid UDID target specific device by UDID\n" + " -n, --network connect to network device\n" + " --detach detach from app after launch, keeping it running\n" + " -e, --env NAME=VALUE set environment variable NAME to VALUE\n" + " -d, --debug enable communication debugging\n" + " -h, --help prints usage information\n" + " -v, --version prints version information\n" + "\n" + "Homepage: <" PACKAGE_URL ">\n" "Bug Reports: <" PACKAGE_BUGREPORT ">\n" ); } @@ -294,13 +293,13 @@ int main(int argc, char *argv[]) break; } } - argc -= optind; argv += optind; if (argc < 1) { fprintf(stderr, "ERROR: Missing command.\n"); print_usage(argc+optind, argv-optind, 1); + return 2; } 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 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <getopt.h> #include <errno.h> #include <signal.h> #ifdef WIN32 @@ -75,26 +76,26 @@ static void clean_exit(int sig) quit_flag++; } -static void print_usage(int argc, char **argv) +static void print_usage(int argc, char **argv, int is_error) { - char *name = NULL; - - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS] [PORT]\n", (name ? name + 1: argv[0])); - printf("\n"); - printf("Proxy debugserver connection from device to a local socket at PORT.\n"); - printf("If PORT is omitted, the next available port will be used and printed\n"); - printf("to stdout.\n"); - printf("\n"); - printf("OPTIONS:\n"); - printf(" -u, --udid UDID\ttarget specific device by UDID\n"); - printf(" -n, --network\t\tconnect to network device\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf(" -v, --version\t\tprints version information\n"); - printf("\n"); - printf("Homepage: <" PACKAGE_URL ">\n"); - printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); + char *name = strrchr(argv[0], '/'); + fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] [PORT]\n", (name ? name + 1: argv[0])); + fprintf(is_error ? stderr : stdout, + "\n" + "Proxy debugserver connection from device to a local socket at PORT.\n" + "If PORT is omitted, the next available port will be used and printed\n" + "to stdout.\n" + "\n" + "OPTIONS:\n" + " -u, --udid UDID target specific device by UDID\n" + " -n, --network connect to network device\n" + " -d, --debug enable communication debugging\n" + " -h, --help prints usage information\n" + " -v, --version prints version information\n" + "\n" + "Homepage: <" PACKAGE_URL ">\n" + "Bug Reports: <" PACKAGE_BUGREPORT ">\n" + ); } static void* connection_handler(void* data) @@ -182,7 +183,15 @@ int main(int argc, char *argv[]) uint16_t local_port = 0; int server_fd; int result = EXIT_SUCCESS; - int i; + int c = 0; + const struct option longopts[] = { + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "udid", required_argument, NULL, 'u' }, + { "network", no_argument, NULL, 'n' }, + { "version", no_argument, NULL, 'v' }, + { NULL, 0, NULL, 0} + }; #ifndef WIN32 struct sigaction sa; @@ -207,43 +216,41 @@ int main(int argc, char *argv[]) #endif /* parse cmdline arguments */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + while ((c = getopt_long(argc, argv, "dhu:nv", longopts, NULL)) != -1) { + switch (c) { + case 'd': debug_mode = 1; idevice_set_debug_level(1); socket_set_verbose(3); - continue; - } - else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { - i++; - if (!argv[i] || !*argv[i]) { - print_usage(argc, argv); - return 0; + break; + case 'u': + if (!*optarg) { + fprintf(stderr, "ERROR: UDID argument must not be empty!\n"); + print_usage(argc, argv, 1); + return 2; } - udid = argv[i]; - continue; - } - else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) { + udid = optarg; + break; + case 'n': use_network = 1; - continue; - } - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); - return EXIT_SUCCESS; - } - else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { + break; + case 'h': + print_usage(argc, argv, 0); + return 0; + case 'v': printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); - return EXIT_SUCCESS; - } - else if (atoi(argv[i]) > 0) { - local_port = atoi(argv[i]); - continue; - } - else { - print_usage(argc, argv); - return EXIT_SUCCESS; + return 0; + default: + print_usage(argc, argv, 1); + return 2; } } + argc -= optind; + argv += optind; + + if (argv[0] && (atoi(argv[0]) > 0)) { + local_port = atoi(argv[0]); + } /* start services and connect to device */ 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 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <getopt.h> #include <errno.h> #include <time.h> #ifndef WIN32 @@ -59,7 +60,34 @@ static void print_xml(plist_t node) } } -void print_usage(int argc, char **argv); +static void print_usage(int argc, char **argv, int is_error) +{ + char *name = strrchr(argv[0], '/'); + fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0])); + fprintf(is_error ? stderr : stdout, + "\n" + "Use diagnostics interface of a device running iOS 4 or later.\n" + "\n" + "Where COMMAND is one of:\n" + " diagnostics [TYPE] print diagnostics information from device by TYPE (All, WiFi, GasGauge, NAND)\n" + " mobilegestalt KEY [...] print mobilegestalt keys passed as arguments separated by a space.\n" + " ioreg [PLANE] print IORegistry of device, optionally by PLANE (IODeviceTree, IOPower, IOService) (iOS 5+ only)\n" + " ioregentry [KEY] print IORegistry entry of device (AppleARMPMUCharger, ASPStorage, ...) (iOS 5+ only)\n" + " shutdown shutdown device\n" + " restart restart device\n" + " sleep put device into sleep mode (disconnects from host)\n" + "\n" + "The following OPTIONS are accepted:\n" + " -u, --udid UDID target specific device by UDID\n" + " -n, --network connect to network device\n" + " -d, --debug enable communication debugging\n" + " -h, --help prints usage information\n" + " -v, --version prints version information\n" + "\n" + "Homepage: <" PACKAGE_URL ">\n" + "Bug Reports: <" PACKAGE_BUGREPORT ">\n" + ); +} int main(int argc, char **argv) { @@ -69,130 +97,119 @@ int main(int argc, char **argv) lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; lockdownd_service_descriptor_t service = NULL; int result = EXIT_FAILURE; - int i; const char *udid = NULL; int use_network = 0; int cmd = CMD_NONE; char* cmd_arg = NULL; plist_t node = NULL; plist_t keys = NULL; + int c = 0; + const struct option longopts[] = { + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "udid", required_argument, NULL, 'u' }, + { "network", no_argument, NULL, 'n' }, + { "version", no_argument, NULL, 'v' }, + { NULL, 0, NULL, 0} + }; #ifndef WIN32 signal(SIGPIPE, SIG_IGN); #endif /* parse cmdline args */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + while ((c = getopt_long(argc, argv, "dhu:nv", longopts, NULL)) != -1) { + switch (c) { + case 'd': idevice_set_debug_level(1); - continue; - } - else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { - i++; - if (!argv[i] || !*argv[i]) { - print_usage(argc, argv); - result = EXIT_SUCCESS; - goto cleanup; + break; + case 'u': + if (!*optarg) { + fprintf(stderr, "ERROR: UDID argument must not be empty!\n"); + print_usage(argc, argv, 1); + return 2; } - udid = argv[i]; - continue; - } - else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) { + udid = optarg; + break; + case 'n': use_network = 1; - continue; - } - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); - result = EXIT_SUCCESS; - goto cleanup; - } - else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { + break; + case 'h': + print_usage(argc, argv, 0); + return 0; + case 'v': printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); - result = EXIT_SUCCESS; - goto cleanup; + return 0; + default: + print_usage(argc, argv, 1); + return 2; } - else if (!strcmp(argv[i], "sleep")) { - cmd = CMD_SLEEP; - } - else if (!strcmp(argv[i], "restart")) { - cmd = CMD_RESTART; - } - else if (!strcmp(argv[i], "shutdown")) { - cmd = CMD_SHUTDOWN; - } - else if (!strcmp(argv[i], "diagnostics")) { - cmd = CMD_DIAGNOSTICS; - /* read type */ - i++; - 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))) { - if (argv[i] == NULL) { - cmd_arg = strdup("All"); - continue; - } + } + argc -= optind; + argv += optind; - if (!strncmp(argv[i], "-", 1)) { - cmd_arg = strdup("All"); - i--; - continue; - } + if (!argv[0]) { + fprintf(stderr, "ERROR: No command specified\n"); + print_usage(argc+optind, argv-optind, 1); + return 2; + } - printf("ERROR: Unknown TYPE %s\n", argv[i]); - print_usage(argc, argv); + if (!strcmp(argv[0], "sleep")) { + cmd = CMD_SLEEP; + } + else if (!strcmp(argv[0], "restart")) { + cmd = CMD_RESTART; + } + else if (!strcmp(argv[0], "shutdown")) { + cmd = CMD_SHUTDOWN; + } + else if (!strcmp(argv[0], "diagnostics")) { + cmd = CMD_DIAGNOSTICS; + /* read type */ + 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))) { + if (argv[1] == NULL) { + cmd_arg = strdup("All"); + } else { + fprintf(stderr, "ERROR: Unknown TYPE %s\n", argv[1]); + print_usage(argc+optind, argv-optind, 1); goto cleanup; } - - cmd_arg = strdup(argv[i]); - continue; } - else if (!strcmp(argv[i], "mobilegestalt")) { - cmd = CMD_MOBILEGESTALT; - /* read keys */ - i++; - - if (!argv[i] || argv[i] == NULL || (!strncmp(argv[i], "-", 1))) { - printf("ERROR: Please supply the key to query.\n"); - print_usage(argc, argv); - goto cleanup; - } - - keys = plist_new_array(); - while(1) { - if (argv[i] && (strlen(argv[i]) >= 2) && (strncmp(argv[i], "-", 1) != 0)) { - plist_array_append_item(keys, plist_new_string(argv[i])); - i++; - } else { - i--; - break; - } - } - continue; + cmd_arg = strdup(argv[1]); + } + else if (!strcmp(argv[0], "mobilegestalt")) { + cmd = CMD_MOBILEGESTALT; + /* read keys */ + if (!argv[1] || !*argv[1]) { + fprintf(stderr, "ERROR: Please supply the key to query.\n"); + print_usage(argc, argv, 1); + goto cleanup; } - else if (!strcmp(argv[i], "ioreg")) { - cmd = CMD_IOREGISTRY; - /* read plane */ + int i = 1; + keys = plist_new_array(); + while (argv[i] && *argv[i]) { + plist_array_append_item(keys, plist_new_string(argv[i])); i++; - if (argv[i]) { - cmd_arg = strdup(argv[i]); - } - continue; } - else if (!strcmp(argv[i], "ioregentry")) { - cmd = CMD_IOREGISTRY_ENTRY; - /* read key */ - i++; - if (argv[i]) { - cmd_arg = strdup(argv[i]); - } - continue; + } + else if (!strcmp(argv[0], "ioreg")) { + cmd = CMD_IOREGISTRY; + /* read plane */ + if (argv[1]) { + cmd_arg = strdup(argv[1]); } - else { - print_usage(argc, argv); - return EXIT_SUCCESS; + } + else if (!strcmp(argv[0], "ioregentry")) { + cmd = CMD_IOREGISTRY_ENTRY; + /* read key */ + if (argv[1]) { + cmd_arg = strdup(argv[1]); } } /* verify options */ if (cmd == CMD_NONE) { - print_usage(argc, argv); + fprintf(stderr, "ERROR: Unsupported command '%s'\n", argv[0]); + print_usage(argc+optind, argv-optind, 1); goto cleanup; } @@ -325,31 +342,3 @@ cleanup: } return result; } - -void print_usage(int argc, char **argv) -{ - char *name = NULL; - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0])); - printf("\n"); - printf("Use diagnostics interface of a device running iOS 4 or later.\n"); - printf("\n"); - printf("Where COMMAND is one of:\n"); - printf(" diagnostics [TYPE]\t\tprint diagnostics information from device by TYPE (All, WiFi, GasGauge, NAND)\n"); - printf(" mobilegestalt KEY [...]\tprint mobilegestalt keys passed as arguments separated by a space.\n"); - printf(" ioreg [PLANE]\t\t\tprint IORegistry of device, optionally by PLANE (IODeviceTree, IOPower, IOService) (iOS 5+ only)\n"); - printf(" ioregentry [KEY]\t\tprint IORegistry entry of device (AppleARMPMUCharger, ASPStorage, ...) (iOS 5+ only)\n"); - printf(" shutdown\t\t\tshutdown device\n"); - printf(" restart\t\t\trestart device\n"); - printf(" sleep\t\t\t\tput device into sleep mode (disconnects from host)\n"); - printf("\n"); - printf("The following OPTIONS are accepted:\n"); - printf(" -u, --udid UDID\ttarget specific device by UDID\n"); - printf(" -n, --network\t\tconnect to network device\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf(" -v, --version\t\tprints version information\n"); - printf("\n"); - printf("Homepage: <" PACKAGE_URL ">\n"); - printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); -} 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 @@ #include <stdio.h> #include <string.h> -#include <errno.h> #include <stdlib.h> +#include <getopt.h> +#include <errno.h> #ifndef WIN32 #include <signal.h> #endif @@ -36,22 +37,22 @@ #include <libimobiledevice/libimobiledevice.h> #include <libimobiledevice/lockdown.h> -static void print_usage(int argc, char **argv) +static void print_usage(int argc, char **argv, int is_error) { - char *name = NULL; - - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS] UDID\n", (name ? name + 1: argv[0])); - printf("\n"); - printf("Makes a device with the supplied UDID enter recovery mode immediately.\n"); - printf("\n"); - printf("OPTIONS:\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf(" -v, --version\t\tprints version information\n"); - printf("\n"); - printf("Homepage: <" PACKAGE_URL ">\n"); - printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); + char *name = strrchr(argv[0], '/'); + fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] UDID\n", (name ? name + 1: argv[0])); + fprintf(is_error ? stderr : stdout, + "\n" + "Makes a device with the supplied UDID enter recovery mode immediately.\n" + "\n" + "OPTIONS:\n" + " -d, --debug enable communication debugging\n" + " -h, --help prints usage information\n" + " -v, --version prints version information\n" + "\n" + "Homepage: <" PACKAGE_URL ">\n" + "Bug Reports: <" PACKAGE_BUGREPORT ">\n" + ); } int main(int argc, char *argv[]) @@ -60,34 +61,44 @@ int main(int argc, char *argv[]) lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR; idevice_t device = NULL; idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; - int i; const char* udid = NULL; + int c = 0; + const struct option longopts[] = { + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'v' }, + { NULL, 0, NULL, 0} + }; #ifndef WIN32 signal(SIGPIPE, SIG_IGN); #endif /* parse cmdline args */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + while ((c = getopt_long(argc, argv, "dhv", longopts, NULL)) != -1) { + switch (c) { + case 'd': idevice_set_debug_level(1); - continue; - } - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); + break; + case 'h': + print_usage(argc, argv, 0); return 0; - } - else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { + case 'v': printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); return 0; + default: + print_usage(argc, argv, 1); + return 2; } } + argc -= optind; + argv += optind; - i--; - if (argc < 2 || !argv[i] || !*argv[i]) { - print_usage(argc, argv); - return 0; + if (!argv[0]) { + fprintf(stderr, "ERROR: No UDID specified\n"); + print_usage(argc+optind, argv-optind, 1); + return 2; } - udid = argv[i]; + udid = argv[0]; ret = idevice_new(&device, udid); 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 { DISK_IMAGE_UPLOAD_TYPE_UPLOAD_IMAGE } disk_image_upload_type_t; -static void print_usage(int argc, char **argv) +static void print_usage(int argc, char **argv, int is_error) { - char *name = NULL; - - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS] IMAGE_FILE IMAGE_SIGNATURE_FILE\n", (name ? name + 1: argv[0])); - printf("\n"); - printf("Mounts the specified disk image on the device.\n"); - printf("\n"); - printf("OPTIONS:\n"); - printf(" -u, --udid UDID\ttarget specific device by UDID\n"); - printf(" -n, --network\t\tconnect to network device\n"); - printf(" -l, --list\t\tList mount information\n"); - printf(" -t, --imagetype\tImage type to use, default is 'Developer'\n"); - printf(" -x, --xml\t\tUse XML output\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf(" -v, --version\t\tprints version information\n"); - printf("\n"); - printf("Homepage: <" PACKAGE_URL ">\n"); - printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); + char *name = strrchr(argv[0], '/'); + fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] IMAGE_FILE IMAGE_SIGNATURE_FILE\n", (name ? name + 1: argv[0])); + fprintf(is_error ? stderr : stdout, + "\n" + "Mounts the specified disk image on the device.\n" + "\n" + "OPTIONS:\n" + " -u, --udid UDID target specific device by UDID\n" + " -n, --network connect to network device\n" + " -l, --list List mount information\n" + " -t, --imagetype TYPE Image type to use, default is 'Developer'\n" + " -x, --xml Use XML output\n" + " -d, --debug enable communication debugging\n" + " -h, --help prints usage information\n" + " -v, --version prints version information\n" + "\n" + "Homepage: <" PACKAGE_URL ">\n" + "Bug Reports: <" PACKAGE_BUGREPORT ">\n" + ); } static void parse_opts(int argc, char **argv) @@ -108,12 +108,12 @@ static void parse_opts(int argc, char **argv) switch (c) { case 'h': - print_usage(argc, argv); + print_usage(argc, argv, 0); exit(0); case 'u': if (!*optarg) { fprintf(stderr, "ERROR: UDID must not be empty!\n"); - print_usage(argc, argv); + print_usage(argc, argv, 1); exit(2); } udid = optarg; @@ -137,7 +137,7 @@ static void parse_opts(int argc, char **argv) printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); exit(0); default: - print_usage(argc, argv); + print_usage(argc, argv, 1); exit(2); } } 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) static void print_usage(int argc, char **argv, int is_error) { int i = 0; - char *name = NULL; - name = strrchr(argv[0], '/'); + char *name = strrchr(argv[0], '/'); fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); fprintf(is_error ? stderr : stdout, - "\n" \ - "Show information about a connected device.\n" \ - "\n" \ - "OPTIONS:\n" \ - " -u, --udid UDID target specific device by UDID\n" \ - " -n, --network connect to network device\n" \ - " -s, --simple use a simple connection to avoid auto-pairing with the device\n" \ - " -q, --domain NAME set domain of query to NAME. Default: None\n" \ - " -k, --key NAME only query key specified by NAME. Default: All keys.\n" \ - " -x, --xml output information as xml plist instead of key/value pairs\n" \ - " -h, --help prints usage information\n" \ - " -d, --debug enable communication debugging\n" \ - " -v, --version prints version information\n" \ + "\n" + "Show information about a connected device.\n" + "\n" + "OPTIONS:\n" + " -u, --udid UDID target specific device by UDID\n" + " -n, --network connect to network device\n" + " -s, --simple use simple connection to avoid auto-pairing with device\n" + " -q, --domain NAME set domain of query to NAME. Default: None\n" \ + " -k, --key NAME only query key specified by NAME. Default: All keys.\n" \ + " -x, --xml output information in XML property list format\n" \ + " -h, --help prints usage information\n" \ + " -d, --debug enable communication debugging\n" \ + " -v, --version prints version information\n" \ "\n" ); 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 @@ #include <libimobiledevice/libimobiledevice.h> #include <libimobiledevice/lockdown.h> -static void print_usage(void) +static void print_usage(int argc, char** argv, int is_error) { - printf("Usage: idevicename [OPTIONS] [NAME]\n"); - printf("\n"); - printf("Display the device name or set it to NAME if specified.\n"); - printf("\n"); - printf("OPTIONS:\n"); - printf(" -u, --udid UDID\ttarget specific device by UDID\n"); - printf(" -n, --network\t\tconnect to network device\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -h, --help\t\tprint usage information\n"); - printf(" -v, --version\t\tprint version information\n"); - printf("\n"); - printf("Homepage: <" PACKAGE_URL ">\n"); - printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); + char *name = strrchr(argv[0], '/'); + fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] [NAME]\n", (name ? name + 1: argv[0])); + fprintf(is_error ? stderr : stdout, + "\n" + "Display the device name or set it to NAME if specified.\n" + "\n" + "OPTIONS:\n" + " -u, --udid UDID target specific device by UDID\n" + " -n, --network connect to network device\n" + " -d, --debug enable communication debugging\n" + " -h, --help print usage information\n" + " -v, --version print version information\n" + "\n" + "Homepage: <" PACKAGE_URL ">\n" + "Bug Reports: <" PACKAGE_BUGREPORT ">\n" + ); } int main(int argc, char** argv) @@ -78,7 +81,7 @@ int main(int argc, char** argv) case 'u': if (!*optarg) { fprintf(stderr, "ERROR: UDID must not be empty!\n"); - print_usage(); + print_usage(argc, argv, 1); exit(2); } udid = optarg; @@ -87,7 +90,7 @@ int main(int argc, char** argv) use_network = 1; break; case 'h': - print_usage(); + print_usage(argc, argv, 0); return 0; case 'd': idevice_set_debug_level(1); @@ -96,7 +99,7 @@ int main(int argc, char** argv) printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); return 0; default: - print_usage(); + print_usage(argc, argv, 1); return 2; } } @@ -105,8 +108,8 @@ int main(int argc, char** argv) argv += optind; if (argc > 1) { - print_usage(); - return -1; + print_usage(argc, argv, 1); + return 2; } 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 @@ #include <stdio.h> #include <string.h> +#include <stdlib.h> +#include <getopt.h> #include <errno.h> #include <signal.h> -#include <stdlib.h> #ifdef WIN32 #include <windows.h> @@ -59,28 +60,29 @@ static void clean_exit(int sig) quit_flag++; } -static void print_usage(int argc, char **argv) +static void print_usage(int argc, char **argv, int is_error) { - char *name = NULL; - - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0])); - printf("\n"); - printf("Post or observe notifications on a device.\n"); - printf("\n"); - printf("Where COMMAND is one of:\n"); - printf(" post ID [...]\t\tpost notification IDs to device and exit\n"); - printf(" observe ID [...]\tobserve notification IDs in the foreground until CTRL+C or signal is received\n"); - printf("\n"); - printf("The following OPTIONS are accepted:\n"); - printf(" -u, --udid UDID\ttarget specific device by UDID\n"); - printf(" -n, --network\t\tconnect to network device\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf(" -v, --version\t\tprints version information\n"); - printf("\n"); - printf("Homepage: <" PACKAGE_URL ">\n"); - printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); + char *name = strrchr(argv[0], '/'); + fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0])); + fprintf(is_error ? stderr : stdout, + "\n" + "Post or observe notifications on a device.\n" + "\n" + "Where COMMAND is one of:\n" + " post ID [...] post notification IDs to device and exit\n" + " observe ID [...] observe notification IDs in foreground until CTRL+C\n" + " or signal is received\n" + "\n" + "The following OPTIONS are accepted:\n" + " -u, --udid UDID target specific device by UDID\n" + " -n, --network connect to network device\n" + " -d, --debug enable communication debugging\n" + " -h, --help prints usage information\n" + " -v, --version prints version information\n" + "\n" + "Homepage: <" PACKAGE_URL ">\n" + "Bug Reports: <" PACKAGE_BUGREPORT ">\n" + ); } static void notify_cb(const char *notification, void *user_data) @@ -97,7 +99,7 @@ int main(int argc, char *argv[]) np_client_t gnp = NULL; int result = -1; - int i; + int i = 0; const char* udid = NULL; int use_network = 0; int cmd = CMD_NONE; @@ -107,6 +109,16 @@ int main(int argc, char *argv[]) char **nspec = NULL; char **nspectmp = NULL; + int c = 0; + const struct option longopts[] = { + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "udid", required_argument, NULL, 'u' }, + { "network", no_argument, NULL, 'n' }, + { "version", no_argument, NULL, 'v' }, + { NULL, 0, NULL, 0} + }; + signal(SIGINT, clean_exit); signal(SIGTERM, clean_exit); #ifndef WIN32 @@ -115,80 +127,82 @@ int main(int argc, char *argv[]) #endif /* parse cmdline args */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + while ((c = getopt_long(argc, argv, "dhu:nv", longopts, NULL)) != -1) { + switch (c) { + case 'd': idevice_set_debug_level(1); - continue; - } - else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { - i++; - if (!argv[i] || !*argv[i]) { - print_usage(argc, argv); - result = 0; - goto cleanup; + break; + case 'u': + if (!*optarg) { + fprintf(stderr, "ERROR: UDID argument must not be empty!\n"); + print_usage(argc, argv, 1); + return 2; } - udid = argv[i]; - continue; - } - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); - result = 0; - goto cleanup; - } - else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) { + udid = optarg; + break; + case 'n': use_network = 1; - continue; - } - else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { + break; + case 'h': + print_usage(argc, argv, 0); + return 0; + case 'v': printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); - result = 0; - goto cleanup; + return 0; + default: + print_usage(argc, argv, 1); + return 2; } - else if (!strcmp(argv[i], "post") || !strcmp(argv[i], "observe")) { - cmd = CMD_POST; - if (!strcmp(argv[i], "observe")) { - cmd = CMD_OBSERVE; - } - - i++; + } + argc -= optind; + argv += optind; - if (!argv[i] || argv[i] == NULL || (!strncmp(argv[i], "-", 1))) { - printf("Please supply a valid notification identifier.\n"); - print_usage(argc, argv); - goto cleanup; - } + if (!argv[i]) { + fprintf(stderr, "ERROR: Missing command\n"); + print_usage(argc+optind, argv-optind, 1); + return 2; + } - count = 0; - nspec = malloc(sizeof(char*) * (count+1)); - - while(1) { - if (argv[i] && (strlen(argv[i]) >= 2) && (strncmp(argv[i], "-", 1) != 0)) { - nspectmp = realloc(nspec, sizeof(char*) * (count+1)); - nspectmp[count] = strdup(argv[i]); - nspec = nspectmp; - count = count+1; - i++; - } else { - i--; - break; - } - } + if (!strcmp(argv[i], "post")) { + cmd = CMD_POST; + } else if (!strcmp(argv[i], "observe")) { + cmd = CMD_OBSERVE; + } - nspectmp = realloc(nspec, sizeof(char*) * (count+1)); - nspectmp[count] = NULL; - nspec = nspectmp; - continue; + if (cmd == CMD_POST || cmd == CMD_OBSERVE) { + i++; + if (!argv[i]) { + fprintf(stderr, "ERROR: Please supply a valid notification identifier.\n"); + print_usage(argc+optind, argv-optind, 1); + return 2; } - else { - print_usage(argc, argv); - return 0; + + count = 0; + nspec = malloc(sizeof(char*) * (count+1)); + + while(1) { + if (argv[i] && (strlen(argv[i]) >= 2) && (strncmp(argv[i], "-", 1) != 0)) { + nspectmp = realloc(nspec, sizeof(char*) * (count+1)); + nspectmp[count] = strdup(argv[i]); + nspec = nspectmp; + count = count+1; + i++; + } else { + i--; + break; + } } + + nspectmp = realloc(nspec, sizeof(char*) * (count+1)); + nspectmp[count] = NULL; + nspec = nspectmp; } /* verify options */ if (cmd == CMD_NONE) { - print_usage(argc, argv); - goto cleanup; + fprintf(stderr, "ERROR: Unsupported command '%s'\n", argv[0]); + print_usage(argc+optind, argv-optind, 1); + return 2; } 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) } } -static void print_usage(int argc, char **argv) +static void print_usage(int argc, char **argv, int is_error) { - char *name = NULL; - - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0])); - printf("\n"); - printf("Manage host pairings with devices and usbmuxd.\n"); - printf("\n"); - printf("Where COMMAND is one of:\n"); - printf(" systembuid print the system buid of the usbmuxd host\n"); - printf(" hostid print the host id for target device\n"); - printf(" pair pair device with this host\n"); - printf(" validate validate if device is paired with this host\n"); - printf(" unpair unpair device with this host\n"); - printf(" list list devices paired with this host\n"); - printf("\n"); - printf("The following OPTIONS are accepted:\n"); - printf(" -u, --udid UDID target specific device by UDID\n"); + char *name = strrchr(argv[0], '/'); + fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0])); + fprintf(is_error ? stderr : stdout, + "\n" + "Manage host pairings with devices and usbmuxd.\n" + "\n" + "Where COMMAND is one of:\n" + " systembuid print the system buid of the usbmuxd host\n" + " hostid print the host id for target device\n" + " pair pair device with this host\n" + " validate validate if device is paired with this host\n" + " unpair unpair device with this host\n" + " list list devices paired with this host\n" + "\n" + "The following OPTIONS are accepted:\n" + " -u, --udid UDID target specific device by UDID\n" + ); #ifdef HAVE_WIRELESS_PAIRING - printf(" -w, --wireless perform wireless pairing (see NOTE)\n"); - printf(" -n, --network connect to network device (see NOTE)\n"); + fprintf(is_error ? stderr : stdout, + " -w, --wireless perform wireless pairing (see NOTE)\n" + " -n, --network connect to network device (see NOTE)\n" + ); #endif - printf(" -d, --debug enable communication debugging\n"); - printf(" -h, --help prints usage information\n"); - printf(" -v, --version prints version information\n"); + fprintf(is_error ? stderr : stdout, + " -d, --debug enable communication debugging\n" + " -h, --help prints usage information\n" + " -v, --version prints version information\n" + ); #ifdef HAVE_WIRELESS_PAIRING - printf("\n"); - printf("NOTE: Pairing over network (wireless pairing) is only supported by Apple TV\n"); - printf("devices. To perform a wireless pairing, you need to use the -w command line\n"); - printf("switch. Make sure to put the device into pairing mode first by opening\n"); - printf("Settings > Remotes and Devices > Remote App and Devices.\n"); + fprintf(is_error ? stderr : stdout, + "\n" + "NOTE: Pairing over network (wireless pairing) is only supported by Apple TV\n" + "devices. To perform a wireless pairing, you need to use the -w command line\n" + "switch. Make sure to put the device into pairing mode first by opening\n" + "Settings > Remotes and Devices > Remote App and Devices.\n" + ); #endif - printf("\n"); - printf("Homepage: <" PACKAGE_URL ">\n"); - printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); + fprintf(is_error ? stderr : stdout, + "\n" + "Homepage: <" PACKAGE_URL ">\n" + "Bug Reports: <" PACKAGE_BUGREPORT ">\n" + ); } int main(int argc, char **argv) @@ -223,12 +231,12 @@ int main(int argc, char **argv) while ((c = getopt_long(argc, argv, SHORT_OPTIONS, longopts, NULL)) != -1) { switch (c) { case 'h': - print_usage(argc, argv); + print_usage(argc, argv, 0); exit(EXIT_SUCCESS); case 'u': if (!*optarg) { fprintf(stderr, "ERROR: UDID must not be empty!\n"); - print_usage(argc, argv); + print_usage(argc, argv, 1); result = EXIT_FAILURE; goto leave; } @@ -280,7 +288,7 @@ int main(int argc, char **argv) result = EXIT_SUCCESS; goto leave; default: - print_usage(argc, argv); + print_usage(argc, argv, 1); result = EXIT_FAILURE; goto leave; } @@ -291,15 +299,15 @@ int main(int argc, char **argv) #endif if ((argc - optind) < 1) { - printf("ERROR: You need to specify a COMMAND!\n"); - print_usage(argc, argv); + fprintf(stderr, "ERROR: You need to specify a COMMAND!\n"); + print_usage(argc, argv, 1); result = EXIT_FAILURE; goto leave; } if (wireless_pairing && use_network) { - printf("ERROR: You cannot use -w and -n together.\n"); - print_usage(argc, argv); + fprintf(stderr, "ERROR: You cannot use -w and -n together.\n"); + print_usage(argc, argv, 1); result = EXIT_FAILURE; goto leave; } @@ -319,16 +327,16 @@ int main(int argc, char **argv) } else if (!strcmp(cmd, "systembuid")) { op = OP_SYSTEMBUID; } else { - printf("ERROR: Invalid command '%s' specified\n", cmd); - print_usage(argc, argv); + fprintf(stderr, "ERROR: Invalid command '%s' specified\n", cmd); + print_usage(argc, argv, 1); result = EXIT_FAILURE; goto leave; } if (wireless_pairing) { if (op == OP_VALIDATE || op == OP_UNPAIR) { - printf("ERROR: Command '%s' is not supported with -w\n", cmd); - print_usage(argc, argv); + fprintf(stderr, "ERROR: Command '%s' is not supported with -w\n", cmd); + print_usage(argc, argv, 1); result = EXIT_FAILURE; goto leave; } 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 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <getopt.h> #include <sys/stat.h> #include <errno.h> #ifndef WIN32 @@ -46,40 +47,40 @@ #include <libimobiledevice/misagent.h> #include <libimobiledevice-glue/utils.h> -static void print_usage(int argc, char **argv) +static void print_usage(int argc, char **argv, int is_error) { - char *name = NULL; - - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0])); - printf("\n"); - printf("Manage provisioning profiles on a device.\n"); - printf("\n"); - printf("Where COMMAND is one of:\n"); - printf(" install FILE\tInstalls the provisioning profile specified by FILE.\n"); - printf(" \tA valid .mobileprovision file is expected.\n"); - printf(" list\t\tGet a list of all provisioning profiles on the device.\n"); - printf(" copy PATH\tRetrieves all provisioning profiles from the device and\n"); - printf(" \tstores them into the existing directory specified by PATH.\n"); - printf(" \tThe files will be stored as UUID.mobileprovision\n"); - printf(" copy UUID PATH Retrieves the provisioning profile identified by UUID\n"); - printf(" \tfrom the device and stores it into the existing directory\n"); - printf(" \tspecified by PATH. The file will be stored as UUID.mobileprovision.\n"); - printf(" remove UUID\tRemoves the provisioning profile identified by UUID.\n"); - printf(" remove-all\tRemoves all installed provisioning profiles.\n"); - printf(" dump FILE\tPrints detailed information about the provisioning profile\n"); - printf(" \tspecified by FILE.\n"); - printf("\n"); - printf("The following OPTIONS are accepted:\n"); - printf(" -u, --udid UDID target specific device by UDID\n"); - printf(" -n, --network connect to network device\n"); - printf(" -x, --xml print XML output when using the 'dump' command\n"); - printf(" -d, --debug enable communication debugging\n"); - printf(" -h, --help prints usage information\n"); - printf(" -v, --version prints version information\n"); - printf("\n"); - printf("Homepage: <" PACKAGE_URL ">\n"); - printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); + char *name = strrchr(argv[0], '/'); + fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0])); + fprintf(is_error ? stderr : stdout, + "\n" + "Manage provisioning profiles on a device.\n" + "\n" + "Where COMMAND is one of:\n" + " install FILE Installs the provisioning profile specified by FILE.\n" + " A valid .mobileprovision file is expected.\n" + " list Get a list of all provisioning profiles on the device.\n" + " copy PATH Retrieves all provisioning profiles from the device and\n" + " stores them into the existing directory specified by PATH.\n" + " The files will be stored as UUID.mobileprovision\n" + " copy UUID PATH Retrieves the provisioning profile identified by UUID\n" + " from the device and stores it into the existing directory\n" + " specified by PATH. The file will be stored as UUID.mobileprovision.\n" + " remove UUID Removes the provisioning profile identified by UUID.\n" + " remove-all Removes all installed provisioning profiles.\n" + " dump FILE Prints detailed information about the provisioning profile\n" + " specified by FILE.\n" + "\n" + "The following OPTIONS are accepted:\n" + " -u, --udid UDID target specific device by UDID\n" + " -n, --network connect to network device\n" + " -x, --xml print XML output when using the 'dump' command\n" + " -d, --debug enable communication debugging\n" + " -h, --help prints usage information\n" + " -v, --version prints version information\n" + "\n" + "Homepage: <" PACKAGE_URL ">\n" + "Bug Reports: <" PACKAGE_BUGREPORT ">\n" + ); } enum { @@ -302,102 +303,115 @@ int main(int argc, char *argv[]) const char* param = NULL; const char* param2 = NULL; int use_network = 0; + int c = 0; + const struct option longopts[] = { + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "udid", required_argument, NULL, 'u' }, + { "network", no_argument, NULL, 'n' }, + { "version", no_argument, NULL, 'v' }, + { "xml", no_argument, NULL, 'x' }, + { NULL, 0, NULL, 0} + }; #ifndef WIN32 signal(SIGPIPE, SIG_IGN); #endif /* parse cmdline args */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + while ((c = getopt_long(argc, argv, "dhu:nvx", longopts, NULL)) != -1) { + switch (c) { + case 'd': idevice_set_debug_level(1); - continue; - } - else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { - i++; - if (!argv[i] || !*argv[i]) { - print_usage(argc, argv); - return 0; + break; + case 'u': + if (!*optarg) { + fprintf(stderr, "ERROR: UDID argument must not be empty!\n"); + print_usage(argc, argv, 1); + return 2; } - udid = argv[i]; - continue; - } - else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) { + udid = optarg; + break; + case 'n': use_network = 1; - continue; - } - else if (!strcmp(argv[i], "install")) { - i++; - if (!argv[i] || (strlen(argv[i]) < 1)) { - print_usage(argc, argv); - return 0; - } - param = argv[i]; - op = OP_INSTALL; - continue; - } - else if (!strcmp(argv[i], "list")) { - op = OP_LIST; - } - else if (!strcmp(argv[i], "copy")) { - i++; - if (!argv[i] || (strlen(argv[i]) < 1)) { - print_usage(argc, argv); - return 0; - } - param = argv[i]; - op = OP_COPY; - i++; - if (argv[i] && (strlen(argv[i]) > 0)) { - param2 = argv[i]; - } - continue; - } - else if (!strcmp(argv[i], "remove")) { - i++; - if (!argv[i] || (strlen(argv[i]) < 1)) { - print_usage(argc, argv); - return 0; - } - param = argv[i]; - op = OP_REMOVE; - continue; - } - else if (!strcmp(argv[i], "remove-all")) { - i++; - op = OP_REMOVE; - continue; + break; + case 'h': + print_usage(argc, argv, 0); + return 0; + case 'v': + printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); + return 0; + case 'x': + output_xml = 1; + break; + default: + print_usage(argc, argv, 1); + return 2; } - else if (!strcmp(argv[i], "dump")) { - i++; - if (!argv[i] || (strlen(argv[i]) < 1)) { - print_usage(argc, argv); - return 0; - } - param = argv[i]; - op = OP_DUMP; - continue; + } + argc -= optind; + argv += optind; + + if (!argv[0]) { + fprintf(stderr, "ERROR: Missing command.\n"); + print_usage(argc+optind, argv-optind, 1); + return 2; + } + + i = 0; + if (!strcmp(argv[i], "install")) { + op = OP_INSTALL; + i++; + if (!argv[i] || !*argv[i]) { + fprintf(stderr, "Missing argument for 'install' command.\n"); + print_usage(argc+optind, argv-optind, 1); + return 2; } - else if (!strcmp(argv[i], "-x") || !strcmp(argv[i], "--xml")) { - output_xml = 1; - continue; + param = argv[i]; + } + else if (!strcmp(argv[i], "list")) { + op = OP_LIST; + } + else if (!strcmp(argv[i], "copy")) { + op = OP_COPY; + i++; + if (!argv[i] || !*argv[i]) { + fprintf(stderr, "Missing argument for 'copy' command.\n"); + print_usage(argc+optind, argv-optind, 1); + return 2; } - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); - return 0; + param = argv[i]; + i++; + if (argv[i] && (strlen(argv[i]) > 0)) { + param2 = argv[i]; } - else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { - printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); - return 0; + } + else if (!strcmp(argv[i], "remove")) { + op = OP_REMOVE; + i++; + if (!argv[i] || !*argv[i]) { + fprintf(stderr, "Missing argument for 'remove' command.\n"); + print_usage(argc+optind, argv-optind, 1); + return 2; } - else { - print_usage(argc, argv); - return 0; + param = argv[i]; + } + else if (!strcmp(argv[i], "remove-all")) { + op = OP_REMOVE; + } + else if (!strcmp(argv[i], "dump")) { + op = OP_DUMP; + i++; + if (!argv[i] || !*argv[i]) { + fprintf(stderr, "Missing argument for 'remove' command.\n"); + print_usage(argc+optind, argv-optind, 1); + return 2; } + param = argv[i]; } - if ((op == -1) || (op >= NUM_OPS)) { - print_usage(argc, argv); - return 0; + fprintf(stderr, "ERROR: Unsupported command '%s'\n", argv[i]); + print_usage(argc+optind, argv-optind, 1); + return 2; } 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 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <getopt.h> #include <errno.h> #include <time.h> #include <unistd.h> @@ -39,8 +40,86 @@ #include <libimobiledevice/lockdown.h> #include <libimobiledevice/screenshotr.h> -void get_image_filename(char *imgdata, char **filename); -void print_usage(int argc, char **argv); +static void get_image_filename(char *imgdata, char **filename) +{ + // If the provided filename already has an extension, use it as is. + if (*filename) { + char *last_dot = strrchr(*filename, '.'); + if (last_dot && !strchr(last_dot, '/')) { + return; + } + } + + // Find the appropriate file extension for the filename. + const char *fileext = NULL; + if (memcmp(imgdata, "\x89PNG", 4) == 0) { + fileext = ".png"; + } else if (memcmp(imgdata, "MM\x00*", 4) == 0) { + fileext = ".tiff"; + } else { + printf("WARNING: screenshot data has unexpected image format.\n"); + fileext = ".dat"; + } + + // If a filename without an extension is provided, append the extension. + // Otherwise, generate a filename based on the current time. + char *basename = NULL; + if (*filename) { + basename = (char*)malloc(strlen(*filename) + 1); + strcpy(basename, *filename); + free(*filename); + *filename = NULL; + } else { + time_t now = time(NULL); + basename = (char*)malloc(32); + strftime(basename, 31, "screenshot-%Y-%m-%d-%H-%M-%S", gmtime(&now)); + } + + // Ensure the filename is unique on disk. + char *unique_filename = (char*)malloc(strlen(basename) + strlen(fileext) + 7); + sprintf(unique_filename, "%s%s", basename, fileext); + int i; + for (i = 2; i < (1 << 16); i++) { + if (access(unique_filename, F_OK) == -1) { + *filename = unique_filename; + break; + } + sprintf(unique_filename, "%s-%d%s", basename, i, fileext); + } + if (!*filename) { + free(unique_filename); + } + free(basename); +} + +static void print_usage(int argc, char **argv, int is_error) +{ + char *name = strrchr(argv[0], '/'); + fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] [FILE]\n", (name ? name + 1: argv[0])); + fprintf(is_error ? stderr : stdout, + "\n" + "Gets a screenshot from a connected device.\n" + "\n" + "The image is in PNG format for iOS 9+ and otherwise in TIFF format.\n" + "The screenshot is saved as an image with the given FILE name.\n" + "If FILE has no extension, FILE will be a prefix of the saved filename.\n" + "If FILE is not specified, \"screenshot-DATE\", will be used as a prefix\n" + "of the filename, e.g.:\n" + " ./screenshot-2013-12-31-23-59-59.tiff\n" + "\n" + "NOTE: A mounted developer disk image is required on the device, otherwise\n" + "the screenshotr service is not available.\n" + "\n" + " -u, --udid UDID target specific device by UDID\n" + " -n, --network connect to network device\n" + " -d, --debug enable communication debugging\n" + " -h, --help prints usage information\n" + " -v, --version prints version information\n" + "\n" + "Homepage: <" PACKAGE_URL ">\n" + "Bug Reports: <" PACKAGE_BUGREPORT ">\n" + ); +} int main(int argc, char **argv) { @@ -50,50 +129,58 @@ int main(int argc, char **argv) screenshotr_client_t shotr = NULL; lockdownd_service_descriptor_t service = NULL; int result = -1; - int i; const char *udid = NULL; int use_network = 0; char *filename = NULL; + int c = 0; + const struct option longopts[] = { + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "udid", required_argument, NULL, 'u' }, + { "network", no_argument, NULL, 'n' }, + { "version", no_argument, NULL, 'v' }, + { NULL, 0, NULL, 0} + }; #ifndef WIN32 signal(SIGPIPE, SIG_IGN); #endif /* parse cmdline args */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + + /* parse cmdline arguments */ + while ((c = getopt_long(argc, argv, "dhu:nv", longopts, NULL)) != -1) { + switch (c) { + case 'd': idevice_set_debug_level(1); - continue; - } - else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { - i++; - if (!argv[i] || !*argv[i]) { - print_usage(argc, argv); - return 0; + break; + case 'u': + if (!*optarg) { + fprintf(stderr, "ERROR: UDID argument must not be empty!\n"); + print_usage(argc, argv, 1); + return 2; } - udid = argv[i]; - continue; - } - else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) { + udid = optarg; + break; + case 'n': use_network = 1; - continue; - } - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); + break; + case 'h': + print_usage(argc, argv, 0); return 0; - } - else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { + case 'v': printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); return 0; - } - else if (argv[i][0] != '-' && !filename) { - filename = strdup(argv[i]); - continue; - } - else { - print_usage(argc, argv); - return 0; + default: + print_usage(argc, argv, 1); + return 2; } } + argc -= optind; + argv += optind; + + if (argv[0]) { + filename = strdup(argv[0]); + } if (IDEVICE_E_SUCCESS != idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX)) { if (udid) { @@ -153,84 +240,3 @@ int main(int argc, char **argv) return result; } - -void get_image_filename(char *imgdata, char **filename) -{ - // If the provided filename already has an extension, use it as is. - if (*filename) { - char *last_dot = strrchr(*filename, '.'); - if (last_dot && !strchr(last_dot, '/')) { - return; - } - } - - // Find the appropriate file extension for the filename. - const char *fileext = NULL; - if (memcmp(imgdata, "\x89PNG", 4) == 0) { - fileext = ".png"; - } else if (memcmp(imgdata, "MM\x00*", 4) == 0) { - fileext = ".tiff"; - } else { - printf("WARNING: screenshot data has unexpected image format.\n"); - fileext = ".dat"; - } - - // If a filename without an extension is provided, append the extension. - // Otherwise, generate a filename based on the current time. - char *basename = NULL; - if (*filename) { - basename = (char*)malloc(strlen(*filename) + 1); - strcpy(basename, *filename); - free(*filename); - *filename = NULL; - } else { - time_t now = time(NULL); - basename = (char*)malloc(32); - strftime(basename, 31, "screenshot-%Y-%m-%d-%H-%M-%S", gmtime(&now)); - } - - // Ensure the filename is unique on disk. - char *unique_filename = (char*)malloc(strlen(basename) + strlen(fileext) + 7); - sprintf(unique_filename, "%s%s", basename, fileext); - int i; - for (i = 2; i < (1 << 16); i++) { - if (access(unique_filename, F_OK) == -1) { - *filename = unique_filename; - break; - } - sprintf(unique_filename, "%s-%d%s", basename, i, fileext); - } - if (!*filename) { - free(unique_filename); - } - free(basename); -} - -void print_usage(int argc, char **argv) -{ - char *name = NULL; - - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS] [FILE]\n", (name ? name + 1: argv[0])); - printf("\n"); - printf("Gets a screenshot from a connected device.\n"); - printf("\n"); - printf("The image is in PNG format for iOS 9+ and otherwise in TIFF format.\n"); - printf("The screenshot is saved as an image with the given FILE name.\n"); - printf("If FILE has no extension, FILE will be a prefix of the saved filename.\n"); - printf("If FILE is not specified, \"screenshot-DATE\", will be used as a prefix\n"); - printf("of the filename, e.g.:\n"); - printf(" ./screenshot-2013-12-31-23-59-59.tiff\n"); - printf("\n"); - printf("NOTE: A mounted developer disk image is required on the device, otherwise\n"); - printf("the screenshotr service is not available.\n"); - printf("\n"); - printf(" -u, --udid UDID\ttarget specific device by UDID\n"); - printf(" -n, --network\t\tconnect to network device\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf(" -v, --version\t\tprints version information\n"); - printf("\n"); - printf("Homepage: <" PACKAGE_URL ">\n"); - printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n"); -} 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) fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] -- <LAT> <LONG>\n", bname); fprintf(is_error ? stderr : stdout, " %s [OPTIONS] reset\n", bname); - fprintf(is_error ? stderr : stdout, "\n" \ - "OPTIONS:\n" \ - " -u, --udid UDID target specific device by UDID\n" \ - " -n, --network connect to network device\n" \ - " -d, --debug enable communication debugging\n" \ - " -h, --help prints usage information\n" \ - " -v, --version prints version information\n" \ - "\n" \ - "Homepage: <" PACKAGE_URL ">\n" \ + fprintf(is_error ? stderr : stdout, + "\n" + "OPTIONS:\n" + " -u, --udid UDID target specific device by UDID\n" + " -n, --network connect to network device\n" + " -d, --debug enable communication debugging\n" + " -h, --help prints usage information\n" + " -v, --version prints version information\n" + "\n" + "Homepage: <" PACKAGE_URL ">\n" "Bug Reports: <" PACKAGE_BUGREPORT ">\n" ); } 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) static void print_usage(int argc, char **argv, int is_error) { - char *name = NULL; - name = strrchr(argv[0], '/'); + char *name = strrchr(argv[0], '/'); fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); fprintf(is_error ? stderr : stdout, - "\n" \ - "Relay syslog of a connected device.\n" \ - "\n" \ - "OPTIONS:\n" \ - " -u, --udid UDID target specific device by UDID\n" \ - " -n, --network connect to network device\n" \ - " -x, --exit exit when device disconnects\n" \ - " -h, --help prints usage information\n" \ - " -d, --debug enable communication debugging\n" \ - " -v, --version prints version information\n" \ - " --no-colors disable colored output\n" \ - "\n" \ - "FILTER OPTIONS:\n" \ - " -m, --match STRING only print messages that contain STRING\n" \ - " -t, --trigger STRING start logging when matching STRING\n" \ - " -T, --untrigger STRING stop logging when matching STRING\n" \ - " -p, --process PROCESS only print messages from matching process(es)\n" \ - " -e, --exclude PROCESS print all messages except matching process(es)\n" \ - " PROCESS is a process name or multiple process names\n" \ - " separated by \"|\".\n" \ - " -q, --quiet set a filter to exclude common noisy processes\n" \ - " --quiet-list prints the list of processes for --quiet and exits\n" \ - " -k, --kernel only print kernel messages\n" \ - " -K, --no-kernel suppress kernel messages\n" \ - "\n" \ - "For filter examples consult idevicesyslog(1) man page.\n" \ - "\n" \ + "\n" + "Relay syslog of a connected device.\n" + "\n" + "OPTIONS:\n" + " -u, --udid UDID target specific device by UDID\n" + " -n, --network connect to network device\n" + " -x, --exit exit when device disconnects\n" + " -h, --help prints usage information\n" + " -d, --debug enable communication debugging\n" + " -v, --version prints version information\n" + " --no-colors disable colored output\n" + "\n" + "FILTER OPTIONS:\n" + " -m, --match STRING only print messages that contain STRING\n" + " -t, --trigger STRING start logging when matching STRING\n" + " -T, --untrigger STRING stop logging when matching STRING\n" + " -p, --process PROCESS only print messages from matching process(es)\n" + " -e, --exclude PROCESS print all messages except matching process(es)\n" + " PROCESS is a process name or multiple process names\n" + " separated by \"|\".\n" + " -q, --quiet set a filter to exclude common noisy processes\n" + " --quiet-list prints the list of processes for --quiet and exits\n" + " -k, --kernel only print kernel messages\n" + " -K, --no-kernel suppress kernel messages\n" + "\n" + "For filter examples consult idevicesyslog(1) man page.\n" + "\n" "Homepage: <" PACKAGE_URL ">\n" "Bug Reports: <" PACKAGE_BUGREPORT ">\n" ); |