diff options
| author | 2014-03-13 01:24:19 +0100 | |
|---|---|---|
| committer | 2014-03-13 02:42:44 +0100 | |
| commit | d78d4e1a959e0c21bc9be025dc4fa6a577853ad3 (patch) | |
| tree | 5d2b4ecf88bd20f41d2a5ab0bb75d86f34c3dd10 /src | |
| parent | bafe6a9e7255e7946ef234f0a91de772ff9df395 (diff) | |
| download | libimobiledevice-d78d4e1a959e0c21bc9be025dc4fa6a577853ad3.tar.gz libimobiledevice-d78d4e1a959e0c21bc9be025dc4fa6a577853ad3.tar.bz2 | |
afc: refactor afc_dispatch_packet and improve afc_file_write performance
Diffstat (limited to 'src')
| -rw-r--r-- | src/afc.c | 361 |
1 files changed, 109 insertions, 252 deletions
| @@ -173,20 +173,17 @@ afc_error_t afc_client_free(afc_client_t client) | |||
| 173 | * Dispatches an AFC packet over a client. | 173 | * Dispatches an AFC packet over a client. |
| 174 | * | 174 | * |
| 175 | * @param client The client to send data through. | 175 | * @param client The client to send data through. |
| 176 | * @param data The data to send. | 176 | * @param operation The operation to perform. |
| 177 | * @param length The length to send. | 177 | * @param data The data to send together with the header. |
| 178 | * @param bytes_sent The number of bytes actually sent. | 178 | * @param data_length The length of the data to send with the header. |
| 179 | * @param payload The data to send after the header has been sent. | ||
| 180 | * @param payload_length The length of data to send after the header. | ||
| 181 | * @param bytes_sent The total number of bytes actually sent. | ||
| 179 | * | 182 | * |
| 180 | * @return AFC_E_SUCCESS on success or an AFC_E_* error value. | 183 | * @return AFC_E_SUCCESS on success or an AFC_E_* error value. |
| 181 | * | ||
| 182 | * @warning set client->afc_packet->this_length and | ||
| 183 | * client->afc_packet->entire_length to 0 before calling this. The | ||
| 184 | * reason is that if you set them to different values, it indicates | ||
| 185 | * you want to send the data as two packets. | ||
| 186 | */ | 184 | */ |
| 187 | static afc_error_t afc_dispatch_packet(afc_client_t client, const char *data, uint32_t length, uint32_t *bytes_sent) | 185 | static afc_error_t afc_dispatch_packet(afc_client_t client, uint64_t operation, const char *data, uint32_t data_length, const char* payload, uint32_t payload_length, uint32_t *bytes_sent) |
| 188 | { | 186 | { |
| 189 | uint32_t offset = 0; | ||
| 190 | uint32_t sent = 0; | 187 | uint32_t sent = 0; |
| 191 | 188 | ||
| 192 | if (!client || !client->parent || !client->afc_packet) | 189 | if (!client || !client->parent || !client->afc_packet) |
| @@ -194,117 +191,89 @@ static afc_error_t afc_dispatch_packet(afc_client_t client, const char *data, ui | |||
| 194 | 191 | ||
| 195 | *bytes_sent = 0; | 192 | *bytes_sent = 0; |
| 196 | 193 | ||
| 197 | if (!data || !length) | 194 | if (!data || !data_length) |
| 198 | length = 0; | 195 | data_length = 0; |
| 196 | if (!payload || !payload_length) | ||
| 197 | payload_length = 0; | ||
| 199 | 198 | ||
| 200 | client->afc_packet->packet_num++; | 199 | client->afc_packet->packet_num++; |
| 201 | if (!client->afc_packet->entire_length) { | 200 | client->afc_packet->operation = operation; |
| 202 | client->afc_packet->entire_length = (length) ? sizeof(AFCPacket) + length : sizeof(AFCPacket); | 201 | client->afc_packet->entire_length = sizeof(AFCPacket) + data_length + payload_length; |
| 203 | client->afc_packet->this_length = client->afc_packet->entire_length; | 202 | client->afc_packet->this_length = sizeof(AFCPacket) + data_length; |
| 204 | } | ||
| 205 | if (!client->afc_packet->this_length) { | ||
| 206 | client->afc_packet->this_length = sizeof(AFCPacket); | ||
| 207 | } | ||
| 208 | /* We want to send two segments; buffer+sizeof(AFCPacket) to this_length | ||
| 209 | is the parameters and everything beyond that is the next packet. | ||
| 210 | (for writing) */ | ||
| 211 | if (client->afc_packet->this_length != client->afc_packet->entire_length) { | ||
| 212 | offset = client->afc_packet->this_length - sizeof(AFCPacket); | ||
| 213 | |||
| 214 | debug_info("Offset: %i", offset); | ||
| 215 | if ((length) < (client->afc_packet->entire_length - client->afc_packet->this_length)) { | ||
| 216 | debug_info("Length did not resemble what it was supposed to based on packet"); | ||
| 217 | debug_info("length minus offset: %i", length - offset); | ||
| 218 | debug_info("rest of packet: %i", client->afc_packet->entire_length - client->afc_packet->this_length); | ||
| 219 | return AFC_E_INTERNAL_ERROR; | ||
| 220 | } | ||
| 221 | 203 | ||
| 222 | /* send AFC packet header */ | 204 | debug_info("packet length = %i", client->afc_packet->this_length); |
| 223 | AFCPacket_to_LE(client->afc_packet); | ||
| 224 | sent = 0; | ||
| 225 | service_send(client->parent, (void*)client->afc_packet, sizeof(AFCPacket), &sent); | ||
| 226 | AFCPacket_from_LE(client->afc_packet); | ||
| 227 | if (sent == 0) { | ||
| 228 | /* FIXME: should this be handled as success?! */ | ||
| 229 | return AFC_E_SUCCESS; | ||
| 230 | } | ||
| 231 | *bytes_sent += sent; | ||
| 232 | |||
| 233 | /* send AFC packet data */ | ||
| 234 | sent = 0; | ||
| 235 | service_send(client->parent, data, offset, &sent); | ||
| 236 | if (sent == 0) { | ||
| 237 | return AFC_E_SUCCESS; | ||
| 238 | } | ||
| 239 | *bytes_sent += sent; | ||
| 240 | 205 | ||
| 241 | debug_info("sent the first now go with the second"); | 206 | debug_buffer((char*)client->afc_packet, sizeof(AFCPacket)); |
| 242 | debug_info("Length: %i", length - offset); | ||
| 243 | debug_info("Buffer: "); | ||
| 244 | debug_buffer(data + offset, length - offset); | ||
| 245 | 207 | ||
| 246 | sent = 0; | 208 | /* send AFC packet header */ |
| 247 | service_send(client->parent, data + offset, length - offset, &sent); | 209 | AFCPacket_to_LE(client->afc_packet); |
| 248 | 210 | sent = 0; | |
| 249 | *bytes_sent = sent; | 211 | service_send(client->parent, (void*)client->afc_packet, sizeof(AFCPacket), &sent); |
| 212 | AFCPacket_from_LE(client->afc_packet); | ||
| 213 | *bytes_sent += sent; | ||
| 214 | if (sent < sizeof(AFCPacket)) { | ||
| 250 | return AFC_E_SUCCESS; | 215 | return AFC_E_SUCCESS; |
| 251 | } else { | 216 | } |
| 252 | debug_info("doin things the old way"); | ||
| 253 | debug_info("packet length = %i", client->afc_packet->this_length); | ||
| 254 | 217 | ||
| 255 | debug_buffer((char*)client->afc_packet, sizeof(AFCPacket)); | 218 | /* send AFC packet data (if there's data to send) */ |
| 219 | sent = 0; | ||
| 220 | if (data_length > 0) { | ||
| 221 | debug_info("packet data follows"); | ||
| 222 | debug_buffer(data, data_length); | ||
| 223 | service_send(client->parent, data, data_length, &sent); | ||
| 224 | } | ||
| 225 | *bytes_sent += sent; | ||
| 226 | if (sent < data_length) { | ||
| 227 | return AFC_E_SUCCESS; | ||
| 228 | } | ||
| 256 | 229 | ||
| 257 | /* send AFC packet header */ | 230 | sent = 0; |
| 258 | AFCPacket_to_LE(client->afc_packet); | 231 | if (payload_length > 0) { |
| 259 | sent = 0; | 232 | debug_info("packet payload follows"); |
| 260 | service_send(client->parent, (void*)client->afc_packet, sizeof(AFCPacket), &sent); | 233 | debug_buffer(payload, payload_length); |
| 261 | AFCPacket_from_LE(client->afc_packet); | 234 | service_send(client->parent, payload, payload_length, &sent); |
| 262 | if (sent == 0) { | 235 | } |
| 263 | return AFC_E_SUCCESS; | 236 | *bytes_sent += sent; |
| 264 | } | 237 | if (sent < payload_length) { |
| 265 | *bytes_sent += sent; | ||
| 266 | /* send AFC packet data (if there's data to send) */ | ||
| 267 | if (length > 0) { | ||
| 268 | debug_info("packet data follows"); | ||
| 269 | |||
| 270 | debug_buffer(data, length); | ||
| 271 | service_send(client->parent, data, length, &sent); | ||
| 272 | *bytes_sent += sent; | ||
| 273 | } | ||
| 274 | return AFC_E_SUCCESS; | 238 | return AFC_E_SUCCESS; |
| 275 | } | 239 | } |
| 276 | return AFC_E_INTERNAL_ERROR; | 240 | |
| 241 | return AFC_E_SUCCESS; | ||
| 277 | } | 242 | } |
| 278 | 243 | ||
| 279 | /** | 244 | /** |
| 280 | * Receives data through an AFC client and sets a variable to the received data. | 245 | * Receives data through an AFC client and sets a variable to the received data. |
| 281 | * | 246 | * |
| 282 | * @param client The client to receive data on. | 247 | * @param client The client to receive data on. |
| 283 | * @param dump_here The char* to point to the newly-received data. | 248 | * @param bytes The char* to point to the newly-received data. |
| 284 | * @param bytes_recv How much data was received. | 249 | * @param bytes_recv How much data was received. |
| 285 | * | 250 | * |
| 286 | * @return AFC_E_SUCCESS on success or an AFC_E_* error value. | 251 | * @return AFC_E_SUCCESS on success or an AFC_E_* error value. |
| 287 | */ | 252 | */ |
| 288 | static afc_error_t afc_receive_data(afc_client_t client, char **dump_here, uint32_t *bytes_recv) | 253 | static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t *bytes_recv) |
| 289 | { | 254 | { |
| 290 | AFCPacket header; | 255 | AFCPacket header; |
| 291 | uint32_t entire_len = 0; | 256 | uint32_t entire_len = 0; |
| 292 | uint32_t this_len = 0; | 257 | uint32_t this_len = 0; |
| 293 | uint32_t current_count = 0; | 258 | uint32_t current_count = 0; |
| 294 | uint64_t param1 = -1; | 259 | uint64_t param1 = -1; |
| 260 | char* dump_here = NULL; | ||
| 295 | 261 | ||
| 296 | *bytes_recv = 0; | 262 | if (bytes_recv) { |
| 263 | *bytes_recv = 0; | ||
| 264 | } | ||
| 265 | if (bytes) { | ||
| 266 | *bytes = NULL; | ||
| 267 | } | ||
| 297 | 268 | ||
| 298 | /* first, read the AFC header */ | 269 | /* first, read the AFC header */ |
| 299 | service_receive(client->parent, (char*)&header, sizeof(AFCPacket), bytes_recv); | 270 | service_receive(client->parent, (char*)&header, sizeof(AFCPacket), bytes_recv); |
| 300 | AFCPacket_from_LE(&header); | 271 | AFCPacket_from_LE(&header); |
| 301 | if (*bytes_recv == 0) { | 272 | if (*bytes_recv == 0) { |
| 302 | debug_info("Just didn't get enough."); | 273 | debug_info("Just didn't get enough."); |
| 303 | *dump_here = NULL; | ||
| 304 | return AFC_E_MUX_ERROR; | 274 | return AFC_E_MUX_ERROR; |
| 305 | } else if (*bytes_recv < sizeof(AFCPacket)) { | 275 | } else if (*bytes_recv < sizeof(AFCPacket)) { |
| 306 | debug_info("Did not even get the AFCPacket header"); | 276 | debug_info("Did not even get the AFCPacket header"); |
| 307 | *dump_here = NULL; | ||
| 308 | return AFC_E_MUX_ERROR; | 277 | return AFC_E_MUX_ERROR; |
| 309 | } | 278 | } |
| 310 | 279 | ||
| @@ -317,19 +286,16 @@ static afc_error_t afc_receive_data(afc_client_t client, char **dump_here, uint3 | |||
| 317 | if (header.packet_num != client->afc_packet->packet_num) { | 286 | if (header.packet_num != client->afc_packet->packet_num) { |
| 318 | /* otherwise print a warning but do not abort */ | 287 | /* otherwise print a warning but do not abort */ |
| 319 | debug_info("ERROR: Unexpected packet number (%lld != %lld) aborting.", header.packet_num, client->afc_packet->packet_num); | 288 | debug_info("ERROR: Unexpected packet number (%lld != %lld) aborting.", header.packet_num, client->afc_packet->packet_num); |
| 320 | *dump_here = NULL; | ||
| 321 | return AFC_E_OP_HEADER_INVALID; | 289 | return AFC_E_OP_HEADER_INVALID; |
| 322 | } | 290 | } |
| 323 | 291 | ||
| 324 | /* then, read the attached packet */ | 292 | /* then, read the attached packet */ |
| 325 | if (header.this_length < sizeof(AFCPacket)) { | 293 | if (header.this_length < sizeof(AFCPacket)) { |
| 326 | debug_info("Invalid AFCPacket header received!"); | 294 | debug_info("Invalid AFCPacket header received!"); |
| 327 | *dump_here = NULL; | ||
| 328 | return AFC_E_OP_HEADER_INVALID; | 295 | return AFC_E_OP_HEADER_INVALID; |
| 329 | } else if ((header.this_length == header.entire_length) | 296 | } else if ((header.this_length == header.entire_length) |
| 330 | && header.entire_length == sizeof(AFCPacket)) { | 297 | && header.entire_length == sizeof(AFCPacket)) { |
| 331 | debug_info("Empty AFCPacket received!"); | 298 | debug_info("Empty AFCPacket received!"); |
| 332 | *dump_here = NULL; | ||
| 333 | *bytes_recv = 0; | 299 | *bytes_recv = 0; |
| 334 | if (header.operation == AFC_OP_DATA) { | 300 | if (header.operation == AFC_OP_DATA) { |
| 335 | return AFC_E_SUCCESS; | 301 | return AFC_E_SUCCESS; |
| @@ -348,17 +314,15 @@ static afc_error_t afc_receive_data(afc_client_t client, char **dump_here, uint3 | |||
| 348 | fprintf(stderr, "%s: entire_len is larger than MAXIMUM_PACKET_SIZE, (%d > %d)!", __func__, entire_len, MAXIMUM_PACKET_SIZE); | 314 | fprintf(stderr, "%s: entire_len is larger than MAXIMUM_PACKET_SIZE, (%d > %d)!", __func__, entire_len, MAXIMUM_PACKET_SIZE); |
| 349 | } | 315 | } |
| 350 | 316 | ||
| 351 | *dump_here = (char*)malloc(entire_len); | 317 | dump_here = (char*)malloc(entire_len); |
| 352 | if (this_len > 0) { | 318 | if (this_len > 0) { |
| 353 | service_receive(client->parent, *dump_here, this_len, bytes_recv); | 319 | service_receive(client->parent, dump_here, this_len, bytes_recv); |
| 354 | if (*bytes_recv <= 0) { | 320 | if (*bytes_recv <= 0) { |
| 355 | free(*dump_here); | 321 | free(dump_here); |
| 356 | *dump_here = NULL; | ||
| 357 | debug_info("Did not get packet contents!"); | 322 | debug_info("Did not get packet contents!"); |
| 358 | return AFC_E_NOT_ENOUGH_DATA; | 323 | return AFC_E_NOT_ENOUGH_DATA; |
| 359 | } else if (*bytes_recv < this_len) { | 324 | } else if (*bytes_recv < this_len) { |
| 360 | free(*dump_here); | 325 | free(dump_here); |
| 361 | *dump_here = NULL; | ||
| 362 | debug_info("Could not receive this_len=%d bytes", this_len); | 326 | debug_info("Could not receive this_len=%d bytes", this_len); |
| 363 | return AFC_E_NOT_ENOUGH_DATA; | 327 | return AFC_E_NOT_ENOUGH_DATA; |
| 364 | } | 328 | } |
| @@ -368,7 +332,7 @@ static afc_error_t afc_receive_data(afc_client_t client, char **dump_here, uint3 | |||
| 368 | 332 | ||
| 369 | if (entire_len > this_len) { | 333 | if (entire_len > this_len) { |
| 370 | while (current_count < entire_len) { | 334 | while (current_count < entire_len) { |
| 371 | service_receive(client->parent, (*dump_here)+current_count, entire_len - current_count, bytes_recv); | 335 | service_receive(client->parent, dump_here+current_count, entire_len - current_count, bytes_recv); |
| 372 | if (*bytes_recv <= 0) { | 336 | if (*bytes_recv <= 0) { |
| 373 | debug_info("Error receiving data (recv returned %d)", *bytes_recv); | 337 | debug_info("Error receiving data (recv returned %d)", *bytes_recv); |
| 374 | break; | 338 | break; |
| @@ -381,12 +345,12 @@ static afc_error_t afc_receive_data(afc_client_t client, char **dump_here, uint3 | |||
| 381 | } | 345 | } |
| 382 | 346 | ||
| 383 | if (current_count >= sizeof(uint64_t)) { | 347 | if (current_count >= sizeof(uint64_t)) { |
| 384 | param1 = le64toh(*(uint64_t*)(*dump_here)); | 348 | param1 = le64toh(*(uint64_t*)(dump_here)); |
| 385 | } | 349 | } |
| 386 | 350 | ||
| 387 | debug_info("packet data size = %i", current_count); | 351 | debug_info("packet data size = %i", current_count); |
| 388 | debug_info("packet data follows"); | 352 | debug_info("packet data follows"); |
| 389 | debug_buffer(*dump_here, current_count); | 353 | debug_buffer(dump_here, current_count); |
| 390 | 354 | ||
| 391 | /* check operation types */ | 355 | /* check operation types */ |
| 392 | if (header.operation == AFC_OP_STATUS) { | 356 | if (header.operation == AFC_OP_STATUS) { |
| @@ -396,8 +360,7 @@ static afc_error_t afc_receive_data(afc_client_t client, char **dump_here, uint3 | |||
| 396 | if (param1 != AFC_E_SUCCESS) { | 360 | if (param1 != AFC_E_SUCCESS) { |
| 397 | /* error status */ | 361 | /* error status */ |
| 398 | /* free buffer */ | 362 | /* free buffer */ |
| 399 | free(*dump_here); | 363 | free(dump_here); |
| 400 | *dump_here = NULL; | ||
| 401 | return (afc_error_t)param1; | 364 | return (afc_error_t)param1; |
| 402 | } | 365 | } |
| 403 | } else if (header.operation == AFC_OP_DATA) { | 366 | } else if (header.operation == AFC_OP_DATA) { |
| @@ -411,8 +374,7 @@ static afc_error_t afc_receive_data(afc_client_t client, char **dump_here, uint3 | |||
| 411 | debug_info("got a tell response, position=%lld", param1); | 374 | debug_info("got a tell response, position=%lld", param1); |
| 412 | } else { | 375 | } else { |
| 413 | /* unknown operation code received */ | 376 | /* unknown operation code received */ |
| 414 | free(*dump_here); | 377 | free(dump_here); |
| 415 | *dump_here = NULL; | ||
| 416 | *bytes_recv = 0; | 378 | *bytes_recv = 0; |
| 417 | 379 | ||
| 418 | debug_info("WARNING: Unknown operation code received 0x%llx param1=%lld", header.operation, param1); | 380 | debug_info("WARNING: Unknown operation code received 0x%llx param1=%lld", header.operation, param1); |
| @@ -423,6 +385,12 @@ static afc_error_t afc_receive_data(afc_client_t client, char **dump_here, uint3 | |||
| 423 | return AFC_E_OP_NOT_SUPPORTED; | 385 | return AFC_E_OP_NOT_SUPPORTED; |
| 424 | } | 386 | } |
| 425 | 387 | ||
| 388 | if (bytes) { | ||
| 389 | *bytes = dump_here; | ||
| 390 | } else { | ||
| 391 | free(dump_here); | ||
| 392 | } | ||
| 393 | |||
| 426 | *bytes_recv = current_count; | 394 | *bytes_recv = current_count; |
| 427 | return AFC_E_SUCCESS; | 395 | return AFC_E_SUCCESS; |
| 428 | } | 396 | } |
| @@ -493,10 +461,7 @@ afc_error_t afc_read_directory(afc_client_t client, const char *dir, char ***lis | |||
| 493 | afc_lock(client); | 461 | afc_lock(client); |
| 494 | 462 | ||
| 495 | /* Send the command */ | 463 | /* Send the command */ |
| 496 | client->afc_packet->operation = AFC_OP_READ_DIR; | 464 | ret = afc_dispatch_packet(client, AFC_OP_READ_DIR, dir, strlen(dir)+1, NULL, 0, &bytes); |
| 497 | client->afc_packet->entire_length = 0; | ||
| 498 | client->afc_packet->this_length = 0; | ||
| 499 | ret = afc_dispatch_packet(client, dir, strlen(dir)+1, &bytes); | ||
| 500 | if (ret != AFC_E_SUCCESS) { | 465 | if (ret != AFC_E_SUCCESS) { |
| 501 | afc_unlock(client); | 466 | afc_unlock(client); |
| 502 | return AFC_E_NOT_ENOUGH_DATA; | 467 | return AFC_E_NOT_ENOUGH_DATA; |
| @@ -504,6 +469,8 @@ afc_error_t afc_read_directory(afc_client_t client, const char *dir, char ***lis | |||
| 504 | /* Receive the data */ | 469 | /* Receive the data */ |
| 505 | ret = afc_receive_data(client, &data, &bytes); | 470 | ret = afc_receive_data(client, &data, &bytes); |
| 506 | if (ret != AFC_E_SUCCESS) { | 471 | if (ret != AFC_E_SUCCESS) { |
| 472 | if (data) | ||
| 473 | free(data); | ||
| 507 | afc_unlock(client); | 474 | afc_unlock(client); |
| 508 | return ret; | 475 | return ret; |
| 509 | } | 476 | } |
| @@ -541,9 +508,7 @@ afc_error_t afc_get_device_info(afc_client_t client, char ***infos) | |||
| 541 | afc_lock(client); | 508 | afc_lock(client); |
| 542 | 509 | ||
| 543 | /* Send the command */ | 510 | /* Send the command */ |
| 544 | client->afc_packet->operation = AFC_OP_GET_DEVINFO; | 511 | ret = afc_dispatch_packet(client, AFC_OP_GET_DEVINFO, NULL, 0, NULL, 0, &bytes); |
| 545 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | ||
| 546 | ret = afc_dispatch_packet(client, NULL, 0, &bytes); | ||
| 547 | if (ret != AFC_E_SUCCESS) { | 512 | if (ret != AFC_E_SUCCESS) { |
| 548 | afc_unlock(client); | 513 | afc_unlock(client); |
| 549 | return AFC_E_NOT_ENOUGH_DATA; | 514 | return AFC_E_NOT_ENOUGH_DATA; |
| @@ -551,6 +516,8 @@ afc_error_t afc_get_device_info(afc_client_t client, char ***infos) | |||
| 551 | /* Receive the data */ | 516 | /* Receive the data */ |
| 552 | ret = afc_receive_data(client, &data, &bytes); | 517 | ret = afc_receive_data(client, &data, &bytes); |
| 553 | if (ret != AFC_E_SUCCESS) { | 518 | if (ret != AFC_E_SUCCESS) { |
| 519 | if (data) | ||
| 520 | free(data); | ||
| 554 | afc_unlock(client); | 521 | afc_unlock(client); |
| 555 | return ret; | 522 | return ret; |
| 556 | } | 523 | } |
| @@ -614,7 +581,6 @@ afc_error_t afc_get_device_info_key(afc_client_t client, const char *key, char * | |||
| 614 | */ | 581 | */ |
| 615 | afc_error_t afc_remove_path(afc_client_t client, const char *path) | 582 | afc_error_t afc_remove_path(afc_client_t client, const char *path) |
| 616 | { | 583 | { |
| 617 | char *response = NULL; | ||
| 618 | uint32_t bytes = 0; | 584 | uint32_t bytes = 0; |
| 619 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | 585 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; |
| 620 | 586 | ||
| @@ -624,17 +590,13 @@ afc_error_t afc_remove_path(afc_client_t client, const char *path) | |||
| 624 | afc_lock(client); | 590 | afc_lock(client); |
| 625 | 591 | ||
| 626 | /* Send command */ | 592 | /* Send command */ |
| 627 | client->afc_packet->this_length = client->afc_packet->entire_length = 0; | 593 | ret = afc_dispatch_packet(client, AFC_OP_REMOVE_PATH, path, strlen(path)+1, NULL, 0, &bytes); |
| 628 | client->afc_packet->operation = AFC_OP_REMOVE_PATH; | ||
| 629 | ret = afc_dispatch_packet(client, path, strlen(path)+1, &bytes); | ||
| 630 | if (ret != AFC_E_SUCCESS) { | 594 | if (ret != AFC_E_SUCCESS) { |
| 631 | afc_unlock(client); | 595 | afc_unlock(client); |
| 632 | return AFC_E_NOT_ENOUGH_DATA; | 596 | return AFC_E_NOT_ENOUGH_DATA; |
| 633 | } | 597 | } |
| 634 | /* Receive response */ | 598 | /* Receive response */ |
| 635 | ret = afc_receive_data(client, &response, &bytes); | 599 | ret = afc_receive_data(client, NULL, &bytes); |
| 636 | if (response) | ||
| 637 | free(response); | ||
| 638 | 600 | ||
| 639 | /* special case; unknown error actually means directory not empty */ | 601 | /* special case; unknown error actually means directory not empty */ |
| 640 | if (ret == AFC_E_UNKNOWN_ERROR) | 602 | if (ret == AFC_E_UNKNOWN_ERROR) |
| @@ -656,7 +618,6 @@ afc_error_t afc_remove_path(afc_client_t client, const char *path) | |||
| 656 | */ | 618 | */ |
| 657 | afc_error_t afc_rename_path(afc_client_t client, const char *from, const char *to) | 619 | afc_error_t afc_rename_path(afc_client_t client, const char *from, const char *to) |
| 658 | { | 620 | { |
| 659 | char *response = NULL; | ||
| 660 | char *send = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32_t))); | 621 | char *send = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32_t))); |
| 661 | uint32_t bytes = 0; | 622 | uint32_t bytes = 0; |
| 662 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | 623 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; |
| @@ -669,18 +630,15 @@ afc_error_t afc_rename_path(afc_client_t client, const char *from, const char *t | |||
| 669 | /* Send command */ | 630 | /* Send command */ |
| 670 | memcpy(send, from, strlen(from) + 1); | 631 | memcpy(send, from, strlen(from) + 1); |
| 671 | memcpy(send + strlen(from) + 1, to, strlen(to) + 1); | 632 | memcpy(send + strlen(from) + 1, to, strlen(to) + 1); |
| 672 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | 633 | ret = afc_dispatch_packet(client, AFC_OP_RENAME_PATH, send, strlen(to)+1 + strlen(from)+1, NULL, 0, &bytes); |
| 673 | client->afc_packet->operation = AFC_OP_RENAME_PATH; | ||
| 674 | ret = afc_dispatch_packet(client, send, strlen(to)+1 + strlen(from)+1, &bytes); | ||
| 675 | free(send); | 634 | free(send); |
| 635 | |||
| 676 | if (ret != AFC_E_SUCCESS) { | 636 | if (ret != AFC_E_SUCCESS) { |
| 677 | afc_unlock(client); | 637 | afc_unlock(client); |
| 678 | return AFC_E_NOT_ENOUGH_DATA; | 638 | return AFC_E_NOT_ENOUGH_DATA; |
| 679 | } | 639 | } |
| 680 | /* Receive response */ | 640 | /* Receive response */ |
| 681 | ret = afc_receive_data(client, &response, &bytes); | 641 | ret = afc_receive_data(client, NULL, &bytes); |
| 682 | if (response) | ||
| 683 | free(response); | ||
| 684 | 642 | ||
| 685 | afc_unlock(client); | 643 | afc_unlock(client); |
| 686 | 644 | ||
| @@ -699,7 +657,6 @@ afc_error_t afc_rename_path(afc_client_t client, const char *from, const char *t | |||
| 699 | afc_error_t afc_make_directory(afc_client_t client, const char *dir) | 657 | afc_error_t afc_make_directory(afc_client_t client, const char *dir) |
| 700 | { | 658 | { |
| 701 | uint32_t bytes = 0; | 659 | uint32_t bytes = 0; |
| 702 | char *response = NULL; | ||
| 703 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | 660 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; |
| 704 | 661 | ||
| 705 | if (!client) | 662 | if (!client) |
| @@ -708,17 +665,13 @@ afc_error_t afc_make_directory(afc_client_t client, const char *dir) | |||
| 708 | afc_lock(client); | 665 | afc_lock(client); |
| 709 | 666 | ||
| 710 | /* Send command */ | 667 | /* Send command */ |
| 711 | client->afc_packet->operation = AFC_OP_MAKE_DIR; | 668 | ret = afc_dispatch_packet(client, AFC_OP_MAKE_DIR, dir, strlen(dir)+1, NULL, 0, &bytes); |
| 712 | client->afc_packet->this_length = client->afc_packet->entire_length = 0; | ||
| 713 | ret = afc_dispatch_packet(client, dir, strlen(dir)+1, &bytes); | ||
| 714 | if (ret != AFC_E_SUCCESS) { | 669 | if (ret != AFC_E_SUCCESS) { |
| 715 | afc_unlock(client); | 670 | afc_unlock(client); |
| 716 | return AFC_E_NOT_ENOUGH_DATA; | 671 | return AFC_E_NOT_ENOUGH_DATA; |
| 717 | } | 672 | } |
| 718 | /* Receive response */ | 673 | /* Receive response */ |
| 719 | ret = afc_receive_data(client, &response, &bytes); | 674 | ret = afc_receive_data(client, NULL, &bytes); |
| 720 | if (response) | ||
| 721 | free(response); | ||
| 722 | 675 | ||
| 723 | afc_unlock(client); | 676 | afc_unlock(client); |
| 724 | 677 | ||
| @@ -748,9 +701,7 @@ afc_error_t afc_get_file_info(afc_client_t client, const char *path, char ***inf | |||
| 748 | afc_lock(client); | 701 | afc_lock(client); |
| 749 | 702 | ||
| 750 | /* Send command */ | 703 | /* Send command */ |
| 751 | client->afc_packet->operation = AFC_OP_GET_FILE_INFO; | 704 | ret = afc_dispatch_packet(client, AFC_OP_GET_FILE_INFO, path, strlen(path)+1, NULL, 0, &bytes); |
| 752 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | ||
| 753 | ret = afc_dispatch_packet(client, path, strlen(path)+1, &bytes); | ||
| 754 | if (ret != AFC_E_SUCCESS) { | 705 | if (ret != AFC_E_SUCCESS) { |
| 755 | afc_unlock(client); | 706 | afc_unlock(client); |
| 756 | return AFC_E_NOT_ENOUGH_DATA; | 707 | return AFC_E_NOT_ENOUGH_DATA; |
| @@ -781,7 +732,7 @@ afc_error_t afc_get_file_info(afc_client_t client, const char *path, char ***inf | |||
| 781 | * | 732 | * |
| 782 | * @return AFC_E_SUCCESS on success or an AFC_E_* error value. | 733 | * @return AFC_E_SUCCESS on success or an AFC_E_* error value. |
| 783 | */ | 734 | */ |
| 784 | afc_error_t | 735 | idevice_error_t |
| 785 | afc_file_open(afc_client_t client, const char *filename, | 736 | afc_file_open(afc_client_t client, const char *filename, |
| 786 | afc_file_mode_t file_mode, uint64_t *handle) | 737 | afc_file_mode_t file_mode, uint64_t *handle) |
| 787 | { | 738 | { |
| @@ -802,9 +753,7 @@ afc_file_open(afc_client_t client, const char *filename, | |||
| 802 | memcpy(data, &file_mode_loc, 8); | 753 | memcpy(data, &file_mode_loc, 8); |
| 803 | memcpy(data + 8, filename, strlen(filename)); | 754 | memcpy(data + 8, filename, strlen(filename)); |
| 804 | data[8 + strlen(filename)] = '\0'; | 755 | data[8 + strlen(filename)] = '\0'; |
| 805 | client->afc_packet->operation = AFC_OP_FILE_OPEN; | 756 | ret = afc_dispatch_packet(client, AFC_OP_FILE_OPEN, data, 8 + strlen(filename) + 1, NULL, 0, &bytes); |
| 806 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | ||
| 807 | ret = afc_dispatch_packet(client, data, 8 + strlen(filename) + 1, &bytes); | ||
| 808 | free(data); | 757 | free(data); |
| 809 | 758 | ||
| 810 | if (ret != AFC_E_SUCCESS) { | 759 | if (ret != AFC_E_SUCCESS) { |
| @@ -841,7 +790,7 @@ afc_file_open(afc_client_t client, const char *filename, | |||
| 841 | * | 790 | * |
| 842 | * @return AFC_E_SUCCESS on success or an AFC_E_* error value. | 791 | * @return AFC_E_SUCCESS on success or an AFC_E_* error value. |
| 843 | */ | 792 | */ |
| 844 | afc_error_t | 793 | idevice_error_t |
| 845 | afc_file_read(afc_client_t client, uint64_t handle, char *data, uint32_t length, uint32_t *bytes_read) | 794 | afc_file_read(afc_client_t client, uint64_t handle, char *data, uint32_t length, uint32_t *bytes_read) |
| 846 | { | 795 | { |
| 847 | char *input = NULL; | 796 | char *input = NULL; |
| @@ -864,9 +813,7 @@ afc_file_read(afc_client_t client, uint64_t handle, char *data, uint32_t length, | |||
| 864 | AFCFilePacket *packet = (AFCFilePacket *) malloc(sizeof(AFCFilePacket)); | 813 | AFCFilePacket *packet = (AFCFilePacket *) malloc(sizeof(AFCFilePacket)); |
| 865 | packet->filehandle = handle; | 814 | packet->filehandle = handle; |
| 866 | packet->size = htole64(((length - current_count) < MAXIMUM_READ_SIZE) ? (length - current_count) : MAXIMUM_READ_SIZE); | 815 | packet->size = htole64(((length - current_count) < MAXIMUM_READ_SIZE) ? (length - current_count) : MAXIMUM_READ_SIZE); |
| 867 | client->afc_packet->operation = AFC_OP_READ; | 816 | ret = afc_dispatch_packet(client, AFC_OP_READ, (const char*)packet, sizeof(AFCFilePacket), NULL, 0, &bytes_loc); |
| 868 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | ||
| 869 | ret = afc_dispatch_packet(client, (char *) packet, sizeof(AFCFilePacket), &bytes_loc); | ||
| 870 | free(packet); | 817 | free(packet); |
| 871 | 818 | ||
| 872 | if (ret != AFC_E_SUCCESS) { | 819 | if (ret != AFC_E_SUCCESS) { |
| @@ -915,15 +862,11 @@ afc_file_read(afc_client_t client, uint64_t handle, char *data, uint32_t length, | |||
| 915 | * | 862 | * |
| 916 | * @return AFC_E_SUCCESS on success or an AFC_E_* error value. | 863 | * @return AFC_E_SUCCESS on success or an AFC_E_* error value. |
| 917 | */ | 864 | */ |
| 918 | afc_error_t | 865 | idevice_error_t |
| 919 | afc_file_write(afc_client_t client, uint64_t handle, const char *data, uint32_t length, uint32_t *bytes_written) | 866 | afc_file_write(afc_client_t client, uint64_t handle, const char *data, uint32_t length, uint32_t *bytes_written) |
| 920 | { | 867 | { |
| 921 | char *acknowledgement = NULL; | 868 | uint32_t current_count = 0; |
| 922 | const uint32_t MAXIMUM_WRITE_SIZE = 1 << 15; | ||
| 923 | uint32_t current_count = 0, i = 0; | ||
| 924 | uint32_t segments = (length / MAXIMUM_WRITE_SIZE); | ||
| 925 | uint32_t bytes_loc = 0; | 869 | uint32_t bytes_loc = 0; |
| 926 | char *out_buffer = NULL; | ||
| 927 | afc_error_t ret = AFC_E_SUCCESS; | 870 | afc_error_t ret = AFC_E_SUCCESS; |
| 928 | 871 | ||
| 929 | if (!client || !client->afc_packet || !client->parent || !bytes_written || (handle == 0)) | 872 | if (!client || !client->afc_packet || !client->parent || !bytes_written || (handle == 0)) |
| @@ -933,53 +876,9 @@ afc_file_write(afc_client_t client, uint64_t handle, const char *data, uint32_t | |||
| 933 | 876 | ||
| 934 | debug_info("Write length: %i", length); | 877 | debug_info("Write length: %i", length); |
| 935 | 878 | ||
| 936 | /* Divide the file into segments. */ | 879 | ret = afc_dispatch_packet(client, AFC_OP_WRITE, (const char*)&handle, 8, data, length, &bytes_loc); |
| 937 | for (i = 0; i < segments; i++) { | ||
| 938 | /* Send the segment */ | ||
| 939 | client->afc_packet->this_length = sizeof(AFCPacket) + 8; | ||
| 940 | client->afc_packet->entire_length = client->afc_packet->this_length + MAXIMUM_WRITE_SIZE; | ||
| 941 | client->afc_packet->operation = AFC_OP_WRITE; | ||
| 942 | out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket)); | ||
| 943 | memcpy(out_buffer, (char *)&handle, sizeof(uint64_t)); | ||
| 944 | memcpy(out_buffer + 8, data + current_count, MAXIMUM_WRITE_SIZE); | ||
| 945 | ret = afc_dispatch_packet(client, out_buffer, MAXIMUM_WRITE_SIZE + 8, &bytes_loc); | ||
| 946 | if (ret != AFC_E_SUCCESS) { | ||
| 947 | afc_unlock(client); | ||
| 948 | return AFC_E_NOT_ENOUGH_DATA; | ||
| 949 | } | ||
| 950 | free(out_buffer); | ||
| 951 | out_buffer = NULL; | ||
| 952 | 880 | ||
| 953 | current_count += bytes_loc; | 881 | current_count += bytes_loc - (sizeof(AFCPacket) + 8); |
| 954 | ret = afc_receive_data(client, &acknowledgement, &bytes_loc); | ||
| 955 | if (ret != AFC_E_SUCCESS) { | ||
| 956 | afc_unlock(client); | ||
| 957 | return ret; | ||
| 958 | } else { | ||
| 959 | free(acknowledgement); | ||
| 960 | } | ||
| 961 | } | ||
| 962 | |||
| 963 | /* By this point, we should be at the end. i.e. the last segment that didn't | ||
| 964 | get sent in the for loop. This length is fine because it's always | ||
| 965 | sizeof(AFCPacket) + 8, but to be sure we do it again */ | ||
| 966 | if (current_count == length) { | ||
| 967 | afc_unlock(client); | ||
| 968 | *bytes_written = current_count; | ||
| 969 | return ret; | ||
| 970 | } | ||
| 971 | |||
| 972 | client->afc_packet->this_length = sizeof(AFCPacket) + 8; | ||
| 973 | client->afc_packet->entire_length = client->afc_packet->this_length + (length - current_count); | ||
| 974 | client->afc_packet->operation = AFC_OP_WRITE; | ||
| 975 | out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket)); | ||
| 976 | memcpy(out_buffer, (char *) &handle, sizeof(uint64_t)); | ||
| 977 | memcpy(out_buffer + 8, data + current_count, (length - current_count)); | ||
| 978 | ret = afc_dispatch_packet(client, out_buffer, (length - current_count) + 8, &bytes_loc); | ||
| 979 | free(out_buffer); | ||
| 980 | out_buffer = NULL; | ||
| 981 | |||
| 982 | current_count += bytes_loc; | ||
| 983 | 882 | ||
| 984 | if (ret != AFC_E_SUCCESS) { | 883 | if (ret != AFC_E_SUCCESS) { |
| 985 | afc_unlock(client); | 884 | afc_unlock(client); |
| @@ -987,12 +886,10 @@ afc_file_write(afc_client_t client, uint64_t handle, const char *data, uint32_t | |||
| 987 | return AFC_E_SUCCESS; | 886 | return AFC_E_SUCCESS; |
| 988 | } | 887 | } |
| 989 | 888 | ||
| 990 | ret = afc_receive_data(client, &acknowledgement, &bytes_loc); | 889 | ret = afc_receive_data(client, NULL, &bytes_loc); |
| 991 | afc_unlock(client); | 890 | afc_unlock(client); |
| 992 | if (ret != AFC_E_SUCCESS) { | 891 | if (ret != AFC_E_SUCCESS) { |
| 993 | debug_info("uh oh?"); | 892 | debug_info("uh oh?"); |
| 994 | } else { | ||
| 995 | free(acknowledgement); | ||
| 996 | } | 893 | } |
| 997 | *bytes_written = current_count; | 894 | *bytes_written = current_count; |
| 998 | return ret; | 895 | return ret; |
| @@ -1006,7 +903,6 @@ afc_file_write(afc_client_t client, uint64_t handle, const char *data, uint32_t | |||
| 1006 | */ | 903 | */ |
| 1007 | afc_error_t afc_file_close(afc_client_t client, uint64_t handle) | 904 | afc_error_t afc_file_close(afc_client_t client, uint64_t handle) |
| 1008 | { | 905 | { |
| 1009 | char *buffer = malloc(sizeof(char) * 8); | ||
| 1010 | uint32_t bytes = 0; | 906 | uint32_t bytes = 0; |
| 1011 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | 907 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; |
| 1012 | 908 | ||
| @@ -1018,12 +914,7 @@ afc_error_t afc_file_close(afc_client_t client, uint64_t handle) | |||
| 1018 | debug_info("File handle %i", handle); | 914 | debug_info("File handle %i", handle); |
| 1019 | 915 | ||
| 1020 | /* Send command */ | 916 | /* Send command */ |
| 1021 | memcpy(buffer, &handle, sizeof(uint64_t)); | 917 | ret = afc_dispatch_packet(client, AFC_OP_FILE_CLOSE, (const char*)&handle, 8, NULL, 0, &bytes); |
| 1022 | client->afc_packet->operation = AFC_OP_FILE_CLOSE; | ||
| 1023 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | ||
| 1024 | ret = afc_dispatch_packet(client, buffer, 8, &bytes); | ||
| 1025 | free(buffer); | ||
| 1026 | buffer = NULL; | ||
| 1027 | 918 | ||
| 1028 | if (ret != AFC_E_SUCCESS) { | 919 | if (ret != AFC_E_SUCCESS) { |
| 1029 | afc_unlock(client); | 920 | afc_unlock(client); |
| @@ -1031,9 +922,7 @@ afc_error_t afc_file_close(afc_client_t client, uint64_t handle) | |||
| 1031 | } | 922 | } |
| 1032 | 923 | ||
| 1033 | /* Receive the response */ | 924 | /* Receive the response */ |
| 1034 | ret = afc_receive_data(client, &buffer, &bytes); | 925 | ret = afc_receive_data(client, NULL, &bytes); |
| 1035 | if (buffer) | ||
| 1036 | free(buffer); | ||
| 1037 | 926 | ||
| 1038 | afc_unlock(client); | 927 | afc_unlock(client); |
| 1039 | 928 | ||
| @@ -1070,9 +959,7 @@ afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t op | |||
| 1070 | memcpy(buffer, &handle, sizeof(uint64_t)); | 959 | memcpy(buffer, &handle, sizeof(uint64_t)); |
| 1071 | memcpy(buffer + 8, &op, 8); | 960 | memcpy(buffer + 8, &op, 8); |
| 1072 | 961 | ||
| 1073 | client->afc_packet->operation = AFC_OP_FILE_LOCK; | 962 | ret = afc_dispatch_packet(client, AFC_OP_FILE_LOCK, buffer, 16, NULL, 0, &bytes); |
| 1074 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | ||
| 1075 | ret = afc_dispatch_packet(client, buffer, 16, &bytes); | ||
| 1076 | free(buffer); | 963 | free(buffer); |
| 1077 | buffer = NULL; | 964 | buffer = NULL; |
| 1078 | 965 | ||
| @@ -1082,11 +969,8 @@ afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t op | |||
| 1082 | return AFC_E_UNKNOWN_ERROR; | 969 | return AFC_E_UNKNOWN_ERROR; |
| 1083 | } | 970 | } |
| 1084 | /* Receive the response */ | 971 | /* Receive the response */ |
| 1085 | ret = afc_receive_data(client, &buffer, &bytes); | 972 | ret = afc_receive_data(client, NULL, &bytes); |
| 1086 | if (buffer) { | 973 | |
| 1087 | debug_buffer(buffer, bytes); | ||
| 1088 | free(buffer); | ||
| 1089 | } | ||
| 1090 | afc_unlock(client); | 974 | afc_unlock(client); |
| 1091 | 975 | ||
| 1092 | return ret; | 976 | return ret; |
| @@ -1119,9 +1003,7 @@ afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, | |||
| 1119 | memcpy(buffer, &handle, sizeof(uint64_t)); /* handle */ | 1003 | memcpy(buffer, &handle, sizeof(uint64_t)); /* handle */ |
| 1120 | memcpy(buffer + 8, &whence_loc, sizeof(uint64_t)); /* fromwhere */ | 1004 | memcpy(buffer + 8, &whence_loc, sizeof(uint64_t)); /* fromwhere */ |
| 1121 | memcpy(buffer + 16, &offset_loc, sizeof(uint64_t)); /* offset */ | 1005 | memcpy(buffer + 16, &offset_loc, sizeof(uint64_t)); /* offset */ |
| 1122 | client->afc_packet->operation = AFC_OP_FILE_SEEK; | 1006 | ret = afc_dispatch_packet(client, AFC_OP_FILE_SEEK, buffer, 24, NULL, 0, &bytes); |
| 1123 | client->afc_packet->this_length = client->afc_packet->entire_length = 0; | ||
| 1124 | ret = afc_dispatch_packet(client, buffer, 24, &bytes); | ||
| 1125 | free(buffer); | 1007 | free(buffer); |
| 1126 | buffer = NULL; | 1008 | buffer = NULL; |
| 1127 | 1009 | ||
| @@ -1130,9 +1012,7 @@ afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, | |||
| 1130 | return AFC_E_NOT_ENOUGH_DATA; | 1012 | return AFC_E_NOT_ENOUGH_DATA; |
| 1131 | } | 1013 | } |
| 1132 | /* Receive response */ | 1014 | /* Receive response */ |
| 1133 | ret = afc_receive_data(client, &buffer, &bytes); | 1015 | ret = afc_receive_data(client, NULL, &bytes); |
| 1134 | if (buffer) | ||
| 1135 | free(buffer); | ||
| 1136 | 1016 | ||
| 1137 | afc_unlock(client); | 1017 | afc_unlock(client); |
| 1138 | 1018 | ||
| @@ -1160,12 +1040,7 @@ afc_error_t afc_file_tell(afc_client_t client, uint64_t handle, uint64_t *positi | |||
| 1160 | afc_lock(client); | 1040 | afc_lock(client); |
| 1161 | 1041 | ||
| 1162 | /* Send the command */ | 1042 | /* Send the command */ |
| 1163 | memcpy(buffer, &handle, sizeof(uint64_t)); /* handle */ | 1043 | ret = afc_dispatch_packet(client, AFC_OP_FILE_TELL, (const char*)&handle, 8, NULL, 0, &bytes); |
| 1164 | client->afc_packet->operation = AFC_OP_FILE_TELL; | ||
| 1165 | client->afc_packet->this_length = client->afc_packet->entire_length = 0; | ||
| 1166 | ret = afc_dispatch_packet(client, buffer, 8, &bytes); | ||
| 1167 | free(buffer); | ||
| 1168 | buffer = NULL; | ||
| 1169 | 1044 | ||
| 1170 | if (ret != AFC_E_SUCCESS) { | 1045 | if (ret != AFC_E_SUCCESS) { |
| 1171 | afc_unlock(client); | 1046 | afc_unlock(client); |
| @@ -1214,9 +1089,7 @@ afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t new | |||
| 1214 | /* Send command */ | 1089 | /* Send command */ |
| 1215 | memcpy(buffer, &handle, sizeof(uint64_t)); /* handle */ | 1090 | memcpy(buffer, &handle, sizeof(uint64_t)); /* handle */ |
| 1216 | memcpy(buffer + 8, &newsize_loc, sizeof(uint64_t)); /* newsize */ | 1091 | memcpy(buffer + 8, &newsize_loc, sizeof(uint64_t)); /* newsize */ |
| 1217 | client->afc_packet->operation = AFC_OP_FILE_SET_SIZE; | 1092 | ret = afc_dispatch_packet(client, AFC_OP_FILE_SET_SIZE, buffer, 16, NULL, 0, &bytes); |
| 1218 | client->afc_packet->this_length = client->afc_packet->entire_length = 0; | ||
| 1219 | ret = afc_dispatch_packet(client, buffer, 16, &bytes); | ||
| 1220 | free(buffer); | 1093 | free(buffer); |
| 1221 | buffer = NULL; | 1094 | buffer = NULL; |
| 1222 | 1095 | ||
| @@ -1225,9 +1098,7 @@ afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t new | |||
| 1225 | return AFC_E_NOT_ENOUGH_DATA; | 1098 | return AFC_E_NOT_ENOUGH_DATA; |
| 1226 | } | 1099 | } |
| 1227 | /* Receive response */ | 1100 | /* Receive response */ |
| 1228 | ret = afc_receive_data(client, &buffer, &bytes); | 1101 | ret = afc_receive_data(client, NULL, &bytes); |
| 1229 | if (buffer) | ||
| 1230 | free(buffer); | ||
| 1231 | 1102 | ||
| 1232 | afc_unlock(client); | 1103 | afc_unlock(client); |
| 1233 | 1104 | ||
| @@ -1245,7 +1116,6 @@ afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t new | |||
| 1245 | */ | 1116 | */ |
| 1246 | afc_error_t afc_truncate(afc_client_t client, const char *path, uint64_t newsize) | 1117 | afc_error_t afc_truncate(afc_client_t client, const char *path, uint64_t newsize) |
| 1247 | { | 1118 | { |
| 1248 | char *response = NULL; | ||
| 1249 | char *send = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8)); | 1119 | char *send = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8)); |
| 1250 | uint32_t bytes = 0; | 1120 | uint32_t bytes = 0; |
| 1251 | uint64_t size_requested = htole64(newsize); | 1121 | uint64_t size_requested = htole64(newsize); |
| @@ -1259,18 +1129,15 @@ afc_error_t afc_truncate(afc_client_t client, const char *path, uint64_t newsize | |||
| 1259 | /* Send command */ | 1129 | /* Send command */ |
| 1260 | memcpy(send, &size_requested, 8); | 1130 | memcpy(send, &size_requested, 8); |
| 1261 | memcpy(send + 8, path, strlen(path) + 1); | 1131 | memcpy(send + 8, path, strlen(path) + 1); |
| 1262 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | 1132 | ret = afc_dispatch_packet(client, AFC_OP_TRUNCATE, send, 8 + strlen(path) + 1, NULL, 0, &bytes); |
| 1263 | client->afc_packet->operation = AFC_OP_TRUNCATE; | ||
| 1264 | ret = afc_dispatch_packet(client, send, 8 + strlen(path) + 1, &bytes); | ||
| 1265 | free(send); | 1133 | free(send); |
| 1134 | |||
| 1266 | if (ret != AFC_E_SUCCESS) { | 1135 | if (ret != AFC_E_SUCCESS) { |
| 1267 | afc_unlock(client); | 1136 | afc_unlock(client); |
| 1268 | return AFC_E_NOT_ENOUGH_DATA; | 1137 | return AFC_E_NOT_ENOUGH_DATA; |
| 1269 | } | 1138 | } |
| 1270 | /* Receive response */ | 1139 | /* Receive response */ |
| 1271 | ret = afc_receive_data(client, &response, &bytes); | 1140 | ret = afc_receive_data(client, NULL, &bytes); |
| 1272 | if (response) | ||
| 1273 | free(response); | ||
| 1274 | 1141 | ||
| 1275 | afc_unlock(client); | 1142 | afc_unlock(client); |
| 1276 | 1143 | ||
| @@ -1289,7 +1156,6 @@ afc_error_t afc_truncate(afc_client_t client, const char *path, uint64_t newsize | |||
| 1289 | */ | 1156 | */ |
| 1290 | afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, const char *target, const char *linkname) | 1157 | afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, const char *target, const char *linkname) |
| 1291 | { | 1158 | { |
| 1292 | char *response = NULL; | ||
| 1293 | char *send = (char *) malloc(sizeof(char) * (strlen(target)+1 + strlen(linkname)+1 + 8)); | 1159 | char *send = (char *) malloc(sizeof(char) * (strlen(target)+1 + strlen(linkname)+1 + 8)); |
| 1294 | uint32_t bytes = 0; | 1160 | uint32_t bytes = 0; |
| 1295 | uint64_t type = htole64(linktype); | 1161 | uint64_t type = htole64(linktype); |
| @@ -1308,18 +1174,14 @@ afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, const c | |||
| 1308 | memcpy(send, &type, 8); | 1174 | memcpy(send, &type, 8); |
| 1309 | memcpy(send + 8, target, strlen(target) + 1); | 1175 | memcpy(send + 8, target, strlen(target) + 1); |
| 1310 | memcpy(send + 8 + strlen(target) + 1, linkname, strlen(linkname) + 1); | 1176 | memcpy(send + 8 + strlen(target) + 1, linkname, strlen(linkname) + 1); |
| 1311 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | 1177 | ret = afc_dispatch_packet(client, AFC_OP_MAKE_LINK, send, 8 + strlen(linkname) + 1 + strlen(target) + 1, NULL, 0, &bytes); |
| 1312 | client->afc_packet->operation = AFC_OP_MAKE_LINK; | ||
| 1313 | ret = afc_dispatch_packet(client, send, 8 + strlen(linkname) + 1 + strlen(target) + 1, &bytes); | ||
| 1314 | free(send); | 1178 | free(send); |
| 1315 | if (ret != AFC_E_SUCCESS) { | 1179 | if (ret != AFC_E_SUCCESS) { |
| 1316 | afc_unlock(client); | 1180 | afc_unlock(client); |
| 1317 | return AFC_E_NOT_ENOUGH_DATA; | 1181 | return AFC_E_NOT_ENOUGH_DATA; |
| 1318 | } | 1182 | } |
| 1319 | /* Receive response */ | 1183 | /* Receive response */ |
| 1320 | ret = afc_receive_data(client, &response, &bytes); | 1184 | ret = afc_receive_data(client, NULL, &bytes); |
| 1321 | if (response) | ||
| 1322 | free(response); | ||
| 1323 | 1185 | ||
| 1324 | afc_unlock(client); | 1186 | afc_unlock(client); |
| 1325 | 1187 | ||
| @@ -1337,7 +1199,6 @@ afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, const c | |||
| 1337 | */ | 1199 | */ |
| 1338 | afc_error_t afc_set_file_time(afc_client_t client, const char *path, uint64_t mtime) | 1200 | afc_error_t afc_set_file_time(afc_client_t client, const char *path, uint64_t mtime) |
| 1339 | { | 1201 | { |
| 1340 | char *response = NULL; | ||
| 1341 | char *send = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8)); | 1202 | char *send = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8)); |
| 1342 | uint32_t bytes = 0; | 1203 | uint32_t bytes = 0; |
| 1343 | uint64_t mtime_loc = htole64(mtime); | 1204 | uint64_t mtime_loc = htole64(mtime); |
| @@ -1351,18 +1212,14 @@ afc_error_t afc_set_file_time(afc_client_t client, const char *path, uint64_t mt | |||
| 1351 | /* Send command */ | 1212 | /* Send command */ |
| 1352 | memcpy(send, &mtime_loc, 8); | 1213 | memcpy(send, &mtime_loc, 8); |
| 1353 | memcpy(send + 8, path, strlen(path) + 1); | 1214 | memcpy(send + 8, path, strlen(path) + 1); |
| 1354 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | 1215 | ret = afc_dispatch_packet(client, AFC_OP_SET_FILE_TIME, send, 8 + strlen(path) + 1, NULL, 0, &bytes); |
| 1355 | client->afc_packet->operation = AFC_OP_SET_FILE_TIME; | ||
| 1356 | ret = afc_dispatch_packet(client, send, 8 + strlen(path) + 1, &bytes); | ||
| 1357 | free(send); | 1216 | free(send); |
| 1358 | if (ret != AFC_E_SUCCESS) { | 1217 | if (ret != AFC_E_SUCCESS) { |
| 1359 | afc_unlock(client); | 1218 | afc_unlock(client); |
| 1360 | return AFC_E_NOT_ENOUGH_DATA; | 1219 | return AFC_E_NOT_ENOUGH_DATA; |
| 1361 | } | 1220 | } |
| 1362 | /* Receive response */ | 1221 | /* Receive response */ |
| 1363 | ret = afc_receive_data(client, &response, &bytes); | 1222 | ret = afc_receive_data(client, NULL, &bytes); |
| 1364 | if (response) | ||
| 1365 | free(response); | ||
| 1366 | 1223 | ||
| 1367 | afc_unlock(client); | 1224 | afc_unlock(client); |
| 1368 | 1225 | ||
