summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/AFC.c66
-rw-r--r--src/AFC.h11
-rw-r--r--src/ifuse.c5
-rw-r--r--src/iphone.c3
-rw-r--r--src/lockdown.c36
-rw-r--r--src/lockdown.h3
-rw-r--r--src/plist.h1
-rw-r--r--src/usbmux.c251
-rw-r--r--src/usbmux.h17
-rw-r--r--src/userpref.c2
10 files changed, 277 insertions, 118 deletions
diff --git a/src/AFC.c b/src/AFC.c
index 675d127..f2f71d5 100644
--- a/src/AFC.c
+++ b/src/AFC.c
@@ -34,7 +34,6 @@ AFClient *afc_connect(iPhone *phone, int s_port, int d_port) {
34 else { 34 else {
35 client->afc_packet = (AFCPacket*)malloc(sizeof(AFCPacket)); 35 client->afc_packet = (AFCPacket*)malloc(sizeof(AFCPacket));
36 if (client->afc_packet) { 36 if (client->afc_packet) {
37 client->phone = phone;
38 client->afc_packet->packet_num = 0; 37 client->afc_packet->packet_num = 0;
39 client->afc_packet->unknown1 = client->afc_packet->unknown2 = client->afc_packet->unknown3 = client->afc_packet->unknown4 = client->afc_packet->entire_length = client->afc_packet->this_length = 0; 38 client->afc_packet->unknown1 = client->afc_packet->unknown2 = client->afc_packet->unknown3 = client->afc_packet->unknown4 = client->afc_packet->entire_length = client->afc_packet->this_length = 0;
40 client->afc_packet->header1 = 0x36414643; 39 client->afc_packet->header1 = 0x36414643;
@@ -42,7 +41,7 @@ AFClient *afc_connect(iPhone *phone, int s_port, int d_port) {
42 client->file_handle = 0; 41 client->file_handle = 0;
43 return client; 42 return client;
44 } else { 43 } else {
45 mux_close_connection(client->phone, client->connection); 44 mux_close_connection(client->connection);
46 free(client); 45 free(client);
47 return NULL; 46 return NULL;
48 } 47 }
@@ -53,8 +52,8 @@ AFClient *afc_connect(iPhone *phone, int s_port, int d_port) {
53 52
54void afc_disconnect(AFClient *client) { 53void afc_disconnect(AFClient *client) {
55 // client and its members should never be NULL is assumed here. 54 // client and its members should never be NULL is assumed here.
56 if (!client || !client->connection || !client->phone || !client->afc_packet) return; 55 if (!client || !client->connection || !client->afc_packet) return;
57 mux_close_connection(client->phone, client->connection); 56 mux_close_connection(client->connection);
58 free(client->afc_packet); 57 free(client->afc_packet);
59 free(client); 58 free(client);
60} 59}
@@ -67,10 +66,10 @@ int count_nullspaces(char *string, int number) {
67 return nulls; 66 return nulls;
68} 67}
69 68
70int dispatch_AFC_packet(AFClient *client, char *data, int length) { 69int dispatch_AFC_packet(AFClient *client, const char *data, int length) {
71 char *buffer; 70 char *buffer;
72 int bytes = 0, offset = 0; 71 int bytes = 0, offset = 0;
73 if (!client || !client->connection || !client->phone || !client->afc_packet) return 0; 72 if (!client || !client->connection || !client->afc_packet) return 0;
74 if (!data || !length) length = 0; 73 if (!data || !length) length = 0;
75 74
76 client->afc_packet->packet_num++; 75 client->afc_packet->packet_num++;
@@ -91,7 +90,7 @@ int dispatch_AFC_packet(AFClient *client, char *data, int length) {
91 } 90 }
92 if (debug) printf("dispatch_AFC_packet: fucked-up packet method (probably a write)\n"); 91 if (debug) printf("dispatch_AFC_packet: fucked-up packet method (probably a write)\n");
93 memcpy(buffer+sizeof(AFCPacket), data, offset); 92 memcpy(buffer+sizeof(AFCPacket), data, offset);
94 bytes = mux_send(client->phone, client->connection, buffer, client->afc_packet->this_length); 93 bytes = mux_send(client->connection, buffer, client->afc_packet->this_length);
95 free(buffer); 94 free(buffer);
96 if (bytes <= 0) { return 0; } 95 if (bytes <= 0) { return 0; }
97 if (debug) { 96 if (debug) {
@@ -102,7 +101,7 @@ int dispatch_AFC_packet(AFClient *client, char *data, int length) {
102 } 101 }
103 102
104 103
105 bytes = mux_send(client->phone, client->connection, data+offset, length-offset); 104 bytes = mux_send(client->connection, data+offset, length-offset);
106 if (bytes <= 0) { return 0; } 105 if (bytes <= 0) { return 0; }
107 else { return bytes; } 106 else { return bytes; }
108 } else { 107 } else {
@@ -114,7 +113,7 @@ int dispatch_AFC_packet(AFClient *client, char *data, int length) {
114 if (length > 0) { memcpy(buffer+sizeof(AFCPacket), data, length); buffer[sizeof(AFCPacket)+length] = '\0'; } 113 if (length > 0) { memcpy(buffer+sizeof(AFCPacket), data, length); buffer[sizeof(AFCPacket)+length] = '\0'; }
115 if (debug) fwrite(buffer, 1, client->afc_packet->this_length, stdout); 114 if (debug) fwrite(buffer, 1, client->afc_packet->this_length, stdout);
116 if (debug) printf("\n"); 115 if (debug) printf("\n");
117 bytes = mux_send(client->phone, client->connection, buffer, client->afc_packet->this_length); 116 bytes = mux_send(client->connection, buffer, client->afc_packet->this_length);
118 if (bytes <= 0) return 0; 117 if (bytes <= 0) return 0;
119 else return bytes; 118 else return bytes;
120 } 119 }
@@ -126,9 +125,9 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
126 char *buffer = (char*)malloc(sizeof(AFCPacket) * 4); 125 char *buffer = (char*)malloc(sizeof(AFCPacket) * 4);
127 char *final_buffer = NULL; 126 char *final_buffer = NULL;
128 int bytes = 0, recv_len = 0, current_count=0; 127 int bytes = 0, recv_len = 0, current_count=0;
129 int retval = 0; 128 int retval = 0;
130 129
131 bytes = mux_recv(client->phone, client->connection, buffer, sizeof(AFCPacket) * 4); 130 bytes = mux_recv(client->connection, buffer, sizeof(AFCPacket) * 4);
132 if (bytes <= 0) { 131 if (bytes <= 0) {
133 free(buffer); 132 free(buffer);
134 printf("Just didn't get enough.\n"); 133 printf("Just didn't get enough.\n");
@@ -151,10 +150,17 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
151 uint32 param1 = buffer[sizeof(AFCPacket)]; 150 uint32 param1 = buffer[sizeof(AFCPacket)];
152 free(buffer); 151 free(buffer);
153 152
154 if (r_packet->operation == 0x01 && !((client->afc_packet->operation == AFC_DELETE && param1 == 7))) { 153 if (r_packet->operation == AFC_ERROR
155 if (debug) printf("Oops? Bad operation code received: 0x%0X\n", r_packet->operation); 154 && !(client->afc_packet->operation == AFC_DELETE && param1 == 7)
156 if (param1 == 0) { 155 )
156 {
157 if (debug) printf("Oops? Bad operation code received: 0x%X, operation=0x%X, param1=%d\n",
158 r_packet->operation, client->afc_packet->operation, param1);
159 recv_len = r_packet->entire_length - r_packet->this_length;
160 if (debug) printf("recv_len=%d\n", recv_len);
161 if(param1 == 0) {
157 if (debug) printf("... false alarm, but still\n"); 162 if (debug) printf("... false alarm, but still\n");
163 *dump_here = NULL;
158 return 1; 164 return 1;
159 } 165 }
160 else { if (debug) printf("Errno %i\n", param1); } 166 else { if (debug) printf("Errno %i\n", param1); }
@@ -167,13 +173,17 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
167 173
168 recv_len = r_packet->entire_length - r_packet->this_length; 174 recv_len = r_packet->entire_length - r_packet->this_length;
169 free(r_packet); 175 free(r_packet);
170 if (!recv_len) return bytes; 176 if (!recv_len)
177 {
178 *dump_here = NULL;
179 return 0;
180 }
171 181
172 // Keep collecting packets until we have received the entire file. 182 // Keep collecting packets until we have received the entire file.
173 buffer = (char*)malloc(sizeof(char) * (recv_len < MAXIMUM_PACKET_SIZE) ? recv_len : MAXIMUM_PACKET_SIZE); 183 buffer = (char*)malloc(sizeof(char) * (recv_len < MAXIMUM_PACKET_SIZE) ? recv_len : MAXIMUM_PACKET_SIZE);
174 final_buffer = (char*)malloc(sizeof(char) * recv_len); 184 final_buffer = (char*)malloc(sizeof(char) * recv_len);
175 while(current_count < recv_len){ 185 while(current_count < recv_len){
176 bytes = mux_recv(client->phone, client->connection, buffer, recv_len-current_count); 186 bytes = mux_recv(client->connection, buffer, recv_len-current_count);
177 if (bytes < 0) 187 if (bytes < 0)
178 { 188 {
179 if(debug) printf("receive_AFC_data: mux_recv failed: %d\n", bytes); 189 if(debug) printf("receive_AFC_data: mux_recv failed: %d\n", bytes);
@@ -200,7 +210,7 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
200 return current_count; 210 return current_count;
201} 211}
202 212
203char **afc_get_dir_list(AFClient *client, char *dir) { 213char **afc_get_dir_list(AFClient *client, const char *dir) {
204 client->afc_packet->operation = AFC_LIST_DIR; 214 client->afc_packet->operation = AFC_LIST_DIR;
205 int bytes = 0; 215 int bytes = 0;
206 char *blah = NULL, **list = NULL; 216 char *blah = NULL, **list = NULL;
@@ -232,7 +242,7 @@ char **make_strings_list(char *tokens, int true_length) {
232} 242}
233 243
234int afc_delete_file(AFClient *client, const char *path) { 244int afc_delete_file(AFClient *client, const char *path) {
235 if (!client || !path || !client->afc_packet || !client->phone ||!client->connection) return 0; 245 if (!client || !path || !client->afc_packet || !client->connection) return 0;
236 246
237 char *receive = NULL; 247 char *receive = NULL;
238 client->afc_packet->this_length = client->afc_packet->entire_length = 0; 248 client->afc_packet->this_length = client->afc_packet->entire_length = 0;
@@ -248,7 +258,7 @@ int afc_delete_file(AFClient *client, const char *path) {
248} 258}
249 259
250int afc_rename_file(AFClient *client, const char *from, const char *to) { 260int afc_rename_file(AFClient *client, const char *from, const char *to) {
251 if (!client || !from || !to || !client->afc_packet || !client->phone || !client->connection) return 0; 261 if (!client || !from || !to || !client->afc_packet || !client->connection) return 0;
252 262
253 char *receive = NULL; 263 char *receive = NULL;
254 char *send = (char*)malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32))); 264 char *send = (char*)malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32)));
@@ -271,7 +281,7 @@ int afc_rename_file(AFClient *client, const char *from, const char *to) {
271 281
272 282
273 283
274AFCFile *afc_get_file_info(AFClient *client, char *path) { 284AFCFile *afc_get_file_info(AFClient *client, const char *path) {
275 client->afc_packet->operation = AFC_GET_INFO; 285 client->afc_packet->operation = AFC_GET_INFO;
276 client->afc_packet->entire_length = client->afc_packet->this_length = 0; 286 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
277 dispatch_AFC_packet(client, path, strlen(path)); 287 dispatch_AFC_packet(client, path, strlen(path));
@@ -312,7 +322,7 @@ AFCFile *afc_get_file_info(AFClient *client, char *path) {
312 322
313AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode) { 323AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode) {
314 if (file_mode != AFC_FILE_READ && file_mode != AFC_FILE_WRITE) return NULL; 324 if (file_mode != AFC_FILE_READ && file_mode != AFC_FILE_WRITE) return NULL;
315 if (!client ||!client->connection || !client->phone ||!client->afc_packet) return NULL; 325 if (!client ||!client->connection || !client->afc_packet) return NULL;
316 char *further_data = (char*)malloc(sizeof(char) * (8 + strlen(filename) + 1)); 326 char *further_data = (char*)malloc(sizeof(char) * (8 + strlen(filename) + 1));
317 AFCFile *file_infos = NULL; 327 AFCFile *file_infos = NULL;
318 memcpy(further_data, &file_mode, 4); 328 memcpy(further_data, &file_mode, 4);
@@ -345,7 +355,7 @@ AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode)
345} 355}
346 356
347int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) { 357int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {
348 if (!client || !client->afc_packet || !client->phone || !client->connection || !file) return -1; 358 if (!client || !client->afc_packet || !client->connection || !file) return -1;
349 AFCFilePacket *packet = (AFCFilePacket*)malloc(sizeof(AFCFilePacket)); 359 AFCFilePacket *packet = (AFCFilePacket*)malloc(sizeof(AFCFilePacket));
350 char *input = NULL; 360 char *input = NULL;
351 packet->unknown1 = packet->unknown2 = 0; 361 packet->unknown1 = packet->unknown2 = 0;
@@ -359,11 +369,15 @@ int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {
359 369
360 if (bytes > 0) { 370 if (bytes > 0) {
361 bytes = receive_AFC_data(client, &input); 371 bytes = receive_AFC_data(client, &input);
362 if (bytes <= 0) { 372 if (bytes < 0) {
363 if (input) free(input); 373 if (input) free(input);
364 return -1; 374 return -1;
375 } else if (bytes == 0) {
376 if (input) free(input);
377 return 0;
365 } else { 378 } else {
366 memcpy(data, input, (bytes > length) ? length : bytes); 379 if (input)
380 memcpy(data, input, (bytes > length) ? length : bytes);
367 free(input); 381 free(input);
368 return (bytes > length) ? length : bytes; 382 return (bytes > length) ? length : bytes;
369 } 383 }
@@ -373,9 +387,9 @@ int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {
373 return 0; 387 return 0;
374} 388}
375 389
376int afc_write_file(AFClient *client, AFCFile *file, char *data, int length) { 390int afc_write_file(AFClient *client, AFCFile *file, const char *data, int length) {
377 char *acknowledgement = NULL; 391 char *acknowledgement = NULL;
378 if (!client ||!client->afc_packet ||!client->phone || !client->connection || !file) return -1; 392 if (!client ||!client->afc_packet || !client->connection || !file) return -1;
379 client->afc_packet->this_length = sizeof(AFCPacket) + 8; 393 client->afc_packet->this_length = sizeof(AFCPacket) + 8;
380 client->afc_packet->entire_length = client->afc_packet->this_length + length; 394 client->afc_packet->entire_length = client->afc_packet->this_length + length;
381 client->afc_packet->operation = AFC_WRITE; 395 client->afc_packet->operation = AFC_WRITE;
diff --git a/src/AFC.h b/src/AFC.h
index 7a08103..bb5f0a7 100644
--- a/src/AFC.h
+++ b/src/AFC.h
@@ -35,8 +35,7 @@ typedef struct {
35} AFCPacket; 35} AFCPacket;
36 36
37typedef struct { 37typedef struct {
38 usbmux_tcp_header *connection; 38 usbmux_connection *connection;
39 iPhone *phone;
40 AFCPacket *afc_packet; 39 AFCPacket *afc_packet;
41 int file_handle; 40 int file_handle;
42} AFClient; 41} AFClient;
@@ -79,14 +78,14 @@ AFClient *afc_connect(iPhone *phone, int s_port, int d_port);
79void afc_disconnect(AFClient *client); 78void afc_disconnect(AFClient *client);
80int count_nullspaces(char *string, int number); 79int count_nullspaces(char *string, int number);
81char **make_strings_list(char *tokens, int true_length); 80char **make_strings_list(char *tokens, int true_length);
82int dispatch_AFC_packet(AFClient *client, char *data, int length); 81int dispatch_AFC_packet(AFClient *client, const char *data, int length);
83int receive_AFC_data(AFClient *client, char **dump_here); 82int receive_AFC_data(AFClient *client, char **dump_here);
84 83
85char **afc_get_dir_list(AFClient *client, char *dir); 84char **afc_get_dir_list(AFClient *client, const char *dir);
86AFCFile *afc_get_file_info(AFClient *client, char *path); 85AFCFile *afc_get_file_info(AFClient *client, const char *path);
87AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode); 86AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode);
88void afc_close_file(AFClient *client, AFCFile *file); 87void afc_close_file(AFClient *client, AFCFile *file);
89int afc_read_file(AFClient *client, AFCFile *file, char *data, int length); 88int afc_read_file(AFClient *client, AFCFile *file, char *data, int length);
90int afc_write_file(AFClient *client, AFCFile *file, char *data, int length); 89int afc_write_file(AFClient *client, AFCFile *file, const char *data, int length);
91int afc_delete_file(AFClient *client, const char *path); 90int afc_delete_file(AFClient *client, const char *path);
92int afc_rename_file(AFClient *client, const char *from, const char *to); 91int afc_rename_file(AFClient *client, const char *from, const char *to);
diff --git a/src/ifuse.c b/src/ifuse.c
index e4d14e5..900bb17 100644
--- a/src/ifuse.c
+++ b/src/ifuse.c
@@ -155,9 +155,10 @@ void *ifuse_init(struct fuse_conn_info *conn) {
155 return afc; 155 return afc;
156} 156}
157 157
158void ifuse_cleanup(AFClient *afc) { 158void ifuse_cleanup(void *data) {
159 AFClient *afc = (AFClient *)data;
159 if (afc) { 160 if (afc) {
160 iPhone *phone = afc->phone; 161 iPhone *phone = afc->connection->phone;
161 afc_disconnect(afc); 162 afc_disconnect(afc);
162 free_iPhone(phone); 163 free_iPhone(phone);
163 } 164 }
diff --git a/src/iphone.c b/src/iphone.c
index e4acea9..aa9687c 100644
--- a/src/iphone.c
+++ b/src/iphone.c
@@ -171,10 +171,11 @@ int send_to_phone(iPhone *phone, char *data, int datalen) {
171int recv_from_phone(iPhone *phone, char *data, int datalen) { 171int recv_from_phone(iPhone *phone, char *data, int datalen) {
172 if (!phone) return -1; 172 if (!phone) return -1;
173 int bytes = 0; 173 int bytes = 0;
174 if (debug) printf("recv_from_phone(): attempting to receive %i bytes\n", datalen);
174 bytes = usb_bulk_read(phone->device, BULKIN, data, datalen, 3500); 175 bytes = usb_bulk_read(phone->device, BULKIN, data, datalen, 3500);
175 if(bytes < 0) 176 if(bytes < 0)
176 { 177 {
177 if(debug) printf("recv_from_iphone(): libusb gave me the error %d: %s (%s)\n", bytes, usb_strerror(), strerror(-bytes)); 178 if(debug) printf("recv_from_phone(): libusb gave me the error %d: %s (%s)\n", bytes, usb_strerror(), strerror(-bytes));
178 return -1; 179 return -1;
179 } 180 }
180 return bytes; 181 return bytes;
diff --git a/src/lockdown.c b/src/lockdown.c
index 7fd3aa6..4fd8a66 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -39,7 +39,6 @@ lockdownd_client *new_lockdownd_client(iPhone *phone) {
39 39
40 control->ssl_session = (gnutls_session_t*)malloc(sizeof(gnutls_session_t)); 40 control->ssl_session = (gnutls_session_t*)malloc(sizeof(gnutls_session_t));
41 control->in_SSL = 0; 41 control->in_SSL = 0;
42 control->iphone = phone;
43 control->gtls_buffer_hack_len = 0; 42 control->gtls_buffer_hack_len = 0;
44 return control; 43 return control;
45} 44}
@@ -47,7 +46,7 @@ lockdownd_client *new_lockdownd_client(iPhone *phone) {
47void lockdown_close(lockdownd_client *control) { 46void lockdown_close(lockdownd_client *control) {
48 if (!control) return; 47 if (!control) return;
49 if (control->connection) { 48 if (control->connection) {
50 mux_close_connection(control->iphone, control->connection); 49 mux_close_connection(control->connection);
51 } 50 }
52 51
53 if (control->ssl_session) free(control->ssl_session); 52 if (control->ssl_session) free(control->ssl_session);
@@ -56,21 +55,23 @@ void lockdown_close(lockdownd_client *control) {
56 55
57 56
58int lockdownd_recv(lockdownd_client *control, char **dump_data) { 57int lockdownd_recv(lockdownd_client *control, char **dump_data) {
58 if (!control) return 0;
59 char *receive; 59 char *receive;
60 uint32 datalen = 0, bytes = 0; 60 uint32 datalen = 0, bytes = 0;
61 61
62 if (!control->in_SSL) bytes = mux_recv(control->iphone, control->connection, &datalen, sizeof(datalen)); 62 if (!control->in_SSL) bytes = mux_recv(control->connection, (char *)&datalen, sizeof(datalen));
63 else bytes = gnutls_record_recv(*control->ssl_session, &datalen, sizeof(datalen)); 63 else bytes = gnutls_record_recv(*control->ssl_session, &datalen, sizeof(datalen));
64 datalen = ntohl(datalen); 64 datalen = ntohl(datalen);
65 65
66 receive = (char*)malloc(sizeof(char) * datalen); 66 receive = (char*)malloc(sizeof(char) * datalen);
67 if (!control->in_SSL) bytes = mux_recv(control->iphone, control->connection, receive, datalen); 67 if (!control->in_SSL) bytes = mux_recv(control->connection, receive, datalen);
68 else bytes = gnutls_record_recv(*control->ssl_session, receive, datalen); 68 else bytes = gnutls_record_recv(*control->ssl_session, receive, datalen);
69 *dump_data = receive; 69 *dump_data = receive;
70 return bytes; 70 return bytes;
71} 71}
72 72
73int lockdownd_send(lockdownd_client *control, char *raw_data, uint32 length) { 73int lockdownd_send(lockdownd_client *control, char *raw_data, uint32 length) {
74 if (!control) return 0;
74 char *real_query; 75 char *real_query;
75 int bytes; 76 int bytes;
76 77
@@ -78,29 +79,39 @@ int lockdownd_send(lockdownd_client *control, char *raw_data, uint32 length) {
78 length = htonl(length); 79 length = htonl(length);
79 memcpy(real_query, &length, sizeof(length)); 80 memcpy(real_query, &length, sizeof(length));
80 memcpy(real_query+4, raw_data, ntohl(length)); 81 memcpy(real_query+4, raw_data, ntohl(length));
81 if (!control->in_SSL) bytes = mux_send(control->iphone, control->connection, real_query, ntohl(length)+sizeof(length)); 82 if (debug) {
83 printf("lockdownd_send(): made the query, sending it along\n");
84 FILE *packet = fopen("grpkt", "w");
85 fwrite(real_query, 1, ntohl(length)+4, packet);
86 fclose(packet);
87 packet = NULL;
88 }
89
90 if (!control->in_SSL) bytes = mux_send(control->connection, real_query, ntohl(length)+sizeof(length));
82 else gnutls_record_send(*control->ssl_session, real_query, ntohl(length)+sizeof(length)); 91 else gnutls_record_send(*control->ssl_session, real_query, ntohl(length)+sizeof(length));
92 if (debug) printf("lockdownd_send(): sent it!\n");
93 free(real_query);
83 return bytes; 94 return bytes;
84} 95}
85 96
86int lockdownd_hello(lockdownd_client *control) { 97int lockdownd_hello(lockdownd_client *control) {
98 if (!control) return 0;
87 xmlDocPtr plist = new_plist(); 99 xmlDocPtr plist = new_plist();
88 xmlNode *dict, *key; 100 xmlNode *dict, *key;
89 char **dictionary; 101 char **dictionary;
90 int bytes = 0, i = 0; 102 int bytes = 0, i = 0;
91 103
104 if (debug) printf("lockdownd_hello() called\n");
92 dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); 105 dict = add_child_to_plist(plist, "dict", "\n", NULL, 0);
93 key = add_key_str_dict_element(plist, dict, "Request", "QueryType", 1); 106 key = add_key_str_dict_element(plist, dict, "Request", "QueryType", 1);
94 char *XML_content; 107 char *XML_content;
95 uint32 length; 108 uint32 length;
96 109
97 xmlDocDumpMemory(plist, &XML_content, &length); 110 xmlDocDumpMemory(plist, (xmlChar **)&XML_content, &length);
98
99 bytes = lockdownd_send(control, XML_content, length); 111 bytes = lockdownd_send(control, XML_content, length);
100 112
101 xmlFree(XML_content); 113 xmlFree(XML_content);
102 xmlFreeDoc(plist); plist = NULL; 114 xmlFreeDoc(plist); plist = NULL;
103
104 bytes = lockdownd_recv(control, &XML_content); 115 bytes = lockdownd_recv(control, &XML_content);
105 116
106 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0); 117 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0);
@@ -118,6 +129,7 @@ int lockdownd_hello(lockdownd_client *control) {
118 for (i = 0; strcmp(dictionary[i], ""); i+=2) { 129 for (i = 0; strcmp(dictionary[i], ""); i+=2) {
119 if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i+1], "Success")) { 130 if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i+1], "Success")) {
120 free_dictionary(dictionary); 131 free_dictionary(dictionary);
132 if (debug) printf("lockdownd_hello(): success\n");
121 return 1; 133 return 1;
122 } 134 }
123 } 135 }
@@ -147,7 +159,7 @@ int lockdownd_start_SSL_session(lockdownd_client *control, const char *HostID) {
147 return 0; 159 return 0;
148 } 160 }
149 161
150 xmlDocDumpMemory(plist, &what2send, &len); 162 xmlDocDumpMemory(plist, (xmlChar **)&what2send, &len);
151 bytes = lockdownd_send(control, what2send, len); 163 bytes = lockdownd_send(control, what2send, len);
152 164
153 xmlFree(what2send); 165 xmlFree(what2send);
@@ -239,7 +251,7 @@ ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size
239 control = (lockdownd_client*)transport; 251 control = (lockdownd_client*)transport;
240 if (debug) printf("lockdownd_secuwrite() called\n"); 252 if (debug) printf("lockdownd_secuwrite() called\n");
241 if (debug) printf("pre-send\nlength = %i\n", length); 253 if (debug) printf("pre-send\nlength = %i\n", length);
242 bytes = mux_send(control->iphone, control->connection, buffer, length); 254 bytes = mux_send(control->connection, buffer, length);
243 if (debug) printf("post-send\nsent %i bytes\n", bytes); 255 if (debug) printf("post-send\nsent %i bytes\n", bytes);
244 if (debug) { 256 if (debug) {
245 FILE *my_ssl_packet = fopen("sslpacketwrite.out", "w+"); 257 FILE *my_ssl_packet = fopen("sslpacketwrite.out", "w+");
@@ -289,7 +301,7 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_
289 char *recv_buffer = (char*)malloc(sizeof(char) * (length * 1000)); // ensuring nothing stupid happens 301 char *recv_buffer = (char*)malloc(sizeof(char) * (length * 1000)); // ensuring nothing stupid happens
290 302
291 if (debug) printf("pre-read\nclient wants %i bytes\n", length); 303 if (debug) printf("pre-read\nclient wants %i bytes\n", length);
292 bytes = mux_recv(control->iphone, control->connection, recv_buffer, (length * 1000)); 304 bytes = mux_recv(control->connection, recv_buffer, (length * 1000));
293 if (debug) printf("post-read\nwe got %i bytes\n", bytes); 305 if (debug) printf("post-read\nwe got %i bytes\n", bytes);
294 if (debug && bytes < 0) { 306 if (debug && bytes < 0) {
295 printf("lockdownd_securead(): uh oh\n"); 307 printf("lockdownd_securead(): uh oh\n");
@@ -339,7 +351,7 @@ int lockdownd_start_service(lockdownd_client *control, const char *service) {
339 key = add_key_str_dict_element(plist, dict, "Service", service, 1); 351 key = add_key_str_dict_element(plist, dict, "Service", service, 1);
340 if (!key) { xmlFreeDoc(plist); return 0; } 352 if (!key) { xmlFreeDoc(plist); return 0; }
341 353
342 xmlDocDumpMemory(plist, &XML_query, &length); 354 xmlDocDumpMemory(plist, (xmlChar **)&XML_query, &length);
343 355
344 lockdownd_send(control, XML_query, length); 356 lockdownd_send(control, XML_query, length);
345 free(XML_query); 357 free(XML_query);
diff --git a/src/lockdown.h b/src/lockdown.h
index 874afb9..4abfe18 100644
--- a/src/lockdown.h
+++ b/src/lockdown.h
@@ -28,9 +28,8 @@
28#include <string.h> 28#include <string.h>
29 29
30typedef struct { 30typedef struct {
31 usbmux_tcp_header *connection; 31 usbmux_connection *connection;
32 gnutls_session_t *ssl_session; 32 gnutls_session_t *ssl_session;
33 iPhone *iphone;
34 int in_SSL; 33 int in_SSL;
35 char *gtls_buffer_hack; 34 char *gtls_buffer_hack;
36 int gtls_buffer_hack_len; 35 int gtls_buffer_hack_len;
diff --git a/src/plist.h b/src/plist.h
index 7b72456..3d1edda 100644
--- a/src/plist.h
+++ b/src/plist.h
@@ -29,5 +29,6 @@ xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode *dict, const char *ke
29xmlNode *add_child_to_plist(xmlDocPtr plist, const char *name, const char *content, xmlNode *to_node, int depth); 29xmlNode *add_child_to_plist(xmlDocPtr plist, const char *name, const char *content, xmlNode *to_node, int depth);
30void free_plist(xmlDocPtr plist); 30void free_plist(xmlDocPtr plist);
31xmlDocPtr new_plist(); 31xmlDocPtr new_plist();
32char **read_dict_element_strings(xmlNode *dict);
32void free_dictionary(char **dictionary); 33void free_dictionary(char **dictionary);
33#endif 34#endif
diff --git a/src/usbmux.c b/src/usbmux.c
index bdeea09..043f8af 100644
--- a/src/usbmux.c
+++ b/src/usbmux.c
@@ -29,6 +29,9 @@
29 29
30extern int debug; 30extern int debug;
31 31
32static usbmux_connection **connlist = NULL;
33static int connections = 0;
34
32usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port) { 35usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port) {
33 usbmux_tcp_header *conn = (usbmux_tcp_header*)malloc(sizeof(usbmux_tcp_header)); 36 usbmux_tcp_header *conn = (usbmux_tcp_header*)malloc(sizeof(usbmux_tcp_header));
34 conn->type = htonl(6); 37 conn->type = htonl(6);
@@ -54,6 +57,47 @@ usbmux_version_header *version_header() {
54 return version; 57 return version;
55} 58}
56 59
60
61// Maintenance functions.
62
63/* delete_connection(connection)
64 * connection: the connection to delete from the tracking list.
65 * Removes a connection from the list of connections made.
66 * The list of connections is necessary for buffering.
67 */
68
69void delete_connection(usbmux_connection *connection) {
70 usbmux_connection **newlist = (usbmux_connection**)malloc(sizeof(usbmux_connection*) * (connections - 1));
71 int i = 0, j = 0;
72 for (i = 0; i < connections; i++) {
73 if (connlist[i] == connection) continue;
74 else {
75 newlist[j] = connlist[i];
76 j++;
77 }
78 }
79 free(connlist);
80 connlist = newlist;
81 connections--;
82 if (connection->recv_buffer) free(connection->recv_buffer);
83 if (connection->header) free(connection->header);
84 connection->r_len = 0;
85 free(connection);
86}
87
88/* add_connection(connection)
89 * connection: the connection to add to the global list of connections.
90 * Adds a connection to the list of connections made.
91 * The connection list is necessary for buffering.
92 */
93
94void add_connection(usbmux_connection *connection) {
95 usbmux_connection **newlist = (usbmux_connection**)realloc(connlist, sizeof(usbmux_connection*) * (connections+1));
96 newlist[connections] = connection;
97 connlist = newlist;
98 connections++;
99}
100
57/* mux_connect(phone, s_port, d_port) 101/* mux_connect(phone, s_port, d_port)
58 * This is a higher-level USBMuxTCP-type function. 102 * This is a higher-level USBMuxTCP-type function.
59 * phone: the iPhone to initialize a connection on. 103 * phone: the iPhone to initialize a connection on.
@@ -64,27 +108,33 @@ usbmux_version_header *version_header() {
64 * Returns a mux TCP header for the connection which is used for tracking and data transfer. 108 * Returns a mux TCP header for the connection which is used for tracking and data transfer.
65 */ 109 */
66 110
67usbmux_tcp_header *mux_connect(iPhone *phone, uint16 s_port, uint16 d_port) { 111usbmux_connection *mux_connect(iPhone *phone, uint16 s_port, uint16 d_port) {
68 if (!phone || !s_port || !d_port) return NULL; 112 if (!phone || !s_port || !d_port) return NULL;
69 int bytes = 0; 113 int bytes = 0;
70 // Initialize connection stuff 114 // Initialize connection stuff
71 usbmux_tcp_header *new_connection; 115 usbmux_connection *new_connection = (usbmux_connection*)malloc(sizeof(usbmux_connection));
72 new_connection = new_mux_packet(s_port, d_port); 116 new_connection->header = new_mux_packet(s_port, d_port);
73 usbmux_tcp_header *response; 117 usbmux_tcp_header *response;
74 response = (usbmux_tcp_header*)malloc(sizeof(usbmux_tcp_header)); 118 response = (usbmux_tcp_header*)malloc(sizeof(usbmux_tcp_header));
75 // blargg 119 // blargg
76 if (new_connection) { 120 if (new_connection && new_connection->header) {
77 new_connection->tcp_flags = 0x02; 121 new_connection->header->tcp_flags = 0x02;
78 new_connection->length = htonl(new_connection->length); 122 new_connection->header->length = htonl(new_connection->header->length);
79 new_connection->length16 = htons(new_connection->length16); 123 new_connection->header->length16 = htons(new_connection->header->length16);
80 124
81 if (send_to_phone(phone, (char*)new_connection, sizeof(*new_connection)) >= 0) { 125 if (send_to_phone(phone, (char*)new_connection->header, sizeof(usbmux_tcp_header)) >= 0) {
82 bytes = recv_from_phone(phone, (char*)response, sizeof(*response)); 126 bytes = recv_from_phone(phone, (char*)response, sizeof(*response));
83 if (response->tcp_flags != 0x12) return NULL; 127 if (response->tcp_flags != 0x12) return NULL;
84 else { 128 else {
85 new_connection->tcp_flags = 0x10; 129 if (debug) printf("mux_connect: connection success\n");
86 new_connection->scnt = 1; 130 new_connection->header->tcp_flags = 0x10;
87 new_connection->ocnt = 1; 131 new_connection->header->scnt = 1;
132 new_connection->header->ocnt = 1;
133 add_connection(new_connection);
134 new_connection->phone = phone;
135 new_connection->recv_buffer = NULL;
136 new_connection->r_len = 0;
137 add_connection(new_connection);
88 return new_connection; 138 return new_connection;
89 } 139 }
90 } else { 140 } else {
@@ -103,23 +153,24 @@ usbmux_tcp_header *mux_connect(iPhone *phone, uint16 s_port, uint16 d_port) {
103 * 153 *
104 * Doesn't return anything; WILL FREE THE CONNECTION'S MEMORY!!! 154 * Doesn't return anything; WILL FREE THE CONNECTION'S MEMORY!!!
105 */ 155 */
106void mux_close_connection(iPhone *phone, usbmux_tcp_header *connection) { 156
107 if (!phone || !connection) return; 157void mux_close_connection(usbmux_connection *connection) {
158 if (!connection || !connection->phone) return;
108 159
109 connection->tcp_flags = 0x04; 160 connection->header->tcp_flags = 0x04;
110 connection->scnt = htonl(connection->scnt); 161 connection->header->scnt = htonl(connection->header->scnt);
111 connection->ocnt = htonl(connection->ocnt); 162 connection->header->ocnt = htonl(connection->header->ocnt);
112 int bytes = 0; 163 int bytes = 0;
113 164
114 bytes = usb_bulk_write(phone->device, BULKOUT, (char*)connection, sizeof(*connection), 800); 165 bytes = usb_bulk_write(connection->phone->device, BULKOUT, (char*)connection->header, sizeof(usbmux_tcp_header), 800);
115 if(debug && bytes < 0) 166 if(debug && bytes < 0)
116 printf("mux_close_connection(): when writing, libusb gave me the error: %s\n", usb_strerror()); 167 printf("mux_close_connection(): when writing, libusb gave me the error: %s\n", usb_strerror());
117 168
118 bytes = usb_bulk_read(phone->device, BULKIN, (char*)connection, sizeof(*connection), 800); 169 bytes = usb_bulk_read(connection->phone->device, BULKIN, (char*)connection->header, sizeof(usbmux_tcp_header), 800);
119 if(debug && bytes < 0) 170 if(debug && bytes < 0)
120 printf("get_iPhone(): when reading, libusb gave me the error: %s\n", usb_strerror()); 171 printf("get_iPhone(): when reading, libusb gave me the error: %s\n", usb_strerror());
121 172
122 free(connection); 173 delete_connection(connection);
123} 174}
124 175
125/* mux_send(phone, connection, data, datalen) 176/* mux_send(phone, connection, data, datalen)
@@ -131,40 +182,46 @@ void mux_close_connection(iPhone *phone, usbmux_tcp_header *connection) {
131 * 182 *
132 * Returns number of bytes sent, minus the header (28), or -1 on error. 183 * Returns number of bytes sent, minus the header (28), or -1 on error.
133 */ 184 */
134int mux_send(iPhone *phone, usbmux_tcp_header *connection, char *data, uint32 datalen) { 185int mux_send(usbmux_connection *connection, const char *data, uint32 datalen) {
135 if (!phone || !connection || !data || datalen == 0) return -1; 186 if (!connection->phone || !connection || !data || datalen == 0) return -1;
136 // connection->scnt and connection->ocnt should already be in host notation... 187 // connection->scnt and connection->ocnt should already be in host notation...
137 // we don't need to change them juuuust yet. 188 // we don't need to change them juuuust yet.
138 int bytes = 0; 189 int bytes = 0;
139 if (debug) printf("mux_send(): client wants to send %i bytes\n", datalen); 190 if (debug) printf("mux_send(): client wants to send %i bytes\n", datalen);
140 char *buffer = (char*)malloc(sizeof(*connection) + datalen + 2); // allow 2 bytes of safety padding 191 char *buffer = (char*)malloc(sizeof(usbmux_tcp_header) + datalen + 2); // allow 2 bytes of safety padding
141 // Set the length and pre-emptively htonl/htons it 192 // Set the length and pre-emptively htonl/htons it
142 connection->length = htonl(sizeof(*connection) + datalen); 193 connection->header->length = htonl(sizeof(usbmux_tcp_header) + datalen);
143 connection->length16 = htons(sizeof(*connection) + datalen); 194 connection->header->length16 = htons(sizeof(usbmux_tcp_header) + datalen);
144 195
145 // Put scnt and ocnt into big-endian notation 196 // Put scnt and ocnt into big-endian notation
146 connection->scnt = htonl(connection->scnt); 197 connection->header->scnt = htonl(connection->header->scnt);
147 connection->ocnt = htonl(connection->ocnt); 198 connection->header->ocnt = htonl(connection->header->ocnt);
148 // Concatenation of stuff in the buffer. 199 // Concatenation of stuff in the buffer.
149 memcpy(buffer, connection, sizeof(*connection)); 200 memcpy(buffer, connection->header, sizeof(usbmux_tcp_header));
150 memcpy(buffer+sizeof(*connection)/*+sizeof(datalen)*/, data, datalen); 201 memcpy(buffer+sizeof(usbmux_tcp_header), data, datalen);
151 202
152 // We have a buffer full of data, we should now send it to the phone. 203 // We have a buffer full of data, we should now send it to the phone.
153 if (debug) printf("actually sending %i bytes of data at %x\n", sizeof(*connection)+datalen, buffer); 204 if (debug) printf("actually sending %i bytes of data at %x\n", sizeof(usbmux_tcp_header)+datalen, buffer);
154 205
155 206
156 bytes = send_to_phone(phone, buffer, sizeof(*connection)+datalen); 207 bytes = send_to_phone(connection->phone, buffer, sizeof(usbmux_tcp_header)+datalen);
157 208 if (debug) printf("mux_send: sent %i bytes!\n", bytes);
158 // Now that we've sent it off, we can clean up after our sloppy selves. 209 // Now that we've sent it off, we can clean up after our sloppy selves.
159 free(buffer); 210 if (debug) {
211 FILE *packet = fopen("packet", "a+");
212 fwrite(buffer, 1, bytes, packet);
213 fclose(packet);
214 printf("\n");
215 }
160 216
217 if (buffer) free(buffer);
161 // Re-calculate scnt and ocnt 218 // Re-calculate scnt and ocnt
162 connection->scnt = ntohl(connection->scnt) + datalen; 219 connection->header->scnt = ntohl(connection->header->scnt) + datalen;
163 connection->ocnt = ntohl(connection->ocnt); 220 connection->header->ocnt = ntohl(connection->header->ocnt);
164 221
165 // Revert lengths 222 // Revert lengths
166 connection->length = ntohl(connection->length); 223 connection->header->length = ntohl(connection->header->length);
167 connection->length16 = ntohs(connection->length16); 224 connection->header->length16 = ntohs(connection->header->length16);
168 225
169 // Now return the bytes. 226 // Now return the bytes.
170 if (bytes < sizeof(*connection)+datalen) { 227 if (bytes < sizeof(*connection)+datalen) {
@@ -186,39 +243,103 @@ int mux_send(iPhone *phone, usbmux_tcp_header *connection, char *data, uint32 da
186 * Returns: how many bytes were read, or -1 if something bad happens. 243 * Returns: how many bytes were read, or -1 if something bad happens.
187 */ 244 */
188 245
189int mux_recv(iPhone *phone, usbmux_tcp_header *connection, char *data, uint32 datalen) { 246int mux_recv(usbmux_connection *connection, char *data, uint32 datalen) {
190 char *buffer = (char*)malloc(sizeof(*connection) + sizeof(datalen) + datalen); 247 /*
191 int bytes = 0, my_datalen = 0; 248 * Order of operation:
249 * 1.) Check if the connection has a pre-received buffer.
250 * 2.) If so, fill data with the buffer, as much as needed.
251 * a.) Return quickly if the buffer has enough
252 * b.) If the buffer is only part of the datalen, get the rest of datalen (and if we can't, just return)
253 * 3.) If not, receive directly from the phone.
254 * a.) Check incoming packet's ports. If proper, follow proper buffering and receiving operation.
255 * b.) If not, find the connection the ports belong to and fill that connection's buffer, then return mux_recv with the same args to try again.
256 */
192 if (debug) printf("mux_recv: datalen == %i\n", datalen); 257 if (debug) printf("mux_recv: datalen == %i\n", datalen);
193 bytes = recv_from_phone(phone, buffer, sizeof(*connection) + datalen); 258 int bytes = 0, i = 0, complex = 0, offset = 0;
194 if (debug) printf("mux_recv: bytes == %i\n", bytes); 259 char *buffer = NULL;
195 if (bytes < datalen) { 260 usbmux_tcp_header *header = NULL;
196 if (bytes < 28) { 261
197 // if they didn't do that annoying thing, something else mighta happened. 262 if (connection->recv_buffer) {
198 if (debug) printf("mux_recv: bytes too low anyway!\n"); 263 if (connection->r_len >= datalen) {
199 free(buffer); 264 memcpy(data, connection->recv_buffer, datalen);
200 return -1; 265 if (connection->r_len == datalen) {
201 } else if (bytes == 28) { // no data... 266 // reset everything
202 free(buffer); 267 free(connection->recv_buffer);
203 return 0; 268 connection->r_len = 0;
204 } else { // bytes > 28 269 connection->recv_buffer = NULL;
205 my_datalen = ntohl(buffer[4]) - 28; 270 } else {
206 connection->ocnt += my_datalen; 271 buffer = (char*)malloc(sizeof(char) * (connection->r_len - datalen));
207 memcpy(data, buffer+28, bytes - 28); 272 memcpy(buffer, connection->recv_buffer+datalen, (connection->r_len - datalen));
208 free(buffer); 273 connection->r_len -= datalen;
209 if (debug) printf("mux_recv: bytes received: %i\n", bytes - 28); 274 free(connection->recv_buffer);
210 return bytes - 28; 275 connection->recv_buffer = buffer;
276 }
277
278 // Since we were able to fill the data straight from our buffer, we can just return datalen. See 2a above.
279 return datalen;
280 } else {
281 memcpy(data, connection->recv_buffer, connection->r_len);
282 free(connection->recv_buffer); // don't need to deal with anymore, but...
283 offset = connection->r_len; // see #2b, above
284 connection->r_len = 0;
211 } 285 }
212 } else {// all's good, they didn't do anything bonky. 286 } // End of what to do if we have a pre-buffer. See #1 and #2 above.
213 my_datalen = ntohl(buffer[4]) - 28; 287
214 connection->ocnt += my_datalen; 288 buffer = (char*)malloc(sizeof(char) * 131072); // make sure we get enough ;)
215 if (bytes == (datalen+28)) memcpy(data, buffer+28, datalen); 289
216 else if (bytes == datalen) memcpy(data, buffer+28, datalen-28); 290 // See #3.
291 bytes = recv_from_phone(connection->phone, buffer, 131072);
292 if (bytes < 28) {
293 free(buffer);
294 if (debug) printf("mux_recv: Did not even get the header.\n");
295 return -1;
296 }
297
298 header = (usbmux_tcp_header*)buffer;
299 if (header->sport != connection->header->dport || header->dport != connection->header->sport) {
300 // Ooooops -- we got someone else's packet.
301 // We gotta stick it in their buffer. (Take that any old way you want ;) )
302 for (i = 0; i < connections; i++) {
303 if (connlist[i]->header->sport == header->dport && connlist[i]->header->dport == header->sport) {
304 // we have a winner.
305 connlist[i]->r_len += bytes - 28;
306 connlist[i]->recv_buffer = (char*)realloc(connlist[i]->recv_buffer, sizeof(char) * connection->r_len); // grow their buffer
307 complex = connlist[i]->r_len - (bytes - 28);
308 memcpy(connlist[i]->recv_buffer+complex, buffer+28, bytes-28); // paste into their buffer
309 connlist[i]->header->ocnt += bytes-28;
310 }
311 }
312 // If it wasn't ours, it's been handled by this point... or forgotten.
313 // Free our buffer and continue.
314 free(buffer);
315 buffer = NULL;
316 return mux_recv(connection, data, datalen); // recurse back in to try again
317 }
318
319 // The packet was absolutely meant for us if it hits this point.
320 // The pre-buffer has been taken care of, so, again, if we're at this point we have to read from the phone.
321
322 if ((bytes-28) > datalen) {
323 // Copy what we need into the data, buffer the rest because we can.
324 memcpy(data+offset, buffer+28, datalen); // data+offset: see #2b, above
325 complex = connection->r_len + (bytes-28) - datalen;
326 connection->recv_buffer = (char*)realloc(connection->recv_buffer, (sizeof(char) * complex));
327 connection->r_len = complex;
328 complex = connection->r_len - (bytes-28) - datalen;
329 memcpy(connection->recv_buffer+complex, buffer+28+datalen, (bytes-28) - datalen);
330 free(buffer);
331 connection->header->ocnt += bytes-28;
332 return datalen;
333 } else {
334 // Fill the data with what we have, and just return.
335 memcpy(data+offset, buffer+28, bytes-28); // data+offset: see #2b, above
336 connection->header->ocnt += bytes-28;
217 free(buffer); 337 free(buffer);
218 if (debug) printf("mux_recv: bytes received: %i\n", bytes - 28); 338 return (bytes-28);
219 return bytes - 28;
220 } 339 }
221 340
222 return bytes; 341 // If we get to this point, 'tis probably bad.
342 if (debug) printf("mux_recv: Heisenbug: bytes and datalen not matching up\n");
343 return -1;
223} 344}
224 345
diff --git a/src/usbmux.h b/src/usbmux.h
index 7c17dd1..332dc8a 100644
--- a/src/usbmux.h
+++ b/src/usbmux.h
@@ -43,6 +43,13 @@ typedef struct {
43 uint16 window, nullnull, length16; 43 uint16 window, nullnull, length16;
44} usbmux_tcp_header; 44} usbmux_tcp_header;
45 45
46typedef struct {
47 usbmux_tcp_header *header;
48 iPhone *phone;
49 char *recv_buffer;
50 int r_len;
51} usbmux_connection;
52
46usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port); 53usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port);
47 54
48typedef struct { 55typedef struct {
@@ -51,8 +58,10 @@ typedef struct {
51 58
52usbmux_version_header *version_header(); 59usbmux_version_header *version_header();
53 60
54usbmux_tcp_header *mux_connect(iPhone *phone, uint16 s_port, uint16 d_port); 61usbmux_connection *mux_connect(iPhone *phone, uint16 s_port, uint16 d_port);
55void mux_close_connection(iPhone *phone, usbmux_tcp_header *connection); 62void mux_close_connection(usbmux_connection *connection);
56int mux_send(iPhone *phone, usbmux_tcp_header *connection, char *data, uint32 datalen); 63int mux_send(usbmux_connection *connection, const char *data, uint32 datalen);
57int mux_recv(iPhone *phone, usbmux_tcp_header *connection, char *data, uint32 datalen); 64int mux_recv(usbmux_connection *connection, char *data, uint32 datalen);
65
66
58#endif 67#endif
diff --git a/src/userpref.c b/src/userpref.c
index 366016c..27aded5 100644
--- a/src/userpref.c
+++ b/src/userpref.c
@@ -20,6 +20,8 @@
20 */ 20 */
21 21
22#include <glib.h> 22#include <glib.h>
23#include <stdio.h>
24#include <string.h>
23#include "userpref.h" 25#include "userpref.h"
24 26
25#define LIBIPHONE_CONF_DIR "libiphone" 27#define LIBIPHONE_CONF_DIR "libiphone"