summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2010-11-27 20:47:24 +0100
committerGravatar Martin Szulecki2011-04-11 19:42:18 +0200
commit5eefa4828535a905f9af5fd7ea0ad00b2f955103 (patch)
tree31ee2bbe24f463c814e5741a3af81c1a3bc79f1e
parent88bdba29da9faab1520881d8f7b6929baeb109ae (diff)
downloadlibimobiledevice-5eefa4828535a905f9af5fd7ea0ad00b2f955103.tar.gz
libimobiledevice-5eefa4828535a905f9af5fd7ea0ad00b2f955103.tar.bz2
idevicebackup4: create (mostly) proper Info.plist
-rw-r--r--tools/idevicebackup4.c155
1 files changed, 135 insertions, 20 deletions
diff --git a/tools/idevicebackup4.c b/tools/idevicebackup4.c
index c682e76..c2e067d 100644
--- a/tools/idevicebackup4.c
+++ b/tools/idevicebackup4.c
@@ -47,6 +47,7 @@
47 47
48static mobilebackup2_client_t mobilebackup2 = NULL; 48static mobilebackup2_client_t mobilebackup2 = NULL;
49static lockdownd_client_t client = NULL; 49static lockdownd_client_t client = NULL;
50static afc_client_t afc = NULL;
50static idevice_t phone = NULL; 51static idevice_t phone = NULL;
51 52
52static int quit_flag = 0; 53static int quit_flag = 0;
@@ -70,6 +71,7 @@ enum device_link_file_status_t {
70 DEVICE_LINK_FILE_STATUS_LAST_HUNK 71 DEVICE_LINK_FILE_STATUS_LAST_HUNK
71}; 72};
72 73
74#if 0
73static void sha1_of_data(const char *input, uint32_t size, unsigned char *hash_out) 75static void sha1_of_data(const char *input, uint32_t size, unsigned char *hash_out)
74{ 76{
75 gcry_md_hash_buffer(GCRY_MD_SHA1, hash_out, input, size); 77 gcry_md_hash_buffer(GCRY_MD_SHA1, hash_out, input, size);
@@ -142,6 +144,7 @@ static void print_hash(const unsigned char *hash, int len)
142 printf("%02x", hash[i]); 144 printf("%02x", hash[i]);
143 } 145 }
144} 146}
147#endif
145 148
146static void notify_cb(const char *notification, void *userdata) 149static void notify_cb(const char *notification, void *userdata)
147{ 150{
@@ -184,6 +187,71 @@ static void debug_buf(const char *data, const int length)
184 fprintf(stdout, "\n"); 187 fprintf(stdout, "\n");
185} 188}
186 189
190static void free_dictionary(char **dictionary)
191{
192 int i = 0;
193
194 if (!dictionary)
195 return;
196
197 for (i = 0; dictionary[i]; i++) {
198 free(dictionary[i]);
199 }
200 free(dictionary);
201}
202
203static void mobilebackup_afc_get_file_contents(const char *filename, char **data, uint64_t *size)
204{
205 if (!afc || !data || !size) {
206 return;
207 }
208
209 char **fileinfo;
210 uint32_t fsize = 0;
211
212 afc_get_file_info(afc, filename, &fileinfo);
213 if (!fileinfo) {
214 return;
215 }
216 int i;
217 for (i = 0; fileinfo[i]; i+=2) {
218 if (!strcmp(fileinfo[i], "st_size")) {
219 fsize = atol(fileinfo[i+1]);
220 break;
221 }
222 }
223 free_dictionary(fileinfo);
224
225 if (fsize == 0) {
226 return;
227 }
228
229 uint64_t f = 0;
230 afc_file_open(afc, filename, AFC_FOPEN_RDONLY, &f);
231 if (!f) {
232 return;
233 }
234 char *buf = (char*)malloc((uint32_t)fsize);
235 uint32_t done = 0;
236 while (done < fsize) {
237 uint32_t bread = 0;
238 afc_file_read(afc, f, buf+done, 65536, &bread);
239 if (bread > 0) {
240
241 } else {
242 break;
243 }
244 done += bread;
245 }
246 if (done == fsize) {
247 *size = fsize;
248 *data = buf;
249 } else {
250 free(buf);
251 }
252 afc_file_close(afc, f);
253}
254
187static plist_t mobilebackup_factory_info_plist_new() 255static plist_t mobilebackup_factory_info_plist_new()
188{ 256{
189 /* gather data from lockdown */ 257 /* gather data from lockdown */
@@ -209,6 +277,10 @@ static plist_t mobilebackup_factory_info_plist_new()
209 /* FIXME: How is the GUID generated? */ 277 /* FIXME: How is the GUID generated? */
210 plist_dict_insert_item(ret, "GUID", plist_new_string("---")); 278 plist_dict_insert_item(ret, "GUID", plist_new_string("---"));
211 279
280 value_node = plist_dict_get_item(root_node, "IntegratedCircuitCardIdentity");
281 if (value_node)
282 plist_dict_insert_item(ret, "ICCID", plist_copy(value_node));
283
212 value_node = plist_dict_get_item(root_node, "InternationalMobileEquipmentIdentity"); 284 value_node = plist_dict_get_item(root_node, "InternationalMobileEquipmentIdentity");
213 if (value_node) 285 if (value_node)
214 plist_dict_insert_item(ret, "IMEI", plist_copy(value_node)); 286 plist_dict_insert_item(ret, "IMEI", plist_copy(value_node));
@@ -216,6 +288,9 @@ static plist_t mobilebackup_factory_info_plist_new()
216 g_get_current_time(&tv); 288 g_get_current_time(&tv);
217 plist_dict_insert_item(ret, "Last Backup Date", plist_new_date(tv.tv_sec, tv.tv_usec)); 289 plist_dict_insert_item(ret, "Last Backup Date", plist_new_date(tv.tv_sec, tv.tv_usec));
218 290
291 value_node = plist_dict_get_item(root_node, "PhoneNumber");
292 plist_dict_insert_item(ret, "Phone Number", plist_copy(value_node));
293
219 value_node = plist_dict_get_item(root_node, "ProductType"); 294 value_node = plist_dict_get_item(root_node, "ProductType");
220 plist_dict_insert_item(ret, "Product Type", plist_copy(value_node)); 295 plist_dict_insert_item(ret, "Product Type", plist_copy(value_node));
221 296
@@ -225,26 +300,68 @@ static plist_t mobilebackup_factory_info_plist_new()
225 value_node = plist_dict_get_item(root_node, "SerialNumber"); 300 value_node = plist_dict_get_item(root_node, "SerialNumber");
226 plist_dict_insert_item(ret, "Serial Number", plist_copy(value_node)); 301 plist_dict_insert_item(ret, "Serial Number", plist_copy(value_node));
227 302
303 /* FIXME Sync Settings? */
304
228 value_node = plist_dict_get_item(root_node, "UniqueDeviceID"); 305 value_node = plist_dict_get_item(root_node, "UniqueDeviceID");
229 idevice_get_uuid(phone, &uuid); 306 idevice_get_uuid(phone, &uuid);
230 plist_dict_insert_item(ret, "Target Identifier", plist_new_string(uuid)); 307 plist_dict_insert_item(ret, "Target Identifier", plist_new_string(uuid));
231 308
309 plist_dict_insert_item(ret, "Target Type", plist_new_string("Device"));
310
232 /* uppercase */ 311 /* uppercase */
233 uuid_uppercase = g_ascii_strup(uuid, -1); 312 uuid_uppercase = g_ascii_strup(uuid, -1);
234 plist_dict_insert_item(ret, "Unique Identifier", plist_new_string(uuid_uppercase)); 313 plist_dict_insert_item(ret, "Unique Identifier", plist_new_string(uuid_uppercase));
235 free(uuid_uppercase); 314 free(uuid_uppercase);
236 free(uuid); 315 free(uuid);
237 316
238 /* FIXME: Embed files as <data> nodes */ 317 char *data_buf = NULL;
318 uint64_t data_size = 0;
319 mobilebackup_afc_get_file_contents("/Books/iBooksData2.plist", &data_buf, &data_size);
320 if (data_buf) {
321 plist_dict_insert_item(ret, "iBooks Data 2", plist_new_data(data_buf, data_size));
322 free(data_buf);
323 }
324
239 plist_t files = plist_new_dict(); 325 plist_t files = plist_new_dict();
326 const char *itunesfiles[] = {
327 "ApertureAlbumPrefs",
328 "IC-Info.sidb",
329 "IC-Info.sidv",
330 "PhotosFolderAlbums",
331 "PhotosFolderName",
332 "PhotosFolderPrefs",
333 "iPhotoAlbumPrefs",
334 "iTunesApplicationIDs",
335 "iTunesPrefs",
336 "iTunesPrefs.plist",
337 NULL
338 };
339 int i = 0;
340 for (i = 0; itunesfiles[i]; i++) {
341 data_buf = NULL;
342 data_size = 0;
343 gchar *fname = g_strconcat("/iTunes_Control/iTunes/", itunesfiles[i], NULL);
344 mobilebackup_afc_get_file_contents(fname, &data_buf, &data_size);
345 g_free(fname);
346 if (data_buf) {
347 plist_dict_insert_item(files, itunesfiles[i], plist_new_data(data_buf, data_size));
348 free(data_buf);
349 }
350 }
240 plist_dict_insert_item(ret, "iTunes Files", files); 351 plist_dict_insert_item(ret, "iTunes Files", files);
241 plist_dict_insert_item(ret, "iTunes Version", plist_new_string("9.0.2")); 352
353 plist_t itunes_settings = plist_new_dict();
354 lockdownd_get_value(client, "com.apple.iTunes", NULL, &itunes_settings);
355 plist_dict_insert_item(ret, "iTunes Settings", itunes_settings);
356
357 plist_dict_insert_item(ret, "iTunes Version", plist_new_string("10.0.1"));
242 358
243 plist_free(root_node); 359 plist_free(root_node);
244 360
245 return ret; 361 return ret;
246} 362}
247 363
364#if 0
248static void mobilebackup_info_update_last_backup_date(plist_t info_plist) 365static void mobilebackup_info_update_last_backup_date(plist_t info_plist)
249{ 366{
250 GTimeVal tv = {0, 0}; 367 GTimeVal tv = {0, 0};
@@ -259,6 +376,7 @@ static void mobilebackup_info_update_last_backup_date(plist_t info_plist)
259 376
260 node = NULL; 377 node = NULL;
261} 378}
379#endif
262 380
263static void buffer_read_from_filename(const char *filename, char **buffer, uint64_t *length) 381static void buffer_read_from_filename(const char *filename, char **buffer, uint64_t *length)
264{ 382{
@@ -505,6 +623,7 @@ static int mobilebackup_info_is_current_device(plist_t info)
505 return ret; 623 return ret;
506}*/ 624}*/
507 625
626#if 0
508static int mobilebackup_check_file_integrity(const char *backup_directory, const char *hash, plist_t filedata) 627static int mobilebackup_check_file_integrity(const char *backup_directory, const char *hash, plist_t filedata)
509{ 628{
510 char *datapath; 629 char *datapath;
@@ -655,6 +774,7 @@ static int mobilebackup_check_file_integrity(const char *backup_directory, const
655 plist_free(mdinfo); 774 plist_free(mdinfo);
656 return res; 775 return res;
657} 776}
777#endif
658 778
659static void do_post_notification(const char *notification) 779static void do_post_notification(const char *notification)
660{ 780{
@@ -1204,8 +1324,6 @@ int main(int argc, char *argv[])
1204 printf("ERROR: Backup directory \"%s\" is invalid. No Info.plist found.\n", backup_directory); 1324 printf("ERROR: Backup directory \"%s\" is invalid. No Info.plist found.\n", backup_directory);
1205 return -1; 1325 return -1;
1206 } 1326 }
1207 } else if (cmd == CMD_BACKUP) {
1208 is_full_backup = 1;
1209 } 1327 }
1210 1328
1211 printf("Backup directory is \"%s\"\n", backup_directory); 1329 printf("Backup directory is \"%s\"\n", backup_directory);
@@ -1233,7 +1351,7 @@ int main(int argc, char *argv[])
1233 printf("ERROR: Could not start service %s.\n", NP_SERVICE_NAME); 1351 printf("ERROR: Could not start service %s.\n", NP_SERVICE_NAME);
1234 } 1352 }
1235 1353
1236 afc_client_t afc = NULL; 1354 afc = NULL;
1237 if (cmd == CMD_BACKUP) { 1355 if (cmd == CMD_BACKUP) {
1238 /* start AFC, we need this for the lock file */ 1356 /* start AFC, we need this for the lock file */
1239 port = 0; 1357 port = 0;
@@ -1277,9 +1395,9 @@ int main(int argc, char *argv[])
1277 if (info_plist && (cmd == CMD_BACKUP)) { 1395 if (info_plist && (cmd == CMD_BACKUP)) {
1278 if (mobilebackup_info_is_current_device(info_plist)) { 1396 if (mobilebackup_info_is_current_device(info_plist)) {
1279 /* update the last backup time within Info.plist */ 1397 /* update the last backup time within Info.plist */
1280 mobilebackup_info_update_last_backup_date(info_plist); 1398 //mobilebackup_info_update_last_backup_date(info_plist);
1281 remove(info_path); 1399 //remove(info_path);
1282 plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML); 1400 //plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML);
1283 } else { 1401 } else {
1284 printf("Aborting backup. Backup is not compatible with the current device.\n"); 1402 printf("Aborting backup. Backup is not compatible with the current device.\n");
1285 cmd = CMD_LEAVE; 1403 cmd = CMD_LEAVE;
@@ -1361,17 +1479,14 @@ checkpoint:
1361 1479
1362 /* Info.plist (Device infos, IC-Info.sidb, photos, app_ids, iTunesPrefs) */ 1480 /* Info.plist (Device infos, IC-Info.sidb, photos, app_ids, iTunesPrefs) */
1363 1481
1364 /* create new Info.plist on new backups */ 1482 /* re-create Info.plist */
1365 if (is_full_backup) { 1483 if (info_plist) {
1366 if (info_plist) { 1484 plist_free(info_plist);
1367 plist_free(info_plist); 1485 info_plist = NULL;
1368 info_plist = NULL;
1369 }
1370 remove(info_path);
1371 printf("Creating Info.plist for new backup.\n");
1372 info_plist = mobilebackup_factory_info_plist_new();
1373 plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML);
1374 } 1486 }
1487 info_plist = mobilebackup_factory_info_plist_new();
1488 remove(info_path);
1489 plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML);
1375 g_free(info_path); 1490 g_free(info_path);
1376 1491
1377 plist_free(info_plist); 1492 plist_free(info_plist);
@@ -1385,10 +1500,10 @@ checkpoint:
1385 1500
1386 err = mobilebackup2_send_request(mobilebackup2, "Backup", uuid, NULL, NULL); 1501 err = mobilebackup2_send_request(mobilebackup2, "Backup", uuid, NULL, NULL);
1387 if (err == MOBILEBACKUP2_E_SUCCESS) { 1502 if (err == MOBILEBACKUP2_E_SUCCESS) {
1388 /*if (is_full_backup) 1503 if (is_full_backup)
1389 printf("Full backup mode.\n"); 1504 printf("Full backup mode.\n");
1390 else 1505 else
1391 printf("Incremental backup mode.\n");*/ 1506 printf("Incremental backup mode.\n");
1392 //printf("Please wait. Device is preparing backup data...\n"); 1507 //printf("Please wait. Device is preparing backup data...\n");
1393 } else { 1508 } else {
1394 if (err == MOBILEBACKUP2_E_BAD_VERSION) { 1509 if (err == MOBILEBACKUP2_E_BAD_VERSION) {