diff options
-rw-r--r-- | tools/idevicebackup4.c | 92 |
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 @@ #define LOCK_ATTEMPTS 50 #define LOCK_WAIT 200000 -#define CODE_NULL 0x00 -#define CODE_ERROR_MSG 0x0b +#define CODE_SUCCESS 0x00 +#define CODE_ERROR_LOCAL 0x06 +#define CODE_ERROR_REMOTE 0x0b #define CODE_FILE_DATA 0x0c static mobilebackup2_client_t mobilebackup2 = NULL; @@ -823,35 +824,38 @@ static int handle_send_file(const char *backup_dir, const char *path, plist_t *e { uint32_t nlen = 0; uint32_t pathlen = strlen(path); - int bytes = 0; + uint32_t bytes = 0; gchar *localfile = g_build_path(G_DIR_SEPARATOR_S, backup_dir, path, NULL); - char buf[16384]; + char buf[32768]; struct stat fst; FILE *f = NULL; uint32_t slen = 0; int errcode = -1; - int e = -1; + int result = -1; + uint32_t length; + off_t total; + off_t sent; mobilebackup2_error_t err; /* send path length */ nlen = GUINT32_TO_BE(pathlen); - err = mobilebackup2_send_raw(mobilebackup2, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes); + err = mobilebackup2_send_raw(mobilebackup2, (const char*)&nlen, sizeof(nlen), &bytes); if (err != MOBILEBACKUP2_E_SUCCESS) { goto leave_proto_err; } - if (bytes != sizeof(nlen)) { + if (bytes != (uint32_t)sizeof(nlen)) { err = MOBILEBACKUP2_E_MUX_ERROR; goto leave_proto_err; } /* send path */ - err = mobilebackup2_send_raw(mobilebackup2, path, pathlen, (uint32_t*)&bytes); + err = mobilebackup2_send_raw(mobilebackup2, path, pathlen, &bytes); if (err != MOBILEBACKUP2_E_SUCCESS) { goto leave_proto_err; } - if ((uint32_t)bytes != pathlen) { + if (bytes != pathlen) { err = MOBILEBACKUP2_E_MUX_ERROR; goto leave_proto_err; } @@ -862,6 +866,17 @@ static int handle_send_file(const char *backup_dir, const char *path, plist_t *e goto leave; } + total = fst.st_size; + + gchar *format_size = g_format_size_for_display(total); + printf("Sending file '%s': (%s)\n", path, format_size); + g_free(format_size); + + if (total == 0) { + errcode = 0; + goto leave; + } + f = fopen(localfile, "rb"); if (!f) { 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 goto leave; } - printf("Sending file '%s'\n", path); - - /* send data size (file size + 1) */ - uint32_t length = (uint32_t)fst.st_size; - nlen = GUINT32_TO_BE(length+1); - memcpy(buf, &nlen, sizeof(nlen)); - /* unknown special byte */ - buf[4] = 0x0C; - err = mobilebackup2_send_raw(mobilebackup2, (const char*)buf, 5, (uint32_t*)&bytes); - if (err != MOBILEBACKUP2_E_SUCCESS) { - goto leave_proto_err; - } - if (bytes != 5) { - goto leave_proto_err; - } + sent = 0; + do { + length = ((total-sent) < (off_t)sizeof(buf)) ? (uint32_t)total-sent : (uint32_t)sizeof(buf); + /* send data size (file size + 1) */ + nlen = GUINT32_TO_BE(length+1); + memcpy(buf, &nlen, sizeof(nlen)); + buf[4] = CODE_FILE_DATA; + err = mobilebackup2_send_raw(mobilebackup2, (const char*)buf, 5, &bytes); + if (err != MOBILEBACKUP2_E_SUCCESS) { + goto leave_proto_err; + } + if (bytes != 5) { + goto leave_proto_err; + } - /* send file contents */ - uint32_t sent = 0; - while (sent < length) { + /* send file contents */ size_t r = fread(buf, 1, sizeof(buf), f); if (r <= 0) { printf("%s: read error\n", __func__); errcode = errno; goto leave; } - err = mobilebackup2_send_raw(mobilebackup2, buf, r, (uint32_t*)&bytes); + err = mobilebackup2_send_raw(mobilebackup2, buf, r, &bytes); if (err != MOBILEBACKUP2_E_SUCCESS) { goto leave_proto_err; } - if ((uint32_t)bytes != r) { - printf("sent only %d from %d\n", bytes, r); + if (bytes != (uint32_t)r) { + printf("Error: sent only %d of %d bytes\n", bytes, (int)r); goto leave_proto_err; } sent += r; - } + } while (sent < total); fclose(f); f = NULL; errcode = 0; leave: if (errcode == 0) { - e = 0; + result = 0; nlen = 1; nlen = GUINT32_TO_BE(nlen); memcpy(buf, &nlen, 4); - buf[4] = 0; - mobilebackup2_send_raw(mobilebackup2, buf, 5, &sent); + buf[4] = CODE_SUCCESS; + mobilebackup2_send_raw(mobilebackup2, buf, 5, &bytes); } else { if (!*errplist) { *errplist = plist_new_dict(); @@ -926,15 +938,15 @@ leave: length = strlen(errdesc); nlen = GUINT32_TO_BE(length+1); memcpy(buf, &nlen, 4); - buf[4] = 0x06; + buf[4] = CODE_ERROR_LOCAL; slen = 5; memcpy(buf+slen, errdesc, length); slen += length; - err = mobilebackup2_send_raw(mobilebackup2, (const char*)buf, slen, (uint32_t*)&bytes); + err = mobilebackup2_send_raw(mobilebackup2, (const char*)buf, slen, &bytes); if (err != MOBILEBACKUP2_E_SUCCESS) { printf("could not send message\n"); } - if ((uint32_t)bytes != slen) { + if (bytes != slen) { printf("could only send %d from %d\n", bytes, slen); } } @@ -943,7 +955,7 @@ leave_proto_err: if (f) fclose(f); g_free(localfile); - return e; + return result; } static 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) mobilebackup2_receive_raw(mobilebackup2, &code, 1, &r); /* TODO remove this */ - if ((code != 0) && (code != CODE_FILE_DATA) && (code != CODE_ERROR_MSG)) { + if ((code != CODE_SUCCESS) && (code != CODE_FILE_DATA) && (code != CODE_ERROR_REMOTE)) { printf("Found new flag %02x\n", code); } @@ -1103,7 +1115,7 @@ static int handle_receive_files(plist_t message, const char *backup_dir) } /* check if an error message was received */ - if (code == CODE_ERROR_MSG) { + if (code == CODE_ERROR_REMOTE) { /* error message */ char *msg = (char*)malloc(nlen); mobilebackup2_receive_raw(mobilebackup2, msg, nlen-1, &r); |