summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2023-03-25 05:54:57 +0100
committerGravatar Nikias Bassen2023-03-25 05:54:57 +0100
commit9525a2a76171e7da82f0e3fd602ad3c7101a30bf (patch)
tree76d427af17df2169a9c1d391258e0ff724489c24
parent14dced8ddab73ea51e42fe8da2180f259feae119 (diff)
downloadideviceinstaller-9525a2a76171e7da82f0e3fd602ad3c7101a30bf.tar.gz
ideviceinstaller-9525a2a76171e7da82f0e3fd602ad3c7101a30bf.tar.bz2
Add -a command line switch to specify return attributes for 'list' command
-rw-r--r--man/ideviceinstaller.119
-rw-r--r--src/ideviceinstaller.c114
2 files changed, 104 insertions, 29 deletions
diff --git a/man/ideviceinstaller.1 b/man/ideviceinstaller.1
index 2520ae0..dbaa0d5 100644
--- a/man/ideviceinstaller.1
+++ b/man/ideviceinstaller.1
@@ -15,8 +15,21 @@ Allows to enumerate, install, upgrade, and uninstall apps on iOS devices.
List installed apps on the device.
.RS
.TP
-\-b <bundleID>
-Only query for given bundle identifier (can be passed multiple times)
+\-a|\-\-attribute <attr>
+Specify attribute to return. This argument can be passed multiple times. If omitted and \f[B]-o xml\f[] is *not* specified, the default attributes \f[B]CFBundleIdentifier\f[], \f[B]CFBundleShortVersionString\f[], and \f[B]CFBundleDisplayName\f[] will be used. The attributes can be found in the app's Info.plist, but also some extra attributes exist. Some examples:
+.RS
+.TP
+\f[B]StaticDiskUsage\f[] disk usage of installed app
+.TP
+\f[B]DynamicDiskUsage\f[] app user data disk usage
+.TP
+\f[B]Path\f[] app installation location
+.TP
+\f[B]SignerIdentity\f[] code signing identity
+.RE
+.TP
+\-b|--bundle-identifier <bundleID>
+Only query given bundle identifier. This argument can be passed multiple times.
.TP
\-o list_user
list user apps only (apps installed by the user)
@@ -94,7 +107,7 @@ Target specific device by UDID.
Connect to network device.
.TP
.B \-w, \-\-notify-wait
-Wait for app installed/uninstalled notification to before reporting success of operation.
+Wait for app installed/uninstalled notification before reporting success of operation.
.TP
.B \-h, \-\-help
Print usage information.
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;
int err_occurred = 0;
int notified = 0;
plist_t bundle_ids = NULL;
+plist_t return_attrs = NULL;
+int return_attrs_have_CFBundleIdentifier = 0;
static void print_apps_header()
{
- /* output app details header */
- printf("%s", "CFBundleIdentifier");
- printf(", %s", "CFBundleShortVersionString");
- printf(", %s", "CFBundleDisplayName");
+ if (!return_attrs) {
+ return;
+ }
+ uint32_t i = 0;
+ for (i = 0; i < plist_array_get_size(return_attrs); i++) {
+ plist_t node = plist_array_get_item(return_attrs, i);
+ if (i > 0) {
+ printf(", ");
+ }
+ printf("%s", plist_get_string_ptr(node, NULL));
+ }
printf("\n");
}
static void print_apps(plist_t apps)
{
+ if (!return_attrs) {
+ return;
+ }
uint32_t i = 0;
for (i = 0; i < plist_array_get_size(apps); i++) {
plist_t app = plist_array_get_item(apps, i);
- plist_t bundle_identifier = plist_dict_get_item(app, "CFBundleIdentifier");
- plist_t display_name = plist_dict_get_item(app, "CFBundleDisplayName");
- plist_t version = plist_dict_get_item(app, "CFBundleShortVersionString");
-
- /* output app details */
- printf("%s", plist_get_string_ptr(bundle_identifier, NULL));
- printf(", \"%s\"", (version) ? plist_get_string_ptr(version, NULL) : "");
- printf(", \"%s\"", (display_name) ? plist_get_string_ptr(display_name, NULL) : plist_get_string_ptr(bundle_identifier, NULL));
+ uint32_t j = 0;
+ for (j = 0; j < plist_array_get_size(return_attrs); j++) {
+ plist_t node = plist_array_get_item(return_attrs, j);
+ if (j > 0) {
+ printf(", ");
+ }
+ const char* key = plist_get_string_ptr(node, NULL);
+ node = plist_dict_get_item(app, key);
+ if (node) {
+ if (!strcmp(key, "CFBundleIdentifier")) {
+ printf("%s", plist_get_string_ptr(node, NULL));
+ } else {
+ uint64_t uval = 0;
+ switch (plist_get_node_type(node)) {
+ case PLIST_STRING:
+ printf("\"%s\"", plist_get_string_ptr(node, NULL));
+ break;
+ case PLIST_INT:
+ plist_get_uint_val(node, &uval);
+ printf("%llu", uval);
+ break;
+ case PLIST_BOOLEAN:
+ printf("%s", plist_bool_val_is_true(node) ? "true" : "false");
+ break;
+ case PLIST_ARRAY:
+ printf("(array)");
+ break;
+ case PLIST_DICT:
+ printf("(dict)");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
printf("\n");
}
}
@@ -375,7 +415,9 @@ static void print_usage(int argc, char **argv, int is_error)
"\n"
"COMMANDS:\n"
" list List installed apps\n"
- " -b, --bundle-identifier Only query for given bundle identifier\n"
+ " -a, --attribute ATTR Specify attribute to return - see man page\n"
+ " (can be passed multiple times)\n"
+ " -b, --bundle-identifier BUNDLEID Only query given bundle identifier\n"
" (can be passed multiple times)\n"
" -o list_user list user apps only (this is the default)\n"
" -o list_system list system apps only\n"
@@ -385,8 +427,9 @@ static void print_usage(int argc, char **argv, int is_error)
" PATH can also be a .ipcc file for carrier bundles.\n"
" uninstall BUNDLEID Uninstall app specified by BUNDLEID.\n"
" upgrade PATH Upgrade app from package file specified by PATH.\n"
+ "\n"
"LEGACY COMMANDS (non-functional with iOS 7 or later):\n"
- " archive BUNDLEID Archive app specified by BUNDLEID, possible options:\n"
+ " archive BUNDLEID Archive app specified by BUNDLEID, possible options:\n"
" -o uninstall uninstall the package after making an archive\n"
" -o app_only archive application data only\n"
" -o docs_only archive documents (user data) only\n"
@@ -401,7 +444,7 @@ static void print_usage(int argc, char **argv, int is_error)
" -u, --udid UDID Target specific device by UDID\n"
" -n, --network Connect to network device\n"
" -w, --notify-wait Wait for app installed/uninstalled notification\n"
- " to before reporting success of operation\n"
+ " before reporting success of operation\n"
" -h, --help Print usage information\n"
" -d, --debug Enable communication debugging\n"
" -v, --version Print version information\n"
@@ -422,12 +465,13 @@ static void parse_opts(int argc, char **argv)
{ "debug", no_argument, NULL, 'd' },
{ "version", no_argument, NULL, 'v' },
{ "bundle-identifier", required_argument, NULL, 'b' },
+ { "attribute", required_argument, NULL, 'a' },
{ NULL, 0, NULL, 0 }
};
int c;
while (1) {
- c = getopt_long(argc, argv, "hu:o:nwdvb:", longopts, (int*)0);
+ c = getopt_long(argc, argv, "hu:o:nwdvb:a:", longopts, (int*)0);
if (c == -1) {
break;
}
@@ -447,6 +491,20 @@ static void parse_opts(int argc, char **argv)
case 'n':
use_network = 1;
break;
+ case 'a':
+ if (!*optarg) {
+ printf("ERROR: attribute must not be empty!\n");
+ print_usage(argc, argv, 1);
+ exit(2);
+ }
+ if (return_attrs == NULL) {
+ return_attrs = plist_new_array();
+ }
+ plist_array_append_item(return_attrs, plist_new_string(optarg));
+ if (!strcmp(optarg, "CFBundleIdentifier")) {
+ return_attrs_have_CFBundleIdentifier = 1;
+ }
+ break;
case 'b':
if (!*optarg) {
printf("ERROR: bundle identifier must not be empty!\n");
@@ -765,16 +823,19 @@ run_again:
plist_dict_set_item(client_opts, "BundleIDs", plist_copy(bundle_ids));
}
- if (!xml_mode) {
- instproxy_client_options_set_return_attributes(client_opts,
- "CFBundleIdentifier",
- "CFBundleDisplayName",
- "CFBundleShortVersionString",
- "CFBundleVersion",
- "StaticDiskUsage",
- "DynamicDiskUsage",
- NULL
- );
+ if (!xml_mode && !return_attrs) {
+ return_attrs = plist_new_array();
+ plist_array_append_item(return_attrs, plist_new_string("CFBundleIdentifier"));
+ return_attrs_have_CFBundleIdentifier = 1;
+ plist_array_append_item(return_attrs, plist_new_string("CFBundleShortVersionString"));
+ plist_array_append_item(return_attrs, plist_new_string("CFBundleDisplayName"));
+ }
+
+ if (return_attrs) {
+ if (!return_attrs_have_CFBundleIdentifier) {
+ plist_array_insert_item(return_attrs, plist_new_string("CFBundleIdentifier"), 0);
+ }
+ instproxy_client_options_add(client_opts, "ReturnAttributes", return_attrs, NULL);
}
if (xml_mode) {
@@ -1489,6 +1550,7 @@ leave_cleanup:
free(options);
free(bundleidentifier);
plist_free(bundle_ids);
+ plist_free(return_attrs);
if (err_occurred && !res) {
res = 128;