Some winsock improvements

This commit is contained in:
mpc
2004-06-27 09:12:05 +00:00
committed by zzz
parent 77a8a46d8e
commit dc04b7cf09
4 changed files with 189 additions and 21 deletions

View File

@ -3,7 +3,7 @@
# #
# #
# Your operating system # Your operating environment
# #
OS = CYGWIN OS = CYGWIN

View File

@ -44,6 +44,7 @@
#define NO_GETHOSTBYNAME2 #define NO_GETHOSTBYNAME2
#define NO_INET_ATON /* implies NO_INET_PTON */ #define NO_INET_ATON /* implies NO_INET_PTON */
#define NO_INET_NTOP #define NO_INET_NTOP
#define NO_SSIZE_T
#define NO_STRL #define NO_STRL
#define NO_Z_FORMAT #define NO_Z_FORMAT
#define WINSOCK #define WINSOCK
@ -103,6 +104,7 @@
#endif #endif
#ifdef WINSOCK #ifdef WINSOCK
#include <windows.h> #include <windows.h>
#include <winsock2.h>
#else #else
#include <unistd.h> #include <unistd.h>
#endif #endif
@ -112,10 +114,12 @@
*/ */
#ifdef WINSOCK #ifdef WINSOCK
typedef SOCKET socket_t; typedef SOCKET socket_t;
typedef signed long ssize_t;
#else #else
typedef int socket_t; typedef int socket_t;
#endif #endif
#ifdef NO_SSIZE_T
typedef signed long ssize_t;
#endif
/* /*
* Prints out the file name, line number, and function name before log message * Prints out the file name, line number, and function name before log message

View File

@ -86,7 +86,7 @@ extern samerr_t sam_connect(const char *samhost, uint16_t samport,
const char *destname, sam_conn_t style, uint_t tunneldepth); const char *destname, sam_conn_t style, uint_t tunneldepth);
extern void sam_naming_lookup(const char *name); extern void sam_naming_lookup(const char *name);
extern bool sam_read_buffer(void); extern bool sam_read_buffer(void);
extern char *sam_strerror(samerr_t code); extern const char *sam_strerror(samerr_t code);
/* SAM controls - callbacks */ /* SAM controls - callbacks */
extern void (*sam_diedback)(void); extern void (*sam_diedback)(void);
extern void (*sam_logback)(char *str); extern void (*sam_logback)(char *str);

View File

@ -41,6 +41,11 @@ static samerr_t sam_session_create(const char *destname, sam_conn_t style,
uint_t tunneldepth); uint_t tunneldepth);
static bool sam_socket_connect(const char *host, uint16_t port); static bool sam_socket_connect(const char *host, uint16_t port);
static bool sam_socket_resolve(const char *hostname, char *ipaddr); static bool sam_socket_resolve(const char *hostname, char *ipaddr);
#ifdef WINSOCK
static samerr_t sam_winsock_cleanup(void);
static samerr_t sam_winsock_startup(void);
static const char *sam_winsock_strerror(int code);
#endif
static ssize_t sam_write(const void *buf, size_t n); static ssize_t sam_write(const void *buf, size_t n);
/* /*
@ -83,6 +88,8 @@ bool sam_close(void)
if (closesocket(samd) == 0) { if (closesocket(samd) == 0) {
samd_connected = false; samd_connected = false;
return true; return true;
if (sam_winsock_cleanup() != SAM_OK)
return false;
#else #else
if (close(samd) == 0) { if (close(samd) == 0) {
samd_connected = false; samd_connected = false;
@ -132,23 +139,9 @@ samerr_t sam_connect(const char *samhost, uint16_t samport,
} }
#ifdef WINSOCK #ifdef WINSOCK
/* rc = sam_winsock_startup();
* Is Windows retarded or what? if (rc != SAM_OK)
*/ return rc;
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
SAMLOGS("WSAStartup() failed");
return SAM_SOCKET_ERROR;
}
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1 ) {
SAMLOGS("Bad WinSock version");
return SAM_SOCKET_ERROR;
}
#endif #endif
if (!sam_socket_connect(samhost, samport)) { if (!sam_socket_connect(samhost, samport)) {
@ -953,7 +946,7 @@ samerr_t sam_stream_send(sam_sid_t stream_id, const void *data, size_t size)
* *
* Returns: error string * Returns: error string
*/ */
char *sam_strerror(samerr_t code) const char *sam_strerror(samerr_t code)
{ {
switch (code) { switch (code) {
case SAM_OK: /* Operation completed succesfully */ case SAM_OK: /* Operation completed succesfully */
@ -994,6 +987,177 @@ char *sam_strerror(samerr_t code)
} }
} }
#ifdef WINSOCK
/*
* Unloads the Winsock network subsystem
*
* Returns: SAM error code
*/
samerr_t sam_winsock_cleanup(void)
{
if (WSACleanup() == SOCKET_ERROR) {
SAMLOG("WSACleanup() failed (%s)",
sam_winsock_strerror(WSAGetLastError()));
return SAM_SOCKET_ERROR;
}
return SAM_OK;
}
/*
* Loads the Winsock network sucksystem
*
* Returns: SAM error code
*/
samerr_t sam_winsock_startup(void)
{
/*
* Is Windows retarded or what?
*/
WORD wVersionRequested;
WSADATA wsaData;
int rc;
wVersionRequested = MAKEWORD(2, 2);
rc = WSAStartup(wVersionRequested, &wsaData);
if (rc != 0) {
SAMLOG("WSAStartup() failed (%s)", sam_winsock_strerror(rc));
return SAM_SOCKET_ERROR;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
SAMLOGS("Bad Winsock version");
sam_winsock_cleanup();
return SAM_SOCKET_ERROR;
}
return SAM_OK;
}
/*
* Apparently Winsock does not have a strerror() equivalent for its functions
*
* code - code from WSAGetLastError()
*
* Returns: error string (from http://msdn.microsoft.com/library/default.asp?
* url=/library/en-us/winsock/winsock/windows_sockets_error_codes_2.asp)
*/
const char *sam_winsock_strerror(int code)
{
switch (code) {
case WSAEINTR:
return "Interrupted function call";
case WSAEACCES: // yes, that is the correct spelling
return "Permission denied";
case WSAEFAULT:
return "Bad address";
case WSAEINVAL:
return "Invalid argument";
case WSAEMFILE:
return "Too many open files";
case WSAEWOULDBLOCK:
return "Resource temporarily unavailable";
case WSAEINPROGRESS:
return "Operation now in progress";
case WSAEALREADY:
return "Operation already in progress";
case WSAENOTSOCK:
return "Socket operations on nonsocket";
case WSAEDESTADDRREQ:
return "Destination address required";
case WSAEMSGSIZE:
return "Message too long";
case WSAEPROTOTYPE:
return "Protocol wrong type for socket";
case WSAENOPROTOOPT:
return "Bad protocol option";
case WSAEPROTONOSUPPORT:
return "Protocol not supported";
case WSAESOCKTNOSUPPORT:
return "Socket type not supported";
case WSAEOPNOTSUPP:
return "Operation not supported";
case WSAEPFNOSUPPORT:
return "Protocol family not supported";
case WSAEAFNOSUPPORT:
return "Address family not supported by protocol family";
case WSAEADDRINUSE:
return "Address already in use";
case WSAEADDRNOTAVAIL:
return "Cannot assign requested address";
case WSAENETDOWN:
return "Network is down";
case WSAENETUNREACH:
return "Network is unreachable";
case WSAENETRESET:
return "Network dropped connection on reset";
case WSAECONNABORTED:
return "Software caused connection abort";
case WSAECONNRESET:
return "Connection reset by peer";
case WSAENOBUFS:
return "No buffer space available";
case WSAEISCONN:
return "Socket is already connected";
case WSAENOTCONN:
return "Socket is not connected";
case WSAESHUTDOWN:
return "Cannot send after socket shutdown";
case WSAETIMEDOUT:
return "Connection timed out";
case WSAECONNREFUSED:
return "Connection refused";
case WSAEHOSTDOWN:
return "Host is down";
case WSAEHOSTUNREACH:
return "No route to host";
case WSAEPROCLIM:
return "Too many processes";
case WSASYSNOTREADY:
return "Network subsystem is unavailable";
case WSAVERNOTSUPPORTED:
return "Winsock.dll version out of range";
case WSANOTINITIALISED:
return "Successful WSAStartup not yet performed";
case WSAEDISCON:
return "Graceful shutdown in progress";
case WSATYPE_NOT_FOUND:
return "Class type not found";
case WSAHOST_NOT_FOUND:
return "Host not found";
case WSATRY_AGAIN:
return "Nonauthoritative host not found";
case WSANO_RECOVERY:
return "This is a nonrecoverable error";
case WSANO_DATA:
return "Valid name, no data record of requested type";
/* None of this shit compiles under Mingw - who knows why...
case WSA_INVALID_HANDLE:
return "Specified event object handle is invalid";
case WSA_INVALID_PARAMETER:
return "One or more parameters are invalid";
case WSA_IO_INCOMPLETE:
return "Overlapped I/O event object not in signaled state";
case WSA_IO_PENDING:
return "Overlapped operations will complete later";
case WSA_NOT_ENOUGH_MEMORY:
return "Insufficient memory available";
case WSA_OPERATION_ABORTED:
return "Overlapped operation aborted";
case WSAINVALIDPROCTABLE:
return "Invalid procedure table from service provider";
case WSAINVALIDPROVIDER:
return "Invalid service provider version number";
case WSAPROVIDERFAILEDINIT:
return "Unable to initialize a service provider";
*/
case WSASYSCALLFAILURE:
return "System call failure";
default:
return "Unknown error";
}
}
#endif
/* /*
* Sends `n' bytes to the SAM host * Sends `n' bytes to the SAM host
* *