From 744e014d5240b8621b8b8a2aec954641e18d3ac7 Mon Sep 17 00:00:00 2001
From: Martin Szulecki
Date: Fri, 27 Sep 2013 17:39:21 +0200
Subject: idevicebackup2: Cloud support broke other commands thus change it be
 a command

The experimental cloud support was triggered on each run of any command
which caused some to break on devices without iCloud setup.
We now trigger the cloud support in a separate command to fix this and allow
further investigation into a proper implementation.
---
 tools/idevicebackup2.c | 75 ++++++++++++++++++++++++++++++++++----------------
 1 file changed, 51 insertions(+), 24 deletions(-)

diff --git a/tools/idevicebackup2.c b/tools/idevicebackup2.c
index eebbd87..353d5f3 100644
--- a/tools/idevicebackup2.c
+++ b/tools/idevicebackup2.c
@@ -71,7 +71,8 @@ enum cmd_mode {
 	CMD_LIST,
 	CMD_UNBACK,
 	CMD_CHANGEPW,
-	CMD_LEAVE
+	CMD_LEAVE,
+	CMD_CLOUD
 };
 
 enum plist_format_t {
@@ -89,7 +90,8 @@ enum cmd_flags {
 	CMD_FLAG_ENCRYPTION_DISABLE         = (1 << 7),
 	CMD_FLAG_ENCRYPTION_CHANGEPW        = (1 << 8),
 	CMD_FLAG_FORCE_FULL_BACKUP          = (1 << 9),
-	CMD_FLAG_ENABLE_CLOUD_BACKUP        = (1 << 10)
+	CMD_FLAG_CLOUD_ENABLE               = (1 << 10),
+	CMD_FLAG_CLOUD_DISABLE              = (1 << 11)
 };
 
 static int backup_domain_changed = 0;
@@ -1278,13 +1280,13 @@ static void print_usage(int argc, char **argv)
 	printf("    NOTE: password will be requested in interactive mode if omitted\n");
 	printf("  changepw [OLD NEW]  change backup password on target device\n");
 	printf("    NOTE: passwords will be requested in interactive mode if omitted\n");
+	printf("  cloud on|off\tenable or disable cloud use (requires iCloud account)\n");
 	printf("\n");
 	printf("options:\n");
 	printf("  -d, --debug\t\tenable communication debugging\n");
 	printf("  -u, --udid UDID\ttarget specific device by its 40-digit device UDID\n");
 	printf("  -s, --source UDID\tuse backup data from device specified by UDID\n");
 	printf("  -i, --interactive\trequest passwords interactively\n");
-	printf("  -c, --cloud\t\tUse cloud storage using iCloud account of device\n");
 	printf("  -h, --help\t\tprints usage information\n");
 	printf("\n");
 }
@@ -1382,8 +1384,22 @@ int main(int argc, char *argv[])
 			backup_password = strdup(argv[i]);
 			continue;
 		}
-		else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--cloud")) {
-			cmd_flags |= CMD_FLAG_ENABLE_CLOUD_BACKUP;
+		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")) {
 			cmd_flags |= CMD_FLAG_FORCE_FULL_BACKUP;
@@ -1474,7 +1490,7 @@ int main(int argc, char *argv[])
 		return -1;
 	}
 
-	if (cmd == CMD_CHANGEPW) {
+	if (cmd == CMD_CHANGEPW || cmd == CMD_CLOUD) {
 		backup_directory = strdup(".this_folder_is_not_present_on_purpose");
 	} else {
 		if (backup_directory == NULL) {
@@ -1519,7 +1535,7 @@ int main(int argc, char *argv[])
 			printf("ERROR: Can't get password input in non-interactive mode. Either pass password(s) on the command line, or enable interactive mode with -i or --interactive.\n");
 			return -1;
 		}
-	} else {
+	} else if (cmd != CMD_CLOUD) {
 		/* backup directory must contain an Info.plist */
 		info_path = build_path(backup_directory, source_udid, "Info.plist", NULL);
 		if (cmd == CMD_RESTORE) {
@@ -1550,7 +1566,7 @@ int main(int argc, char *argv[])
 		PRINT_VERBOSE(1, "Backup directory is \"%s\"\n", backup_directory);
 	}
 
-	if (is_encrypted) {
+	if (cmd != CMD_CLOUD && is_encrypted) {
 		PRINT_VERBOSE(1, "This is an encrypted backup.\n");
 		if (backup_password == NULL) {
 			if (interactive_mode) {
@@ -1639,7 +1655,7 @@ int main(int argc, char *argv[])
 		}
 
 		/* verify existing Info.plist */
-		if (info_path && (stat(info_path, &st) == 0)) {
+		if (info_path && (stat(info_path, &st) == 0) && cmd != CMD_CLOUD) {
 			PRINT_VERBOSE(1, "Reading Info.plist from backup.\n");
 			plist_read_from_filename(&info_plist, info_path);
 
@@ -1656,21 +1672,6 @@ int main(int argc, char *argv[])
 			}
 		}
 
-		opts = plist_new_dict();
-		if (cmd_flags & CMD_FLAG_ENABLE_CLOUD_BACKUP) {
-			PRINT_VERBOSE(1, "Enabling cloud backup for device...\n");
-		} else {
-			PRINT_VERBOSE(1, "Disabling cloud backup for device...\n");
-		}
-		plist_dict_insert_item(opts, "CloudBackupState", plist_new_bool(cmd & CMD_FLAG_ENABLE_CLOUD_BACKUP ? 1: 0));
-		err = mobilebackup2_send_request(mobilebackup2, "EnableCloudBackup", udid, source_udid, opts);
-		plist_free(opts);
-		opts = NULL;
-		if (err != MOBILEBACKUP2_E_SUCCESS) {
-			printf("Error setting cloud backup state on device, error code %d\n", err);
-			cmd = CMD_LEAVE;
-		}
-
 		uint64_t lockfile = 0;
 		if (cmd == CMD_BACKUP) {
 			do_post_notification(device, NP_SYNC_WILL_START);
@@ -1715,6 +1716,17 @@ int main(int argc, char *argv[])
 checkpoint:
 
 		switch(cmd) {
+			case CMD_CLOUD:
+			opts = plist_new_dict();
+			plist_dict_insert_item(opts, "CloudBackupState", plist_new_bool(cmd_flags & CMD_FLAG_CLOUD_ENABLE ? 1: 0));
+			err = mobilebackup2_send_request(mobilebackup2, "EnableCloudBackup", udid, source_udid, opts);
+			plist_free(opts);
+			opts = NULL;
+			if (err != MOBILEBACKUP2_E_SUCCESS) {
+				printf("Error setting cloud backup state on device, error code %d\n", err);
+				cmd = CMD_LEAVE;
+			}
+			break;
 			case CMD_BACKUP:
 			PRINT_VERBOSE(1, "Starting backup...\n");
 
@@ -2214,6 +2226,21 @@ files_out:
 
 			/* report operation status to user */
 			switch (cmd) {
+				case CMD_CLOUD:
+				if (cmd_flags & CMD_FLAG_CLOUD_ENABLE) {
+					if (operation_ok) {
+						PRINT_VERBOSE(1, "Cloud backup has been enabled successfully.\n");
+					} else {
+						PRINT_VERBOSE(1, "Could not enable cloud backup.\n");
+					}
+				} else if (cmd_flags & CMD_FLAG_CLOUD_DISABLE) {
+					if (operation_ok) {
+						PRINT_VERBOSE(1, "Cloud backup has been disabled successfully.\n");
+					} else {
+						PRINT_VERBOSE(1, "Could not disable cloud backup.\n");
+					}
+				}
+				break;
 				case CMD_BACKUP:
 					PRINT_VERBOSE(1, "Received %d files from device.\n", file_count);
 					if (operation_ok && mb2_status_check_snapshot_state(backup_directory, udid, "finished")) {
-- 
cgit v1.1-32-gdbae