summaryrefslogtreecommitdiffstats
path: root/tools/idevicebackup.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/idevicebackup.c')
-rw-r--r--tools/idevicebackup.c133
1 files changed, 92 insertions, 41 deletions
diff --git a/tools/idevicebackup.c b/tools/idevicebackup.c
index f744e70..25f8014 100644
--- a/tools/idevicebackup.c
+++ b/tools/idevicebackup.c
@@ -29,7 +29,6 @@
29#include <errno.h> 29#include <errno.h>
30#include <stdlib.h> 30#include <stdlib.h>
31#include <signal.h> 31#include <signal.h>
32#include <glib.h>
33#ifdef HAVE_OPENSSL 32#ifdef HAVE_OPENSSL
34#include <openssl/sha.h> 33#include <openssl/sha.h>
35#else 34#else
@@ -222,10 +221,63 @@ static void notify_cb(const char *notification, void *userdata)
222 } 221 }
223} 222}
224 223
224static char *str_toupper(char* str)
225{
226 char *res = strdup(str);
227 int i;
228 for (i = 0; i < strlen(res); i++) {
229 res[i] = toupper(res[i]);
230 }
231 return res;
232}
233
234char* build_path(const char* elem, ...)
235{
236 if (!elem) return NULL;
237 va_list args;
238 int len = strlen(elem)+1;
239 va_start(args, elem);
240 char *arg = va_arg(args, char*);
241 while (arg) {
242 len += strlen(arg)+1;
243 arg = va_arg(args, char*);
244 }
245 va_end(args);
246
247 char* out = (char*)malloc(len);
248 strcpy(out, elem);
249
250 va_start(args, elem);
251 arg = va_arg(args, char*);
252 while (arg) {
253 strcat(out, "/");
254 strcat(out, arg);
255 arg = va_arg(args, char*);
256 }
257 va_end(args);
258 return out;
259}
260
261static char* format_size_for_display(uint64_t size)
262{
263 char buf[32];
264 double sz;
265 if (size >= 1000000000LL) {
266 sz = ((double)size / 1000000000.0f);
267 sprintf(buf, "%0.1f GB", sz);
268 } else if (size >= 1000000LL) {
269 sz = ((double)size / 1000000.0f);
270 sprintf(buf, "%0.1f MB", sz);
271 } else if (size >= 1000LL) {
272 sz = ((double)size / 1000.0f);
273 sprintf(buf, "%0.1f kB", sz);
274 }
275 return strdup(buf);
276}
277
225static plist_t mobilebackup_factory_info_plist_new() 278static plist_t mobilebackup_factory_info_plist_new()
226{ 279{
227 /* gather data from lockdown */ 280 /* gather data from lockdown */
228 GTimeVal tv = {0, 0};
229 plist_t value_node = NULL; 281 plist_t value_node = NULL;
230 plist_t root_node = NULL; 282 plist_t root_node = NULL;
231 char *uuid = NULL; 283 char *uuid = NULL;
@@ -251,8 +303,7 @@ static plist_t mobilebackup_factory_info_plist_new()
251 if (value_node) 303 if (value_node)
252 plist_dict_insert_item(ret, "IMEI", plist_copy(value_node)); 304 plist_dict_insert_item(ret, "IMEI", plist_copy(value_node));
253 305
254 g_get_current_time(&tv); 306 plist_dict_insert_item(ret, "Last Backup Date", plist_new_date(time(NULL), 0));
255 plist_dict_insert_item(ret, "Last Backup Date", plist_new_date(tv.tv_sec, tv.tv_usec));
256 307
257 value_node = plist_dict_get_item(root_node, "ProductType"); 308 value_node = plist_dict_get_item(root_node, "ProductType");
258 plist_dict_insert_item(ret, "Product Type", plist_copy(value_node)); 309 plist_dict_insert_item(ret, "Product Type", plist_copy(value_node));
@@ -268,7 +319,7 @@ static plist_t mobilebackup_factory_info_plist_new()
268 plist_dict_insert_item(ret, "Target Identifier", plist_new_string(uuid)); 319 plist_dict_insert_item(ret, "Target Identifier", plist_new_string(uuid));
269 320
270 /* uppercase */ 321 /* uppercase */
271 uuid_uppercase = g_ascii_strup(uuid, -1); 322 uuid_uppercase = str_toupper(uuid);
272 plist_dict_insert_item(ret, "Unique Identifier", plist_new_string(uuid_uppercase)); 323 plist_dict_insert_item(ret, "Unique Identifier", plist_new_string(uuid_uppercase));
273 free(uuid_uppercase); 324 free(uuid_uppercase);
274 free(uuid); 325 free(uuid);
@@ -285,15 +336,13 @@ static plist_t mobilebackup_factory_info_plist_new()
285 336
286static void mobilebackup_info_update_last_backup_date(plist_t info_plist) 337static void mobilebackup_info_update_last_backup_date(plist_t info_plist)
287{ 338{
288 GTimeVal tv = {0, 0};
289 plist_t node = NULL; 339 plist_t node = NULL;
290 340
291 if (!info_plist) 341 if (!info_plist)
292 return; 342 return;
293 343
294 g_get_current_time(&tv);
295 node = plist_dict_get_item(info_plist, "Last Backup Date"); 344 node = plist_dict_get_item(info_plist, "Last Backup Date");
296 plist_set_date_val(node, tv.tv_sec, tv.tv_usec); 345 plist_set_date_val(node, time(NULL), 0);
297 346
298 node = NULL; 347 node = NULL;
299} 348}
@@ -396,11 +445,13 @@ static int plist_strcmp(plist_t node, const char *str)
396 return ret; 445 return ret;
397} 446}
398 447
399static gchar *mobilebackup_build_path(const char *backup_directory, const char *name, const char *extension) 448static char *mobilebackup_build_path(const char *backup_directory, const char *name, const char *extension)
400{ 449{
401 gchar *filename = g_strconcat(name, extension, NULL); 450 char* filename = (char*)malloc(strlen(name)+strlen(extension)+1);
402 gchar *path = g_build_path(G_DIR_SEPARATOR_S, backup_directory, filename, NULL); 451 strcpy(filename, name);
403 g_free(filename); 452 strcat(filename, extension);
453 char *path = build_path(backup_directory, filename, NULL);
454 free(filename);
404 return path; 455 return path;
405} 456}
406 457
@@ -409,7 +460,7 @@ static void mobilebackup_write_status(const char *path, int status)
409 struct stat st; 460 struct stat st;
410 plist_t status_plist = plist_new_dict(); 461 plist_t status_plist = plist_new_dict();
411 plist_dict_insert_item(status_plist, "Backup Success", plist_new_bool(status)); 462 plist_dict_insert_item(status_plist, "Backup Success", plist_new_bool(status));
412 gchar *file_path = mobilebackup_build_path(path, "Status", ".plist"); 463 char *file_path = mobilebackup_build_path(path, "Status", ".plist");
413 464
414 if (stat(file_path, &st) == 0) 465 if (stat(file_path, &st) == 0)
415 remove(file_path); 466 remove(file_path);
@@ -419,17 +470,17 @@ static void mobilebackup_write_status(const char *path, int status)
419 plist_free(status_plist); 470 plist_free(status_plist);
420 status_plist = NULL; 471 status_plist = NULL;
421 472
422 g_free(file_path); 473 free(file_path);
423} 474}
424 475
425static int mobilebackup_read_status(const char *path) 476static int mobilebackup_read_status(const char *path)
426{ 477{
427 int ret = -1; 478 int ret = -1;
428 plist_t status_plist = NULL; 479 plist_t status_plist = NULL;
429 gchar *file_path = mobilebackup_build_path(path, "Status", ".plist"); 480 char *file_path = mobilebackup_build_path(path, "Status", ".plist");
430 481
431 plist_read_from_filename(&status_plist, file_path); 482 plist_read_from_filename(&status_plist, file_path);
432 g_free(file_path); 483 free(file_path);
433 if (!status_plist) { 484 if (!status_plist) {
434 printf("Could not read Status.plist!\n"); 485 printf("Could not read Status.plist!\n");
435 return ret; 486 return ret;
@@ -510,14 +561,14 @@ static int mobilebackup_info_is_current_device(plist_t info)
510static int mobilebackup_delete_backup_file_by_hash(const char *backup_directory, const char *hash) 561static int mobilebackup_delete_backup_file_by_hash(const char *backup_directory, const char *hash)
511{ 562{
512 int ret = 0; 563 int ret = 0;
513 gchar *path = mobilebackup_build_path(backup_directory, hash, ".mddata"); 564 char *path = mobilebackup_build_path(backup_directory, hash, ".mddata");
514 printf("Removing \"%s\" ", path); 565 printf("Removing \"%s\" ", path);
515 if (!remove( path )) 566 if (!remove( path ))
516 ret = 1; 567 ret = 1;
517 else 568 else
518 ret = 0; 569 ret = 0;
519 570
520 g_free(path); 571 free(path);
521 572
522 if (!ret) 573 if (!ret)
523 return ret; 574 return ret;
@@ -529,7 +580,7 @@ static int mobilebackup_delete_backup_file_by_hash(const char *backup_directory,
529 else 580 else
530 ret = 0; 581 ret = 0;
531 582
532 g_free(path); 583 free(path);
533 584
534 return ret; 585 return ret;
535} 586}
@@ -666,9 +717,9 @@ static int mobilebackup_check_file_integrity(const char *backup_directory, const
666 hash_ok = 1; 717 hash_ok = 1;
667 } 718 }
668 719
669 g_free(domain); 720 free(domain);
670 g_free(version); 721 free(version);
671 g_free(destpath); 722 free(destpath);
672 723
673 if (!hash_ok) { 724 if (!hash_ok) {
674 printf("\r\n"); 725 printf("\r\n");
@@ -680,7 +731,7 @@ static int mobilebackup_check_file_integrity(const char *backup_directory, const
680 printf("\n"); 731 printf("\n");
681 res = 0; 732 res = 0;
682 } 733 }
683 g_free(data_hash); 734 free(data_hash);
684 plist_free(mdinfo); 735 plist_free(mdinfo);
685 return res; 736 return res;
686} 737}
@@ -841,7 +892,7 @@ int main(int argc, char *argv[])
841 char *info_path = mobilebackup_build_path(backup_directory, "Info", ".plist"); 892 char *info_path = mobilebackup_build_path(backup_directory, "Info", ".plist");
842 if (cmd == CMD_RESTORE) { 893 if (cmd == CMD_RESTORE) {
843 if (stat(info_path, &st) != 0) { 894 if (stat(info_path, &st) != 0) {
844 g_free(info_path); 895 free(info_path);
845 printf("ERROR: Backup directory \"%s\" is invalid. No Info.plist found.\n", backup_directory); 896 printf("ERROR: Backup directory \"%s\" is invalid. No Info.plist found.\n", backup_directory);
846 return -1; 897 return -1;
847 } 898 }
@@ -1010,7 +1061,7 @@ int main(int argc, char *argv[])
1010 info_plist = mobilebackup_factory_info_plist_new(); 1061 info_plist = mobilebackup_factory_info_plist_new();
1011 plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML); 1062 plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML);
1012 } 1063 }
1013 g_free(info_path); 1064 free(info_path);
1014 1065
1015 plist_free(info_plist); 1066 plist_free(info_plist);
1016 info_plist = NULL; 1067 info_plist = NULL;
@@ -1060,7 +1111,7 @@ int main(int argc, char *argv[])
1060 char *filename_mddata = NULL; 1111 char *filename_mddata = NULL;
1061 char *filename_source = NULL; 1112 char *filename_source = NULL;
1062 char *format_size = NULL; 1113 char *format_size = NULL;
1063 gboolean is_manifest = FALSE; 1114 int is_manifest = 0;
1064 uint8_t b = 0; 1115 uint8_t b = 0;
1065 1116
1066 /* process series of DLSendFile messages */ 1117 /* process series of DLSendFile messages */
@@ -1085,9 +1136,9 @@ int main(int argc, char *argv[])
1085 node = plist_dict_get_item(node_tmp, "BackupTotalSizeKey"); 1136 node = plist_dict_get_item(node_tmp, "BackupTotalSizeKey");
1086 if (node) { 1137 if (node) {
1087 plist_get_uint_val(node, &backup_total_size); 1138 plist_get_uint_val(node, &backup_total_size);
1088 format_size = g_format_size_for_display(backup_total_size); 1139 format_size = format_size_for_display(backup_total_size);
1089 printf("Backup data requires %s on the disk.\n", format_size); 1140 printf("Backup data requires %s on the disk.\n", format_size);
1090 g_free(format_size); 1141 free(format_size);
1091 } 1142 }
1092 } 1143 }
1093 1144
@@ -1102,7 +1153,7 @@ int main(int argc, char *argv[])
1102 if (node) { 1153 if (node) {
1103 plist_get_bool_val(node, &b); 1154 plist_get_bool_val(node, &b);
1104 } 1155 }
1105 is_manifest = (b == 1) ? TRUE: FALSE; 1156 is_manifest = (b == 1) ? 1 : 0;
1106 1157
1107 if ((hunk_index == 0) && (!is_manifest)) { 1158 if ((hunk_index == 0) && (!is_manifest)) {
1108 /* get source filename */ 1159 /* get source filename */
@@ -1115,17 +1166,17 @@ int main(int argc, char *argv[])
1115 plist_get_uint_val(node, &file_size); 1166 plist_get_uint_val(node, &file_size);
1116 backup_real_size += file_size; 1167 backup_real_size += file_size;
1117 1168
1118 format_size = g_format_size_for_display(backup_real_size); 1169 format_size = format_size_for_display(backup_real_size);
1119 printf("(%s", format_size); 1170 printf("(%s", format_size);
1120 g_free(format_size); 1171 free(format_size);
1121 1172
1122 format_size = g_format_size_for_display(backup_total_size); 1173 format_size = format_size_for_display(backup_total_size);
1123 printf("/%s): ", format_size); 1174 printf("/%s): ", format_size);
1124 g_free(format_size); 1175 free(format_size);
1125 1176
1126 format_size = g_format_size_for_display(file_size); 1177 format_size = format_size_for_display(file_size);
1127 printf("Receiving file %s (%s)... \n", filename_source, format_size); 1178 printf("Receiving file %s (%s)... \n", filename_source, format_size);
1128 g_free(format_size); 1179 free(format_size);
1129 1180
1130 if (filename_source) 1181 if (filename_source)
1131 free(filename_source); 1182 free(filename_source);
@@ -1148,7 +1199,7 @@ int main(int argc, char *argv[])
1148 node = plist_dict_get_item(node_tmp, "BackupFileInfo"); 1199 node = plist_dict_get_item(node_tmp, "BackupFileInfo");
1149 plist_write_to_filename(node, filename_mdinfo, PLIST_FORMAT_BINARY); 1200 plist_write_to_filename(node, filename_mdinfo, PLIST_FORMAT_BINARY);
1150 1201
1151 g_free(filename_mdinfo); 1202 free(filename_mdinfo);
1152 } 1203 }
1153 1204
1154 file_index++; 1205 file_index++;
@@ -1182,7 +1233,7 @@ int main(int argc, char *argv[])
1182 free(buffer); 1233 free(buffer);
1183 buffer = NULL; 1234 buffer = NULL;
1184 1235
1185 g_free(filename_mddata); 1236 free(filename_mddata);
1186 } 1237 }
1187 1238
1188 if ((!is_manifest)) { 1239 if ((!is_manifest)) {
@@ -1220,7 +1271,7 @@ files_out:
1220 1271
1221 /* remove any atomic Manifest.plist.tmp */ 1272 /* remove any atomic Manifest.plist.tmp */
1222 if (manifest_path) 1273 if (manifest_path)
1223 g_free(manifest_path); 1274 free(manifest_path);
1224 1275
1225 manifest_path = mobilebackup_build_path(backup_directory, "Manifest", ".plist.tmp"); 1276 manifest_path = mobilebackup_build_path(backup_directory, "Manifest", ".plist.tmp");
1226 if (stat(manifest_path, &st) == 0) 1277 if (stat(manifest_path, &st) == 0)
@@ -1330,12 +1381,12 @@ files_out:
1330 } else { 1381 } else {
1331 printf("Could not get AuthSignature from manifest!\n"); 1382 printf("Could not get AuthSignature from manifest!\n");
1332 } 1383 }
1333 g_free(auth_sig); 1384 free(auth_sig);
1334 } else if (auth_ver) { 1385 } else if (auth_ver) {
1335 printf("Unknown AuthVersion '%s', cannot verify AuthSignature\n", auth_ver); 1386 printf("Unknown AuthVersion '%s', cannot verify AuthSignature\n", auth_ver);
1336 } 1387 }
1337 plist_from_bin(bin, (uint32_t)binsize, &backup_data); 1388 plist_from_bin(bin, (uint32_t)binsize, &backup_data);
1338 g_free(bin); 1389 free(bin);
1339 } 1390 }
1340 if (!backup_data) { 1391 if (!backup_data) {
1341 printf("Could not read plist from Manifest.plist Data key!\n"); 1392 printf("Could not read plist from Manifest.plist Data key!\n");
@@ -1615,7 +1666,7 @@ files_out:
1615 do_post_notification(NP_SYNC_DID_FINISH); 1666 do_post_notification(NP_SYNC_DID_FINISH);
1616 } 1667 }
1617 if (manifest_path) 1668 if (manifest_path)
1618 g_free(manifest_path); 1669 free(manifest_path);
1619 } else { 1670 } else {
1620 printf("ERROR: Could not start service %s.\n", MOBILEBACKUP_SERVICE_NAME); 1671 printf("ERROR: Could not start service %s.\n", MOBILEBACKUP_SERVICE_NAME);
1621 lockdownd_client_free(client); 1672 lockdownd_client_free(client);