summaryrefslogtreecommitdiffstats
path: root/src/AFC.c
diff options
context:
space:
mode:
authorGravatar Matt Colyer2008-08-04 23:41:56 -0700
committerGravatar Matt Colyer2008-08-04 23:41:56 -0700
commit62bcedced863a9c4ecc3601638635dfe172a9130 (patch)
tree9937b4f6fbb848c1854e0add40f7ee86bba10d88 /src/AFC.c
parent294f6080e7c26cb390093eead11c8e0757e00fe2 (diff)
downloadlibimobiledevice-62bcedced863a9c4ecc3601638635dfe172a9130.tar.gz
libimobiledevice-62bcedced863a9c4ecc3601638635dfe172a9130.tar.bz2
Zack's C. rewrite of usbmux (with a few additions by Matt Colyer).
Diffstat (limited to 'src/AFC.c')
-rw-r--r--src/AFC.c66
1 files changed, 40 insertions, 26 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;