📄 server.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 + -