diff options
Diffstat (limited to 'src/ideviceinstaller.c')
| -rw-r--r-- | src/ideviceinstaller.c | 88 |
1 files changed, 48 insertions, 40 deletions
diff --git a/src/ideviceinstaller.c b/src/ideviceinstaller.c index 51fbe7b..2d07a03 100644 --- a/src/ideviceinstaller.c +++ b/src/ideviceinstaller.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <libgen.h> | 34 | #include <libgen.h> |
| 35 | #include <inttypes.h> | 35 | #include <inttypes.h> |
| 36 | #include <limits.h> | 36 | #include <limits.h> |
| 37 | #include <sys/stat.h> | ||
| 37 | 38 | ||
| 38 | #include <libimobiledevice/libimobiledevice.h> | 39 | #include <libimobiledevice/libimobiledevice.h> |
| 39 | #include <libimobiledevice/lockdown.h> | 40 | #include <libimobiledevice/lockdown.h> |
| @@ -381,6 +382,52 @@ static void parse_opts(int argc, char **argv) | |||
| 381 | } | 382 | } |
| 382 | } | 383 | } |
| 383 | 384 | ||
| 385 | static int afc_upload_file(afc_client_t afc, const char* filename, const char* dstfn) | ||
| 386 | { | ||
| 387 | FILE *f = NULL; | ||
| 388 | uint64_t af = 0; | ||
| 389 | char buf[8192]; | ||
| 390 | |||
| 391 | f = fopen(filename, "rb"); | ||
| 392 | if (!f) { | ||
| 393 | fprintf(stderr, "fopen: %s: %s\n", appid, strerror(errno)); | ||
| 394 | return -1; | ||
| 395 | } | ||
| 396 | |||
| 397 | if ((afc_file_open(afc, dstfn, AFC_FOPEN_WRONLY, &af) != AFC_E_SUCCESS) || !af) { | ||
| 398 | fclose(f); | ||
| 399 | fprintf(stderr, "afc_file_open on '%s' failed!\n", dstfn); | ||
| 400 | return -1; | ||
| 401 | } | ||
| 402 | |||
| 403 | size_t amount = 0; | ||
| 404 | do { | ||
| 405 | amount = fread(buf, 1, sizeof(buf), f); | ||
| 406 | if (amount > 0) { | ||
| 407 | uint32_t written, total = 0; | ||
| 408 | while (total < amount) { | ||
| 409 | written = 0; | ||
| 410 | if (afc_file_write(afc, af, buf, amount, &written) != AFC_E_SUCCESS) { | ||
| 411 | fprintf(stderr, "AFC Write error!\n"); | ||
| 412 | break; | ||
| 413 | } | ||
| 414 | total += written; | ||
| 415 | } | ||
| 416 | if (total != amount) { | ||
| 417 | fprintf(stderr, "Error: wrote only %d of %zu\n", total, amount); | ||
| 418 | afc_file_close(afc, af); | ||
| 419 | fclose(f); | ||
| 420 | return -1; | ||
| 421 | } | ||
| 422 | } | ||
| 423 | } while (amount > 0); | ||
| 424 | |||
| 425 | afc_file_close(afc, af); | ||
| 426 | fclose(f); | ||
| 427 | |||
| 428 | return 0; | ||
| 429 | } | ||
| 430 | |||
| 384 | int main(int argc, char **argv) | 431 | int main(int argc, char **argv) |
| 385 | { | 432 | { |
| 386 | idevice_t phone = NULL; | 433 | idevice_t phone = NULL; |
| @@ -560,7 +607,6 @@ run_again: | |||
| 560 | plist_t meta = NULL; | 607 | plist_t meta = NULL; |
| 561 | char *pkgname = NULL; | 608 | char *pkgname = NULL; |
| 562 | struct stat fst; | 609 | struct stat fst; |
| 563 | FILE *f = NULL; | ||
| 564 | uint64_t af = 0; | 610 | uint64_t af = 0; |
| 565 | char buf[8192]; | 611 | char buf[8192]; |
| 566 | 612 | ||
| @@ -777,12 +823,6 @@ run_again: | |||
| 777 | } | 823 | } |
| 778 | 824 | ||
| 779 | /* copy archive to device */ | 825 | /* copy archive to device */ |
| 780 | f = fopen(appid, "rb"); | ||
| 781 | if (!f) { | ||
| 782 | fprintf(stderr, "fopen: %s: %s\n", appid, strerror(errno)); | ||
| 783 | goto leave_cleanup; | ||
| 784 | } | ||
| 785 | |||
| 786 | pkgname = NULL; | 826 | pkgname = NULL; |
| 787 | if (asprintf(&pkgname, "%s/%s", PKG_PATH, basename(appid)) < 0) { | 827 | if (asprintf(&pkgname, "%s/%s", PKG_PATH, basename(appid)) < 0) { |
| 788 | fprintf(stderr, "Out of memory!?\n"); | 828 | fprintf(stderr, "Out of memory!?\n"); |
| @@ -806,43 +846,11 @@ run_again: | |||
| 806 | free(strs); | 846 | free(strs); |
| 807 | } | 847 | } |
| 808 | 848 | ||
| 809 | if ((afc_file_open(afc, pkgname, AFC_FOPEN_WRONLY, &af) != | 849 | if (afc_upload_file(afc, appid, pkgname) < 0) { |
| 810 | AFC_E_SUCCESS) || !af) { | ||
| 811 | fclose(f); | ||
| 812 | fprintf(stderr, "afc_file_open on '%s' failed!\n", pkgname); | ||
| 813 | free(pkgname); | 850 | free(pkgname); |
| 814 | goto leave_cleanup; | 851 | goto leave_cleanup; |
| 815 | } | 852 | } |
| 816 | 853 | ||
| 817 | size_t amount = 0; | ||
| 818 | do { | ||
| 819 | amount = fread(buf, 1, sizeof(buf), f); | ||
| 820 | if (amount > 0) { | ||
| 821 | uint32_t written, total = 0; | ||
| 822 | while (total < amount) { | ||
| 823 | written = 0; | ||
| 824 | if (afc_file_write(afc, af, buf, amount, &written) != | ||
| 825 | AFC_E_SUCCESS) { | ||
| 826 | fprintf(stderr, "AFC Write error!\n"); | ||
| 827 | break; | ||
| 828 | } | ||
| 829 | total += written; | ||
| 830 | } | ||
| 831 | if (total != amount) { | ||
| 832 | fprintf(stderr, "Error: wrote only %d of %zu\n", total, | ||
| 833 | amount); | ||
| 834 | afc_file_close(afc, af); | ||
| 835 | fclose(f); | ||
| 836 | free(pkgname); | ||
| 837 | goto leave_cleanup; | ||
| 838 | } | ||
| 839 | } | ||
| 840 | } | ||
| 841 | while (amount > 0); | ||
| 842 | |||
| 843 | afc_file_close(afc, af); | ||
| 844 | fclose(f); | ||
| 845 | |||
| 846 | printf("done.\n"); | 854 | printf("done.\n"); |
| 847 | 855 | ||
| 848 | if (sinf) { | 856 | if (sinf) { |
