Filled in enough of tcpip32 and doscalls to run OS/2's TCPIP/bin/FTP.EXE.

It crashes right after a completed download, but otherwise seems to
fully work!
This commit is contained in:
Ryan C. Gordon committed 2018-01-04 02:50:26 -05:00
1 parent c2e43984c2
commit 40b9b9e141
4 files changed
+282 -6

No files matched your search

+26 -1
View File
@@ -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),
@@ -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),
@@ -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);
@@ -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);
@@ -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
View File
@@ -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,
@@ -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);
@@ -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
}
+198 -5
View File
@@ -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>
@@ -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;
@@ -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
@@ -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()
+44
View File
@@ -30,6 +30,33 @@ extern "C" {
#define OS2_SOCK_STREAM 1
#define OS2_SOCK_DGRAM 2
#define OS2_SOL_SOCKET 0xffff
#define OS2_SO_DEBUG 0x0001
#define OS2_SO_ACCEPTCONN 0x0002
#define OS2_SO_REUSEADDR 0x0004
#define OS2_SO_KEEPALIVE 0x0008
#define OS2_SO_DONTROUTE 0x0010
#define OS2_SO_BROADCAST 0x0020
#define OS2_SO_USELOOPBACK 0x0040
#define OS2_SO_LINGER 0x0080
#define OS2_SO_OOBINLINE 0x0100
#define OS2_SO_L_BROADCAST 0x0200
#define OS2_SO_RCV_SHUTDOWN 0x0400
#define OS2_SO_SND_SHUTDOWN 0x0800
#define OS2_SO_REUSEPORT 0x1000
#define OS2_SO_TTCP 0x2000
#define OS2_SO_SNDBUF 0x1001
#define OS2_SO_RCVBUF 0x1002
#define OS2_SO_SNDLOWAT 0x1003
#define OS2_SO_RCVLOWAT 0x1004
#define OS2_SO_SNDTIMEO 0x1005
#define OS2_SO_RCVTIMEO 0x1006
#define OS2_SO_ERROR 0x1007
#define OS2_SO_TYPE 0x1008
#define OS2_SO_OPTIONS 0x1010
#pragma pack(push, 1)
typedef struct OS2_sockaddr
{
@@ -82,6 +109,12 @@ typedef struct OS2_timeval
sint32 tv_sec;
sint32 tv_usec;
} OS2_timeval;
typedef struct OS2_timezone
{
sint32 tz_minuteswest;
sint32 tz_dsttime;
} OS2_timezone;
#pragma pack(pop)
OS2EXPORT int OS2API OS2_sock_init(void);
@@ -99,6 +132,17 @@ OS2EXPORT char * OS2API OS2_inet_ntoa(OS2_in_addr os2inaddr);
OS2EXPORT OS2_servent * OS2API OS2_getservbyname(const char *name, const char *proto);
OS2EXPORT int OS2API OS2_select(int sock, OS2_fd_set *readfds, OS2_fd_set *writefds, OS2_fd_set *errorfds, OS2_timeval *timeout);
OS2EXPORT int OS2API OS2_os2_select(int *socks, int noreads, int nowrites, int noexcept, long timeout);
OS2EXPORT int OS2API OS2_getsockname(int sock, OS2_sockaddr *os2name, int *namelen);
OS2EXPORT int OS2API OS2_setsockopt(int sock, int os2level, int os2name, const void *value, int len);
OS2EXPORT int OS2API OS2_bind(int sock, const OS2_sockaddr *os2name, int os2namelen);
OS2EXPORT int OS2API OS2_accept(int sock, OS2_sockaddr *os2name, int *os2namelen);
OS2EXPORT int OS2API OS2_Rgetsockname(int sock, OS2_sockaddr *os2name, int *namelen);
OS2EXPORT int OS2API OS2_Rbind(int sock, OS2_sockaddr *os2name, int os2namelen, OS2_sockaddr *os2remote);
OS2EXPORT int OS2API OS2_Raccept(int sock, OS2_sockaddr *os2name, int *os2namelen);
OS2EXPORT int OS2API OS2_Rconnect(int sock, const OS2_sockaddr *os2name, int os2namelen);
OS2EXPORT int OS2API OS2_Rlisten(int sock, int backlog);
OS2EXPORT OS2_hostent * OS2API OS2_Rgethostbyname(const char *name);
OS2EXPORT int OS2API OS2_gettimeofday(OS2_timeval *os2tv, OS2_timezone *os2tz);
#ifdef __cplusplus
}