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

📄 server.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 <stdio.h>#include <stdlib.h>#include <string.h>#include <malloc.h>#include <gccore.h>#include <ogcsys.h>#include <ogc/es.h>#include "../../shared.h"#include "global.h"#include "fs_wrapper.h"#include "usb.h"// TODO// use the "authenticated" flag before executing commands// kick out clients when receiving another auth// take usb.c from libdb insteadstruct client_request * read_request () {        u8 buf[PACKET_REQUEST_PAYLOAD];        struct client_request *request;        u8 fn_size;        LOG (3, "waiting for a request...");        _usb_receivebuffersafe (buf, PACKET_REQUEST_PAYLOAD);        if (buf[0] != 'W' || buf[1] != 'F' || buf[2] != 'R')                return NULL;        request = (struct client_request *)                  malloc (sizeof (struct client_request));        memset (request, 0, sizeof (struct client_request));        request->command = buf[3];        fn_size = buf[4];        request->data_size = get_be16 (&buf[5]);        if (fn_size) {                request->filename = malloc (fn_size + 1);                LOG (3, "waiting for filename (%d)", fn_size);                _usb_receivebuffersafe (request->filename, fn_size);                request->filename[fn_size] = 0;        }        if (request->data_size) {                request->data = malloc (request->data_size);                LOG (3, "waiting for data (%d)", request->data_size);                _usb_receivebuffersafe (request->data, request->data_size);        }        return request;}void send_response (const enum remote_result result, const u8 *data,                    const u16 data_size) {        u8 buf[PACKET_RESPONSE_PAYLOAD];        memset (buf, 0, PACKET_RESPONSE_PAYLOAD);        buf[0] = 'W';        buf[1] = 'F';        buf[2] = 'A';        buf[3] = result;        if (data)                put_be16 (&buf[4], data_size);        LOG (3, "sending response");        _usb_sendbuffersafe (buf, PACKET_RESPONSE_PAYLOAD);        if (data) {                LOG (3, "sending response data (%d)", data_size);                _usb_sendbuffersafe (data, data_size);        }}enum remote_result identify (struct client_request *request, u8 **data,                             u16 *data_size) {        u8 *p;        u32 certs_size;        u32 tmd_size;        u32 tik_size;        u8 *sb_certs;        u8 *sb_tmd;        u8 *sb_tik;        s32 res;        u64 title_id;        u16 gid;        if (!request->data || request->data_size < 6)                return RES_UNKNOWN;        p = request->data;        certs_size = get_be16 (p);        p += 2;        tmd_size = get_be16 (p);        p += 2;        tik_size = get_be16 (p);;        p += 2;        if (request->data_size != certs_size + tmd_size + tik_size + 6)                return RES_UNKNOWN;        sb_certs = memalign (32, certs_size);        memcpy (sb_certs, p, certs_size);        p += certs_size;        sb_tmd = memalign (32, tmd_size);        memcpy (sb_tmd, p, tmd_size);        p += tmd_size;        sb_tik = memalign (32, tik_size);        memcpy (sb_tik, p, tik_size);        printf ("identifying...\n");        res = ES_Identify ((signed_blob *) sb_certs, certs_size,                           (signed_blob *) sb_tmd, tmd_size,                           (signed_blob *) sb_tik, tik_size, NULL);        gid = 0xffff;        if (IS_VALID_SIGNATURE ((signed_blob *) sb_tmd))                gid = ((tmd *)                       SIGNATURE_PAYLOAD ((signed_blob *) sb_tmd))->group_id;        free (sb_certs);        free (sb_tmd);        free (sb_tik);        if (res) {                LOG_ERR ("ES_Identify failed: %d", res);                return RES_UNKNOWN;        }        res = ES_GetTitleID (&title_id);        if (res) {                LOG_ERR ("error getting the title id: %d", res);                return RES_UNKNOWN;        }        printf ("identified as: 0x%016llx, group id: 0x%04x\n", title_id, gid);        return RES_OK;}void server_run () {        struct client_request *request;        u8 authenticated = 0;        char *auth = WIIFUSE_AUTH_DATA;        u8 exit = 0;        u8 init = 0;        enum remote_result result;        u8 *data;        u16 data_size;        printf ("awaiting requests, fire up wiifuse on the other end\n");        while (1) {                request = read_request ();                if (!request) {                        LOG_ERR ("received invalid packet");                        return;                }                result = RES_UNKNOWN;                data = NULL;                data_size = 0;                switch (request->command) {                case CMD_AUTH:                        if (request->data &&                            request->data_size == strlen (auth) &&                            !memcmp (request->data, auth, strlen (auth)))                                result = RES_OK;                        if (result == RES_OK)                                printf ("granted access to client\n");                        else                                printf ("refused client access\n");                        authenticated = result == RES_OK;                        exit = result != RES_OK;                        break;                case CMD_LOGLEVEL:                        if (request->data && request->data_size == 1) {                                verbose_level = request->data[0];                                printf ("using verbose level %u\n",                                        verbose_level);                                result = RES_OK;                        }                        break;                case CMD_UMOUNT:                        printf ("\nreceived umount command, stopping server\n");                        result = RES_OK;                        exit = 1;                        break;                case CMD_ES_IDENTIFY:                        result = identify (request, &data, &data_size);                        exit = result != RES_OK;                        init = result == RES_OK;                        break;                case CMD_FS_ACCESS:                        result = wrapper_access (request);                        break;                case CMD_FS_GETATTR:                        result = wrapper_getattr (request, &data, &data_size);                        break;                case CMD_FS_OPEN:                        result = wrapper_open (request);                        break;                case CMD_FS_READ:                        result = wrapper_read (request, &data, &data_size);                        break;                case CMD_FS_OPENDIR:                        result = wrapper_opendir (request);                        break;                case CMD_FS_READDIR:                        result = wrapper_readdir (request, &data, &data_size);                        break;                case CMD_FS_MKDIR:                        result = wrapper_mkdir (request);                        break;                case CMD_FS_RMDIR:                        result = wrapper_rmdir (request);                        break;                case CMD_FS_CREATE:                        result = wrapper_create (request);                        break;                case CMD_FS_WRITE:                        result = wrapper_write (request, &data, &data_size);                        break;                case CMD_FS_CHOWN:                        result = wrapper_chown (request);                        break;                case CMD_FS_CHMOD:                        result = wrapper_chmod (request);                        break;                case CMD_FS_RENAME:                        result = wrapper_rename (request);                        break;                case CMD_FS_UNLINK:                        result = wrapper_unlink (request);                        break;                case CMD_FS_STATFS:                        result = wrapper_statfs (request, &data, &data_size);                        break;                default:                        LOG_ERR ("received an unknown command");                        exit = 1;                        break;                }                if (init) {                        if (!wrapper_init (&data, &data_size)) {                                printf ("wrapper_init failed\n");                                exit = 1;                        }                        init = 0;                }                send_response (result, data, data_size);                if (data)                        free (data);                if (exit)                        break;        }        printf ("server was stopped\n");        if (!wrapper_deinit ())                printf ("wrapper_deinit failed\n");}

⌨️ 快捷键说明

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