diff options
Diffstat (limited to 'src/ifuse.c')
-rw-r--r-- | src/ifuse.c | 351 |
1 files changed, 0 insertions, 351 deletions
diff --git a/src/ifuse.c b/src/ifuse.c deleted file mode 100644 index aef24bd..0000000 --- a/src/ifuse.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * ifuse.c - * A Fuse filesystem which exposes the iPhone's filesystem. - * - * Copyright (c) 2008 Matt Colyer All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define FUSE_USE_VERSION 26 - -#include <fuse.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <fcntl.h> -#include <usb.h> -#include <libxml/parser.h> -#include <libxml/tree.h> -#include <glib.h> -#include <unistd.h> - -#include <libiphone/libiphone.h> - -GHashTable *file_handles; -int fh_index = 0; - -iphone_device_t phone = NULL; -iphone_lckd_client_t control = NULL; - -int debug = 0; - -static int ifuse_getattr(const char *path, struct stat *stbuf) -{ - int res = 0; - - iphone_afc_client_t afc = fuse_get_context()->private_data; - iphone_error_t ret = iphone_afc_get_file_attr(afc, path, stbuf); - - if (ret != IPHONE_E_SUCCESS) - res = -ENOENT; - - return res; -} - -static int ifuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) -{ - int i; - char **dirs = NULL; - iphone_afc_client_t afc = fuse_get_context()->private_data; - - iphone_afc_get_dir_list(afc, path, &dirs); - - if (!dirs) - return -ENOENT; - - for (i = 0; dirs[i]; i++) { - filler(buf, dirs[i], NULL, 0); - } - - free_dictionary(dirs); - - return 0; -} - -static int ifuse_create(const char *path, mode_t mode, struct fuse_file_info *fi) -{ - // exactly the same as open but using a different mode - iphone_afc_file_t file = NULL; - iphone_afc_client_t afc = fuse_get_context()->private_data; - - iphone_afc_open_file(afc, path, IPHONE_AFC_FILE_WRITE, &file); - fh_index++; - fi->fh = fh_index; - g_hash_table_insert(file_handles, &fh_index, file); - return 0; -} - -static int ifuse_open(const char *path, struct fuse_file_info *fi) -{ - iphone_afc_file_t file = NULL; - iphone_afc_client_t afc = fuse_get_context()->private_data; - uint32_t mode = 0; - - if ((fi->flags & 3) == O_RDWR || (fi->flags & 3) == O_WRONLY) { - mode = IPHONE_AFC_FILE_READ; - } else if ((fi->flags & 3) == O_RDONLY) { - mode = IPHONE_AFC_FILE_READ; - } else { - mode = IPHONE_AFC_FILE_READ; - } - - iphone_afc_open_file(afc, path, mode, &file); - - fh_index++; - fi->fh = fh_index; - g_hash_table_insert(file_handles, &fh_index, file); - - return 0; -} - -static int ifuse_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) -{ - int bytes = 0; - iphone_afc_file_t file; - iphone_afc_client_t afc = fuse_get_context()->private_data; - - if (size == 0) - return 0; - - file = g_hash_table_lookup(file_handles, &(fi->fh)); - if (!file) { - return -ENOENT; - } - - if (IPHONE_E_SUCCESS == iphone_afc_seek_file(afc, file, offset)) - iphone_afc_read_file(afc, file, buf, size, &bytes); - return bytes; -} - -static int ifuse_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) -{ - int bytes = 0; - iphone_afc_file_t file = NULL; - iphone_afc_client_t afc = fuse_get_context()->private_data; - - if (size == 0) - return 0; - - file = g_hash_table_lookup(file_handles, &(fi->fh)); - if (!file) - return -ENOENT; - - if (IPHONE_E_SUCCESS == iphone_afc_seek_file(afc, file, offset)) - iphone_afc_write_file(afc, file, buf, size, &bytes); - return bytes; -} - -static int ifuse_fsync(const char *path, int datasync, struct fuse_file_info *fi) -{ - return 0; -} - -static int ifuse_release(const char *path, struct fuse_file_info *fi) -{ - iphone_afc_file_t file = NULL; - iphone_afc_client_t afc = fuse_get_context()->private_data; - - file = g_hash_table_lookup(file_handles, &(fi->fh)); - if (!file) { - return -ENOENT; - } - iphone_afc_close_file(afc, file); - - g_hash_table_remove(file_handles, &(fi->fh)); - - return 0; -} - -void *ifuse_init_with_service(struct fuse_conn_info *conn, const char *service_name) -{ - int port = 0; - iphone_afc_client_t afc = NULL; - - conn->async_read = 0; - - file_handles = g_hash_table_new(g_int_hash, g_int_equal); - - iphone_get_device(&phone); - if (!phone) { - fprintf(stderr, "No iPhone found, is it connected?\n"); - return NULL; - } - - - if (IPHONE_E_SUCCESS != iphone_lckd_new_client(phone, &control)) { - iphone_free_device(phone); - fprintf(stderr, "Something went wrong in the lockdownd client.\n"); - return NULL; - } - - if (IPHONE_E_SUCCESS == iphone_lckd_start_service(control, service_name, &port) && !port) { - iphone_lckd_free_client(control); - iphone_free_device(phone); - fprintf(stderr, "Something went wrong when starting AFC."); - return NULL; - } - - iphone_afc_new_client(phone, 3432, port, &afc); - - return afc; -} - -void ifuse_cleanup(void *data) -{ - iphone_afc_client_t afc = (iphone_afc_client_t) data; - - iphone_afc_free_client(afc); - iphone_lckd_free_client(control); - iphone_free_device(phone); -} - -int ifuse_flush(const char *path, struct fuse_file_info *fi) -{ - return 0; -} - -int ifuse_statfs(const char *path, struct statvfs *stats) -{ - iphone_afc_client_t afc = fuse_get_context()->private_data; - char **info_raw = NULL; - uint32_t totalspace = 0, freespace = 0, blocksize = 0, i = 0; - - iphone_afc_get_devinfo(afc, &info_raw); - if (!info_raw) - return -ENOENT; - - for (i = 0; info_raw[i]; i++) { - if (!strcmp(info_raw[i], "FSTotalBytes")) { - totalspace = atoi(info_raw[i + 1]); - } else if (!strcmp(info_raw[i], "FSFreeBytes")) { - freespace = atoi(info_raw[i + 1]); - } else if (!strcmp(info_raw[i], "FSBlockSize")) { - blocksize = atoi(info_raw[i + 1]); - } - } - 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 - return 0; -} - -int ifuse_truncate(const char *path, off_t size) -{ - int result = 0; - iphone_afc_client_t afc = fuse_get_context()->private_data; - iphone_afc_file_t tfile = NULL; - iphone_afc_open_file(afc, path, IPHONE_AFC_FILE_READ, &tfile); - if (!tfile) - return -1; - - result = iphone_afc_truncate_file(afc, tfile, size); - iphone_afc_close_file(afc, tfile); - return result; -} - -int ifuse_ftruncate(const char *path, off_t size, struct fuse_file_info *fi) -{ - iphone_afc_client_t afc = fuse_get_context()->private_data; - iphone_afc_file_t file = g_hash_table_lookup(file_handles, &fi->fh); - if (!file) - return -ENOENT; - - return iphone_afc_truncate_file(afc, file, size); -} - -int ifuse_unlink(const char *path) -{ - iphone_afc_client_t afc = fuse_get_context()->private_data; - if (IPHONE_E_SUCCESS == iphone_afc_delete_file(afc, path)) - return 0; - else - return -1; -} - -int ifuse_rename(const char *from, const char *to) -{ - iphone_afc_client_t afc = fuse_get_context()->private_data; - if (IPHONE_E_SUCCESS == iphone_afc_rename_file(afc, from, to)) - return 0; - else - return -1; -} - -int ifuse_mkdir(const char *dir, mode_t ignored) -{ - iphone_afc_client_t afc = fuse_get_context()->private_data; - if (IPHONE_E_SUCCESS == iphone_afc_mkdir(afc, dir)) - return 0; - else - return -1; -} - -void *ifuse_init_normal(struct fuse_conn_info *conn) -{ - return ifuse_init_with_service(conn, "com.apple.afc"); -} - -void *ifuse_init_jailbroken(struct fuse_conn_info *conn) -{ - return ifuse_init_with_service(conn, "com.apple.afc2"); -} - -static struct fuse_operations ifuse_oper = { - .getattr = ifuse_getattr, - .statfs = ifuse_statfs, - .readdir = ifuse_readdir, - .mkdir = ifuse_mkdir, - .rmdir = ifuse_unlink, // AFC uses the same op for both. - .create = ifuse_create, - .open = ifuse_open, - .read = ifuse_read, - .write = ifuse_write, - .truncate = ifuse_truncate, - .ftruncate = ifuse_ftruncate, - .unlink = ifuse_unlink, - .rename = ifuse_rename, - .fsync = ifuse_fsync, - .release = ifuse_release, - .init = ifuse_init_normal, - .destroy = ifuse_cleanup -}; - -int main(int argc, char *argv[]) -{ - char **ammended_argv; - int i, j; - - // Parse extra options - if (argc > 2 && (ammended_argv = malloc((argc + 1) * sizeof(*ammended_argv)))) { - for (i = j = 0; ammended_argv[j] = argv[i], i < argc; i++) { - // Try to use the (jailbroken) com.apple.afc2 if requested by the user - if (argv[i] && (!strcmp("--root", argv[i]) || !strcmp("--afc2", argv[i]))) { - ifuse_oper.init = ifuse_init_jailbroken; - continue; - } - j++; - } - argv = ammended_argv; - argc = j; - } - - return fuse_main(argc, argv, &ifuse_oper, NULL); -} |