diff options
| author | 2010-01-25 01:31:10 +0100 | |
|---|---|---|
| committer | 2010-01-25 01:31:10 +0100 | |
| commit | 9f1677222b06f41c4ab309918511f3c3918a822e (patch) | |
| tree | b135afcee0eaa8c36e643b6383f915509b013882 | |
| parent | 8f133b0e0e89f4a44b80a442f70ef28cc7efa3df (diff) | |
| download | libimobiledevice-9f1677222b06f41c4ab309918511f3c3918a822e.tar.gz libimobiledevice-9f1677222b06f41c4ab309918511f3c3918a822e.tar.bz2 | |
Implement storing received files as backup including new Manifest
| -rw-r--r-- | tools/iphonebackup.c | 315 |
1 files changed, 157 insertions, 158 deletions
diff --git a/tools/iphonebackup.c b/tools/iphonebackup.c index 611c0f2..1ad4116 100644 --- a/tools/iphonebackup.c +++ b/tools/iphonebackup.c | |||
| @@ -40,7 +40,8 @@ static int quit_flag = 0; | |||
| 40 | 40 | ||
| 41 | enum cmd_mode { | 41 | enum cmd_mode { |
| 42 | CMD_BACKUP, | 42 | CMD_BACKUP, |
| 43 | CMD_RESTORE | 43 | CMD_RESTORE, |
| 44 | CMD_LEAVE | ||
| 44 | }; | 45 | }; |
| 45 | 46 | ||
| 46 | static plist_t mobilebackup_factory_info_plist() | 47 | static plist_t mobilebackup_factory_info_plist() |
| @@ -102,150 +103,24 @@ static plist_t mobilebackup_factory_info_plist() | |||
| 102 | return ret; | 103 | return ret; |
| 103 | } | 104 | } |
| 104 | 105 | ||
| 105 | static plist_t mobilebackup_factory_metadata_plist() | ||
| 106 | { | ||
| 107 | plist_t ret = NULL; | ||
| 108 | /* | ||
| 109 | Metadata key is: | ||
| 110 | <dict> | ||
| 111 | <key>Path</key> | ||
| 112 | <string>Library/SMS/sms.db</string> | ||
| 113 | <key>Version</key> | ||
| 114 | <string>3.0</string> | ||
| 115 | <key>Greylist</key> | ||
| 116 | <false/> | ||
| 117 | <key>Domain</key> | ||
| 118 | <string>HomeDomain</string> | ||
| 119 | </dict> | ||
| 120 | */ | ||
| 121 | /* | ||
| 122 | <dict> | ||
| 123 | <key>Metadata</key> | ||
| 124 | <data><!-- binary plist --> | ||
| 125 | YnBsaXN0MDDUAQIDBAUGBwhUUGF0aFdWZXJzaW9uWEdyZXlsaXN0VkRvbWFp | ||
| 126 | bl8QEkxpYnJhcnkvU01TL3Ntcy5kYlMzLjAIWkhvbWVEb21haW4IERYeJy5D | ||
| 127 | R0gAAAAAAAABAQAAAAAAAAAJAAAAAAAAAAAAAAAAAAAAUw== | ||
| 128 | </data> | ||
| 129 | <key>StorageVersion</key> | ||
| 130 | <string>1.0</string> | ||
| 131 | <key>Version</key> | ||
| 132 | <string>3.0</string> | ||
| 133 | <key>AuthVersion</key> | ||
| 134 | <string>1.0</string> | ||
| 135 | <key>IsEncrypted</key> | ||
| 136 | <false/> | ||
| 137 | </dict> | ||
| 138 | */ | ||
| 139 | return ret; | ||
| 140 | } | ||
| 141 | |||
| 142 | /** | ||
| 143 | * Generates a manifest data plist with all files and corresponding hashes | ||
| 144 | */ | ||
| 145 | static plist_t mobilebackup_factory_manifest_data_plist() | ||
| 146 | { | ||
| 147 | plist_t ret = NULL; | ||
| 148 | plist_t value_node = NULL; | ||
| 149 | char *uuid = NULL; | ||
| 150 | GTimeVal tv = {0, 0}; | ||
| 151 | |||
| 152 | ret = plist_new_dict(); | ||
| 153 | |||
| 154 | /* get basic device information in one go */ | ||
| 155 | lockdownd_get_value(client, NULL, "IntegratedCircuitCardIdentity", &value_node); | ||
| 156 | |||
| 157 | iphone_device_get_uuid(phone, &uuid); | ||
| 158 | plist_dict_insert_item(ret, "DeviceId", plist_new_string(uuid)); | ||
| 159 | free(uuid); | ||
| 160 | |||
| 161 | plist_dict_insert_item(ret, "Version", plist_new_string("6.2")); | ||
| 162 | |||
| 163 | /* TODO: add all Applications */ | ||
| 164 | |||
| 165 | /* TODO: add all Files */ | ||
| 166 | plist_t files = plist_new_dict(); | ||
| 167 | |||
| 168 | /* single file entry */ | ||
| 169 | plist_t info_node = plist_new_dict(); | ||
| 170 | g_get_current_time(&tv); | ||
| 171 | plist_dict_insert_item(info_node, "ModificationTime", plist_new_date(tv.tv_sec, tv.tv_usec)); | ||
| 172 | plist_dict_insert_item(info_node, "FileLength", plist_new_uint(131072)); | ||
| 173 | plist_dict_insert_item(info_node, "Domain", plist_new_string("HomeDomain")); | ||
| 174 | |||
| 175 | /* FIXME: calculate correct data hash */ | ||
| 176 | /* Data hash is: sha1(<file>) */ | ||
| 177 | plist_dict_insert_item(info_node, "DataHash", plist_new_data(NULL, 0)); | ||
| 178 | plist_dict_insert_item(info_node, "Group ID", plist_new_uint(501)); | ||
| 179 | plist_dict_insert_item(info_node, "User ID", plist_new_uint(501)); | ||
| 180 | plist_dict_insert_item(info_node, "Mode ID", plist_new_uint(420)); | ||
| 181 | |||
| 182 | /* FIXME: calculate correct file hash */ | ||
| 183 | /* File hash is: sha1(<Domain>-<Relative File Path>) */ | ||
| 184 | plist_dict_insert_item(files, "3d0d7e5fb2ce288813306e4d4636395e047a3d28", info_node); | ||
| 185 | plist_dict_insert_item(ret, "Files", files); | ||
| 186 | |||
| 187 | /* last node with ICCID */ | ||
| 188 | if (value_node) | ||
| 189 | plist_dict_insert_item(ret, "DeviceICCID", &value_node); | ||
| 190 | |||
| 191 | return ret; | ||
| 192 | } | ||
| 193 | |||
| 194 | /** | ||
| 195 | * Generates a manifest plist with all needed information and hashes | ||
| 196 | */ | ||
| 197 | static plist_t mobilebackup_factory_manifest_plist(plist_t manifest_data) | ||
| 198 | { | ||
| 199 | char *buffer = NULL; | ||
| 200 | char *s = NULL; | ||
| 201 | uint32_t length; | ||
| 202 | unsigned char sha1[20]; | ||
| 203 | gsize sha1_len; | ||
| 204 | GChecksum *checksum; | ||
| 205 | plist_t ret = NULL; | ||
| 206 | |||
| 207 | if (!manifest_data) | ||
| 208 | return ret; | ||
| 209 | |||
| 210 | ret = plist_new_dict(); | ||
| 211 | plist_dict_insert_item(ret, "AuthVersion", plist_new_string("2.0")); | ||
| 212 | |||
| 213 | /* AuthSignature Hash is: sha1(<manifest_data>) */ | ||
| 214 | plist_to_bin(manifest_data, &buffer, &length); | ||
| 215 | |||
| 216 | sha1_len = g_checksum_type_get_length(G_CHECKSUM_SHA1); | ||
| 217 | checksum = g_checksum_new(G_CHECKSUM_SHA1); | ||
| 218 | g_checksum_update(checksum, (guchar *)buffer, length); | ||
| 219 | g_checksum_get_digest(checksum, sha1, &sha1_len); | ||
| 220 | s = (char *)g_checksum_get_string(checksum); | ||
| 221 | printf("SHA1 AuthSignature: %s\n", s); | ||
| 222 | plist_dict_insert_item(ret, "AuthSignature", plist_new_data((char*)sha1, sha1_len)); | ||
| 223 | g_checksum_free(checksum); | ||
| 224 | |||
| 225 | |||
| 226 | plist_dict_insert_item(ret, "IsEncrypted", plist_new_uint(0)); | ||
| 227 | plist_dict_insert_item(ret, "Data", plist_new_data(buffer, length)); | ||
| 228 | |||
| 229 | free(buffer); | ||
| 230 | |||
| 231 | return ret; | ||
| 232 | } | ||
| 233 | |||
| 234 | enum plist_format_t { | 106 | enum plist_format_t { |
| 235 | PLIST_FORMAT_XML, | 107 | PLIST_FORMAT_XML, |
| 236 | PLIST_FORMAT_BINARY | 108 | PLIST_FORMAT_BINARY |
| 237 | }; | 109 | }; |
| 238 | 110 | ||
| 239 | static int plist_read_from_filename(char *filename, plist_t *plist) | 111 | static void buffer_to_filename(char *filename, char *buffer, uint32_t length) |
| 240 | { | 112 | { |
| 241 | return 1; | 113 | FILE *f; |
| 114 | |||
| 115 | f = fopen(filename, "ab"); | ||
| 116 | fwrite(buffer, sizeof(char), length, f); | ||
| 117 | fclose(f); | ||
| 242 | } | 118 | } |
| 243 | 119 | ||
| 244 | static int plist_write_to_filename(plist_t plist, char *filename, enum plist_format_t format) | 120 | static int plist_write_to_filename(plist_t plist, char *filename, enum plist_format_t format) |
| 245 | { | 121 | { |
| 246 | char *buffer = NULL; | 122 | char *buffer = NULL; |
| 247 | uint32_t length; | 123 | uint32_t length; |
| 248 | FILE *f; | ||
| 249 | 124 | ||
| 250 | if (!plist || !filename) | 125 | if (!plist || !filename) |
| 251 | return 0; | 126 | return 0; |
| @@ -257,9 +132,7 @@ static int plist_write_to_filename(plist_t plist, char *filename, enum plist_for | |||
| 257 | else | 132 | else |
| 258 | return 0; | 133 | return 0; |
| 259 | 134 | ||
| 260 | f = fopen(filename, "wb"); | 135 | buffer_to_filename(filename, buffer, length); |
| 261 | fwrite(buffer, sizeof(char), length, f); | ||
| 262 | fclose(f); | ||
| 263 | 136 | ||
| 264 | free(buffer); | 137 | free(buffer); |
| 265 | 138 | ||
| @@ -281,25 +154,50 @@ static int plist_strcmp(plist_t node, const char *str) | |||
| 281 | return ret; | 154 | return ret; |
| 282 | } | 155 | } |
| 283 | 156 | ||
| 157 | static plist_t device_link_message_factory_process_message_new(plist_t content) | ||
| 158 | { | ||
| 159 | plist_t ret = plist_new_array(); | ||
| 160 | plist_array_append_item(ret, plist_new_string("DLMessageProcessMessage")); | ||
| 161 | plist_array_append_item(ret, content); | ||
| 162 | return ret; | ||
| 163 | } | ||
| 164 | |||
| 165 | static void mobilebackup_cancel_backup_with_error(const char *reason) | ||
| 166 | { | ||
| 167 | plist_t node = plist_new_dict(); | ||
| 168 | plist_dict_insert_item(node, "BackupMessageTypeKey", plist_new_string("BackupMessageError")); | ||
| 169 | plist_dict_insert_item(node, "BackupErrorReasonKey", plist_new_string(reason)); | ||
| 170 | |||
| 171 | plist_t message = device_link_message_factory_process_message_new(node); | ||
| 172 | |||
| 173 | mobilebackup_send(mobilebackup, message); | ||
| 174 | |||
| 175 | plist_free(message); | ||
| 176 | message = NULL; | ||
| 177 | } | ||
| 178 | |||
| 284 | static void mobilebackup_write_status(char *path, int status) | 179 | static void mobilebackup_write_status(char *path, int status) |
| 285 | { | 180 | { |
| 181 | struct stat st; | ||
| 286 | plist_t status_plist = plist_new_dict(); | 182 | plist_t status_plist = plist_new_dict(); |
| 287 | plist_dict_insert_item(status_plist, "Backup Success", plist_new_bool(status)); | 183 | plist_dict_insert_item(status_plist, "Backup Success", plist_new_bool(status)); |
| 288 | char *file_path = g_build_path(G_DIR_SEPARATOR_S, path, "Status.plist", NULL); | 184 | char *file_path = g_build_path(G_DIR_SEPARATOR_S, path, "Status.plist", NULL); |
| 185 | if (stat(file_path, &st) == 0) | ||
| 186 | remove(file_path); | ||
| 289 | plist_write_to_filename(status_plist, file_path, PLIST_FORMAT_XML); | 187 | plist_write_to_filename(status_plist, file_path, PLIST_FORMAT_XML); |
| 290 | g_free(file_path); | 188 | g_free(file_path); |
| 291 | plist_free(status_plist); | 189 | plist_free(status_plist); |
| 292 | } | 190 | } |
| 293 | 191 | ||
| 294 | static void debug_plist(plist_t plist) | 192 | static void debug_plist(plist_t a) |
| 295 | { | 193 | { |
| 296 | char *buffer = NULL; | 194 | char *buffer = NULL; |
| 297 | uint32_t length = 0; | 195 | uint32_t length = 0; |
| 298 | 196 | ||
| 299 | if (!plist) | 197 | if (a == NULL) |
| 300 | return; | 198 | return; |
| 301 | 199 | ||
| 302 | plist_to_xml(plist, &buffer, &length); | 200 | plist_to_xml(a, &buffer, &length); |
| 303 | 201 | ||
| 304 | printf("Printing %i bytes plist:\n%s\n", length, buffer); | 202 | printf("Printing %i bytes plist:\n%s\n", length, buffer); |
| 305 | free(buffer); | 203 | free(buffer); |
| @@ -341,6 +239,9 @@ int main(int argc, char *argv[]) | |||
| 341 | char *backup_directory = NULL; | 239 | char *backup_directory = NULL; |
| 342 | struct stat st; | 240 | struct stat st; |
| 343 | plist_t node = NULL; | 241 | plist_t node = NULL; |
| 242 | plist_t node_tmp = NULL; | ||
| 243 | char *buffer = NULL; | ||
| 244 | uint64_t length = 0; | ||
| 344 | 245 | ||
| 345 | /* we need to exit cleanly on running backups and restores or we cause havok */ | 246 | /* we need to exit cleanly on running backups and restores or we cause havok */ |
| 346 | signal(SIGINT, clean_exit); | 247 | signal(SIGINT, clean_exit); |
| @@ -440,6 +341,11 @@ int main(int argc, char *argv[]) | |||
| 440 | printf("Started \"%s\" service on port %d.\n", MOBILEBACKUP_SERVICE_NAME, port); | 341 | printf("Started \"%s\" service on port %d.\n", MOBILEBACKUP_SERVICE_NAME, port); |
| 441 | mobilebackup_client_new(phone, port, &mobilebackup); | 342 | mobilebackup_client_new(phone, port, &mobilebackup); |
| 442 | 343 | ||
| 344 | if (quit_flag > 0) { | ||
| 345 | printf("Aborting backup. Cancelled by user.\n"); | ||
| 346 | cmd = CMD_LEAVE; | ||
| 347 | } | ||
| 348 | |||
| 443 | switch(cmd) { | 349 | switch(cmd) { |
| 444 | case CMD_BACKUP: | 350 | case CMD_BACKUP: |
| 445 | printf("Starting backup...\n"); | 351 | printf("Starting backup...\n"); |
| @@ -451,29 +357,32 @@ int main(int argc, char *argv[]) | |||
| 451 | /* create Info.plist (Device infos, IC-Info.sidb, photos, app_ids, iTunesPrefs) */ | 357 | /* create Info.plist (Device infos, IC-Info.sidb, photos, app_ids, iTunesPrefs) */ |
| 452 | printf("Creating \"%s/Info.plist\".\n", backup_directory); | 358 | printf("Creating \"%s/Info.plist\".\n", backup_directory); |
| 453 | plist_t info_plist = mobilebackup_factory_info_plist(); | 359 | plist_t info_plist = mobilebackup_factory_info_plist(); |
| 360 | if (stat(info_path, &st) == 0) | ||
| 361 | remove(info_path); | ||
| 454 | plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML); | 362 | plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML); |
| 455 | g_free(info_path); | 363 | g_free(info_path); |
| 456 | 364 | ||
| 365 | if (client) { | ||
| 366 | lockdownd_client_free(client); | ||
| 367 | client = NULL; | ||
| 368 | } | ||
| 369 | |||
| 457 | /* create Manifest.plist (backup manifest (backup state)) */ | 370 | /* create Manifest.plist (backup manifest (backup state)) */ |
| 458 | printf("Creating \"%s/Manifest.plist\".\n", backup_directory); | 371 | printf("Creating \"%s/Manifest.plist\".\n", backup_directory); |
| 459 | char *manifest_path = g_build_path(G_DIR_SEPARATOR_S, backup_directory, "Manifest.plist", NULL); | 372 | char *manifest_path = g_build_path(G_DIR_SEPARATOR_S, backup_directory, "Manifest.plist", NULL); |
| 460 | plist_t manifest_data = mobilebackup_factory_manifest_data_plist(); | 373 | plist_t manifest_plist = NULL; |
| 461 | plist_t manifest_plist = mobilebackup_factory_manifest_plist(manifest_data); | 374 | if (stat(manifest_path, &st) == 0) |
| 462 | plist_write_to_filename(manifest_plist, manifest_path, PLIST_FORMAT_XML); | 375 | remove(manifest_path); |
| 463 | g_free(manifest_path); | ||
| 464 | 376 | ||
| 465 | /* create Status.plist with failed status for now */ | 377 | /* create Status.plist with failed status for now */ |
| 466 | mobilebackup_write_status(backup_directory, 0); | 378 | mobilebackup_write_status(backup_directory, 0); |
| 467 | 379 | ||
| 468 | /* close down lockdown connection as it is no longer needed */ | 380 | /* request backup from device with manifest from last backup */ |
| 469 | lockdownd_client_free(client); | ||
| 470 | client = NULL; | ||
| 471 | |||
| 472 | /* request backup from device with manifest */ | ||
| 473 | printf("Sending manifest and requesting backup.\n"); | 381 | printf("Sending manifest and requesting backup.\n"); |
| 474 | 382 | ||
| 475 | node = plist_new_dict(); | 383 | node = plist_new_dict(); |
| 476 | plist_dict_insert_item(node, "BackupManifestKey", manifest_plist); | 384 | if (manifest_plist) |
| 385 | plist_dict_insert_item(node, "BackupManifestKey", manifest_plist); | ||
| 477 | plist_dict_insert_item(node, "BackupComputerBasePathKey", plist_new_string("/")); | 386 | plist_dict_insert_item(node, "BackupComputerBasePathKey", plist_new_string("/")); |
| 478 | plist_dict_insert_item(node, "BackupMessageTypeKey", plist_new_string("BackupMessageBackupRequest")); | 387 | plist_dict_insert_item(node, "BackupMessageTypeKey", plist_new_string("BackupMessageBackupRequest")); |
| 479 | plist_dict_insert_item(node, "BackupProtocolVersion", plist_new_string("1.6")); | 388 | plist_dict_insert_item(node, "BackupProtocolVersion", plist_new_string("1.6")); |
| @@ -514,21 +423,66 @@ int main(int argc, char *argv[]) | |||
| 514 | 423 | ||
| 515 | /* receive and save DLSendFile files and metadata, ACK each */ | 424 | /* receive and save DLSendFile files and metadata, ACK each */ |
| 516 | int file_index = 0; | 425 | int file_index = 0; |
| 426 | char *file_path = NULL; | ||
| 427 | char *file_ext = NULL; | ||
| 428 | char *filename_mdinfo = NULL; | ||
| 429 | char *filename_mddata = NULL; | ||
| 430 | char *filename_source = NULL; | ||
| 517 | do { | 431 | do { |
| 518 | mobilebackup_receive(mobilebackup, &message); | 432 | mobilebackup_receive(mobilebackup, &message); |
| 519 | node = plist_array_get_item(message, 0); | 433 | node = plist_array_get_item(message, 0); |
| 520 | if (plist_strcmp(node, "DLSendFile")) | 434 | if (plist_strcmp(node, "DLSendFile")) |
| 521 | break; | 435 | break; |
| 522 | 436 | ||
| 523 | printf("Receiving file %d...\n", file_index); | 437 | /* get source filename and print it */ |
| 524 | /* TODO: save <hash>.mdinfo */ | 438 | node_tmp = plist_array_get_item(message, 2); |
| 525 | /* TODO: save <hash>.mddata */ | 439 | node = plist_dict_get_item(node_tmp, "DLFileSource"); |
| 526 | debug_plist(message); | 440 | plist_get_string_val(node, &filename_source); |
| 441 | printf("Received file %s...", filename_source); | ||
| 442 | free(filename_source); | ||
| 443 | |||
| 444 | /* save <hash>.mdinfo */ | ||
| 445 | node = plist_dict_get_item(node_tmp, "BackupFileInfo"); | ||
| 446 | if (node) { | ||
| 447 | node = plist_dict_get_item(node_tmp, "DLFileDest"); | ||
| 448 | plist_get_string_val(node, &file_path); | ||
| 449 | file_ext = (char *)g_strconcat(file_path, ".mdinfo", NULL); | ||
| 450 | filename_mdinfo = g_build_path(G_DIR_SEPARATOR_S, backup_directory, file_ext, NULL); | ||
| 451 | node = plist_dict_get_item(node_tmp, "BackupFileInfo"); | ||
| 452 | plist_write_to_filename(node, filename_mdinfo, PLIST_FORMAT_BINARY); | ||
| 453 | g_free(file_ext); | ||
| 454 | g_free(filename_mdinfo); | ||
| 455 | } | ||
| 456 | |||
| 457 | /* save <hash>.mddata */ | ||
| 458 | node = plist_dict_get_item(node_tmp, "BackupFileInfo"); | ||
| 459 | if (node_tmp && file_path) { | ||
| 460 | node = plist_dict_get_item(node_tmp, "DLFileDest"); | ||
| 461 | plist_get_string_val(node, &file_path); | ||
| 462 | file_ext = (char *)g_strconcat(file_path, ".mddata", NULL); | ||
| 463 | filename_mddata = g_build_path(G_DIR_SEPARATOR_S, backup_directory, file_ext, NULL); | ||
| 464 | node_tmp = plist_array_get_item(message, 1); | ||
| 465 | plist_get_data_val(node_tmp, &buffer, &length); | ||
| 466 | buffer_to_filename(filename_mddata, buffer, length); | ||
| 467 | free(buffer); | ||
| 468 | buffer = NULL; | ||
| 469 | g_free(filename_mddata); | ||
| 470 | } | ||
| 471 | |||
| 472 | printf("DONE\n"); | ||
| 473 | |||
| 474 | if (file_ext) | ||
| 475 | free(file_ext); | ||
| 476 | |||
| 527 | plist_free(message); | 477 | plist_free(message); |
| 528 | message = NULL; | 478 | message = NULL; |
| 529 | 479 | ||
| 530 | if (quit_flag) { | 480 | if (quit_flag > 0) { |
| 531 | /* FIXME: need to cancel the backup here */ | 481 | /* need to cancel the backup here */ |
| 482 | mobilebackup_cancel_backup_with_error("Cancelling DLSendFile"); | ||
| 483 | |||
| 484 | plist_free(message); | ||
| 485 | message = NULL; | ||
| 532 | break; | 486 | break; |
| 533 | } | 487 | } |
| 534 | 488 | ||
| @@ -550,17 +504,58 @@ int main(int argc, char *argv[]) | |||
| 550 | printf("Received %d files from device.\n", file_index); | 504 | printf("Received %d files from device.\n", file_index); |
| 551 | 505 | ||
| 552 | if (!plist_strcmp(node, "DLMessageProcessMessage")) { | 506 | if (!plist_strcmp(node, "DLMessageProcessMessage")) { |
| 553 | node = plist_array_get_item(message, 1); | 507 | node_tmp = plist_array_get_item(message, 1); |
| 554 | node = plist_dict_get_item(node, "BackupMessageTypeKey"); | 508 | node = plist_dict_get_item(node_tmp, "BackupMessageTypeKey"); |
| 555 | /* wait until received final backup finished message */ | 509 | /* wait until received final backup finished message */ |
| 556 | if (node && !plist_strcmp(node, "BackupMessageBackupFinished")) { | 510 | if (node && !plist_strcmp(node, "BackupMessageBackupFinished")) { |
| 557 | /* backup finished */ | 511 | /* backup finished */ |
| 512 | |||
| 513 | /* process BackupFilesToDeleteKey */ | ||
| 514 | node = plist_dict_get_item(node_tmp, "BackupFilesToDeleteKey"); | ||
| 515 | if (node) { | ||
| 516 | length = plist_array_get_size(node); | ||
| 517 | i = 0; | ||
| 518 | while ((node_tmp = plist_array_get_item(node, i++)) != NULL) { | ||
| 519 | plist_get_string_val(node_tmp, &file_path); | ||
| 520 | |||
| 521 | file_ext = (char *)g_strconcat(file_path, ".mddata", NULL); | ||
| 522 | filename_mddata = g_build_path(G_DIR_SEPARATOR_S, backup_directory, file_ext, NULL); | ||
| 523 | g_free(file_ext); | ||
| 524 | printf("Removing \"%s\"... ", filename_mddata); | ||
| 525 | if (!remove( filename_mddata )) { | ||
| 526 | printf("DONE\n"); | ||
| 527 | } else | ||
| 528 | printf("FAILED\n"); | ||
| 529 | |||
| 530 | file_ext = (char *)g_strconcat(file_path, ".mdinfo", NULL); | ||
| 531 | filename_mdinfo = g_build_path(G_DIR_SEPARATOR_S, backup_directory, file_ext, NULL); | ||
| 532 | g_free(file_ext); | ||
| 533 | printf("Removing \"%s\"... ", filename_mdinfo); | ||
| 534 | if (!remove( filename_mdinfo )) { | ||
| 535 | printf("DONE\n"); | ||
| 536 | } else | ||
| 537 | printf("FAILED\n"); | ||
| 538 | } | ||
| 539 | } | ||
| 540 | |||
| 541 | /* save new Manifest.plist */ | ||
| 542 | node_tmp = plist_array_get_item(message, 1); | ||
| 543 | manifest_plist = plist_dict_get_item(node_tmp, "BackupManifestKey"); | ||
| 544 | if (manifest_plist) { | ||
| 545 | if (stat(manifest_path, &st) != 0) | ||
| 546 | remove(manifest_path); | ||
| 547 | plist_write_to_filename(manifest_plist, manifest_path, PLIST_FORMAT_XML); | ||
| 548 | } | ||
| 549 | |||
| 558 | /* create: Status.plist (Info on how the backup process turned out) */ | 550 | /* create: Status.plist (Info on how the backup process turned out) */ |
| 559 | printf("Backup Successful.\n"); | 551 | printf("Backup Successful.\n"); |
| 560 | mobilebackup_write_status(backup_directory, 1); | 552 | mobilebackup_write_status(backup_directory, 1); |
| 561 | } | 553 | } |
| 562 | } | 554 | } |
| 563 | 555 | ||
| 556 | if (manifest_path) | ||
| 557 | g_free(manifest_path); | ||
| 558 | |||
| 564 | if (node) | 559 | if (node) |
| 565 | plist_free(node); | 560 | plist_free(node); |
| 566 | 561 | ||
| @@ -575,6 +570,7 @@ int main(int argc, char *argv[]) | |||
| 575 | lockdownd_client_free(client); | 570 | lockdownd_client_free(client); |
| 576 | client = NULL; | 571 | client = NULL; |
| 577 | break; | 572 | break; |
| 573 | case CMD_LEAVE: | ||
| 578 | default: | 574 | default: |
| 579 | break; | 575 | break; |
| 580 | } | 576 | } |
| @@ -584,11 +580,14 @@ int main(int argc, char *argv[]) | |||
| 584 | client = NULL; | 580 | client = NULL; |
| 585 | } | 581 | } |
| 586 | 582 | ||
| 587 | if (client) | 583 | if (client) { |
| 588 | lockdownd_client_free(client); | 584 | lockdownd_client_free(client); |
| 585 | client = NULL; | ||
| 586 | } | ||
| 589 | 587 | ||
| 590 | if (mobilebackup) | 588 | if (mobilebackup) |
| 591 | mobilebackup_client_free(mobilebackup); | 589 | mobilebackup_client_free(mobilebackup); |
| 590 | |||
| 592 | iphone_device_free(phone); | 591 | iphone_device_free(phone); |
| 593 | 592 | ||
| 594 | return 0; | 593 | return 0; |
