summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/ideviceimagemounter.c143
1 files changed, 86 insertions, 57 deletions
diff --git a/tools/ideviceimagemounter.c b/tools/ideviceimagemounter.c
index 09363fd..d47507a 100644
--- a/tools/ideviceimagemounter.c
+++ b/tools/ideviceimagemounter.c
@@ -262,6 +262,11 @@ static void print_xml(plist_t node)
262 puts(xml); 262 puts(xml);
263} 263}
264 264
265static ssize_t mim_upload_cb(void* buf, size_t size, void* userdata)
266{
267 return fread(buf, 1, size, (FILE*)userdata);
268}
269
265int main(int argc, char **argv) 270int main(int argc, char **argv)
266{ 271{
267 idevice_t device = NULL; 272 idevice_t device = NULL;
@@ -271,6 +276,7 @@ int main(int argc, char **argv)
271 lockdownd_service_descriptor_t service = NULL; 276 lockdownd_service_descriptor_t service = NULL;
272 int res = -1; 277 int res = -1;
273 char *image_path = NULL; 278 char *image_path = NULL;
279 size_t image_size = 0;
274 char *image_sig_path = NULL; 280 char *image_sig_path = NULL;
275 281
276 parse_opts(argc, argv); 282 parse_opts(argc, argv);
@@ -304,6 +310,21 @@ int main(int argc, char **argv)
304 goto leave; 310 goto leave;
305 } 311 }
306 312
313 plist_t pver = NULL;
314 char *product_version = NULL;
315 lockdownd_get_value(lckd, NULL, "ProductVersion", &pver);
316 if (pver && plist_get_node_type(pver) == PLIST_STRING) {
317 plist_get_string_val(pver, &product_version);
318 }
319 int ge70 = 0;
320 if (product_version) {
321 int maj = 0;
322 int min = 0;
323 if (sscanf(product_version, "%d.%d.%*d", &maj, &min) == 2) {
324 ge70 = (maj >= 7);
325 }
326 }
327
307 lockdownd_start_service(lckd, "com.apple.mobile.mobile_image_mounter", &service); 328 lockdownd_start_service(lckd, "com.apple.mobile.mobile_image_mounter", &service);
308 329
309 if (!service || service->port == 0) { 330 if (!service || service->port == 0) {
@@ -323,23 +344,26 @@ int main(int argc, char **argv)
323 344
324 if (!list_mode) { 345 if (!list_mode) {
325 struct stat fst; 346 struct stat fst;
326 if ((lockdownd_start_service(lckd, "com.apple.afc", &service) != 347 if (!ge70) {
327 LOCKDOWN_E_SUCCESS) || !service || !service->port) { 348 if ((lockdownd_start_service(lckd, "com.apple.afc", &service) !=
328 fprintf(stderr, "Could not start com.apple.afc!\n"); 349 LOCKDOWN_E_SUCCESS) || !service || !service->port) {
329 goto leave; 350 fprintf(stderr, "Could not start com.apple.afc!\n");
330 } 351 goto leave;
331 if (afc_client_new(device, service, &afc) != AFC_E_SUCCESS) { 352 }
332 fprintf(stderr, "Could not connect to AFC!\n"); 353 if (afc_client_new(device, service, &afc) != AFC_E_SUCCESS) {
333 goto leave; 354 fprintf(stderr, "Could not connect to AFC!\n");
334 } 355 goto leave;
335 if (service) { 356 }
336 lockdownd_service_descriptor_free(service); 357 if (service) {
337 service = NULL; 358 lockdownd_service_descriptor_free(service);
359 service = NULL;
360 }
338 } 361 }
339 if (stat(image_path, &fst) != 0) { 362 if (stat(image_path, &fst) != 0) {
340 fprintf(stderr, "ERROR: stat: %s: %s\n", image_path, strerror(errno)); 363 fprintf(stderr, "ERROR: stat: %s: %s\n", image_path, strerror(errno));
341 goto leave; 364 goto leave;
342 } 365 }
366 image_size = fst.st_size;
343 if (stat(image_sig_path, &fst) != 0) { 367 if (stat(image_sig_path, &fst) != 0) {
344 fprintf(stderr, "ERROR: stat: %s: %s\n", image_sig_path, strerror(errno)); 368 fprintf(stderr, "ERROR: stat: %s: %s\n", image_sig_path, strerror(errno));
345 goto leave; 369 goto leave;
@@ -403,64 +427,69 @@ int main(int argc, char **argv)
403 427
404 printf("Copying '%s' --> '%s'\n", image_path, targetname); 428 printf("Copying '%s' --> '%s'\n", image_path, targetname);
405 429
406 char **strs = NULL; 430 if (!imagetype) {
407 if (afc_get_file_info(afc, PKG_PATH, &strs) != AFC_E_SUCCESS) { 431 imagetype = strdup("Developer");
408 if (afc_make_directory(afc, PKG_PATH) != AFC_E_SUCCESS) {
409 fprintf(stderr, "WARNING: Could not create directory '%s' on device!\n", PKG_PATH);
410 }
411 } 432 }
412 if (strs) { 433
413 int i = 0; 434 if (ge70) {
414 while (strs[i]) { 435 err = mobile_image_mounter_upload_image(mim, imagetype, image_size, mim_upload_cb, f);
415 free(strs[i]); 436 } else {
416 i++; 437 char **strs = NULL;
438 if (afc_get_file_info(afc, PKG_PATH, &strs) != AFC_E_SUCCESS) {
439 if (afc_make_directory(afc, PKG_PATH) != AFC_E_SUCCESS) {
440 fprintf(stderr, "WARNING: Could not create directory '%s' on device!\n", PKG_PATH);
441 }
442 }
443 if (strs) {
444 int i = 0;
445 while (strs[i]) {
446 free(strs[i]);
447 i++;
448 }
449 free(strs);
417 } 450 }
418 free(strs);
419 }
420 451
421 uint64_t af = 0; 452 uint64_t af = 0;
422 if ((afc_file_open(afc, targetname, AFC_FOPEN_WRONLY, &af) != 453 if ((afc_file_open(afc, targetname, AFC_FOPEN_WRONLY, &af) !=
423 AFC_E_SUCCESS) || !af) { 454 AFC_E_SUCCESS) || !af) {
424 fclose(f); 455 fclose(f);
425 fprintf(stderr, "afc_file_open on '%s' failed!\n", targetname); 456 fprintf(stderr, "afc_file_open on '%s' failed!\n", targetname);
426 goto leave; 457 goto leave;
427 } 458 }
428 459
429 char buf[8192]; 460 char buf[8192];
430 size_t amount = 0; 461 size_t amount = 0;
431 do { 462 do {
432 amount = fread(buf, 1, sizeof(buf), f); 463 amount = fread(buf, 1, sizeof(buf), f);
433 if (amount > 0) { 464 if (amount > 0) {
434 uint32_t written, total = 0; 465 uint32_t written, total = 0;
435 while (total < amount) { 466 while (total < amount) {
436 written = 0; 467 written = 0;
437 if (afc_file_write(afc, af, buf, amount, &written) != 468 if (afc_file_write(afc, af, buf, amount, &written) !=
438 AFC_E_SUCCESS) { 469 AFC_E_SUCCESS) {
439 fprintf(stderr, "AFC Write error!\n"); 470 fprintf(stderr, "AFC Write error!\n");
440 break; 471 break;
472 }
473 total += written;
474 }
475 if (total != amount) {
476 fprintf(stderr, "Error: wrote only %d of %d\n", total,
477 (unsigned int)amount);
478 afc_file_close(afc, af);
479 fclose(f);
480 goto leave;
441 } 481 }
442 total += written;
443 }
444 if (total != amount) {
445 fprintf(stderr, "Error: wrote only %d of %d\n", total,
446 (unsigned int)amount);
447 afc_file_close(afc, af);
448 fclose(f);
449 goto leave;
450 } 482 }
451 } 483 }
452 } 484 while (amount > 0);
453 while (amount > 0);
454 485
455 afc_file_close(afc, af); 486 afc_file_close(afc, af);
487 }
456 fclose(f); 488 fclose(f);
457 489
458 printf("done.\n"); 490 printf("done.\n");
459 491
460 printf("Mounting...\n"); 492 printf("Mounting...\n");
461 if (!imagetype) {
462 imagetype = strdup("Developer");
463 }
464 err = mobile_image_mounter_mount_image(mim, mountname, sig, sig_length, imagetype, &result); 493 err = mobile_image_mounter_mount_image(mim, mountname, sig, sig_length, imagetype, &result);
465 free(imagetype); 494 free(imagetype);
466 if (err == MOBILE_IMAGE_MOUNTER_E_SUCCESS) { 495 if (err == MOBILE_IMAGE_MOUNTER_E_SUCCESS) {