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

📄 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 <stdlib.h>#include <string.h>#include <unistd.h>#include <pthread.h>#include "global.h"#include "gecko.h"#include "client.h"static pthread_mutex_t gecko_mutex;int get_id_file_size (const char *fn, u16 *size) {        struct stat st;        if (stat (fn, &st)) {                perror (fn);                return 1;        }        if (st.st_size > 0xffff)                return 1;        *size = st.st_size & 0xffff;        return 0;}int load_id_file (const char *fn, void *data, const u16 size) {        FILE *f;        f = fopen (fn, "rb");        if (f == NULL) {                perror (fn);                return 1;        }        if (size != fread (data, 1, size, f)) {                perror (fn);                fclose (f);                return 1;        }        fclose (f);        return 0;}int get_identity (const char *id, u8 **data, u16 *data_size) {        char fn_certs[MAX_FILENAME_SIZE];        char fn_tmd[MAX_FILENAME_SIZE];        char fn_tik[MAX_FILENAME_SIZE];        u16 certs_size, tmd_size, tik_size;        u16 total_size;        u8 *p;        int res;        snprintf (fn_certs, MAX_FILENAME_SIZE, "%s/%s.certs", DATA_PREFIX, id);        snprintf (fn_tmd, MAX_FILENAME_SIZE, "%s/%s.tmd", DATA_PREFIX, id);        snprintf (fn_tik, MAX_FILENAME_SIZE, "%s/%s.tik", DATA_PREFIX, id);                if (get_id_file_size (fn_certs, &certs_size))                return 1;        if (get_id_file_size (fn_tmd, &tmd_size))                return 1;        if (get_id_file_size (fn_tik, &tik_size))                return 1;        total_size = certs_size + tmd_size + tik_size + 6;        *data = malloc (total_size);        if (*data == NULL)                return 1;        p = *data;        put_be16 (p, certs_size);        p += 2;        put_be16 (p, tmd_size);        p += 2;        put_be16 (p, tik_size);        p += 2;        res = 0;        res |= load_id_file (fn_certs, p, certs_size);        p += certs_size;        res |= load_id_file (fn_tmd, p, tmd_size);        p += tmd_size;        res |= load_id_file (fn_tik, p, tik_size);        if (res) {                free (*data);                return 1;        }        *data_size = total_size;        return 0;}int client_init (const char *dev, const char *id) {        struct server_response * r;        char *auth = WIIFUSE_AUTH_DATA;        u8 *identity;        u16 identity_size;        char *path;        if (get_identity (id, &identity, &identity_size)) {                LOG_ERR ("identity data \"%s\" not available!", id);                return 1;        }        LOG (1, "initializing gecko interface");        pthread_mutex_init (&gecko_mutex, NULL);        if (gecko_open (dev)) {                LOG_ERR ("error using device %s", dev);                return 1;        }        LOG (1, "authenticating against server");        r = client_request (CMD_AUTH, NULL, auth, strlen (auth));        if (!r) {                LOG_ERR ("error while communicating with the server");                return 1;        }        if (r->result != RES_OK) {                LOG_ERR ("server won't let you in :p");                client_free_response (r);                return 1;        }        client_free_response (r);        LOG (1, "authenticated");        r = client_request (CMD_LOGLEVEL, NULL, &verbose_level, 1);        if (!r) {                LOG_ERR ("error while setting the server verbose level");                return 1;        }        if (r->result != RES_OK) {                LOG_ERR ("server didn't accept the verbose level (%d)",                         r->result);                client_free_response (r);                return 1;        }        client_free_response (r);        LOG (1, "sending identity data");        r = client_request (CMD_ES_IDENTIFY, NULL, identity, identity_size);        if (!r) {                LOG_ERR ("error while communicating with the server");                return 1;        }        if (r->result != RES_OK || !r->data_size) {                LOG_ERR ("server failed to set the identity");                client_free_response (r);                return 1;        }        path = malloc (r->data_size + 1);        memcpy (path, r->data, r->data_size);        path[r->data_size] = 0;        printf ("title's data path is \"%s\"\n", path);        client_free_response (r);        return 0;}void client_deinit () {        gecko_close ();        pthread_mutex_destroy (&gecko_mutex);}void client_free_response (struct server_response *response) {        if (!response)                return;        if (response->data)                free (response->data);        free (response);}struct server_response *client_request (const enum remote_command command,                                        const char *filename,                                        const void *data, const u16 data_size) {        u8 *buf;        u8 fn_len = 0;        struct server_response *response;        buf = malloc (PACKET_REQUEST_PAYLOAD);        memset (buf, 0, PACKET_REQUEST_PAYLOAD);        buf[0] = 'W';        buf[1] = 'F';        buf[2] = 'R';        buf[3] = command;        if (filename) {                fn_len = strlen (filename);                buf[4] = fn_len;        }        if (data)                put_be16 (&buf[5], data_size);        pthread_mutex_lock (&gecko_mutex);        if (gecko_write (buf, PACKET_REQUEST_PAYLOAD)) {                pthread_mutex_unlock (&gecko_mutex);                LOG_ERR ("error sending request");                free (buf);                return NULL;        }        free (buf);        if (filename) {                LOG (3, "sending filename (%d)", fn_len);                if (gecko_write (filename, fn_len)) {                        pthread_mutex_unlock (&gecko_mutex);                        LOG_ERR ("error sending filename");                        return NULL;                }        }        if (data) {                LOG (3, "sending data (%d)", data_size);                if (gecko_write (data, data_size)) {                        pthread_mutex_unlock (&gecko_mutex);                        LOG_ERR ("error sending data");                        return NULL;                }        }        buf = malloc (PACKET_RESPONSE_PAYLOAD);        memset (buf, 0, PACKET_RESPONSE_PAYLOAD);        LOG (3, "reading response");        if (gecko_read (buf, PACKET_RESPONSE_PAYLOAD)) {                pthread_mutex_unlock (&gecko_mutex);                LOG_ERR ("error reading response");                free (buf);                return NULL;        }        LOG (3, "received a response");        if (buf[0] != 'W' || buf[1] != 'F' || buf[2] != 'A') {                pthread_mutex_unlock (&gecko_mutex);                LOG_ERR ("received an invalid response");                free (buf);                return NULL;        }        response = (struct server_response *)                   malloc (sizeof (struct server_response));        memset (response, 0, sizeof (struct server_response));        response->result = buf[3];        response->data_size = get_be16 (&buf[4]);        free (buf);        if (response->data_size) {                LOG (3, "waiting for response data (%u)", response->data_size);                response->data = malloc (response->data_size);                if (gecko_read (response->data, response->data_size)) {                        pthread_mutex_unlock (&gecko_mutex);                        LOG_ERR ("error reading response data");                        free (response);                        return NULL;                }        }        LOG (3, "received the response data");                pthread_mutex_unlock (&gecko_mutex);        return response;}

⌨️ 快捷键说明

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