diff options
| -rw-r--r-- | include/libiphone/libiphone.h | 7 | ||||
| -rw-r--r-- | src/AFC.c | 52 |
2 files changed, 58 insertions, 1 deletions
diff --git a/include/libiphone/libiphone.h b/include/libiphone/libiphone.h index fc24d35..463efa7 100644 --- a/include/libiphone/libiphone.h +++ b/include/libiphone/libiphone.h | |||
| @@ -63,6 +63,11 @@ typedef enum { | |||
| 63 | AFC_FOPEN_RDAPPEND = 0x00000006 // a+ O_RDWR | O_APPEND | O_CREAT | 63 | AFC_FOPEN_RDAPPEND = 0x00000006 // a+ O_RDWR | O_APPEND | O_CREAT |
| 64 | } iphone_afc_file_mode_t; | 64 | } iphone_afc_file_mode_t; |
| 65 | 65 | ||
| 66 | typedef enum { | ||
| 67 | IPHONE_AFC_HARDLINK = 1, | ||
| 68 | IPHONE_AFC_SYMLINK = 2 | ||
| 69 | } iphone_afc_link_type_t; | ||
| 70 | |||
| 66 | struct iphone_device_int; | 71 | struct iphone_device_int; |
| 67 | typedef struct iphone_device_int *iphone_device_t; | 72 | typedef struct iphone_device_int *iphone_device_t; |
| 68 | 73 | ||
| @@ -127,7 +132,7 @@ iphone_error_t iphone_afc_delete_file ( iphone_afc_client_t client, const char * | |||
| 127 | iphone_error_t iphone_afc_rename_file ( iphone_afc_client_t client, const char *from, const char *to); | 132 | iphone_error_t iphone_afc_rename_file ( iphone_afc_client_t client, const char *from, const char *to); |
| 128 | iphone_error_t iphone_afc_mkdir ( iphone_afc_client_t client, const char *dir); | 133 | iphone_error_t iphone_afc_mkdir ( iphone_afc_client_t client, const char *dir); |
| 129 | iphone_error_t iphone_afc_truncate(iphone_afc_client_t client, const char *path, off_t newsize); | 134 | iphone_error_t iphone_afc_truncate(iphone_afc_client_t client, const char *path, off_t newsize); |
| 130 | 135 | iphone_error_t iphone_afc_make_link ( iphone_afc_client_t client, iphone_afc_link_type_t linktype, const char *target, const char *linkname); | |
| 131 | 136 | ||
| 132 | 137 | ||
| 133 | iphone_error_t iphone_msync_new_client(iphone_device_t device, int dst_port, | 138 | iphone_error_t iphone_msync_new_client(iphone_device_t device, int dst_port, |
| @@ -1170,3 +1170,55 @@ iphone_error_t iphone_afc_truncate(iphone_afc_client_t client, const char *path, | |||
| 1170 | } | 1170 | } |
| 1171 | return IPHONE_E_SUCCESS; | 1171 | return IPHONE_E_SUCCESS; |
| 1172 | } | 1172 | } |
| 1173 | |||
| 1174 | /** Creates a hard link or symbolic link on the device. | ||
| 1175 | * | ||
| 1176 | * @param client The client to use for making a link | ||
| 1177 | * @param type 1 = hard link, 2 = symlink | ||
| 1178 | * @param target The file to be linked. | ||
| 1179 | * @param linkname The name of link. | ||
| 1180 | * | ||
| 1181 | * @return IPHONE_E_SUCCESS if everything went well, IPHONE_E_INVALID_ARG | ||
| 1182 | * if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise. | ||
| 1183 | */ | ||
| 1184 | iphone_error_t iphone_afc_make_link(iphone_afc_client_t client, iphone_afc_link_type_t linktype, const char *target, const char *linkname) | ||
| 1185 | { | ||
| 1186 | char *response = NULL; | ||
| 1187 | char *send = (char *) malloc(sizeof(char) * (strlen(target)+1 + strlen(linkname)+1 + 8)); | ||
| 1188 | int bytes = 0; | ||
| 1189 | uint64_t type = linktype; | ||
| 1190 | |||
| 1191 | if (!client || !target || !linkname || !client->afc_packet || client->sfd < 0) | ||
| 1192 | return IPHONE_E_INVALID_ARG; | ||
| 1193 | |||
| 1194 | afc_lock(client); | ||
| 1195 | |||
| 1196 | log_debug_msg("link type: %lld\n", type); | ||
| 1197 | log_debug_msg("target: %s, length:%d\n", target, strlen(target)); | ||
| 1198 | log_debug_msg("linkname: %s, length:%d\n", linkname, strlen(linkname)); | ||
| 1199 | |||
| 1200 | // Send command | ||
| 1201 | memcpy(send, &type, 8); | ||
| 1202 | memcpy(send + 8, target, strlen(target) + 1); | ||
| 1203 | memcpy(send + 8 + strlen(target) + 1, linkname, strlen(linkname) + 1); | ||
| 1204 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | ||
| 1205 | client->afc_packet->operation = AFC_MAKE_LINK; | ||
| 1206 | bytes = dispatch_AFC_packet(client, send, 8 + strlen(linkname) + 1 + strlen(target) + 1); | ||
| 1207 | free(send); | ||
| 1208 | if (bytes <= 0) { | ||
| 1209 | afc_unlock(client); | ||
| 1210 | return IPHONE_E_NOT_ENOUGH_DATA; | ||
| 1211 | } | ||
| 1212 | // Receive response | ||
| 1213 | bytes = receive_AFC_data(client, &response); | ||
| 1214 | if (response) | ||
| 1215 | free(response); | ||
| 1216 | |||
| 1217 | afc_unlock(client); | ||
| 1218 | |||
| 1219 | if (bytes < 0) { | ||
| 1220 | return IPHONE_E_NOT_ENOUGH_DATA; | ||
| 1221 | } else { | ||
| 1222 | return IPHONE_E_SUCCESS; | ||
| 1223 | } | ||
| 1224 | } | ||
