summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/idevicebackup4.c92
1 files changed, 52 insertions, 40 deletions
diff --git a/tools/idevicebackup4.c b/tools/idevicebackup4.c
index ef3fdd0..55b7802 100644
--- a/tools/idevicebackup4.c
+++ b/tools/idevicebackup4.c
@@ -42,8 +42,9 @@
42#define LOCK_ATTEMPTS 50 42#define LOCK_ATTEMPTS 50
43#define LOCK_WAIT 200000 43#define LOCK_WAIT 200000
44 44
45#define CODE_NULL 0x00 45#define CODE_SUCCESS 0x00
46#define CODE_ERROR_MSG 0x0b 46#define CODE_ERROR_LOCAL 0x06
47#define CODE_ERROR_REMOTE 0x0b
47#define CODE_FILE_DATA 0x0c 48#define CODE_FILE_DATA 0x0c
48 49
49static mobilebackup2_client_t mobilebackup2 = NULL; 50static mobilebackup2_client_t mobilebackup2 = NULL;
@@ -823,35 +824,38 @@ static int handle_send_file(const char *backup_dir, const char *path, plist_t *e
823{ 824{
824 uint32_t nlen = 0; 825 uint32_t nlen = 0;
825 uint32_t pathlen = strlen(path); 826 uint32_t pathlen = strlen(path);
826 int bytes = 0; 827 uint32_t bytes = 0;
827 gchar *localfile = g_build_path(G_DIR_SEPARATOR_S, backup_dir, path, NULL); 828 gchar *localfile = g_build_path(G_DIR_SEPARATOR_S, backup_dir, path, NULL);
828 char buf[16384]; 829 char buf[32768];
829 struct stat fst; 830 struct stat fst;
830 831
831 FILE *f = NULL; 832 FILE *f = NULL;
832 uint32_t slen = 0; 833 uint32_t slen = 0;
833 int errcode = -1; 834 int errcode = -1;
834 int e = -1; 835 int result = -1;
836 uint32_t length;
837 off_t total;
838 off_t sent;
835 839
836 mobilebackup2_error_t err; 840 mobilebackup2_error_t err;
837 841
838 /* send path length */ 842 /* send path length */
839 nlen = GUINT32_TO_BE(pathlen); 843 nlen = GUINT32_TO_BE(pathlen);
840 err = mobilebackup2_send_raw(mobilebackup2, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes); 844 err = mobilebackup2_send_raw(mobilebackup2, (const char*)&nlen, sizeof(nlen), &bytes);
841 if (err != MOBILEBACKUP2_E_SUCCESS) { 845 if (err != MOBILEBACKUP2_E_SUCCESS) {
842 goto leave_proto_err; 846 goto leave_proto_err;
843 } 847 }
844 if (bytes != sizeof(nlen)) { 848 if (bytes != (uint32_t)sizeof(nlen)) {
845 err = MOBILEBACKUP2_E_MUX_ERROR; 849 err = MOBILEBACKUP2_E_MUX_ERROR;
846 goto leave_proto_err; 850 goto leave_proto_err;
847 } 851 }
848 852
849 /* send path */ 853 /* send path */
850 err = mobilebackup2_send_raw(mobilebackup2, path, pathlen, (uint32_t*)&bytes); 854 err = mobilebackup2_send_raw(mobilebackup2, path, pathlen, &bytes);
851 if (err != MOBILEBACKUP2_E_SUCCESS) { 855 if (err != MOBILEBACKUP2_E_SUCCESS) {
852 goto leave_proto_err; 856 goto leave_proto_err;
853 } 857 }
854 if ((uint32_t)bytes != pathlen) { 858 if (bytes != pathlen) {
855 err = MOBILEBACKUP2_E_MUX_ERROR; 859 err = MOBILEBACKUP2_E_MUX_ERROR;
856 goto leave_proto_err; 860 goto leave_proto_err;
857 } 861 }
@@ -862,6 +866,17 @@ static int handle_send_file(const char *backup_dir, const char *path, plist_t *e
862 goto leave; 866 goto leave;
863 } 867 }
864 868
869 total = fst.st_size;
870
871 gchar *format_size = g_format_size_for_display(total);
872 printf("Sending file '%s': (%s)\n", path, format_size);
873 g_free(format_size);
874
875 if (total == 0) {
876 errcode = 0;
877 goto leave;
878 }
879
865 f = fopen(localfile, "rb"); 880 f = fopen(localfile, "rb");
866 if (!f) { 881 if (!f) {
867 printf("%s: Error opening local file '%s': %d\n", __func__, localfile, errno); 882 printf("%s: Error opening local file '%s': %d\n", __func__, localfile, errno);
@@ -869,53 +884,50 @@ static int handle_send_file(const char *backup_dir, const char *path, plist_t *e
869 goto leave; 884 goto leave;
870 } 885 }
871 886
872 printf("Sending file '%s'\n", path); 887 sent = 0;
873 888 do {
874 /* send data size (file size + 1) */ 889 length = ((total-sent) < (off_t)sizeof(buf)) ? (uint32_t)total-sent : (uint32_t)sizeof(buf);
875 uint32_t length = (uint32_t)fst.st_size; 890 /* send data size (file size + 1) */
876 nlen = GUINT32_TO_BE(length+1); 891 nlen = GUINT32_TO_BE(length+1);
877 memcpy(buf, &nlen, sizeof(nlen)); 892 memcpy(buf, &nlen, sizeof(nlen));
878 /* unknown special byte */ 893 buf[4] = CODE_FILE_DATA;
879 buf[4] = 0x0C; 894 err = mobilebackup2_send_raw(mobilebackup2, (const char*)buf, 5, &bytes);
880 err = mobilebackup2_send_raw(mobilebackup2, (const char*)buf, 5, (uint32_t*)&bytes); 895 if (err != MOBILEBACKUP2_E_SUCCESS) {
881 if (err != MOBILEBACKUP2_E_SUCCESS) { 896 goto leave_proto_err;
882 goto leave_proto_err; 897 }
883 } 898 if (bytes != 5) {
884 if (bytes != 5) { 899 goto leave_proto_err;
885 goto leave_proto_err; 900 }
886 }
887 901
888 /* send file contents */ 902 /* send file contents */
889 uint32_t sent = 0;
890 while (sent < length) {
891 size_t r = fread(buf, 1, sizeof(buf), f); 903 size_t r = fread(buf, 1, sizeof(buf), f);
892 if (r <= 0) { 904 if (r <= 0) {
893 printf("%s: read error\n", __func__); 905 printf("%s: read error\n", __func__);
894 errcode = errno; 906 errcode = errno;
895 goto leave; 907 goto leave;
896 } 908 }
897 err = mobilebackup2_send_raw(mobilebackup2, buf, r, (uint32_t*)&bytes); 909 err = mobilebackup2_send_raw(mobilebackup2, buf, r, &bytes);
898 if (err != MOBILEBACKUP2_E_SUCCESS) { 910 if (err != MOBILEBACKUP2_E_SUCCESS) {
899 goto leave_proto_err; 911 goto leave_proto_err;
900 } 912 }
901 if ((uint32_t)bytes != r) { 913 if (bytes != (uint32_t)r) {
902 printf("sent only %d from %d\n", bytes, r); 914 printf("Error: sent only %d of %d bytes\n", bytes, (int)r);
903 goto leave_proto_err; 915 goto leave_proto_err;
904 } 916 }
905 sent += r; 917 sent += r;
906 } 918 } while (sent < total);
907 fclose(f); 919 fclose(f);
908 f = NULL; 920 f = NULL;
909 errcode = 0; 921 errcode = 0;
910 922
911leave: 923leave:
912 if (errcode == 0) { 924 if (errcode == 0) {
913 e = 0; 925 result = 0;
914 nlen = 1; 926 nlen = 1;
915 nlen = GUINT32_TO_BE(nlen); 927 nlen = GUINT32_TO_BE(nlen);
916 memcpy(buf, &nlen, 4); 928 memcpy(buf, &nlen, 4);
917 buf[4] = 0; 929 buf[4] = CODE_SUCCESS;
918 mobilebackup2_send_raw(mobilebackup2, buf, 5, &sent); 930 mobilebackup2_send_raw(mobilebackup2, buf, 5, &bytes);
919 } else { 931 } else {
920 if (!*errplist) { 932 if (!*errplist) {
921 *errplist = plist_new_dict(); 933 *errplist = plist_new_dict();
@@ -926,15 +938,15 @@ leave:
926 length = strlen(errdesc); 938 length = strlen(errdesc);
927 nlen = GUINT32_TO_BE(length+1); 939 nlen = GUINT32_TO_BE(length+1);
928 memcpy(buf, &nlen, 4); 940 memcpy(buf, &nlen, 4);
929 buf[4] = 0x06; 941 buf[4] = CODE_ERROR_LOCAL;
930 slen = 5; 942 slen = 5;
931 memcpy(buf+slen, errdesc, length); 943 memcpy(buf+slen, errdesc, length);
932 slen += length; 944 slen += length;
933 err = mobilebackup2_send_raw(mobilebackup2, (const char*)buf, slen, (uint32_t*)&bytes); 945 err = mobilebackup2_send_raw(mobilebackup2, (const char*)buf, slen, &bytes);
934 if (err != MOBILEBACKUP2_E_SUCCESS) { 946 if (err != MOBILEBACKUP2_E_SUCCESS) {
935 printf("could not send message\n"); 947 printf("could not send message\n");
936 } 948 }
937 if ((uint32_t)bytes != slen) { 949 if (bytes != slen) {
938 printf("could only send %d from %d\n", bytes, slen); 950 printf("could only send %d from %d\n", bytes, slen);
939 } 951 }
940 } 952 }
@@ -943,7 +955,7 @@ leave_proto_err:
943 if (f) 955 if (f)
944 fclose(f); 956 fclose(f);
945 g_free(localfile); 957 g_free(localfile);
946 return e; 958 return result;
947} 959}
948 960
949static void handle_send_files(plist_t message, const char *backup_dir) 961static void handle_send_files(plist_t message, const char *backup_dir)
@@ -1050,7 +1062,7 @@ static int handle_receive_files(plist_t message, const char *backup_dir)
1050 mobilebackup2_receive_raw(mobilebackup2, &code, 1, &r); 1062 mobilebackup2_receive_raw(mobilebackup2, &code, 1, &r);
1051 1063
1052 /* TODO remove this */ 1064 /* TODO remove this */
1053 if ((code != 0) && (code != CODE_FILE_DATA) && (code != CODE_ERROR_MSG)) { 1065 if ((code != CODE_SUCCESS) && (code != CODE_FILE_DATA) && (code != CODE_ERROR_REMOTE)) {
1054 printf("Found new flag %02x\n", code); 1066 printf("Found new flag %02x\n", code);
1055 } 1067 }
1056 1068
@@ -1103,7 +1115,7 @@ static int handle_receive_files(plist_t message, const char *backup_dir)
1103 } 1115 }
1104 1116
1105 /* check if an error message was received */ 1117 /* check if an error message was received */
1106 if (code == CODE_ERROR_MSG) { 1118 if (code == CODE_ERROR_REMOTE) {
1107 /* error message */ 1119 /* error message */
1108 char *msg = (char*)malloc(nlen); 1120 char *msg = (char*)malloc(nlen);
1109 mobilebackup2_receive_raw(mobilebackup2, msg, nlen-1, &r); 1121 mobilebackup2_receive_raw(mobilebackup2, msg, nlen-1, &r);