diff options
| author | 2008-08-04 23:41:56 -0700 | |
|---|---|---|
| committer | 2008-08-04 23:41:56 -0700 | |
| commit | 62bcedced863a9c4ecc3601638635dfe172a9130 (patch) | |
| tree | 9937b4f6fbb848c1854e0add40f7ee86bba10d88 /src/AFC.c | |
| parent | 294f6080e7c26cb390093eead11c8e0757e00fe2 (diff) | |
| download | libimobiledevice-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.c | 66 |
1 files changed, 40 insertions, 26 deletions
| @@ -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 | ||
| 54 | void afc_disconnect(AFClient *client) { | 53 | void 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 | ||
| 70 | int dispatch_AFC_packet(AFClient *client, char *data, int length) { | 69 | int 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 | ||
| 203 | char **afc_get_dir_list(AFClient *client, char *dir) { | 213 | char **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 | ||
| 234 | int afc_delete_file(AFClient *client, const char *path) { | 244 | int 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 | ||
| 250 | int afc_rename_file(AFClient *client, const char *from, const char *to) { | 260 | int 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 | ||
| 274 | AFCFile *afc_get_file_info(AFClient *client, char *path) { | 284 | AFCFile *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 | ||
| 313 | AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode) { | 323 | AFCFile *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 | ||
| 347 | int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) { | 357 | int 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 | ||
| 376 | int afc_write_file(AFClient *client, AFCFile *file, char *data, int length) { | 390 | int 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; |
