summaryrefslogtreecommitdiffstats
path: root/AFC.c
diff options
context:
space:
mode:
authorGravatar Zach C2008-07-29 01:13:51 -0700
committerGravatar Matt Colyer2008-07-29 01:13:51 -0700
commit0f4aeb11abce2f36d840b19d028e5aa34ccf5aba (patch)
tree978d11b1f46fb323db044fa76e2020c09aab89d4 /AFC.c
parente2ff1128351d75eafd5426af7f96f9719c1af3e6 (diff)
downloadlibimobiledevice-0f4aeb11abce2f36d840b19d028e5aa34ccf5aba.tar.gz
libimobiledevice-0f4aeb11abce2f36d840b19d028e5aa34ccf5aba.tar.bz2
Version 0.09, added ability to talk to 2.0 firmware.
Diffstat (limited to 'AFC.c')
-rw-r--r--AFC.c162
1 files changed, 132 insertions, 30 deletions
diff --git a/AFC.c b/AFC.c
index 29c0f97..f3d538e 100644
--- a/AFC.c
+++ b/AFC.c
@@ -17,7 +17,7 @@ AFClient *afc_connect(iPhone *phone, int s_port, int d_port) {
17 if (client->afc_packet) { 17 if (client->afc_packet) {
18 client->phone = phone; 18 client->phone = phone;
19 client->afc_packet->packet_num = 0; 19 client->afc_packet->packet_num = 0;
20 client->afc_packet->unknown1 = client->afc_packet->unknown2 = client->afc_packet->unknown3 = client->afc_packet->unknown4 = 0; 20 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;
21 client->afc_packet->header1 = 0x36414643; 21 client->afc_packet->header1 = 0x36414643;
22 client->afc_packet->header2 = 0x4141504C; 22 client->afc_packet->header2 = 0x4141504C;
23 client->file_handle = 0; 23 client->file_handle = 0;
@@ -50,29 +50,55 @@ int count_nullspaces(char *string, int number) {
50 50
51int dispatch_AFC_packet(AFClient *client, char *data, int length) { 51int dispatch_AFC_packet(AFClient *client, char *data, int length) {
52 char *buffer; 52 char *buffer;
53 int bytes = 0; 53 int bytes = 0, offset = 0;
54 if (!client || !client->connection || !client->phone || !client->afc_packet) return 0; 54 if (!client || !client->connection || !client->phone || !client->afc_packet) return 0;
55 if (!data || !length) length = 0; 55 if (!data || !length) length = 0;
56 56
57 client->afc_packet->packet_num++; 57 client->afc_packet->packet_num++;
58 client->afc_packet->entire_length = client->afc_packet->this_length = (length) ? sizeof(AFCPacket) + length + 1 : sizeof(AFCPacket); 58 if (!client->afc_packet->entire_length) client->afc_packet->entire_length = client->afc_packet->this_length = (length) ? sizeof(AFCPacket) + length + 1 : sizeof(AFCPacket);
59 59 if (!client->afc_packet->this_length) client->afc_packet->this_length = sizeof(AFCPacket);
60 if (!length) { 60
61 bytes = mux_send(client->phone, client->connection, (char*)client->afc_packet, client->afc_packet->this_length); 61 if (client->afc_packet->this_length != client->afc_packet->entire_length) {
62 if (bytes <= 0) return 0; 62 // We want to send two segments; buffer+sizeof(AFCPacket) to this_length is the parameters
63 else return bytes; 63 // And everything beyond that is the next packet. (for writing)
64 } else { 64 char *buffer = (char*)malloc(client->afc_packet->this_length);
65 buffer = (char*)malloc(sizeof(char) * client->afc_packet->this_length); 65 memcpy(buffer, (char*)client->afc_packet, sizeof(AFCPacket));
66 memcpy(buffer, client->afc_packet, sizeof(AFCPacket)); 66 offset = client->afc_packet->this_length - sizeof(AFCPacket);
67 memcpy(buffer+sizeof(AFCPacket), data, length); 67 if (debug) printf("dispatch_AFC_packet: Offset: %i\n", offset);
68 buffer[client->afc_packet->this_length-1] = '\0'; 68 if ((length) < (client->afc_packet->entire_length - client->afc_packet->this_length)) {
69 if (debug) printf("dispatch_AFC_packet: Length did not resemble what it was supposed to based on the packet.\nlength minus offset: %i\nrest of packet: %i\n", length-offset, client->afc_packet->entire_length - client->afc_packet->this_length);
70 free(buffer);
71 return 0;
72 }
73 if (debug) printf("dispatch_AFC_packet: fucked-up packet method (probably a write)\n");
74 memcpy(buffer+sizeof(AFCPacket), data, offset);
75 bytes = mux_send(client->phone, client->connection, buffer, client->afc_packet->this_length);
76 free(buffer);
77 if (bytes <= 0) { return 0; }
78 if (debug) {
79 printf("dispatch_AFC_packet: sent the first now go with the second\n");
80 printf("Length: %i\n", length-offset);
81 printf("Buffer: \n");
82 fwrite(data+offset, 1, length-offset, stdout);
83 }
84
69 85
86 bytes = mux_send(client->phone, client->connection, data+offset, length-offset);
87 if (bytes <= 0) { return 0; }
88 else { return bytes; }
89 } else {
90 if (debug) printf("dispatch_AFC_packet doin things the old way\n");
91 char *buffer = (char*)malloc(sizeof(char) * client->afc_packet->this_length);
92 if (debug) printf("dispatch_AFC_packet packet length = %i\n", client->afc_packet->this_length);
93 memcpy(buffer, (char*)client->afc_packet, sizeof(AFCPacket));
94 if (debug) printf("dispatch_AFC_packet packet data follows\n");
95 if (length > 0) { memcpy(buffer+sizeof(AFCPacket), data, length); buffer[sizeof(AFCPacket)+length] = '\0'; }
96 if (debug) fwrite(buffer, 1, client->afc_packet->this_length, stdout);
97 if (debug) printf("\n");
70 bytes = mux_send(client->phone, client->connection, buffer, client->afc_packet->this_length); 98 bytes = mux_send(client->phone, client->connection, buffer, client->afc_packet->this_length);
71 free(buffer); // don't need it
72 if (bytes <= 0) return 0; 99 if (bytes <= 0) return 0;
73 else return bytes; 100 else return bytes;
74 } 101 }
75
76 return 0; 102 return 0;
77} 103}
78 104
@@ -103,19 +129,23 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
103 uint32 param1 = buffer[sizeof(AFCPacket)]; 129 uint32 param1 = buffer[sizeof(AFCPacket)];
104 free(buffer); 130 free(buffer);
105 131
106 if (r_packet->operation == 0x01) { 132 if (r_packet->operation == 0x01 && !((client->afc_packet->operation == AFC_DELETE && param1 == 7))) {
107 printf("Oops? Bad operation code received.\n"); 133 if (debug) printf("Oops? Bad operation code received.\n");
108 if (param1 == 0) printf("... false alarm, but still\n"); 134 if (param1 == 0) {
109 else printf("Errno %i\n", param1); 135 if (debug) printf("... false alarm, but still\n");
136 return 1;
137 }
138 else { if (debug) printf("Errno %i\n", param1); }
110 free(r_packet); 139 free(r_packet);
111 *dump_here = NULL; 140 *dump_here = NULL;
112 return 0; 141 return 0;
113 } else { 142 } else {
114 printf("Operation code %x\nFull length %i and this length %i\n", r_packet->operation, r_packet->entire_length, r_packet->this_length); 143 if (debug) printf("Operation code %x\nFull length %i and this length %i\n", r_packet->operation, r_packet->entire_length, r_packet->this_length);
115 } 144 }
116 145
117 recv_len = r_packet->entire_length - r_packet->this_length; 146 recv_len = r_packet->entire_length - r_packet->this_length;
118 free(r_packet); 147 free(r_packet);
148 if (!recv_len) return bytes;
119 buffer = (char*)malloc(sizeof(char) * recv_len); 149 buffer = (char*)malloc(sizeof(char) * recv_len);
120 bytes = mux_recv(client->phone, client->connection, buffer, recv_len); 150 bytes = mux_recv(client->phone, client->connection, buffer, recv_len);
121 if (bytes <= 0) { 151 if (bytes <= 0) {
@@ -133,6 +163,7 @@ char **afc_get_dir_list(AFClient *client, char *dir) {
133 client->afc_packet->operation = AFC_LIST_DIR; 163 client->afc_packet->operation = AFC_LIST_DIR;
134 int bytes = 0; 164 int bytes = 0;
135 char *blah = NULL, **list = NULL; 165 char *blah = NULL, **list = NULL;
166 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
136 bytes = dispatch_AFC_packet(client, dir, strlen(dir)); 167 bytes = dispatch_AFC_packet(client, dir, strlen(dir));
137 if (!bytes) return NULL; 168 if (!bytes) return NULL;
138 169
@@ -159,8 +190,49 @@ char **make_strings_list(char *tokens, int true_length) {
159 return list; 190 return list;
160} 191}
161 192
193int afc_delete_file(AFClient *client, const char *path) {
194 if (!client || !path || !client->afc_packet || !client->phone ||!client->connection) return 0;
195
196 char *receive = NULL;
197 client->afc_packet->this_length = client->afc_packet->entire_length = 0;
198 client->afc_packet->operation = AFC_DELETE;
199 int bytes;
200 bytes = dispatch_AFC_packet(client, path, strlen(path));
201 if (bytes <= 0) return 0;
202
203 bytes = receive_AFC_data(client, &receive);
204 free(receive);
205 if (bytes <= 0) return 0;
206 else return 1;
207}
208
209int afc_rename_file(AFClient *client, const char *from, const char *to) {
210 if (!client || !from || !to || !client->afc_packet || !client->phone || !client->connection) return 0;
211
212 char *receive = NULL;
213 char *send = (char*)malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32)));
214 int bytes = 0;
215
216 memcpy(send, from, strlen(from)+1);
217 memcpy(send+strlen(from)+1, to, strlen(to));
218 fwrite(send, 1, strlen(from)+1+strlen(to), stdout);
219 printf("\n");
220 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
221 client->afc_packet->operation = AFC_RENAME;
222 bytes = dispatch_AFC_packet(client, send, strlen(to) + strlen(from) + 2);
223 if (bytes <= 0) return 0;
224
225 bytes = receive_AFC_data(client, &receive);
226 free(receive);
227 if (bytes <= 0) return 0;
228 else return 1;
229}
230
231
232
162AFCFile *afc_get_file_info(AFClient *client, char *path) { 233AFCFile *afc_get_file_info(AFClient *client, char *path) {
163 client->afc_packet->operation = AFC_GET_INFO; 234 client->afc_packet->operation = AFC_GET_INFO;
235 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
164 dispatch_AFC_packet(client, path, strlen(path)); 236 dispatch_AFC_packet(client, path, strlen(path));
165 237
166 char *received, **list; 238 char *received, **list;
@@ -210,26 +282,24 @@ AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode)
210 int bytes = 0, length_thing = 0; 282 int bytes = 0, length_thing = 0;
211 client->afc_packet->operation = AFC_FILE_OPEN; 283 client->afc_packet->operation = AFC_FILE_OPEN;
212 284
285 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
213 bytes = dispatch_AFC_packet(client, further_data, 8+strlen(filename)); 286 bytes = dispatch_AFC_packet(client, further_data, 8+strlen(filename));
214 free(further_data); 287 free(further_data);
215 if (bytes <= 0) { 288 if (bytes <= 0) {
216 printf("didn't read enough\n"); 289 if (debug) printf("didn't read enough\n");
217 return NULL; 290 return NULL;
218 } else { 291 } else {
219 printf("O HAI\n");
220 length_thing = receive_AFC_data(client, &further_data); 292 length_thing = receive_AFC_data(client, &further_data);
221 if (length_thing && further_data) { 293 if (length_thing && further_data) {
222 printf("ARA\n");
223 file_infos = afc_get_file_info(client, filename); 294 file_infos = afc_get_file_info(client, filename);
224 memcpy(&file_infos->filehandle, further_data, 4); 295 memcpy(&file_infos->filehandle, further_data, 4);
225 printf("gr\n");
226 return file_infos; 296 return file_infos;
227 } else { 297 } else {
228 printf("didn't get further data or something\n"); 298 if (debug) printf("didn't get further data or something\n");
229 return NULL; 299 return NULL;
230 } 300 }
231 } 301 }
232 printf("what the fuck\n"); 302 if (debug) printf("what the fuck\n");
233 return NULL; 303 return NULL;
234} 304}
235 305
@@ -243,14 +313,17 @@ int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {
243 int bytes = 0; 313 int bytes = 0;
244 314
245 client->afc_packet->operation = AFC_READ; 315 client->afc_packet->operation = AFC_READ;
246 bytes = dispatch_AFC_packet(client, packet, sizeof(AFCFilePacket)); 316 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
317 bytes = dispatch_AFC_packet(client, (char*)packet, sizeof(AFCFilePacket));
247 318
248 if (bytes > 0) { 319 if (bytes > 0) {
249 bytes = receive_AFC_data(client, &input); 320 bytes = receive_AFC_data(client, &input);
250 if (bytes <= 0) { 321 if (bytes <= 0) {
322 if (input) free(input);
251 return -1; 323 return -1;
252 } else { 324 } else {
253 memcpy(data, input, (bytes > length) ? length : bytes); 325 memcpy(data, input, (bytes > length) ? length : bytes);
326 free(input);
254 return (bytes > length) ? length : bytes; 327 return (bytes > length) ? length : bytes;
255 } 328 }
256 } else { 329 } else {
@@ -259,21 +332,50 @@ int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {
259 return 0; 332 return 0;
260} 333}
261 334
335int afc_write_file(AFClient *client, AFCFile *file, char *data, int length) {
336 char *acknowledgement = NULL;
337 if (!client ||!client->afc_packet ||!client->phone || !client->connection || !file) return -1;
338 client->afc_packet->this_length = sizeof(AFCPacket) + 8;
339 client->afc_packet->entire_length = client->afc_packet->this_length + length;
340 client->afc_packet->operation = AFC_WRITE;
341 if (debug) printf("afc_write_file: Write length: %i\n", length);
342 uint32 zero = 0, bytes = 0;
343
344 char *out_buffer = NULL;
345 out_buffer = (char*)malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket));
346 memcpy(out_buffer, (char*)&file->filehandle, sizeof(uint32));
347 memcpy(out_buffer+4, (char*)&zero, sizeof(uint32));
348 memcpy(out_buffer+8, data, length);
349
350 bytes = dispatch_AFC_packet(client, out_buffer, length + 8);
351 if (!bytes) return -1;
352
353 zero = bytes;
354 bytes = receive_AFC_data(client, &acknowledgement);
355 if (bytes <= 0) {
356 if (debug) printf("afc_write_file: uh oh?\n");
357 }
358
359 return zero;
360}
361
262void afc_close_file(AFClient *client, AFCFile *file) { 362void afc_close_file(AFClient *client, AFCFile *file) {
263 char *buffer = malloc(sizeof(char) * 8); 363 char *buffer = malloc(sizeof(char) * 8);
264 uint32 zero = 0; 364 uint32 zero = 0;
265 if (debug) printf("File handle %i\n", file->filehandle); 365 if (debug) printf("File handle %i\n", file->filehandle);
266 memcpy(buffer, &file->filehandle, sizeof(uint32)); 366 memcpy(buffer, &file->filehandle, sizeof(uint32));
267 memcpy(buffer, &zero, sizeof(zero)); 367 memcpy(buffer+sizeof(uint32), &zero, sizeof(zero));
268 client->afc_packet->operation = AFC_FILE_CLOSE; 368 client->afc_packet->operation = AFC_FILE_CLOSE;
269 int bytes = 0; 369 int bytes = 0;
370 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
270 bytes = dispatch_AFC_packet(client, buffer, sizeof(char) * 8); 371 bytes = dispatch_AFC_packet(client, buffer, sizeof(char) * 8);
372
271 free(buffer); 373 free(buffer);
374 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
272 if (!bytes) return; 375 if (!bytes) return;
273 376
274 bytes = receive_AFC_data(client, &buffer); 377 bytes = receive_AFC_data(client, &buffer);
275 if (bytes<=0 && !buffer) printf("closefile: all went as expected\n"); 378 return;
276 else { printf("We have a buffer!??!?\nLength %i\n", bytes); fwrite(buffer, 1, bytes, stdout); printf("\n"); }
277 if (buffer) free(buffer); // we're *SUPPOSED* to get an "error" here. 379 if (buffer) free(buffer); // we're *SUPPOSED* to get an "error" here.
278} 380}
279 381