Skip to content

Commit

Permalink
Filled in enough of tcpip32 and doscalls to run OS/2's TCPIP/bin/FTP.…
Browse files Browse the repository at this point in the history
…EXE.

It crashes right after a completed download, but otherwise seems to
fully work!
  • Loading branch information
icculus committed Jan 4, 2018
1 parent c2e4398 commit 40b9b9e
Show file tree
Hide file tree
Showing 4 changed files with 282 additions and 6 deletions.
27 changes: 26 additions & 1 deletion native/doscalls.c
Expand Up @@ -235,11 +235,13 @@ LX_NATIVE_MODULE_INIT({ if (!initDoscalls()) return NULL; })
LX_NATIVE_EXPORT(DosQueryCurrentDir, 274),
LX_NATIVE_EXPORT(DosQueryCurrentDisk, 275),
LX_NATIVE_EXPORT(DosQueryFHState, 276),
LX_NATIVE_EXPORT(DosQueryFSAttach, 277),
LX_NATIVE_EXPORT(DosQueryFileInfo, 279),
LX_NATIVE_EXPORT(DosWaitChild, 280),
LX_NATIVE_EXPORT(DosRead, 281),
LX_NATIVE_EXPORT(DosWrite, 282),
LX_NATIVE_EXPORT(DosExecPgm, 283),
LX_NATIVE_EXPORT(DosSetProcessCp, 289),
LX_NATIVE_EXPORT(DosQueryCp, 291),
LX_NATIVE_EXPORT(DosExitList, 296),
LX_NATIVE_EXPORT(DosAllocMem, 299),
Expand Down Expand Up @@ -267,6 +269,7 @@ LX_NATIVE_MODULE_INIT({ if (!initDoscalls()) return NULL; })
LX_NATIVE_EXPORT(DosSubFreeMem, 346),
LX_NATIVE_EXPORT(DosQuerySysInfo, 348),
LX_NATIVE_EXPORT(DosSetExceptionHandler, 354),
LX_NATIVE_EXPORT(DosUnsetExceptionHandler, 355),
LX_NATIVE_EXPORT(DosQuerySysState, 368),
LX_NATIVE_EXPORT(DosSetSignalExceptionFocus, 378),
LX_NATIVE_EXPORT(DosEnterMustComplete, 380),
Expand Down Expand Up @@ -650,6 +653,13 @@ APIRET DosSetExceptionHandler(PEXCEPTIONREGISTRATIONRECORD rec)
return NO_ERROR;
} // DosSetExceptionHandler

// !!! FIXME: this is obviously not correct.
APIRET DosUnsetExceptionHandler(PEXCEPTIONREGISTRATIONRECORD rec)
{
TRACE_NATIVE("DosUnsetExceptionHandler(%p)", rec);
return NO_ERROR;
} // DosSetExceptionHandler

ULONG _DosFlatToSel(PVOID ptr)
{
TRACE_NATIVE("DosFlatToSel(%p)", ptr);
Expand Down Expand Up @@ -3010,7 +3020,6 @@ static APIRET16 bridge16to32_DosSemSet(uint8 *args)
return DosSemSet(sem);
} // bridge16to32_DosSemSet


APIRET DosCloseMutexSem(HMTX hmtx)
{
TRACE_NATIVE("DosCloseMutexSem(%u)", (uint) hmtx);
Expand All @@ -3029,5 +3038,21 @@ APIRET DosCloseMutexSem(HMTX hmtx)
return ERROR_INVALID_HANDLE;
} // DosCloseMutexSem

APIRET DosSetProcessCp(ULONG cp)
{
TRACE_NATIVE("DosSetProcessCp(%u)", (unsigned int) cp);
if (cp != 437) { // United States
FIXME("non-US codepages unsupported at the moment");
return ERROR_INVALID_CODE_PAGE;
}
return NO_ERROR;
} // DosSetProcessCp

APIRET DosQueryFSAttach(PSZ pszDeviceName, ULONG ulOrdinal, ULONG ulFSAInfoLevel, PFSQBUFFER2 pfsqb, PULONG pcbBuffLength)
{
TRACE_NATIVE("DosQueryFSAttach('%s', %u, %u, %p, %p)", pszDeviceName, (unsigned int) ulOrdinal, (unsigned int) ulFSAInfoLevel, pfsqb, pcbBuffLength);
return ERROR_INVALID_FUNCTION;
} // DosQueryFSAttach

// end of doscalls.c ...

14 changes: 14 additions & 0 deletions native/doscalls.h
Expand Up @@ -342,6 +342,17 @@ typedef struct
CHAR achName[CCHMAXPATHCOMP];
} FILEFINDBUF4, *PFILEFINDBUF4;

typedef struct
{
USHORT iType;
USHORT cbName;
USHORT cbFSDName;
USHORT cbFSAData;
UCHAR szName[1];
UCHAR szFSDName[1];
UCHAR rgFSAData[1];
} FSQBUFFER2, *PFSQBUFFER2;

enum
{
DEVINFO_PRINTER,
Expand Down Expand Up @@ -393,6 +404,7 @@ OS2EXPORT APIRET OS2API DosExitList(ULONG ordercode, PFNEXITLIST pfn);
OS2EXPORT APIRET OS2API DosCreateEventSem(PSZ pszName, PHEV phev, ULONG flAttr, BOOL32 fState);
OS2EXPORT APIRET OS2API DosCreateMutexSem(PSZ pszName, PHMTX phmtx, ULONG flAttr, BOOL32 fState);
OS2EXPORT APIRET OS2API DosSetExceptionHandler(PEXCEPTIONREGISTRATIONRECORD pERegRec);
OS2EXPORT APIRET OS2API DosUnsetExceptionHandler(PEXCEPTIONREGISTRATIONRECORD pERegRec);
OS2EXPORT ULONG OS2API DosFlatToSel(VOID);
OS2EXPORT APIRET OS2API DosSetSignalExceptionFocus(BOOL32 flag, PULONG pulTimes);
OS2EXPORT APIRET OS2API DosSetRelMaxFH(PLONG pcbReqCount, PULONG pcbCurMaxFH);
Expand Down Expand Up @@ -447,6 +459,8 @@ OS2EXPORT APIRET OS2API DosSetMaxFH(ULONG cFH);
OS2EXPORT APIRET OS2API DosQueryThreadContext(TID tid, ULONG level, PCONTEXTRECORD pcxt);
OS2EXPORT ULONG OS2API DosSelToFlat(VOID);
OS2EXPORT APIRET OS2API DosCloseMutexSem(HMTX hmtx);
OS2EXPORT APIRET OS2API DosSetProcessCp(ULONG cp);
OS2EXPORT APIRET OS2API DosQueryFSAttach(PSZ pszDeviceName, ULONG ulOrdinal, ULONG ulFSAInfoLevel, PFSQBUFFER2 pfsqb, PULONG pcbBuffLength);

#ifdef __cplusplus
}
Expand Down
203 changes: 198 additions & 5 deletions native/tcpip32.c
@@ -1,6 +1,7 @@
#include "os2native.h"
#include "tcpip32.h"

#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
Expand All @@ -17,6 +18,26 @@ int OS2_sock_init(void)
return 1; // always succeeds.
} // OS2_sock_init

// !!! FIXME: currently expects you're doing IPv4
static void mapOS2SockAddrIn(const OS2_sockaddr *os2addr, struct sockaddr_in *bsdaddr)
{
const OS2_sockaddr_in *os2addrin = (const OS2_sockaddr_in *) os2addr;
memset(bsdaddr, '\0', sizeof (*bsdaddr));
bsdaddr->sin_family = AF_INET;
bsdaddr->sin_port = os2addrin->sin_port;
bsdaddr->sin_addr.s_addr = os2addrin->sin_addr.s_addr;
} // mapOS2SockAddrIn

// !!! FIXME: currently expects you're doing IPv4
static void mapBSDSockAddrIn(const struct sockaddr_in *bsdaddr, OS2_sockaddr *os2addr)
{
OS2_sockaddr_in *os2addrin = (OS2_sockaddr_in *) os2addr;
memset(os2addrin, '\0', sizeof (*os2addrin));
os2addrin->sin_family = OS2_AF_INET;
os2addrin->sin_port = bsdaddr->sin_port;
os2addrin->sin_addr.s_addr = bsdaddr->sin_addr.s_addr;
} // mapBSDSockAddrIn

static int mapOS2MsgFlags(const int os2flags)
{
int bsdflags = 0;
Expand Down Expand Up @@ -57,10 +78,7 @@ int OS2_connect(int sock, const struct OS2_sockaddr *os2addr, int addrlen)
}

struct sockaddr_in bsdaddr;
memset(&bsdaddr, '\0', sizeof (bsdaddr));
bsdaddr.sin_family = AF_INET;
bsdaddr.sin_port = ((const OS2_sockaddr_in *) os2addr)->sin_port;
bsdaddr.sin_addr.s_addr = ((const OS2_sockaddr_in *) os2addr)->sin_addr.s_addr;
mapOS2SockAddrIn(os2addr, &bsdaddr);
return connect(sock, &bsdaddr, (socklen_t) sizeof (bsdaddr));
} // OS2_connect

Expand Down Expand Up @@ -215,22 +233,197 @@ int OS2_os2_select(int *socks, int noreads, int nowrites, int noexcept, long tim
return poll(origfds, nfds, timeout * 1000);
} // OS2_os2_select

int OS2_getsockname(int sock, OS2_sockaddr *os2name, int *os2namelen)
{
TRACE_NATIVE("getsockname(%d, %p, %p)", sock, os2name, os2namelen);

struct sockaddr_in bsdaddr;
socklen_t namelen = sizeof (bsdaddr);
const int rc = getsockname(sock, &bsdaddr, &namelen);
if (rc == -1) {
return -1;
} else if (bsdaddr.sin_family != AF_INET) {
FIXME("this only deals with IPv4 at the moment");
return -1;
} else if (*os2namelen < sizeof (OS2_sockaddr_in)) {
return -1;
}

mapBSDSockAddrIn(&bsdaddr, os2name);
*os2namelen = sizeof (OS2_sockaddr_in);
return rc;
} // OS2_getsockname

int OS2_bind(int sock, const OS2_sockaddr *os2name, int os2namelen)
{
TRACE_NATIVE("bind(%d, %p, %d)", sock, os2name, os2namelen);
struct sockaddr_in bsdaddr;
mapOS2SockAddrIn(os2name, &bsdaddr);
return bind(sock, (struct sockaddr *) &bsdaddr, sizeof (bsdaddr));
} // OS2_bind

int OS2_listen(int sock, int backlog)
{
TRACE_NATIVE("listen(%d, %d)", sock, backlog);
return listen(sock, backlog);
} // OS2_listen

int OS2_accept(int sock, OS2_sockaddr *os2name, int *os2namelen)
{
TRACE_NATIVE("bind(%d, %p, %p)", sock, os2name, os2namelen);
struct sockaddr_in bsdaddr;
socklen_t bsdaddrlen = sizeof (bsdaddr);
const int retval = accept(sock, (struct sockaddr *) &bsdaddr, &bsdaddrlen);

if (os2name != NULL) {
mapBSDSockAddrIn(&bsdaddr, os2name);
}

if (os2namelen != NULL) {
*os2namelen = sizeof (OS2_sockaddr_in);
}

return retval;
} // OS2_accept

static int mapOS2SocketOption(const int os2name)
{
switch (os2name) {
#define MAPSOOPT(f) case OS2_##f: return f
MAPSOOPT(SO_DEBUG);
MAPSOOPT(SO_ACCEPTCONN);
MAPSOOPT(SO_REUSEADDR);
MAPSOOPT(SO_KEEPALIVE);
MAPSOOPT(SO_DONTROUTE);
MAPSOOPT(SO_BROADCAST);
//MAPSOOPT(SO_USELOOPBACK);
MAPSOOPT(SO_LINGER);
MAPSOOPT(SO_OOBINLINE);
//MAPSOOPT(SO_L_BROADCAST);
//MAPSOOPT(SO_RCV_SHUTDOWN);
//MAPSOOPT(SO_SND_SHUTDOWN);
MAPSOOPT(SO_REUSEPORT);
//MAPSOOPT(SO_TTCP);
MAPSOOPT(SO_SNDBUF);
MAPSOOPT(SO_RCVBUF);
MAPSOOPT(SO_SNDLOWAT);
MAPSOOPT(SO_RCVLOWAT);
MAPSOOPT(SO_SNDTIMEO);
MAPSOOPT(SO_RCVTIMEO);
MAPSOOPT(SO_ERROR);
MAPSOOPT(SO_TYPE);
//MAPSOOPT(SO_OPTIONS);
#undef MAPSOOPT
default: break;
}

FIXME("unsupported OS/2 socket option");
return 0;
} // mapOS2SocketOption

int OS2_setsockopt(int sock, int os2level, int os2name, const void *value, int len)
{
const int bsdname = mapOS2SocketOption(os2name);
const int bsdlevel = SOL_SOCKET;
if (!bsdname) {
return -1;
} else if (os2level != OS2_SOL_SOCKET) {
return -1;
}
return setsockopt(sock, bsdlevel, bsdname, value, len);
} // OS2_setsockopt

int OS2_gettimeofday(OS2_timeval *os2tv, OS2_timezone *os2tz)
{
struct timeval bsdtv;
struct timezone bsdtz;
const int retval = gettimeofday(&bsdtv, &bsdtz);

if (os2tv) {
os2tv->tv_sec = bsdtv.tv_sec;
os2tv->tv_usec = bsdtv.tv_usec;
}

if (os2tz) {
os2tz->tz_minuteswest = bsdtz.tz_minuteswest;
os2tz->tz_dsttime = bsdtz.tz_dsttime;
}

return retval;
} // OS2_gettimeofday

// SOCKS support...

int OS2_Rgetsockname(int sock, OS2_sockaddr *os2name, int *os2namelen)
{
// !!! FIXME: this doesn't talk to a SOCKS proxy at all.
TRACE_NATIVE("Rgetsockname(%d, %p, %p)", sock, os2name, os2namelen);
return OS2_getsockname(sock, os2name, os2namelen);
} // OS2_Rgetsockname

int OS2_Rbind(int sock, OS2_sockaddr *os2name, int os2namelen, OS2_sockaddr *os2remote)
{
// !!! FIXME: this doesn't talk to a SOCKS proxy at all.
TRACE_NATIVE("Rbind(%d, %p, %d, %p)", sock, os2name, os2namelen, os2remote);
return OS2_bind(sock, os2name, os2namelen);
} // OS2_Rbind

int OS2_Raccept(int sock, OS2_sockaddr *os2name, int *os2namelen)
{
// !!! FIXME: this doesn't talk to a SOCKS proxy at all.
TRACE_NATIVE("Raccept(%d, %p, %p)", sock, os2name, os2namelen);
return OS2_accept(sock, os2name, os2namelen);
} // OS2_Raccept

int OS2_Rconnect(int sock, const OS2_sockaddr *os2name, int os2namelen)
{
// !!! FIXME: this doesn't talk to a SOCKS proxy at all.
TRACE_NATIVE("Rconnect(%d, %p, %d)", sock, os2name, os2namelen);
return OS2_connect(sock, os2name, os2namelen);
} // OS2_Rconnect

int OS2_Rlisten(int sock, int backlog)
{
// !!! FIXME: this doesn't talk to a SOCKS proxy at all.
TRACE_NATIVE("Rlisten(%d, %d)", sock, backlog);
return OS2_listen(sock, backlog);
} // OS2_Rlisten

OS2_hostent *OS2_Rgethostbyname(const char *name)
{
// !!! FIXME: this doesn't talk to a SOCKS proxy at all.
TRACE_NATIVE("Rgethostbyname('%s')", name);
return OS2_gethostbyname(name);
} // OS2_Rgethostbyname


LX_NATIVE_MODULE_INIT()
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_accept, "accept", 1),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_bind, "bind", 2),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_connect, "connect", 3),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_getsockname, "getsockname", 6),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_listen, "listen", 9),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_recv, "recv", 10),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_os2_select, "os2_select", 12),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_send, "send", 13),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_setsockopt, "setsockopt", 15),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_socket, "socket", 16),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_soclose, "soclose", 17),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_sock_errno, "sock_errno", 20),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_shutdown, "shutdown", 25),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_sock_init, "sock_init", 26),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_select, "select", 32),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_gettimeofday, "gettimeofday", 102),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_inet_addr, "inet_addr", 105),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_inet_ntoa, "inet_ntoa", 110),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_gethostbyname, "gethostbyname", 111),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_getservbyname, "getservbyname",124),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_getservbyname, "getservbyname", 124),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Raccept, "Raccept", 156),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rbind, "Rbind", 157),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rconnect, "Rconnect", 158),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rgetsockname, "Rgetsockname", 159),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rlisten, "Rlisten", 160),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rgethostbyname, "Rgethostbyname", 161),
LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_htons, "htons", 205)
LX_NATIVE_MODULE_INIT_END()

Expand Down

0 comments on commit 40b9b9e

Please sign in to comment.