diff options
Diffstat (limited to 'tools/ideviceimagemounter.c')
| -rw-r--r-- | tools/ideviceimagemounter.c | 143 |
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 | ||
| 265 | static ssize_t mim_upload_cb(void* buf, size_t size, void* userdata) | ||
| 266 | { | ||
| 267 | return fread(buf, 1, size, (FILE*)userdata); | ||
| 268 | } | ||
| 269 | |||
| 265 | int main(int argc, char **argv) | 270 | int 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) { |
