Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile.platform
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
.PHONY: gc_all gc_install nds_all nds_install wii_all wii_install 3ds_all 3ds_install wiiu_all wiiu_install switch_all switch_install dc_all dc_install ps2_ee_all ps2_ee_install ps2_ips_all ps2_ips_install ps2_iop_all ps2_iop_install ps4_all ps4_install

gc_all:
cmake -S . -B build "-DCMAKE_TOOLCHAIN_FILE=${DEVKITPRO}/cmake/GameCube.cmake"
cmake -S . -B build -G Ninja "-DCMAKE_TOOLCHAIN_FILE=${DEVKITPRO}/cmake/GameCube.cmake"
cmake --build build

gc_install: gc_all
Expand All @@ -32,7 +32,7 @@ nds_install: nds_all
cmake --build build --target install

wii_all:
cmake -S . -B build "-DCMAKE_TOOLCHAIN_FILE=${DEVKITPRO}/cmake/Wii.cmake"
cmake -S . -B build -G Ninja "-DCMAKE_TOOLCHAIN_FILE=${DEVKITPRO}/cmake/Wii.cmake"
cmake --build build

wii_install: wii_all
Expand Down
42 changes: 36 additions & 6 deletions cmake/ConfigureChecks.cmake
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
include(CheckIncludeFile)
include(CheckIncludeFiles)

set(SMB2_OGC_SINGLE_NETWORK_HEADER FALSE)
if(CMAKE_SYSTEM_NAME MATCHES NintendoGameCube OR CMAKE_SYSTEM_NAME MATCHES NintendoWii)
set(SMB2_OGC_SINGLE_NETWORK_HEADER TRUE)
endif()

if(SMB2_OGC_SINGLE_NETWORK_HEADER)
set(HAVE_ARPA_INET_H OFF)
else()
check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
endif()
check_include_file("dlfcn.h" HAVE_DLFCN_H)
check_include_file("fcntl.h" HAVE_FCNTL_H)
# CommonCrypto.framework is not always reachable on Apple platforms
Expand All @@ -22,9 +32,21 @@ check_include_file("krb5/krb5.h" HAVE_LIBKRB5)
check_include_file("GSS/GSS.h" HAVE_GSS_GSS_H)
endif()
check_include_file("inttypes.h" HAVE_INTTYPES_H)
check_include_file("netdb.h" HAVE_NETDB_H)
check_include_file("netinet/in.h" HAVE_NETINET_IN_H)
check_include_files("sys/types.h;netinet/tcp.h" HAVE_NETINET_TCP_H)
if(SMB2_OGC_SINGLE_NETWORK_HEADER)
set(HAVE_NETDB_H OFF)
else()
check_include_file("netdb.h" HAVE_NETDB_H)
endif()
if(SMB2_OGC_SINGLE_NETWORK_HEADER)
set(HAVE_NETINET_IN_H OFF)
else()
check_include_file("netinet/in.h" HAVE_NETINET_IN_H)
endif()
if(SMB2_OGC_SINGLE_NETWORK_HEADER)
set(HAVE_NETINET_TCP_H OFF)
else()
check_include_files("sys/types.h;netinet/tcp.h" HAVE_NETINET_TCP_H)
endif()
check_include_file("poll.h" HAVE_POLL_H)
check_include_file("stdint.h" HAVE_STDINT_H)
check_include_file("stdio.h" HAVE_STDIO_H)
Expand All @@ -35,7 +57,11 @@ check_include_file("sys/ioctl.h" HAVE_SYS_IOCTL_H)
if(NOT PS4)
check_include_file("sys/poll.h" HAVE_SYS_POLL_H)
endif()
if(SMB2_OGC_SINGLE_NETWORK_HEADER)
set(HAVE_SYS_SOCKET_H OFF)
else()
check_include_file("sys/socket.h" HAVE_SYS_SOCKET_H)
endif()
check_include_file("sys/stat.h" HAVE_SYS_STAT_H)
check_include_file("sys/types.h" HAVE_SYS_TYPES_H)
check_include_file("sys/uio.h" HAVE_SYS_UIO_H)
Expand All @@ -51,11 +77,15 @@ check_include_file("errno.h" HAVE_ERRNO_H)
check_include_file("stddef.h" STDC_HEADERS)

include(CheckStructHasMember)
if(SMB2_OGC_SINGLE_NETWORK_HEADER)
set(HAVE_SOCKADDR_LEN OFF)
check_struct_has_member("struct sockaddr_storage" ss_family "sys/types.h;network.h" HAVE_SOCKADDR_STORAGE)
check_struct_has_member("struct addrinfo" ai_next "sys/types.h;network.h" HAVE_STRUCT_ADDRINFO)
check_struct_has_member("struct iovec" iov_base "sys/types.h;network.h" HAVE_STRUCT_IOVEC)
check_struct_has_member("struct linger" l_linger network.h HAVE_LINGER)
else()
check_struct_has_member("struct sockaddr" sa_len sys/socket.h HAVE_SOCKADDR_LEN)
check_struct_has_member("struct sockaddr_storage" ss_family sys/socket.h HAVE_SOCKADDR_STORAGE)
if(CMAKE_SYSTEM_NAME MATCHES NintendoGameCube OR CMAKE_SYSTEM_NAME MATCHES NintendoWii)
check_struct_has_member("struct linger" l_linger network.h HAVE_LINGER)
else()
check_struct_has_member("struct linger" l_linger sys/socket.h HAVE_LINGER)
endif()

Expand Down
2 changes: 2 additions & 0 deletions cmake/config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@

/* Whether we have sockaddr_Storage */
#cmakedefine HAVE_SOCKADDR_STORAGE "@HAVE_SOCKADDR_STORAGE@"
#cmakedefine HAVE_STRUCT_ADDRINFO "@HAVE_STRUCT_ADDRINFO@"
#cmakedefine HAVE_STRUCT_IOVEC "@HAVE_STRUCT_IOVEC@"

/* Whether we have linger */
#cmakedefine HAVE_LINGER "@HAVE_LINGER@"
Expand Down
152 changes: 147 additions & 5 deletions lib/compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ int iop_connect(int sockfd, struct sockaddr *addr, socklen_t addrlen)
#include <3ds/types.h>
#elif defined(__wii__) || defined(__gamecube__)
#include <gctypes.h>
#include <stdarg.h>
#elif defined(__WIIU__)
#include <wut_types.h>
#elif defined(__NDS__)
Expand All @@ -240,16 +241,153 @@ int iop_connect(int sockfd, struct sockaddr *addr, socklen_t addrlen)
#define login_num ENXIO

#if defined(__wii__) || defined(__gamecube__)
s32 getsockopt(int sockfd, int level, int optname, void *optval,
socklen_t *optlen)
int smb2_net_connect(int fd, struct sockaddr *addr, socklen_t addrlen)
{
s32 ret = net_connect(fd, addr, addrlen);
if (ret < 0) {
errno = -ret;
return -1;
}
return 0;
}

int smb2_net_close(int fd)
{
s32 ret = net_close(fd);
if (ret < 0) {
errno = -ret;
return -1;
}
return 0;
}

int smb2_net_fcntl(int fd, int cmd, ...)
{
u32 val = 0;
va_list ap;

va_start(ap, cmd);
val = (u32)va_arg(ap, int);
va_end(ap);

s32 ret = net_fcntl(fd, (u32)cmd, val);
if (ret < 0) {
errno = -ret;
return -1;
}
return (int)ret;
}

ssize_t smb2_net_write(int fd, const void *buf, size_t count)
{
s32 ret = net_write(fd, buf, count);
if (ret < 0) {
errno = -ret;
return -1;
}
return ret;
}

ssize_t smb2_net_read(int fd, void *buf, size_t count)
{
#ifdef __wii__
/* On the Wii net_read() can block when there is nothing to read even
* though the socket is non-blocking, so libsmb2's "read until EAGAIN"
* loop never ends and smb2_service() does not return. Only read when
* select() says there is data (or an error/hangup, which net_read()
* then reports), otherwise report EAGAIN. */
fd_set rd, ex;
struct timeval tv;

FD_ZERO(&rd);
FD_SET(fd, &rd);
FD_ZERO(&ex);
FD_SET(fd, &ex);
tv.tv_sec = 0;
tv.tv_usec = 0;
if (net_select(fd + 1, &rd, NULL, &ex, &tv) == 0) {
errno = EAGAIN;
return -1;
}
#endif
s32 ret = net_read(fd, buf, count);
if (ret < 0) {
errno = -ret;
return -1;
}
return ret;
}

int smb2_net_socket(int domain, int type, int protocol)
{
s32 ret = net_socket((u32)domain, (u32)type, (u32)protocol);
if (ret < 0) {
errno = -ret;
return -1;
}
return (int)ret;
}

int smb2_net_getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen)
{
#ifdef __gamecube__
return net_getsockopt(sockfd, level, optname, optval, optlen);
#else
return 0;
s32 ret = net_getsockopt(fd, (u32)level, (u32)optname, optval, optlen);
if (ret < 0) {
errno = -ret;
return -1;
}
#endif
return 0;
}

int smb2_net_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
{
s32 ret = net_setsockopt(fd, (u32)level, (u32)optname, optval, optlen);
if (ret < 0) {
errno = -ret;
return -1;
}
return 0;
}

int smb2_net_bind(int fd, struct sockaddr *addr, socklen_t addrlen)
{
s32 ret = net_bind(fd, addr, addrlen);
if (ret < 0) {
errno = -ret;
return -1;
}
return 0;
}

int smb2_net_listen(int fd, int backlog)
{
s32 ret = net_listen(fd, (u32)backlog);
if (ret < 0) {
errno = -ret;
return -1;
}
return 0;
}

int smb2_net_accept(int fd, struct sockaddr *addr, socklen_t *addrlen)
{
s32 ret = net_accept(fd, addr, addrlen);
if (ret < 0) {
errno = -ret;
return -1;
}
return (int)ret;
}

int smb2_net_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
{
s32 ret = net_select(nfds, readfds, writefds, exceptfds, timeout);
if (ret < 0) {
errno = -ret;
return -1;
}
return (int)ret;
}
#endif

Expand Down Expand Up @@ -460,7 +598,11 @@ ssize_t readv(t_socket fd, const struct iovec* vector, int count)
#endif

#ifdef NEED_POLL
#ifdef SMB2_HAVE_OGC_POLL_H
int poll(struct pollfd *fds, nfds_t nfds, int timo)
#else
int poll(struct pollfd *fds, unsigned int nfds, int timo)
#endif
{
struct timeval timeout, *toptr;
fd_set ifds, ofds, efds, *ip, *op;
Expand Down
80 changes: 69 additions & 11 deletions lib/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -650,16 +650,25 @@ ssize_t readv(t_socket fd, const struct iovec *iov, int iovcnt);

#include <sys/types.h>

#if defined(__wii__) || defined(__gamecube__)
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#endif

#if defined(__3DS__) || defined(__wii__) || defined(__gamecube__) || defined(__WIIU__) || defined(__NDS__)
#if !defined(HAVE_STRUCT_IOVEC)
struct iovec {
void *iov_base;
size_t iov_len;
};
};
#endif
#if defined(__wii__) || defined(__gamecube__) || defined(__NDS__)
#ifndef __NDS__
#include <network.h>
#endif

#if !defined(HAVE_STRUCT_ADDRINFO)
struct addrinfo {
int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
int ai_family; /* PF_xxx */
Expand All @@ -670,6 +679,29 @@ struct addrinfo {
struct sockaddr *ai_addr; /* binary address */
struct addrinfo *ai_next; /* next structure in linked list */
};
#endif

#if defined(__wii__) || defined(__gamecube__)
#if !defined(HAVE_SOCKADDR_STORAGE)
/*
* RFC 2553: protocol-independent placeholder for socket addresses.
* libogc's <network.h> has no sockaddr_storage of its own.
*/
#define _SS_MAXSIZE 128
#define _SS_ALIGNSIZE (sizeof(double))
#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(unsigned short))
#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(unsigned short) - \
_SS_PAD1SIZE - _SS_ALIGNSIZE)

struct sockaddr_storage {
unsigned char ss_len;
unsigned char ss_family;
char __ss_pad1[_SS_PAD1SIZE];
double __ss_align;
char __ss_pad2[_SS_PAD2SIZE];
};
#endif
#endif

#endif
#define sockaddr_in6 sockaddr_in
Expand Down Expand Up @@ -741,23 +773,49 @@ void smb2_freeaddrinfo(struct addrinfo *res);
#define freeaddrinfo smb2_freeaddrinfo

#ifndef __NDS__
#define connect net_connect
#define socket net_socket
#define setsockopt net_setsockopt
s32 getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
#define select net_select
#define accept net_accept
#define listen net_listen
#define bind net_bind
#endif

int smb2_net_connect(int fd, struct sockaddr *addr, socklen_t addrlen);
int smb2_net_close(int fd);
int smb2_net_fcntl(int fd, int cmd, ...);
ssize_t smb2_net_write(int fd, const void *buf, size_t count);
ssize_t smb2_net_read(int fd, void *buf, size_t count);
int smb2_net_socket(int domain, int type, int protocol);
int smb2_net_getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen);
int smb2_net_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen);
int smb2_net_bind(int fd, struct sockaddr *addr, socklen_t addrlen);
int smb2_net_listen(int fd, int backlog);
int smb2_net_accept(int fd, struct sockaddr *addr, socklen_t *addrlen);
int smb2_net_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

#define socket smb2_net_socket
#define getsockopt smb2_net_getsockopt
#define setsockopt smb2_net_setsockopt
#define select smb2_net_select
#define accept smb2_net_accept
#define listen smb2_net_listen
#define bind smb2_net_bind
#define connect smb2_net_connect
#define close smb2_net_close
#define fcntl smb2_net_fcntl
#define write smb2_net_write
#define read smb2_net_read
#endif

#if defined(__has_include)
#if __has_include(<poll.h>)
#include <poll.h>
#define SMB2_HAVE_OGC_POLL_H 1
#endif
#endif

#ifndef SMB2_HAVE_OGC_POLL_H
struct pollfd {
int fd;
short events;
short revents;
};

int poll(struct pollfd *fds, unsigned int nfds, int timo);
#endif

#endif

Expand Down
Loading