diff options
-rw-r--r-- | src/ifuse.c | 294 |
1 files changed, 192 insertions, 102 deletions
diff --git a/src/ifuse.c b/src/ifuse.c index 2bc0c2f..3e8ecb5 100644 --- a/src/ifuse.c +++ b/src/ifuse.c @@ -58,6 +58,94 @@ static void free_dictionary(char **dictionary) free(dictionary); } +struct afc_error_mapping { + afc_error_t from; + int to; +} static afc_error_to_errno_map[] = { + {AFC_E_SUCCESS , 0}, + {AFC_E_OP_HEADER_INVALID , EIO}, + {AFC_E_NO_RESOURCES , EMFILE}, + {AFC_E_READ_ERROR , ENOTDIR}, + {AFC_E_WRITE_ERROR , EIO}, + {AFC_E_UNKNOWN_PACKET_TYPE , EIO}, + {AFC_E_INVALID_ARGUMENT , EINVAL}, + {AFC_E_OBJECT_NOT_FOUND , ENOENT}, + {AFC_E_OBJECT_IS_DIR , EISDIR}, + {AFC_E_PERM_DENIED , EPERM}, + {AFC_E_SERVICE_NOT_CONNECTED , ENXIO}, + {AFC_E_OP_TIMEOUT , ETIMEDOUT}, + {AFC_E_TOO_MUCH_DATA , EFBIG}, + {AFC_E_END_OF_DATA , ENODATA}, + {AFC_E_OP_NOT_SUPPORTED , ENOSYS}, + {AFC_E_OBJECT_EXISTS , EEXIST}, + {AFC_E_OBJECT_BUSY , EBUSY}, + {AFC_E_NO_SPACE_LEFT , ENOSPC}, + {AFC_E_OP_WOULD_BLOCK , EWOULDBLOCK}, + {AFC_E_IO_ERROR , EIO}, + {AFC_E_OP_INTERRUPTED , EINTR}, + {AFC_E_OP_IN_PROGRESS , EALREADY}, + {AFC_E_INTERNAL_ERROR , EIO}, + {-1} +}; + +/** + * Tries to convert the AFC error value into a meaningful errno value. + * + * @param client AFC client to retrieve status value from. + * + * @return errno value. + */ +static int get_afc_error_as_errno(afc_error_t error) +{ + int i = 0; + int res = -1; + + while (afc_error_to_errno_map[i++].from != -1) { + if (afc_error_to_errno_map[i].from == error) { + res = afc_error_to_errno_map[i++].to; + break; + } + } + + if (res == -1) { + fprintf(stderr, "Unknown AFC status %d.\n", error); + res = EIO; + } + + return res; +} + +static int get_afc_file_mode(afc_file_mode_t *afc_mode, int flags) +{ + switch (flags & O_ACCMODE) { + case O_RDONLY: + *afc_mode = AFC_FOPEN_RDONLY; + break; + case O_WRONLY: + if ((flags & O_TRUNC) == O_TRUNC) { + *afc_mode = AFC_FOPEN_WRONLY; + } else if ((flags & O_APPEND) == O_APPEND) { + *afc_mode = AFC_FOPEN_APPEND; + } else { + *afc_mode = AFC_FOPEN_RW; + } + break; + case O_RDWR: + if ((flags & O_TRUNC) == O_TRUNC) { + *afc_mode = AFC_FOPEN_WR; + } else if ((flags & O_APPEND) == O_APPEND) { + *afc_mode = AFC_FOPEN_RDAPPEND; + } else { + *afc_mode = AFC_FOPEN_RW; + } + break; + default: + *afc_mode = 0; + return -1; + } + return 0; +} + static int ifuse_getattr(const char *path, struct stat *stbuf) { int i; @@ -65,18 +153,12 @@ static int ifuse_getattr(const char *path, struct stat *stbuf) char **info = NULL; afc_client_t afc = fuse_get_context()->private_data; - iphone_error_t ret = afc_get_file_info(afc, path, &info); + afc_error_t ret = afc_get_file_info(afc, path, &info); memset(stbuf, 0, sizeof(struct stat)); - if (ret == IPHONE_E_AFC_ERROR) { - int e = afc_get_errno(afc); - if (e < 0) { - res = -EACCES; - } else { - res = -e; - } - } else if (ret != IPHONE_E_SUCCESS) { - res = -EACCES; + if (ret != AFC_E_SUCCESS) { + int e = get_afc_error_as_errno(ret); + res = -e; } else if (!info) { res = -1; } else { @@ -114,7 +196,7 @@ static int ifuse_getattr(const char *path, struct stat *stbuf) } else if (S_ISLNK(stbuf->st_mode)) { stbuf->st_mode |= 0777; } else { - stbuf->st_mode |= 0644; + stbuf->st_mode |= 0644; } // and set some additional info @@ -133,7 +215,7 @@ static int ifuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, of char **dirs = NULL; afc_client_t afc = fuse_get_context()->private_data; - afc_get_dir_list(afc, path, &dirs); + afc_read_directory(afc, path, &dirs); if (!dirs) return -ENOENT; @@ -147,59 +229,22 @@ static int ifuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, of return 0; } -static int get_afc_file_mode(afc_file_mode_t *afc_mode, int flags) -{ - switch (flags & O_ACCMODE) { - case O_RDONLY: - *afc_mode = AFC_FOPEN_RDONLY; - break; - case O_WRONLY: - if ((flags & O_TRUNC) == O_TRUNC) { - *afc_mode = AFC_FOPEN_WRONLY; - } else if ((flags & O_APPEND) == O_APPEND) { - *afc_mode = AFC_FOPEN_APPEND; - } else { - *afc_mode = AFC_FOPEN_RW; - } - break; - case O_RDWR: - if ((flags & O_TRUNC) == O_TRUNC) { - *afc_mode = AFC_FOPEN_WR; - } else if ((flags & O_APPEND) == O_APPEND) { - *afc_mode = AFC_FOPEN_RDAPPEND; - } else { - *afc_mode = AFC_FOPEN_RW; - } - break; - default: - *afc_mode = 0; - return -1; - } - return 0; -} - - static int ifuse_open(const char *path, struct fuse_file_info *fi) { int i; afc_client_t afc = fuse_get_context()->private_data; - iphone_error_t err; - afc_file_mode_t mode = 0; - - if (get_afc_file_mode(&mode, fi->flags) < 0 || (mode == 0)) { + afc_error_t err; + afc_file_mode_t mode = 0; + + err = get_afc_file_mode(&mode, fi->flags); + if (err != AFC_E_SUCCESS || (mode == 0)) { return -EPERM; } - err = afc_open_file(afc, path, mode, &fi->fh); - if (err == IPHONE_E_AFC_ERROR) { - int res = afc_get_errno(afc); - if (res < 0) { - return -EACCES; - } else { - return res; - } - } else if (err != IPHONE_E_SUCCESS) { - return -EINVAL; + err = afc_file_open(afc, path, mode, &fi->fh); + if (err != AFC_E_SUCCESS) { + int res = get_afc_error_as_errno(err); + return -res; } return 0; @@ -218,8 +263,18 @@ static int ifuse_read(const char *path, char *buf, size_t size, off_t offset, st if (size == 0) return 0; - if (IPHONE_E_SUCCESS == afc_seek_file(afc, fi->fh, offset, SEEK_SET)) - afc_read_file(afc, fi->fh, buf, size, &bytes); + afc_error_t err = afc_file_seek(afc, fi->fh, offset, SEEK_SET); + if (err != AFC_E_SUCCESS) { + int res = get_afc_error_as_errno(err); + return -res; + } + + err = afc_file_read(afc, fi->fh, buf, size, &bytes); + if (err != AFC_E_SUCCESS) { + int res = get_afc_error_as_errno(err); + return -res; + } + return bytes; } @@ -231,8 +286,18 @@ static int ifuse_write(const char *path, const char *buf, size_t size, off_t off if (size == 0) return 0; - if (IPHONE_E_SUCCESS == afc_seek_file(afc, fi->fh, offset, SEEK_SET)) - afc_write_file(afc, fi->fh, buf, size, &bytes); + afc_error_t err = afc_file_seek(afc, fi->fh, offset, SEEK_SET); + if (err != AFC_E_SUCCESS) { + int res = get_afc_error_as_errno(err); + return -res; + } + + err = afc_file_write(afc, fi->fh, buf, size, &bytes); + if (err != AFC_E_SUCCESS) { + int res = get_afc_error_as_errno(err); + return -res; + } + return bytes; } @@ -245,7 +310,7 @@ static int ifuse_release(const char *path, struct fuse_file_info *fi) { afc_client_t afc = fuse_get_context()->private_data; - afc_close_file(afc, fi->fh); + afc_file_close(afc, fi->fh); return 0; } @@ -257,23 +322,23 @@ void *ifuse_init_with_service(struct fuse_conn_info *conn, const char *service_n conn->async_read = 0; - if (IPHONE_E_SUCCESS == lockdownd_start_service(control, service_name, &port) && !port) { - lockdownd_free_client(control); - iphone_free_device(phone); + if (LOCKDOWN_E_SUCCESS == lockdownd_start_service(control, service_name, &port) && !port) { + lockdownd_client_free(control); + iphone_device_free(phone); fprintf(stderr, "Something went wrong when starting AFC."); return NULL; } - afc_new_client(phone, port, &afc); + afc_client_new(phone, port, &afc); - lockdownd_free_client(control); + lockdownd_client_free(control); control = NULL; if (afc) { // get file system block size int i; char **info_raw = NULL; - if ((IPHONE_E_SUCCESS == afc_get_devinfo(afc, &info_raw)) && info_raw) { + if ((AFC_E_SUCCESS == afc_get_device_info(afc, &info_raw)) && info_raw) { for (i = 0; info_raw[i]; i+=2) { if (!strcmp(info_raw[i], "FSBlockSize")) { g_blocksize = atoi(info_raw[i + 1]); @@ -291,11 +356,11 @@ void ifuse_cleanup(void *data) { afc_client_t afc = (afc_client_t) data; - afc_free_client(afc); + afc_client_free(afc); if (control) { - lockdownd_free_client(control); + lockdownd_client_free(control); } - iphone_free_device(phone); + iphone_device_free(phone); } int ifuse_flush(const char *path, struct fuse_file_info *fi) @@ -310,7 +375,11 @@ int ifuse_statfs(const char *path, struct statvfs *stats) uint64_t totalspace = 0, freespace = 0; int i = 0, blocksize = 0; - afc_get_devinfo(afc, &info_raw); + afc_error_t err = afc_get_device_info(afc, &info_raw); + if (err != AFC_E_SUCCESS) { + int res = get_afc_error_as_errno(err); + return -res; + } if (!info_raw) return -ENOENT; @@ -325,26 +394,36 @@ int ifuse_statfs(const char *path, struct statvfs *stats) } free_dictionary(info_raw); - // Now to fill the struct. stats->f_bsize = stats->f_frsize = blocksize; - stats->f_blocks = totalspace / blocksize; // gets the blocks by dividing bytes by blocksize - stats->f_bfree = stats->f_bavail = freespace / blocksize; // all bytes are free to everyone, I guess. - stats->f_namemax = 255; // blah - stats->f_files = stats->f_ffree = 1000000000; // make up any old thing, I guess + stats->f_blocks = totalspace / blocksize; + stats->f_bfree = stats->f_bavail = freespace / blocksize; + stats->f_namemax = 255; + stats->f_files = stats->f_ffree = 1000000000; + return 0; } int ifuse_truncate(const char *path, off_t size) { afc_client_t afc = fuse_get_context()->private_data; - return afc_truncate(afc, path, size); + afc_error_t err = afc_truncate(afc, path, size); + if (err != AFC_E_SUCCESS) { + int res = get_afc_error_as_errno(err); + return -res; + } + return 0; } int ifuse_ftruncate(const char *path, off_t size, struct fuse_file_info *fi) { afc_client_t afc = fuse_get_context()->private_data; - return afc_truncate_file(afc, fi->fh, size); + afc_error_t err = afc_file_truncate(afc, fi->fh, size); + if (err != AFC_E_SUCCESS) { + int res = get_afc_error_as_errno(err); + return -res; + } + return 0; } int ifuse_readlink(const char *path, char *linktarget, size_t buflen) @@ -356,8 +435,8 @@ int ifuse_readlink(const char *path, char *linktarget, size_t buflen) } linktarget[0] = '\0'; // in case the link target cannot be determined afc_client_t afc = fuse_get_context()->private_data; - iphone_error_t res = afc_get_file_info(afc, path, &info); - if ((res == IPHONE_E_SUCCESS) && info) { + afc_error_t err = afc_get_file_info(afc, path, &info); + if ((err == AFC_E_SUCCESS) && info) { ret = -1; for (i = 0; info[i]; i+=2) { if (!strcmp(info[i], "LinkTarget")) { @@ -368,55 +447,66 @@ int ifuse_readlink(const char *path, char *linktarget, size_t buflen) } free_dictionary(info); } else { - ret = -1; + ret = get_afc_error_as_errno(err); + return -ret; } - + return ret; } int ifuse_symlink(const char *target, const char *linkname) { afc_client_t afc = fuse_get_context()->private_data; - if (IPHONE_E_SUCCESS == afc_make_link(afc, AFC_SYMLINK, target, linkname)) + + afc_error_t err = afc_make_link(afc, AFC_SYMLINK, target, linkname); + if (err == AFC_E_SUCCESS) return 0; - else - return -1; + + return -get_afc_error_as_errno(err); } int ifuse_link(const char *target, const char *linkname) { afc_client_t afc = fuse_get_context()->private_data; - if (IPHONE_E_SUCCESS == afc_make_link(afc, AFC_HARDLINK, target, linkname)) + + afc_error_t err = afc_make_link(afc, AFC_HARDLINK, target, linkname); + if (err == AFC_E_SUCCESS) return 0; - else - return -1; + + return -get_afc_error_as_errno(err); } int ifuse_unlink(const char *path) { afc_client_t afc = fuse_get_context()->private_data; - if (IPHONE_E_SUCCESS == afc_delete_file(afc, path)) + + afc_error_t err = afc_remove_path(afc, path); + if (err == AFC_E_SUCCESS) return 0; - else - return -1; + + return -get_afc_error_as_errno(err); } int ifuse_rename(const char *from, const char *to) { afc_client_t afc = fuse_get_context()->private_data; - if (IPHONE_E_SUCCESS == afc_rename_file(afc, from, to)) + + afc_error_t err = afc_rename_path(afc, from, to); + if (err == AFC_E_SUCCESS) return 0; - else - return -1; + + return -get_afc_error_as_errno(err); } int ifuse_mkdir(const char *dir, mode_t ignored) { afc_client_t afc = fuse_get_context()->private_data; - if (IPHONE_E_SUCCESS == afc_mkdir(afc, dir)) + + afc_error_t err = afc_make_directory(afc, dir); + if (err == AFC_E_SUCCESS) return 0; - else - return -1; + + return -get_afc_error_as_errno(err); } void *ifuse_init_normal(struct fuse_conn_info *conn) @@ -467,7 +557,7 @@ static int ifuse_opt_proc(void *data, const char *arg, int key, struct fuse_args return 0; } else if (strcmp(arg, "--debug") == 0) { iphone_set_debug_mask(DBGMASK_ALL); - iphone_set_debug(1); + iphone_set_debug_level(1); return 0; } else return 0; @@ -508,8 +598,8 @@ int main(int argc, char *argv[]) return 0; } - if (IPHONE_E_SUCCESS != lockdownd_client_new(phone, &control)) { - iphone_free_device(phone); + if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &control)) { + iphone_device_free(phone); fprintf(stderr, "Failed to connect to lockdownd service on the device.\n"); fprintf(stderr, "Try again. If it still fails try rebooting your device.\n"); return 0; |