diff options
| author | 2023-03-25 05:54:57 +0100 | |
|---|---|---|
| committer | 2023-03-25 05:54:57 +0100 | |
| commit | 9525a2a76171e7da82f0e3fd602ad3c7101a30bf (patch) | |
| tree | 76d427af17df2169a9c1d391258e0ff724489c24 /src/ideviceinstaller.c | |
| parent | 14dced8ddab73ea51e42fe8da2180f259feae119 (diff) | |
| download | ideviceinstaller-9525a2a76171e7da82f0e3fd602ad3c7101a30bf.tar.gz ideviceinstaller-9525a2a76171e7da82f0e3fd602ad3c7101a30bf.tar.bz2 | |
Add -a command line switch to specify return attributes for 'list' command
Diffstat (limited to 'src/ideviceinstaller.c')
| -rw-r--r-- | src/ideviceinstaller.c | 114 |
1 files changed, 88 insertions, 26 deletions
diff --git a/src/ideviceinstaller.c b/src/ideviceinstaller.c index 5dcd900..ecf63c6 100644 --- a/src/ideviceinstaller.c +++ b/src/ideviceinstaller.c | |||
| @@ -121,29 +121,69 @@ int ignore_events = 0; | |||
| 121 | int err_occurred = 0; | 121 | int err_occurred = 0; |
| 122 | int notified = 0; | 122 | int notified = 0; |
| 123 | plist_t bundle_ids = NULL; | 123 | plist_t bundle_ids = NULL; |
| 124 | plist_t return_attrs = NULL; | ||
| 125 | int return_attrs_have_CFBundleIdentifier = 0; | ||
| 124 | 126 | ||
| 125 | static void print_apps_header() | 127 | static void print_apps_header() |
| 126 | { | 128 | { |
| 127 | /* output app details header */ | 129 | if (!return_attrs) { |
| 128 | printf("%s", "CFBundleIdentifier"); | 130 | return; |
| 129 | printf(", %s", "CFBundleShortVersionString"); | 131 | } |
| 130 | printf(", %s", "CFBundleDisplayName"); | 132 | uint32_t i = 0; |
| 133 | for (i = 0; i < plist_array_get_size(return_attrs); i++) { | ||
| 134 | plist_t node = plist_array_get_item(return_attrs, i); | ||
| 135 | if (i > 0) { | ||
| 136 | printf(", "); | ||
| 137 | } | ||
| 138 | printf("%s", plist_get_string_ptr(node, NULL)); | ||
| 139 | } | ||
| 131 | printf("\n"); | 140 | printf("\n"); |
| 132 | } | 141 | } |
| 133 | 142 | ||
| 134 | static void print_apps(plist_t apps) | 143 | static void print_apps(plist_t apps) |
| 135 | { | 144 | { |
| 145 | if (!return_attrs) { | ||
| 146 | return; | ||
| 147 | } | ||
| 136 | uint32_t i = 0; | 148 | uint32_t i = 0; |
| 137 | for (i = 0; i < plist_array_get_size(apps); i++) { | 149 | for (i = 0; i < plist_array_get_size(apps); i++) { |
| 138 | plist_t app = plist_array_get_item(apps, i); | 150 | plist_t app = plist_array_get_item(apps, i); |
| 139 | plist_t bundle_identifier = plist_dict_get_item(app, "CFBundleIdentifier"); | 151 | uint32_t j = 0; |
| 140 | plist_t display_name = plist_dict_get_item(app, "CFBundleDisplayName"); | 152 | for (j = 0; j < plist_array_get_size(return_attrs); j++) { |
| 141 | plist_t version = plist_dict_get_item(app, "CFBundleShortVersionString"); | 153 | plist_t node = plist_array_get_item(return_attrs, j); |
| 142 | 154 | if (j > 0) { | |
| 143 | /* output app details */ | 155 | printf(", "); |
| 144 | printf("%s", plist_get_string_ptr(bundle_identifier, NULL)); | 156 | } |
| 145 | printf(", \"%s\"", (version) ? plist_get_string_ptr(version, NULL) : ""); | 157 | const char* key = plist_get_string_ptr(node, NULL); |
| 146 | printf(", \"%s\"", (display_name) ? plist_get_string_ptr(display_name, NULL) : plist_get_string_ptr(bundle_identifier, NULL)); | 158 | node = plist_dict_get_item(app, key); |
| 159 | if (node) { | ||
| 160 | if (!strcmp(key, "CFBundleIdentifier")) { | ||
| 161 | printf("%s", plist_get_string_ptr(node, NULL)); | ||
| 162 | } else { | ||
| 163 | uint64_t uval = 0; | ||
| 164 | switch (plist_get_node_type(node)) { | ||
| 165 | case PLIST_STRING: | ||
| 166 | printf("\"%s\"", plist_get_string_ptr(node, NULL)); | ||
| 167 | break; | ||
| 168 | case PLIST_INT: | ||
| 169 | plist_get_uint_val(node, &uval); | ||
| 170 | printf("%llu", uval); | ||
| 171 | break; | ||
| 172 | case PLIST_BOOLEAN: | ||
| 173 | printf("%s", plist_bool_val_is_true(node) ? "true" : "false"); | ||
| 174 | break; | ||
| 175 | case PLIST_ARRAY: | ||
| 176 | printf("(array)"); | ||
| 177 | break; | ||
| 178 | case PLIST_DICT: | ||
| 179 | printf("(dict)"); | ||
| 180 | break; | ||
| 181 | default: | ||
| 182 | break; | ||
| 183 | } | ||
| 184 | } | ||
| 185 | } | ||
| 186 | } | ||
| 147 | printf("\n"); | 187 | printf("\n"); |
| 148 | } | 188 | } |
| 149 | } | 189 | } |
| @@ -375,7 +415,9 @@ static void print_usage(int argc, char **argv, int is_error) | |||
| 375 | "\n" | 415 | "\n" |
| 376 | "COMMANDS:\n" | 416 | "COMMANDS:\n" |
| 377 | " list List installed apps\n" | 417 | " list List installed apps\n" |
| 378 | " -b, --bundle-identifier Only query for given bundle identifier\n" | 418 | " -a, --attribute ATTR Specify attribute to return - see man page\n" |
| 419 | " (can be passed multiple times)\n" | ||
| 420 | " -b, --bundle-identifier BUNDLEID Only query given bundle identifier\n" | ||
| 379 | " (can be passed multiple times)\n" | 421 | " (can be passed multiple times)\n" |
| 380 | " -o list_user list user apps only (this is the default)\n" | 422 | " -o list_user list user apps only (this is the default)\n" |
| 381 | " -o list_system list system apps only\n" | 423 | " -o list_system list system apps only\n" |
| @@ -385,8 +427,9 @@ static void print_usage(int argc, char **argv, int is_error) | |||
| 385 | " PATH can also be a .ipcc file for carrier bundles.\n" | 427 | " PATH can also be a .ipcc file for carrier bundles.\n" |
| 386 | " uninstall BUNDLEID Uninstall app specified by BUNDLEID.\n" | 428 | " uninstall BUNDLEID Uninstall app specified by BUNDLEID.\n" |
| 387 | " upgrade PATH Upgrade app from package file specified by PATH.\n" | 429 | " upgrade PATH Upgrade app from package file specified by PATH.\n" |
| 430 | "\n" | ||
| 388 | "LEGACY COMMANDS (non-functional with iOS 7 or later):\n" | 431 | "LEGACY COMMANDS (non-functional with iOS 7 or later):\n" |
| 389 | " archive BUNDLEID Archive app specified by BUNDLEID, possible options:\n" | 432 | " archive BUNDLEID Archive app specified by BUNDLEID, possible options:\n" |
| 390 | " -o uninstall uninstall the package after making an archive\n" | 433 | " -o uninstall uninstall the package after making an archive\n" |
| 391 | " -o app_only archive application data only\n" | 434 | " -o app_only archive application data only\n" |
| 392 | " -o docs_only archive documents (user data) only\n" | 435 | " -o docs_only archive documents (user data) only\n" |
| @@ -401,7 +444,7 @@ static void print_usage(int argc, char **argv, int is_error) | |||
| 401 | " -u, --udid UDID Target specific device by UDID\n" | 444 | " -u, --udid UDID Target specific device by UDID\n" |
| 402 | " -n, --network Connect to network device\n" | 445 | " -n, --network Connect to network device\n" |
| 403 | " -w, --notify-wait Wait for app installed/uninstalled notification\n" | 446 | " -w, --notify-wait Wait for app installed/uninstalled notification\n" |
| 404 | " to before reporting success of operation\n" | 447 | " before reporting success of operation\n" |
| 405 | " -h, --help Print usage information\n" | 448 | " -h, --help Print usage information\n" |
| 406 | " -d, --debug Enable communication debugging\n" | 449 | " -d, --debug Enable communication debugging\n" |
| 407 | " -v, --version Print version information\n" | 450 | " -v, --version Print version information\n" |
| @@ -422,12 +465,13 @@ static void parse_opts(int argc, char **argv) | |||
| 422 | { "debug", no_argument, NULL, 'd' }, | 465 | { "debug", no_argument, NULL, 'd' }, |
| 423 | { "version", no_argument, NULL, 'v' }, | 466 | { "version", no_argument, NULL, 'v' }, |
| 424 | { "bundle-identifier", required_argument, NULL, 'b' }, | 467 | { "bundle-identifier", required_argument, NULL, 'b' }, |
| 468 | { "attribute", required_argument, NULL, 'a' }, | ||
| 425 | { NULL, 0, NULL, 0 } | 469 | { NULL, 0, NULL, 0 } |
| 426 | }; | 470 | }; |
| 427 | int c; | 471 | int c; |
| 428 | 472 | ||
| 429 | while (1) { | 473 | while (1) { |
| 430 | c = getopt_long(argc, argv, "hu:o:nwdvb:", longopts, (int*)0); | 474 | c = getopt_long(argc, argv, "hu:o:nwdvb:a:", longopts, (int*)0); |
| 431 | if (c == -1) { | 475 | if (c == -1) { |
| 432 | break; | 476 | break; |
| 433 | } | 477 | } |
| @@ -447,6 +491,20 @@ static void parse_opts(int argc, char **argv) | |||
| 447 | case 'n': | 491 | case 'n': |
| 448 | use_network = 1; | 492 | use_network = 1; |
| 449 | break; | 493 | break; |
| 494 | case 'a': | ||
| 495 | if (!*optarg) { | ||
| 496 | printf("ERROR: attribute must not be empty!\n"); | ||
| 497 | print_usage(argc, argv, 1); | ||
| 498 | exit(2); | ||
| 499 | } | ||
| 500 | if (return_attrs == NULL) { | ||
| 501 | return_attrs = plist_new_array(); | ||
| 502 | } | ||
| 503 | plist_array_append_item(return_attrs, plist_new_string(optarg)); | ||
| 504 | if (!strcmp(optarg, "CFBundleIdentifier")) { | ||
| 505 | return_attrs_have_CFBundleIdentifier = 1; | ||
| 506 | } | ||
| 507 | break; | ||
| 450 | case 'b': | 508 | case 'b': |
| 451 | if (!*optarg) { | 509 | if (!*optarg) { |
| 452 | printf("ERROR: bundle identifier must not be empty!\n"); | 510 | printf("ERROR: bundle identifier must not be empty!\n"); |
| @@ -765,16 +823,19 @@ run_again: | |||
| 765 | plist_dict_set_item(client_opts, "BundleIDs", plist_copy(bundle_ids)); | 823 | plist_dict_set_item(client_opts, "BundleIDs", plist_copy(bundle_ids)); |
| 766 | } | 824 | } |
| 767 | 825 | ||
| 768 | if (!xml_mode) { | 826 | if (!xml_mode && !return_attrs) { |
| 769 | instproxy_client_options_set_return_attributes(client_opts, | 827 | return_attrs = plist_new_array(); |
| 770 | "CFBundleIdentifier", | 828 | plist_array_append_item(return_attrs, plist_new_string("CFBundleIdentifier")); |
| 771 | "CFBundleDisplayName", | 829 | return_attrs_have_CFBundleIdentifier = 1; |
| 772 | "CFBundleShortVersionString", | 830 | plist_array_append_item(return_attrs, plist_new_string("CFBundleShortVersionString")); |
| 773 | "CFBundleVersion", | 831 | plist_array_append_item(return_attrs, plist_new_string("CFBundleDisplayName")); |
| 774 | "StaticDiskUsage", | 832 | } |
| 775 | "DynamicDiskUsage", | 833 | |
| 776 | NULL | 834 | if (return_attrs) { |
| 777 | ); | 835 | if (!return_attrs_have_CFBundleIdentifier) { |
| 836 | plist_array_insert_item(return_attrs, plist_new_string("CFBundleIdentifier"), 0); | ||
| 837 | } | ||
| 838 | instproxy_client_options_add(client_opts, "ReturnAttributes", return_attrs, NULL); | ||
| 778 | } | 839 | } |
| 779 | 840 | ||
| 780 | if (xml_mode) { | 841 | if (xml_mode) { |
| @@ -1489,6 +1550,7 @@ leave_cleanup: | |||
| 1489 | free(options); | 1550 | free(options); |
| 1490 | free(bundleidentifier); | 1551 | free(bundleidentifier); |
| 1491 | plist_free(bundle_ids); | 1552 | plist_free(bundle_ids); |
| 1553 | plist_free(return_attrs); | ||
| 1492 | 1554 | ||
| 1493 | if (err_occurred && !res) { | 1555 | if (err_occurred && !res) { |
| 1494 | res = 128; | 1556 | res = 128; |
