⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fs_client.c

📁 WiiFuse is a FUSE filesystem module for Linux and Mac OS X. It will let you mount a Wii disc ISO an
💻 C
字号:
/* *  Copyright (C) 2008 dhewg, #wiidev efnet * *  this file is part of wiifuse *  http://wiibrew.org/index.php?title=Wiifuse * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program 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 General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <ctype.h>#include <errno.h>#include "global.h"#include "client.h"#include "fs_client.h"int fs_client_get_native_error (const enum remote_result result) {        switch (result) {        case RES_ENOENT:                return -ENOENT;        case RES_ENOTDIR:                return -ENOTDIR;        case RES_EISDIR:                return -EISDIR;        case RES_EACCES:                return -EACCES;        case RES_ENAMETOOLONG:                return -ENAMETOOLONG;        default:                return -EFAULT;        }}void get_remote_attr (struct remote_attr *attributes, const u8 *data) {        attributes->is_dir = data[0];        attributes->nlink = get_be16 (&data[1]);        attributes->size = get_be32 (&data[3]);        attributes->owner = get_be32 (&data[7]);        attributes->group = get_be32 (&data[11]);        attributes->perms = get_be16 (&data[15]);}void put_remote_attr (u8 *data, const struct remote_attr *attributes) {        data[0] = attributes->is_dir;        put_be16 (&data[1], attributes->nlink);        put_be32 (&data[3], attributes->size);        put_be32 (&data[7], attributes->owner);        put_be32 (&data[11], attributes->group);        put_be16 (&data[15], attributes->perms);}void get_remote_perms (mode_t *mode, const u16 perms) {        *mode = 0;        if (perms & MODE_IRUSR)                *mode |= S_IRUSR;        if (perms & MODE_IWUSR)                *mode |= S_IWUSR;        if (perms & MODE_IXUSR)                *mode |= S_IXUSR;                        if (perms & MODE_IRGRP)                *mode |= S_IRGRP;        if (perms & MODE_IWGRP)                *mode |= S_IWGRP;        if (perms & MODE_IXGRP)                *mode |= S_IXGRP;                        if (perms & MODE_IROTH)                *mode |= S_IROTH;        if (perms & MODE_IWOTH)                *mode |= S_IWOTH;        if (perms & MODE_IXOTH)                *mode |= S_IXOTH;}void put_remote_perms (u16 *perms, const mode_t mode) {        *perms = 0;        if (mode & S_IRUSR)                *perms |= MODE_IRUSR;        if (mode & S_IWUSR)                *perms |= MODE_IWUSR;        if (mode & S_IXUSR)                *perms |= MODE_IXUSR;                        if (mode & S_IRGRP)                *perms |= MODE_IRGRP;        if (mode & S_IWGRP)                *perms |= MODE_IWGRP;        if (mode & S_IXGRP)                *perms |= MODE_IXGRP;                        if (mode & S_IROTH)                *perms |= MODE_IROTH;        if (mode & S_IWOTH)                *perms |= MODE_IWOTH;        if (mode & S_IXOTH)                *perms |= MODE_IXOTH;}int fs_client_access (const char *path, int mode) {        struct server_response *r;        int res;        u8 data;        data = 0;        if (mode & R_OK)                data |= ACCESS_R_OK;        if (mode & W_OK)                data |= ACCESS_W_OK;        if (mode & X_OK)                data |= ACCESS_X_OK;        r = client_request (CMD_FS_ACCESS, path, &data, 1);        if (!r)                return -EFAULT;        if (r->result != RES_OK) {                res = fs_client_get_native_error (r->result);                client_free_response (r);                return res;        }        client_free_response (r);        return 0;}int fs_client_getattr (const char *path, struct stat *stbuf) {        struct server_response *r;        int res;        struct remote_attr attributes;        memset (stbuf, 0, sizeof (struct stat));        r = client_request (CMD_FS_GETATTR, path, NULL, 0);        if (!r)                return -EFAULT;        if (!r->data || r->data_size != 17) {                client_free_response (r);                return -ENOENT;        }        if (r->result != RES_OK) {                res = fs_client_get_native_error (r->result);                client_free_response (r);                return res;        }        get_remote_attr (&attributes, r->data);        get_remote_perms (&(stbuf->st_mode), attributes.perms);        if (attributes.is_dir)                stbuf->st_mode |= S_IFDIR;        else                stbuf->st_mode |= S_IFREG;        stbuf->st_nlink = attributes.nlink;        stbuf->st_size = attributes.size;        stbuf->st_blocks = attributes.size / 512;        stbuf->st_uid = attributes.owner;        stbuf->st_gid = attributes.group;        client_free_response (r);        return 0;}int fs_client_open (const char *path, struct fuse_file_info *fi) {        struct server_response *r;        int res;        (void) fi;        r = client_request (CMD_FS_OPEN, path, NULL, 0);        if (!r)                return -EFAULT;        if (r->result != RES_OK) {                res = fs_client_get_native_error (r->result);                client_free_response (r);                return res;        }        client_free_response (r);        return 0;}int fs_client_read (const char *path, char *buf, size_t size,                    off_t offset, struct fuse_file_info *fi) {        struct server_response *r;        u8 data[10];        int bytes_read;        int res;        (void) fi;	//        if (size > 0xffff)	//                return -EFAULT;        put_be16 (data, size);        put_be64 (&data[2], offset);        r = client_request (CMD_FS_READ, path, data, 10);        if (!r)                return -EIO;        if (r->result != RES_OK) {                res = fs_client_get_native_error (r->result);                client_free_response (r);                return res;        }        bytes_read = r->data_size;        if (bytes_read > 0)                memcpy (buf, r->data, bytes_read);        client_free_response (r);        return bytes_read;}int fs_client_opendir (const char *path, struct fuse_file_info *fi) {        struct server_response *r;        int res;        (void) fi;        r = client_request (CMD_FS_OPENDIR, path, NULL, 0);        if (!r)                return -EFAULT;        if (r->result != RES_OK) {                res = fs_client_get_native_error (r->result);                client_free_response (r);                return res;        }        client_free_response (r);        return 0;}int fs_client_readdir (const char *path, void *buf, fuse_fill_dir_t filler,                       off_t offset, struct fuse_file_info *fi) {        struct server_response *r;        char *p;        size_t s;        int res;        (void) offset;        (void) fi;        r = client_request (CMD_FS_READDIR, path, NULL, 0);        if (!r)                return -EFAULT;        if (r->result != RES_OK) {                res = fs_client_get_native_error (r->result);                client_free_response (r);                return res;        }        filler (buf, ".", NULL, 0);        filler (buf, "..", NULL, 0);        if (r->data) {                p = (char *) r->data;                while (*p) {                        s = strlen (p);                        filler (buf, p, NULL, 0);                        p += s + 1;                }        }        client_free_response (r);        return 0;}int fs_client_mkdir (const char *path, mode_t mode) {        struct server_response *r;        int res;        u16 perms;        u8 data[2];        put_remote_perms (&perms, mode);        put_be16 (data, perms);        r = client_request (CMD_FS_MKDIR, path, data, 2);        if (!r)                return -EFAULT;        if (r->result != RES_OK) {                res = fs_client_get_native_error (r->result);                client_free_response (r);                return res;        }        client_free_response (r);        return 0;}int fs_client_rmdir (const char *path) {        struct server_response *r;        int res;        r = client_request (CMD_FS_RMDIR, path, NULL, 0);        if (!r)                return -EFAULT;        if (r->result != RES_OK) {                res = fs_client_get_native_error (r->result);                client_free_response (r);                return res;        }        client_free_response (r);        return 0;}int fs_client_create (const char *path, mode_t mode,                      struct fuse_file_info *fi) {        struct server_response *r;        int res;        u16 perms;        u8 data[2];        (void) fi;        put_remote_perms (&perms, mode);        put_be16 (data, perms);        r = client_request (CMD_FS_CREATE, path, data, 2);        if (!r)                return -EFAULT;        if (r->result != RES_OK) {                res = fs_client_get_native_error (r->result);                client_free_response (r);                return res;        }        client_free_response (r);        return 0;}int fs_client_write (const char *path, const char *buf, size_t size,                     off_t offset, struct fuse_file_info *fi) {        struct server_response *r;        u8 *data;        int bytes_written;        int res;        (void) fi;        if (size > 0xffff)                return -EFAULT;        data = malloc (size + 10);        put_be16 (data, size);        put_be64 (&data[2], offset);        memcpy (&data[10], buf, size);        r = client_request (CMD_FS_WRITE, path, data, size + 10);        free (data);        if (!r)                return -EIO;        if (r->result != RES_OK) {                res = fs_client_get_native_error (r->result);                client_free_response (r);                return res;        }        if (r->data_size != 8) {                client_free_response (r);                return -EIO;        }        bytes_written = get_be64 (r->data);        client_free_response (r);        return bytes_written;}int fs_client_chown (const char *filename, uid_t uid, gid_t gid) {        struct server_response *r;        int res;        u32 owner;        u32 group;        u8 data[8];        owner = uid;        group = gid;        put_be32 (data, owner);        put_be32 (&data[4], group);        r = client_request (CMD_FS_CHOWN, filename, data, 8);        if (!r)                return -EFAULT;        if (r->result != RES_OK) {                res = fs_client_get_native_error (r->result);                client_free_response (r);                return res;        }        client_free_response (r);        return 0;}int fs_client_chmod (const char *filename, mode_t mode) {        struct server_response *r;        int res;        u16 perms;        u8 data[2];        put_remote_perms (&perms, mode);        put_be16 (data, perms);        r = client_request (CMD_FS_CHMOD, filename, &data, 2);        if (!r)                return -EFAULT;        if (r->result != RES_OK) {                res = fs_client_get_native_error (r->result);                client_free_response (r);                return res;        }        client_free_response (r);        return 0;}int fs_client_rename (const char *src, const char *dst) {        struct server_response *r;        int res;        r = client_request (CMD_FS_RENAME, src, dst, strlen (dst));        if (!r)                return -EFAULT;        if (r->result != RES_OK) {                res = fs_client_get_native_error (r->result);                client_free_response (r);                return res;        }        client_free_response (r);        return 0;}int fs_client_unlink (const char *path) {        struct server_response *r;        int res;        r = client_request (CMD_FS_UNLINK, path, NULL, 0);        if (!r)                return -EFAULT;        if (r->result != RES_OK) {                res = fs_client_get_native_error (r->result);                client_free_response (r);                return res;        }        client_free_response (r);        return 0;}int fs_client_statfs (const char *path, struct statvfs *svfs) {        struct server_response *r;        int res;        memset (svfs, 0, sizeof (struct statvfs));        r = client_request (CMD_FS_STATFS, path, NULL, 0);        if (!r)                return -EFAULT;        if (r->result != RES_OK) {                res = fs_client_get_native_error (r->result);                client_free_response (r);                return res;        }        if (r->data_size != 5 * 8) {                client_free_response (r);                return -EIO;        }        svfs->f_bsize = get_be64 (r->data);        svfs->f_blocks = get_be64 (&(r->data[8]));        svfs->f_bfree = get_be64 (&(r->data[16]));        svfs->f_files = get_be64 (&(r->data[24]));        svfs->f_ffree = get_be64 (&(r->data[32]));        client_free_response (r);        return 0;}void fs_client_destroy () {        struct server_response *r;                r = client_request (CMD_UMOUNT, NULL, NULL, 0);        if (!r) {                LOG_ERR ("server did not ack the umount");                return;        }        if (r->result != RES_OK)                LOG_ERR ("server did not umount (%d)", r->result);        client_free_response (r);}void fs_client_get_ops (struct fuse_operations *fs_ops) {        memset (fs_ops, 0, sizeof (struct fuse_operations));        fs_ops->access = fs_client_access;        fs_ops->getattr = fs_client_getattr;        fs_ops->open = fs_client_open;        fs_ops->read = fs_client_read;        fs_ops->opendir = fs_client_opendir;        fs_ops->readdir = fs_client_readdir;        fs_ops->mkdir = fs_client_mkdir;        fs_ops->unlink = fs_client_unlink;        fs_ops->rmdir = fs_client_rmdir;        fs_ops->chown = fs_client_chown;        fs_ops->chmod = fs_client_chmod;        fs_ops->rename = fs_client_rename;        fs_ops->write = fs_client_write;        fs_ops->create = fs_client_create;        fs_ops->statfs = fs_client_statfs;        fs_ops->destroy = fs_client_destroy;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -