diff options
Diffstat (limited to 'tools/idevicebackup.c')
-rw-r--r-- | tools/idevicebackup.c | 385 |
1 files changed, 208 insertions, 177 deletions
diff --git a/tools/idevicebackup.c b/tools/idevicebackup.c index cd69bcc..5694c12 100644 --- a/tools/idevicebackup.c +++ b/tools/idevicebackup.c @@ -24,15 +24,31 @@ #include <config.h> #endif +#define TOOL_NAME "idevicebackup" + #include <stdio.h> #include <string.h> #include <errno.h> #include <stdlib.h> #include <signal.h> -#ifdef HAVE_OPENSSL +#include <getopt.h> +#if defined(HAVE_OPENSSL) #include <openssl/sha.h> -#else +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include <openssl/evp.h> +#endif +#elif defined(HAVE_GNUTLS) #include <gcrypt.h> +#elif defined(HAVE_MBEDTLS) +#include <mbedtls/sha1.h> +#if MBEDTLS_VERSION_NUMBER < 0x03000000 +#define mbedtls_sha1 mbedtls_sha1_ret +#define mbedtls_sha1_starts mbedtls_sha1_starts_ret +#define mbedtls_sha1_update mbedtls_sha1_update_ret +#define mbedtls_sha1_finish mbedtls_sha1_finish_ret +#endif +#else +#error No supported crypto library enabled #endif #include <unistd.h> #include <ctype.h> @@ -43,7 +59,8 @@ #include <libimobiledevice/mobilebackup.h> #include <libimobiledevice/notification_proxy.h> #include <libimobiledevice/afc.h> -#include "common/utils.h" +#include <libimobiledevice-glue/utils.h> +#include <plist/plist.h> #define MOBILEBACKUP_SERVICE_NAME "com.apple.mobilebackup" #define NP_SERVICE_NAME "com.apple.mobile.notification_proxy" @@ -76,10 +93,12 @@ enum device_link_file_status_t { static void sha1_of_data(const char *input, uint32_t size, unsigned char *hash_out) { -#ifdef HAVE_OPENSSL +#if defined(HAVE_OPENSSL) SHA1((const unsigned char*)input, size, hash_out); -#else +#elif defined(HAVE_GNUTLS) gcry_md_hash_buffer(GCRY_MD_SHA1, hash_out, input, size); +#elif defined(HAVE_MBEDTLS) + mbedtls_sha1((unsigned char*)input, size, hash_out); #endif } @@ -94,12 +113,34 @@ static int compare_hash(const unsigned char *hash1, const unsigned char *hash2, return 1; } +static void _sha1_update(void* context, const char* data, size_t len) +{ +#if defined(HAVE_OPENSSL) +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_DigestUpdate(context, data, len); +#else + SHA1_Update(context, data, len); +#endif +#elif defined(HAVE_GNUTLS) + gcry_md_write(context, data, len); +#elif defined(HAVE_MBEDTLS) + mbedtls_sha1_update(context, (const unsigned char*)data, len); +#endif +} + static void compute_datahash(const char *path, const char *destpath, uint8_t greylist, const char *domain, const char *appid, const char *version, unsigned char *hash_out) { -#ifdef HAVE_OPENSSL +#if defined(HAVE_OPENSSL) +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_MD_CTX* sha1 = EVP_MD_CTX_new(); + EVP_DigestInit(sha1, EVP_sha1()); + void* psha1 = sha1; +#else SHA_CTX sha1; SHA1_Init(&sha1); -#else + void* psha1 = &sha1; +#endif +#elif defined(HAVE_GNUTLS) gcry_md_hd_t hd = NULL; gcry_md_open(&hd, GCRY_MD_SHA1, 0); if (!hd) { @@ -107,102 +148,68 @@ static void compute_datahash(const char *path, const char *destpath, uint8_t gre return; } gcry_md_reset(hd); + void* psha1 = hd; +#elif defined(HAVE_MBEDTLS) + mbedtls_sha1_context sha1; + mbedtls_sha1_init(&sha1); + mbedtls_sha1_starts(&sha1); + void* psha1 = &sha1; #endif FILE *f = fopen(path, "rb"); if (f) { unsigned char buf[16384]; size_t len; while ((len = fread(buf, 1, 16384, f)) > 0) { -#ifdef HAVE_OPENSSL - SHA1_Update(&sha1, buf, len); -#else - gcry_md_write(hd, buf, len); -#endif + _sha1_update(psha1, (const char*)buf, len); } fclose(f); -#ifdef HAVE_OPENSSL - SHA1_Update(&sha1, destpath, strlen(destpath)); - SHA1_Update(&sha1, ";", 1); -#else - gcry_md_write(hd, destpath, strlen(destpath)); - gcry_md_write(hd, ";", 1); -#endif + _sha1_update(psha1, destpath, strlen(destpath)); + _sha1_update(psha1, ";", 1); + if (greylist == 1) { -#ifdef HAVE_OPENSSL - SHA1_Update(&sha1, "true", 4); -#else - gcry_md_write(hd, "true", 4); -#endif + _sha1_update(psha1, "true", 4); } else { -#ifdef HAVE_OPENSSL - SHA1_Update(&sha1, "false", 5); -#else - gcry_md_write(hd, "false", 5); -#endif + _sha1_update(psha1, "false", 5); } -#ifdef HAVE_OPENSSL - SHA1_Update(&sha1, ";", 1); -#else - gcry_md_write(hd, ";", 1); -#endif + _sha1_update(psha1, ";", 1); + if (domain) { -#ifdef HAVE_OPENSSL - SHA1_Update(&sha1, domain, strlen(domain)); -#else - gcry_md_write(hd, domain, strlen(domain)); -#endif + _sha1_update(psha1, domain, strlen(domain)); } else { -#ifdef HAVE_OPENSSL - SHA1_Update(&sha1, "(null)", 6); -#else - gcry_md_write(hd, "(null)", 6); -#endif + _sha1_update(psha1, "(null)", 6); } -#ifdef HAVE_OPENSSL - SHA1_Update(&sha1, ";", 1); -#else - gcry_md_write(hd, ";", 1); -#endif + _sha1_update(psha1, ";", 1); + if (appid) { -#ifdef HAVE_OPENSSL - SHA1_Update(&sha1, appid, strlen(appid)); -#else - gcry_md_write(hd, appid, strlen(appid)); -#endif + _sha1_update(psha1, appid, strlen(appid)); } else { -#ifdef HAVE_OPENSSL - SHA1_Update(&sha1, "(null)", 6); -#else - gcry_md_write(hd, "(null)", 6); -#endif + _sha1_update(psha1, "(null)", 6); } -#ifdef HAVE_OPENSSL - SHA1_Update(&sha1, ";", 1); -#else - gcry_md_write(hd, ";", 1); -#endif + _sha1_update(psha1, ";", 1); + if (version) { -#ifdef HAVE_OPENSSL - SHA1_Update(&sha1, version, strlen(version)); -#else - gcry_md_write(hd, version, strlen(version)); -#endif + _sha1_update(psha1, version, strlen(version)); } else { -#ifdef HAVE_OPENSSL - SHA1_Update(&sha1, "(null)", 6); -#else - gcry_md_write(hd, "(null)", 6); -#endif + _sha1_update(psha1, "(null)", 6); } -#ifdef HAVE_OPENSSL - SHA1_Final(hash_out, &sha1); +#if defined(HAVE_OPENSSL) +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_DigestFinal(sha1, hash_out, NULL); + EVP_MD_CTX_destroy(sha1); #else + SHA1_Final(hash_out, &sha1); +#endif +#elif defined(HAVE_GNUTLS) unsigned char *newhash = gcry_md_read(hd, GCRY_MD_SHA1); memcpy(hash_out, newhash, 20); +#elif defined(HAVE_MBEDTLS) + mbedtls_sha1_finish(&sha1, hash_out); #endif } -#ifndef HAVE_OPENSSL +#if defined(HAVE_GNUTLS) gcry_md_close(hd); +#elif defined(HAVE_MBEDTLS) + mbedtls_sha1_free(&sha1); #endif } @@ -329,7 +336,7 @@ static void mobilebackup_write_status(const char *path, int status) if (stat(file_path, &st) == 0) remove(file_path); - plist_write_to_filename(status_plist, file_path, PLIST_FORMAT_XML); + plist_write_to_file(status_plist, file_path, PLIST_FORMAT_XML, 0); plist_free(status_plist); status_plist = NULL; @@ -343,7 +350,7 @@ static int mobilebackup_read_status(const char *path) plist_t status_plist = NULL; char *file_path = mobilebackup_build_path(path, "Status", ".plist"); - plist_read_from_filename(&status_plist, file_path); + plist_read_from_file(file_path, &status_plist, NULL); free(file_path); if (!status_plist) { printf("Could not read Status.plist!\n"); @@ -466,7 +473,7 @@ static int mobilebackup_check_file_integrity(const char *backup_directory, const } infopath = mobilebackup_build_path(backup_directory, hash, ".mdinfo"); - plist_read_from_filename(&mdinfo, infopath); + plist_read_from_file(infopath, &mdinfo, NULL); free(infopath); if (!mdinfo) { printf("\r\n"); @@ -546,7 +553,7 @@ static int mobilebackup_check_file_integrity(const char *backup_directory, const for ( i = 0; i < 20; i++, p += 2 ) { snprintf (p, 3, "%02x", (unsigned char)fnhash[i] ); } - if (strcmp(fnamehash, hash)) { + if (strcmp(fnamehash, hash) != 0) { printf("\r\n"); printf("WARNING: filename hash does not match for entry '%s'\n", hash); } @@ -557,7 +564,7 @@ static int mobilebackup_check_file_integrity(const char *backup_directory, const plist_get_string_val(node, &auth_version); } - if (strcmp(auth_version, "1.0")) { + if (strcmp(auth_version, "1.0") != 0) { printf("\r\n"); printf("WARNING: Unknown AuthVersion '%s', DataHash cannot be verified!\n", auth_version); } @@ -606,20 +613,20 @@ static void do_post_notification(const char *notification) np_client_t np; if (!client) { - if (lockdownd_client_new_with_handshake(device, &client, "idevicebackup") != LOCKDOWN_E_SUCCESS) { + if (lockdownd_client_new_with_handshake(device, &client, TOOL_NAME) != LOCKDOWN_E_SUCCESS) { return; } } - lockdownd_start_service(client, NP_SERVICE_NAME, &service); - if (service && service->port) { + lockdownd_error_t ldret = lockdownd_start_service(client, NP_SERVICE_NAME, &service); + if (ldret == LOCKDOWN_E_SUCCESS) { np_client_new(device, service, &np); if (np) { np_post_notification(np, notification); np_client_free(np); } } else { - printf("Could not start %s\n", NP_SERVICE_NAME); + printf("Could not start %s: %s\n", NP_SERVICE_NAME, lockdownd_strerror(ldret)); } if (service) { @@ -660,21 +667,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("Create or restore backup from the current or specified directory.\n\n"); - printf("commands:\n"); - printf(" backup\tSaves a device backup into DIRECTORY\n"); - printf(" restore\tRestores a device backup from DIRECTORY.\n\n"); - printf("options:\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -u, --udid UDID\ttarget specific device by UDID\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf("\n"); - printf("Homepage: <" PACKAGE_URL ">\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[]) @@ -683,6 +697,7 @@ int main(int argc, char *argv[]) lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR; int i; char* udid = NULL; + int use_network = 0; lockdownd_service_descriptor_t service = NULL; int cmd = -1; int is_full_backup = 0; @@ -697,7 +712,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); @@ -708,52 +731,59 @@ 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], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); + udid = strdup(optarg); + break; + case 'n': + use_network = 1; + break; + case 'h': + print_usage(argc, argv, 0); 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); + case 'v': + printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); 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) { printf("ERROR: Backup directory \"%s\" does not exist!\n", backup_directory); @@ -772,25 +802,24 @@ int main(int argc, char *argv[]) printf("Backup directory is \"%s\"\n", backup_directory); - if (udid) { - ret = idevice_new(&device, udid); - if (ret != IDEVICE_E_SUCCESS) { - printf("No device found with udid %s, is it plugged in?\n", udid); - return -1; + ret = idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX); + if (ret != IDEVICE_E_SUCCESS) { + if (udid) { + printf("No device found with udid %s.\n", udid); + } else { + printf("No device found.\n"); } + return -1; } - else - { - ret = idevice_new(&device, NULL); - if (ret != IDEVICE_E_SUCCESS) { - printf("No device found, is it plugged in?\n"); - return -1; - } + + if (!udid) { + idevice_get_udid(device, &udid); } - if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new_with_handshake(device, &client, "idevicebackup"))) { + 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; } @@ -810,6 +839,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; } } @@ -830,7 +860,7 @@ int main(int argc, char *argv[]) }; np_observe_notifications(np, noties); } else { - printf("ERROR: Could not start service %s.\n", NP_SERVICE_NAME); + printf("ERROR: Could not start service %s: %s\n", NP_SERVICE_NAME, lockdownd_strerror(ldret)); } afc_client_t afc = NULL; @@ -838,9 +868,11 @@ int main(int argc, char *argv[]) /* start AFC, we need this for the lock file */ service->port = 0; service->ssl_enabled = 0; - ldret = lockdownd_start_service(client, "com.apple.afc", &service); + ldret = lockdownd_start_service(client, AFC_SERVICE_NAME, &service); if ((ldret == LOCKDOWN_E_SUCCESS) && service->port) { afc_client_new(device, service, &afc); + } else { + printf("ERROR: Could not start service %s: %s\n", AFC_SERVICE_NAME, lockdownd_strerror(ldret)); } } @@ -853,7 +885,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); @@ -869,7 +901,7 @@ int main(int argc, char *argv[]) /* verify existing Info.plist */ if (stat(info_path, &st) == 0) { printf("Reading Info.plist from backup.\n"); - plist_read_from_filename(&info_plist, info_path); + plist_read_from_file(info_path, &info_plist, NULL); if (!info_plist) { printf("Could not read Info.plist\n"); @@ -880,7 +912,7 @@ int main(int argc, char *argv[]) /* update the last backup time within Info.plist */ mobilebackup_info_update_last_backup_date(info_plist); remove(info_path); - plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML); + plist_write_to_file(info_plist, info_path, PLIST_FORMAT_XML, 0); } else { printf("Aborting backup. Backup is not compatible with the current device.\n"); cmd = CMD_LEAVE; @@ -913,15 +945,16 @@ int main(int argc, char *argv[]) if (aerr == AFC_E_SUCCESS) { do_post_notification(NP_SYNC_DID_START); break; - } else if (aerr == AFC_E_OP_WOULD_BLOCK) { + } + if (aerr == AFC_E_OP_WOULD_BLOCK) { usleep(LOCK_WAIT); continue; - } else { - fprintf(stderr, "ERROR: could not lock file! error code: %d\n", aerr); - afc_file_close(afc, lockfile); - lockfile = 0; - cmd = CMD_LEAVE; } + + fprintf(stderr, "ERROR: could not lock file! error code: %d\n", aerr); + afc_file_close(afc, lockfile); + lockfile = 0; + cmd = CMD_LEAVE; } if (i == LOCK_ATTEMPTS) { fprintf(stderr, "ERROR: timeout while locking for sync\n"); @@ -945,7 +978,7 @@ int main(int argc, char *argv[]) /* read the last Manifest.plist */ if (!is_full_backup) { printf("Reading existing Manifest.\n"); - plist_read_from_filename(&manifest_plist, manifest_path); + plist_read_from_file(manifest_path, &manifest_plist, NULL); if (!manifest_plist) { printf("Could not read Manifest.plist, switching to full backup mode.\n"); is_full_backup = 1; @@ -963,7 +996,7 @@ int main(int argc, char *argv[]) remove(info_path); printf("Creating Info.plist for new backup.\n"); info_plist = mobilebackup_factory_info_plist_new(udid); - plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML); + plist_write_to_file(info_plist, info_path, PLIST_FORMAT_XML, 0); } free(info_path); @@ -995,7 +1028,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 occured\n"); + printf("ERROR: Could not start backup process: unspecified error occurred (%d)\n", err); } break; } @@ -1017,6 +1050,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 { @@ -1048,8 +1082,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"); @@ -1101,7 +1135,7 @@ int main(int argc, char *argv[]) remove(filename_mdinfo); node = plist_dict_get_item(node_tmp, "BackupFileInfo"); - plist_write_to_filename(node, filename_mdinfo, PLIST_FORMAT_BINARY); + plist_write_to_file(node, filename_mdinfo, PLIST_FORMAT_BINARY, 0); free(filename_mdinfo); } @@ -1143,9 +1177,8 @@ int main(int argc, char *argv[]) if ((!is_manifest)) { if (hunk_index == 0 && file_status == DEVICE_LINK_FILE_STATUS_LAST_HUNK) { print_progress(100); - } else { - if (file_size > 0) - print_progress((double)((file_size_current*100)/file_size)); + } else if (file_size > 0) { + print_progress((double)(file_size_current*100)/file_size); } } @@ -1214,7 +1247,7 @@ files_out: if (manifest_plist) { remove(manifest_path); printf("Storing Manifest.plist...\n"); - plist_write_to_filename(manifest_plist, manifest_path, PLIST_FORMAT_XML); + plist_write_to_file(manifest_plist, manifest_path, PLIST_FORMAT_XML, 0); } backup_ok = 1; @@ -1245,7 +1278,7 @@ files_out: } /* now make sure backup integrity is ok! verify all files */ printf("Reading existing Manifest.\n"); - plist_read_from_filename(&manifest_plist, manifest_path); + plist_read_from_file(manifest_path, &manifest_plist, NULL); if (!manifest_plist) { printf("Could not read Manifest.plist. Aborting.\n"); break; @@ -1342,7 +1375,7 @@ files_out: } else if (err == MOBILEBACKUP_E_REPLY_NOT_OK) { printf("ERROR: Could not start restore process: device refused to start the restore process.\n"); } else { - printf("ERROR: Could not start restore process: unspecified error occured (%d)\n", err); + printf("ERROR: Could not start restore process: unspecified error occurred (%d)\n", err); } plist_free(backup_data); break; @@ -1372,7 +1405,7 @@ files_out: while (node) { /* TODO: read mddata/mdinfo files and send to device using DLSendFile */ file_info_path = mobilebackup_build_path(backup_directory, hash, ".mdinfo"); - plist_read_from_filename(&file_info, file_info_path); + plist_read_from_file(file_info_path, &file_info, NULL); /* get encryption state */ tmp_node = plist_dict_get_item(file_info, "IsEncrypted"); @@ -1592,7 +1625,7 @@ files_out: if (manifest_path) free(manifest_path); } else { - printf("ERROR: Could not start service %s.\n", MOBILEBACKUP_SERVICE_NAME); + printf("ERROR: Could not start service %s: %s\n", MOBILEBACKUP_SERVICE_NAME, lockdownd_strerror(ldret)); lockdownd_client_free(client); client = NULL; } @@ -1613,9 +1646,7 @@ files_out: idevice_free(device); - if (udid) { - free(udid); - } + free(udid); return 0; } |