summaryrefslogtreecommitdiffstats
path: root/src/AFC.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/AFC.c')
-rw-r--r--src/AFC.c106
1 files changed, 105 insertions, 1 deletions
diff --git a/src/AFC.c b/src/AFC.c
index 67d37f3..dfe8af7 100644
--- a/src/AFC.c
+++ b/src/AFC.c
@@ -178,7 +178,7 @@ static int dispatch_AFC_packet(iphone_afc_client_t client, const char *data, int
178 log_debug_msg("dispatch_AFC_packet: sent the first now go with the second\n"); 178 log_debug_msg("dispatch_AFC_packet: sent the first now go with the second\n");
179 log_debug_msg("Length: %i\n", length - offset); 179 log_debug_msg("Length: %i\n", length - offset);
180 log_debug_msg("Buffer: \n"); 180 log_debug_msg("Buffer: \n");
181 log_debug_msg(data + offset); 181 log_debug_buffer(data + offset, length - offset);
182 182
183 iphone_mux_send(client->connection, data + offset, length - offset, &bytes); 183 iphone_mux_send(client->connection, data + offset, length - offset, &bytes);
184 return bytes; 184 return bytes;
@@ -916,6 +916,63 @@ iphone_error_t iphone_afc_close_file(iphone_afc_client_t client, iphone_afc_file
916 return IPHONE_E_SUCCESS; 916 return IPHONE_E_SUCCESS;
917} 917}
918 918
919/** Locks or unlocks a file on the phone.
920 *
921 * makes use of flock, see
922 * http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/flock.2.html
923 *
924 * operation (same as in sys/file.h on linux):
925 *
926 * LOCK_SH 1 // shared lock
927 * LOCK_EX 2 // exclusive lock
928 * LOCK_NB 4 // don't block when locking
929 * LOCK_UN 8 // unlock
930 *
931 * @param client The client to close the file with.
932 * @param file A pointer to an AFCFile struct containing the file handle of the
933 * file to close.
934 * @operation the lock or unlock operation to perform.
935 */
936iphone_error_t iphone_afc_lock_file(iphone_afc_client_t client, iphone_afc_file_t file, int operation)
937{
938 if (!client || !file)
939 return IPHONE_E_INVALID_ARG;
940 char *buffer = malloc(16);
941 uint32_t zero = 0;
942 int bytes = 0;
943 uint64_t op = operation;
944
945 afc_lock(client);
946
947 log_debug_msg("afc_lock_file: File handle %i\n", file->filehandle);
948
949 // Send command
950 memcpy(buffer, &file->filehandle, sizeof(uint32_t));
951 memcpy(buffer + sizeof(uint32_t), &zero, sizeof(zero));
952 memcpy(buffer + 8, &op, 8);
953
954 client->afc_packet->operation = AFC_FILE_LOCK;
955 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
956 bytes = dispatch_AFC_packet(client, buffer, 15);
957 free(buffer);
958 buffer = NULL;
959
960 if (bytes <= 0) {
961 afc_unlock(client);
962 log_debug_msg("fuck\n");
963 return IPHONE_E_UNKNOWN_ERROR;
964 }
965 // Receive the response
966 bytes = receive_AFC_data(client, &buffer);
967 log_debug_msg("%s: receiving response (%d bytes)\n", __func__, bytes);
968 if (buffer) {
969 log_debug_buffer(buffer, bytes);
970 free(buffer);
971 }
972 afc_unlock(client);
973 return IPHONE_E_SUCCESS;
974}
975
919/** Seeks to a given position of a pre-opened file on the phone. 976/** Seeks to a given position of a pre-opened file on the phone.
920 * 977 *
921 * @param client The client to use to seek to the position. 978 * @param client The client to use to seek to the position.
@@ -1016,6 +1073,53 @@ iphone_error_t iphone_afc_truncate_file(iphone_afc_client_t client, iphone_afc_f
1016 } 1073 }
1017} 1074}
1018 1075
1076/** Sets the size of a file on the phone without prior opening it.
1077 *
1078 * @param client The client to use to set the file size.
1079 * @param path The path of the file to be truncated.
1080 * @param newsize The size to set the file to.
1081 *
1082 * @return IPHONE_E_SUCCESS if everything went well, IPHONE_E_INVALID_ARG
1083 * if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise.
1084 */
1085iphone_error_t iphone_afc_truncate(iphone_afc_client_t client, const char *path, off_t newsize)
1086{
1087 char *response = NULL;
1088 char *send = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8));
1089 int bytes = 0;
1090 uint64_t size_requested = newsize;
1091
1092 if (!client || !path || !client->afc_packet || !client->connection)
1093 return IPHONE_E_INVALID_ARG;
1094
1095 afc_lock(client);
1096
1097 // Send command
1098 memcpy(send, &size_requested, 8);
1099 memcpy(send + 8, path, strlen(path) + 1);
1100 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
1101 client->afc_packet->operation = AFC_TRUNCATE;
1102 bytes = dispatch_AFC_packet(client, send, 8 + strlen(path));
1103 free(send);
1104 if (bytes <= 0) {
1105 afc_unlock(client);
1106 return IPHONE_E_NOT_ENOUGH_DATA;
1107 }
1108 // Receive response
1109 bytes = receive_AFC_data(client, &response);
1110 if (response)
1111 free(response);
1112
1113 afc_unlock(client);
1114
1115 if (bytes < 0) {
1116 return IPHONE_E_NOT_ENOUGH_DATA;
1117 } else {
1118 return IPHONE_E_SUCCESS;
1119 }
1120}
1121
1122
1019uint32_t iphone_afc_get_file_handle(iphone_afc_file_t file) 1123uint32_t iphone_afc_get_file_handle(iphone_afc_file_t file)
1020{ 1124{
1021 return file->filehandle; 1125 return file->filehandle;