From 7440fd4419acfc9c784f142fb9dee3e64c9a18c2 Mon Sep 17 00:00:00 2001 From: simon Date: Sun, 12 Oct 2003 13:46:12 +0000 Subject: [PATCH] The WinSock library is now loaded at run-time, which means we can attempt to load WS2 and then fall back to WS1 if that fails. This should allow us to use WS2-specific functionality to find out the local system's list of IP addresses, thus fixing winnet-if2lo, while degrading gracefully back to the previous behaviour if that functionality is unavailable. (I haven't yet actually done this; I've just laid the groundwork.) This checkin _may_ cause instability; it seemed fine to me on initial testing, but it's a bit of an upheaval and I wouldn't like to make bets on it just yet. git-svn-id: svn://svn.tartarus.org/sgt/putty@3502 cda61777-01e9-0310-a592-d414129be87e --- Recipe | 14 ++-- console.c | 3 - noise.c | 1 - pageant.c | 9 ++- pageantc.c | 1 - plink.c | 38 +++-------- printing.c | 2 - puttygen.c | 5 +- puttyps.h | 1 - sizetip.c | 2 - unicode.c | 4 -- wincfg.c | 2 - winctrls.c | 7 +- windefs.c | 8 +-- windlg.c | 9 ++- window.c | 72 ++++++-------------- winmisc.c | 2 - winnet.c | 224 +++++++++++++++++++++++++++++++++++++++++++------------------ winsftp.c | 32 +-------- winstore.c | 1 - winstuff.h | 21 ++++++ 21 files changed, 229 insertions(+), 229 deletions(-) diff --git a/Recipe b/Recipe index a9b0ec9d..64b1cb95 100644 --- a/Recipe +++ b/Recipe @@ -124,24 +124,22 @@ MACMISC = misc version macstore settings tree234 macnet mtcpnet otnet proxy # Character set library, for use in pterm. CHARSET = sbcsdat slookup sbcs utf8 toucs fromucs xenc mimeenc macenc localenc -# Standard libraries, and the same with WinSocks 1 and 2. +# Standard libraries. LIBS = advapi32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib + shell32.lib winmm.lib imm32.lib winspool.lib -LIBS1 = LIBS wsock32.lib -LIBS2 = LIBS ws2_32.lib # Definitions of actual programs. The program name, followed by a # colon, followed by a list of objects. Also in the list may be the # keywords [G] for Windows GUI app, [C] for Console app, [X] for # X/GTK Unix app, [U] for command-line Unix app, [M] for Macintosh app. -putty : [G] GUITERM NONSSH WINSSH be_all WINMISC win_res.res LIBS1 -puttytel : [G] GUITERM NONSSH be_nossh WINMISC win_res.res LIBS1 +putty : [G] GUITERM NONSSH WINSSH be_all WINMISC win_res.res LIBS +puttytel : [G] GUITERM NONSSH be_nossh WINMISC win_res.res LIBS plink : [C] plink console NONSSH WINSSH be_all logging WINMISC - + plink.res LIBS2 + + plink.res LIBS pscp : [C] scp winsftp console WINSSH be_none SFTP wildcard WINMISC - + scp.res LIBS1 -psftp : [C] psftp winsftp console WINSSH be_none SFTP WINMISC scp.res LIBS1 + + scp.res LIBS +psftp : [C] psftp winsftp console WINSSH be_none SFTP WINMISC scp.res LIBS pageant : [G] pageant sshrsa sshpubk sshdes sshbn sshmd5 version tree234 + misc sshaes sshsha pageantc sshdss sshsh512 winutils winmisc diff --git a/console.c b/console.c index 039716c6..c589a456 100644 --- a/console.c +++ b/console.c @@ -3,8 +3,6 @@ * the console PuTTY tools */ -#include - #include #include #include @@ -26,7 +24,6 @@ void cleanup_exit(int code) * Clean up. */ sk_cleanup(); - WSACleanup(); random_save_seed(); #ifdef MSCRYPTOAPI diff --git a/noise.c b/noise.c index a9dfa892..00719bbd 100644 --- a/noise.c +++ b/noise.c @@ -3,7 +3,6 @@ * generator. */ -#include #include #include "putty.h" diff --git a/pageant.c b/pageant.c index 4d69cb5e..9d39e46d 100644 --- a/pageant.c +++ b/pageant.c @@ -2,10 +2,6 @@ * Pageant: the PuTTY Authentication Agent. */ -#include -#ifndef NO_SECURITY -#include -#endif #include #include #include @@ -16,7 +12,10 @@ #include "ssh.h" #include "misc.h" #include "tree234.h" -#include "winstuff.h" + +#ifndef NO_SECURITY +#include +#endif #define IDI_MAINICON 200 #define IDI_TRAYICON 201 diff --git a/pageantc.c b/pageantc.c index 3d5e61f2..7d840f96 100644 --- a/pageantc.c +++ b/pageantc.c @@ -2,7 +2,6 @@ * Pageant client code. */ -#include #include #include diff --git a/plink.c b/plink.c index f0fe60cf..b46c5d6b 100644 --- a/plink.c +++ b/plink.c @@ -2,10 +2,6 @@ * PLink - a command-line (stdin/stdout) variant of PuTTY. */ -#ifndef AUTO_WINSOCK -#include -#endif -#include #include #include #include @@ -35,7 +31,6 @@ void fatalbox(char *p, ...) vfprintf(stderr, p, ap); va_end(ap); fputc('\n', stderr); - WSACleanup(); cleanup_exit(1); } void modalfatalbox(char *p, ...) @@ -46,7 +41,6 @@ void modalfatalbox(char *p, ...) vfprintf(stderr, p, ap); va_end(ap); fputc('\n', stderr); - WSACleanup(); cleanup_exit(1); } void connection_fatal(void *frontend, char *p, ...) @@ -57,7 +51,6 @@ void connection_fatal(void *frontend, char *p, ...) vfprintf(stderr, p, ap); va_end(ap); fputc('\n', stderr); - WSACleanup(); cleanup_exit(1); } void cmdline_error(char *p, ...) @@ -251,12 +244,12 @@ char *do_select(SOCKET skt, int startup) } else { events = 0; } - if (WSAEventSelect(skt, netevent, events) == SOCKET_ERROR) { - switch (WSAGetLastError()) { + if (p_WSAEventSelect(skt, netevent, events) == SOCKET_ERROR) { + switch (p_WSAGetLastError()) { case WSAENETDOWN: return "Network is down"; default: - return "WSAAsyncSelect(): unknown error"; + return "WSAEventSelect(): unknown error"; } } return NULL; @@ -264,8 +257,6 @@ char *do_select(SOCKET skt, int startup) int main(int argc, char **argv) { - WSADATA wsadata; - WORD winsock_ver; WSAEVENT stdinevent, stdoutevent, stderrevent; HANDLE handles[4]; DWORD in_threadid, out_threadid, err_threadid; @@ -545,22 +536,11 @@ int main(int argc, char **argv) if (portnumber != -1) cfg.port = portnumber; - /* - * Initialise WinSock. - */ - winsock_ver = MAKEWORD(2, 0); - if (WSAStartup(winsock_ver, &wsadata)) { - MessageBox(NULL, "Unable to initialise WinSock", "WinSock Error", - MB_OK | MB_ICONEXCLAMATION); - return 1; - } - if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wVersion) != 0) { - MessageBox(NULL, "WinSock version is incompatible with 2.0", - "WinSock Error", MB_OK | MB_ICONEXCLAMATION); - WSACleanup(); + sk_init(); + if (p_WSAEventSelect == NULL) { + fprintf(stderr, "Plink requires WinSock 2\n"); return 1; } - sk_init(); /* * Start up the connection. @@ -702,7 +682,7 @@ int main(int argc, char **argv) WPARAM wp; socket = sklist[i]; wp = (WPARAM) socket; - if (!WSAEnumNetworkEvents(socket, NULL, &things)) { + if (!p_WSAEnumNetworkEvents(socket, NULL, &things)) { static const struct { int bit, mask; } eventtypes[] = { {FD_CONNECT_BIT, FD_CONNECT}, {FD_READ_BIT, FD_READ}, @@ -780,11 +760,11 @@ int main(int argc, char **argv) bufchain_size(&stderr_data) == 0) break; /* we closed the connection */ } - WSACleanup(); exitcode = back->exitcode(backhandle); if (exitcode < 0) { fprintf(stderr, "Remote process exit code unavailable\n"); exitcode = 1; /* this is an error condition */ } - return exitcode; + cleanup_exit(exitcode); + return 0; /* placate compiler warning */ } diff --git a/printing.c b/printing.c index 0b619f10..6248881d 100644 --- a/printing.c +++ b/printing.c @@ -2,9 +2,7 @@ * Printing interface for PuTTY. */ -#include #include "putty.h" -#include "winstuff.h" struct printer_enum_tag { int nprinters; diff --git a/puttygen.c b/puttygen.c index 3e43b052..ffe4317d 100644 --- a/puttygen.c +++ b/puttygen.c @@ -2,8 +2,6 @@ * PuTTY key generation front end. */ -#include -#include #include #include #include @@ -12,7 +10,8 @@ #include "putty.h" #include "ssh.h" -#include "winstuff.h" + +#include #ifdef MSVC4 #define ICON_BIG 1 diff --git a/puttyps.h b/puttyps.h index 64c38c73..976f598e 100644 --- a/puttyps.h +++ b/puttyps.h @@ -3,7 +3,6 @@ #ifdef _WINDOWS -#include #include "winstuff.h" #elif defined(macintosh) diff --git a/sizetip.c b/sizetip.c index 320fa0ae..2073a09f 100644 --- a/sizetip.c +++ b/sizetip.c @@ -1,10 +1,8 @@ -#include #include #include #include #include "putty.h" -#include "winstuff.h" static ATOM tip_class = 0; diff --git a/unicode.c b/unicode.c index d46d6576..1d5e66fe 100644 --- a/unicode.c +++ b/unicode.c @@ -1,7 +1,3 @@ -#ifdef WINDOWS -#include -#endif - #include #include #include diff --git a/wincfg.c b/wincfg.c index 992d5dbf..4c3d8a94 100644 --- a/wincfg.c +++ b/wincfg.c @@ -3,8 +3,6 @@ * box. */ -#include - #include #include diff --git a/winctrls.c b/winctrls.c index 85b6dfb5..4a35cb6b 100644 --- a/winctrls.c +++ b/winctrls.c @@ -13,17 +13,14 @@ * button. */ -#include -#include #include #include -#include "winstuff.h" +#include "putty.h" #include "misc.h" #include "dialog.h" -#include "puttymem.h" -#include "putty.h" +#include #define GAPBETWEEN 3 #define GAPWITHIN 1 diff --git a/windefs.c b/windefs.c index 6c65c205..2acc5e36 100644 --- a/windefs.c +++ b/windefs.c @@ -2,14 +2,10 @@ * windefs.c: default settings that are specific to Windows. */ -#include -#include - -#include "winstuff.h" -#include "puttymem.h" - #include "putty.h" +#include + FontSpec platform_default_fontspec(const char *name) { FontSpec ret; diff --git a/windlg.c b/windlg.c index 7f6d88c3..3bdcefff 100644 --- a/windlg.c +++ b/windlg.c @@ -1,6 +1,3 @@ -#include -#include -#include #include #include #include @@ -8,13 +5,15 @@ #include #include -#include "ssh.h" #include "putty.h" -#include "winstuff.h" +#include "ssh.h" #include "win_res.h" #include "storage.h" #include "dialog.h" +#include +#include + #ifdef MSVC4 #define TVINSERTSTRUCT TV_INSERTSTRUCT #define TVITEM TV_ITEM diff --git a/window.c b/window.c index 1e84972e..5174b46f 100644 --- a/window.c +++ b/window.c @@ -1,23 +1,3 @@ -#include -#include -#include -#include -#include -#ifndef AUTO_WINSOCK -#ifdef WINSOCK_TWO -#include -#else -#include -#endif -#endif - -#ifndef NO_MULTIMON -#if WINVER < 0x0500 -#define COMPILE_MULTIMON_STUBS -#include -#endif -#endif - #include #include #include @@ -27,10 +7,21 @@ #define PUTTY_DO_GLOBALS /* actually _define_ globals */ #include "putty.h" #include "terminal.h" -#include "winstuff.h" #include "storage.h" #include "win_res.h" +#ifndef NO_MULTIMON +#if WINVER < 0x0500 +#define COMPILE_MULTIMON_STUBS +#include +#endif +#endif + +#include +#include +#include +#include + #define IDM_SHOWLOG 0x0010 #define IDM_NEWSESS 0x0020 #define IDM_DUPSESS 0x0030 @@ -178,8 +169,6 @@ static char *window_name, *icon_name; static int compose_state = 0; -static int wsa_started = 0; - static UINT wm_mousewheel = WM_MOUSEWHEEL; /* Dummy routine, only required in plink. */ @@ -189,8 +178,6 @@ void ldisc_update(void *frontend, int echo, int edit) int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { - WORD winsock_ver; - WSADATA wsadata; WNDCLASS wndclass; MSG msg; int guess_width, guess_height; @@ -198,20 +185,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) hinst = inst; flags = FLAG_VERBOSE | FLAG_INTERACTIVE; - winsock_ver = MAKEWORD(1, 1); - if (WSAStartup(winsock_ver, &wsadata)) { - MessageBox(NULL, "Unable to initialise WinSock", "WinSock Error", - MB_OK | MB_ICONEXCLAMATION); - return 1; - } - if (LOBYTE(wsadata.wVersion) != 1 || HIBYTE(wsadata.wVersion) != 1) { - MessageBox(NULL, "WinSock version is incompatible with 1.1", - "WinSock Error", MB_OK | MB_ICONEXCLAMATION); - WSACleanup(); - return 1; - } - wsa_started = 1; - /* WISHLIST: maybe allow config tweaking even if winsock not present? */ sk_init(); InitCommonControls(); @@ -305,8 +278,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) p[i] = '\0'; do_defaults(p + 1, &cfg); if (!*cfg.host && !do_config()) { - WSACleanup(); - return 0; + cleanup_exit(0); } } else if (*p == '&') { /* @@ -324,8 +296,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) UnmapViewOfFile(cp); CloseHandle(filemap); } else if (!do_config()) { - WSACleanup(); - return 0; + cleanup_exit(0); } } else { /* @@ -430,8 +401,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) cmdline_run_saved(&cfg); if (!*cfg.host && !do_config()) { - WSACleanup(); - return 0; + cleanup_exit(0); } /* @@ -493,8 +463,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) MessageBox(NULL, "Unsupported protocol number found", str, MB_OK | MB_ICONEXCLAMATION); sfree(str); - WSACleanup(); - return 1; + cleanup_exit(1); } } @@ -504,8 +473,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) MessageBox(NULL, "Invalid Port Number", str, MB_OK | MB_ICONEXCLAMATION); sfree(str); - WSACleanup(); - return 1; + cleanup_exit(1); } if (!prev) { @@ -840,8 +808,6 @@ void cleanup_exit(int code) if (pal) DeleteObject(pal); sk_cleanup(); - if (wsa_started) - WSACleanup(); if (cfg.protocol == PROT_SSH) { random_save_seed(); @@ -868,8 +834,8 @@ char *do_select(SOCKET skt, int startup) } if (!hwnd) return "do_select(): internal error (hwnd==NULL)"; - if (WSAAsyncSelect(skt, hwnd, msg, events) == SOCKET_ERROR) { - switch (WSAGetLastError()) { + if (p_WSAAsyncSelect(skt, hwnd, msg, events) == SOCKET_ERROR) { + switch (p_WSAGetLastError()) { case WSAENETDOWN: return "Network is down"; default: diff --git a/winmisc.c b/winmisc.c index a524b96f..7e58e93d 100644 --- a/winmisc.c +++ b/winmisc.c @@ -2,11 +2,9 @@ * winmisc.c: miscellaneous Windows-specific things. */ -#include #include #include #include "putty.h" -#include "winstuff.h" OSVERSIONINFO osVersion; diff --git a/winnet.c b/winnet.c index c211f539..25cfc191 100644 --- a/winnet.c +++ b/winnet.c @@ -38,14 +38,6 @@ */ /* #define IPV6 1 */ -#ifdef IPV6 -#include -#include -#include -#else -#include -#endif -#include #include #include #include @@ -55,8 +47,13 @@ #include "network.h" #include "tree234.h" +#ifdef IPV6 +#include +#include +#endif + #define ipv4_is_loopback(addr) \ - ((ntohl(addr.s_addr) & 0xFF000000L) == 0x7F000000L) + ((p_ntohl(addr.s_addr) & 0xFF000000L) == 0x7F000000L) struct Socket_tag { const struct socket_function_table *fn; @@ -128,8 +125,101 @@ static int cmpforsearch(void *av, void *bv) return 0; } +#define NOTHING +#define DECL_WINSOCK_FUNCTION(linkage, rettype, name, params) \ + typedef rettype (WINAPI *t_##name) params; \ + linkage t_##name p_##name +#define GET_WINSOCK_FUNCTION(name) \ + p_##name = (t_##name) GetProcAddress(winsock_module, #name) + +DECL_WINSOCK_FUNCTION(NOTHING, int, WSAAsyncSelect, + (SOCKET, HWND, u_int, long)); +DECL_WINSOCK_FUNCTION(NOTHING, int, WSAEventSelect, (SOCKET, WSAEVENT, long)); +DECL_WINSOCK_FUNCTION(NOTHING, int, select, + (int, fd_set FAR *, fd_set FAR *, + fd_set FAR *, const struct timeval FAR *)); +DECL_WINSOCK_FUNCTION(NOTHING, int, WSAGetLastError, (void)); +DECL_WINSOCK_FUNCTION(NOTHING, int, WSAEnumNetworkEvents, + (SOCKET, WSAEVENT, LPWSANETWORKEVENTS)); +DECL_WINSOCK_FUNCTION(static, int, WSAStartup, (WORD, LPWSADATA)); +DECL_WINSOCK_FUNCTION(static, int, WSACleanup, (void)); +DECL_WINSOCK_FUNCTION(static, int, closesocket, (SOCKET)); +DECL_WINSOCK_FUNCTION(static, u_long, ntohl, (u_long)); +DECL_WINSOCK_FUNCTION(static, u_long, htonl, (u_long)); +DECL_WINSOCK_FUNCTION(static, u_short, htons, (u_short)); +DECL_WINSOCK_FUNCTION(static, u_short, ntohs, (u_short)); +DECL_WINSOCK_FUNCTION(static, struct hostent FAR *, gethostbyname, + (const char FAR *)); +DECL_WINSOCK_FUNCTION(static, struct servent FAR *, getservbyname, + (const char FAR *, const char FAR *)); +DECL_WINSOCK_FUNCTION(static, unsigned long, inet_addr, (const char FAR *)); +DECL_WINSOCK_FUNCTION(static, char FAR *, inet_ntoa, (struct in_addr)); +DECL_WINSOCK_FUNCTION(static, int, connect, + (SOCKET, const struct sockaddr FAR *, int)); +DECL_WINSOCK_FUNCTION(static, int, bind, + (SOCKET, const struct sockaddr FAR *, int)); +DECL_WINSOCK_FUNCTION(static, int, setsockopt, + (SOCKET, int, int, const char FAR *, int)); +DECL_WINSOCK_FUNCTION(static, SOCKET, socket, (int, int, int)); +DECL_WINSOCK_FUNCTION(static, int, listen, (SOCKET, int)); +DECL_WINSOCK_FUNCTION(static, int, send, (SOCKET, const char FAR *, int, int)); +DECL_WINSOCK_FUNCTION(static, int, ioctlsocket, + (SOCKET, long, u_long FAR *)); +DECL_WINSOCK_FUNCTION(static, SOCKET, accept, + (SOCKET, struct sockaddr FAR *, int FAR *)); +DECL_WINSOCK_FUNCTION(static, int, recv, (SOCKET, char FAR *, int, int)); + +static HMODULE winsock_module; + void sk_init(void) { + WORD winsock_ver; + WSADATA wsadata; + + winsock_ver = MAKEWORD(2, 0); + winsock_module = LoadLibrary("WS2_32.DLL"); + if (!winsock_module) { + winsock_module = LoadLibrary("WSOCK32.DLL"); + winsock_ver = MAKEWORD(1, 1); + } + if (!winsock_module) + fatalbox("Unable to load any WinSock library"); + + GET_WINSOCK_FUNCTION(WSAAsyncSelect); + GET_WINSOCK_FUNCTION(WSAEventSelect); + GET_WINSOCK_FUNCTION(select); + GET_WINSOCK_FUNCTION(WSAGetLastError); + GET_WINSOCK_FUNCTION(WSAEnumNetworkEvents); + GET_WINSOCK_FUNCTION(WSAStartup); + GET_WINSOCK_FUNCTION(WSACleanup); + GET_WINSOCK_FUNCTION(closesocket); + GET_WINSOCK_FUNCTION(ntohl); + GET_WINSOCK_FUNCTION(htonl); + GET_WINSOCK_FUNCTION(htons); + GET_WINSOCK_FUNCTION(ntohs); + GET_WINSOCK_FUNCTION(gethostbyname); + GET_WINSOCK_FUNCTION(getservbyname); + GET_WINSOCK_FUNCTION(inet_addr); + GET_WINSOCK_FUNCTION(inet_ntoa); + GET_WINSOCK_FUNCTION(connect); + GET_WINSOCK_FUNCTION(bind); + GET_WINSOCK_FUNCTION(setsockopt); + GET_WINSOCK_FUNCTION(socket); + GET_WINSOCK_FUNCTION(listen); + GET_WINSOCK_FUNCTION(send); + GET_WINSOCK_FUNCTION(ioctlsocket); + GET_WINSOCK_FUNCTION(accept); + GET_WINSOCK_FUNCTION(recv); + + if (p_WSAStartup(winsock_ver, &wsadata)) { + fatalbox("Unable to initialise WinSock"); + } + if (LOBYTE(wsadata.wVersion) != LOBYTE(winsock_ver)) { + p_WSACleanup(); + fatalbox("WinSock version is incompatible with %d.%d", + LOBYTE(winsock_ver), HIBYTE(winsock_ver)); + } + sktree = newtree234(cmpfortree); } @@ -140,9 +230,13 @@ void sk_cleanup(void) if (sktree) { for (i = 0; (s = index234(sktree, i)) != NULL; i++) { - closesocket(s->s); + p_closesocket(s->s); } } + + p_WSACleanup(); + if (winsock_module) + FreeLibrary(winsock_module); } char *winsock_error_string(int error) @@ -236,7 +330,7 @@ SockAddr sk_namelookup(const char *host, char **canonicalname) ret->family = 0; /* We set this one when we have resolved the host. */ *realhost = '\0'; - if ((a = inet_addr(host)) == (unsigned long) INADDR_NONE) { + if ((a = p_inet_addr(host)) == (unsigned long) INADDR_NONE) { #ifdef IPV6 /* Try to get the getaddrinfo() function from wship6.dll */ @@ -272,14 +366,14 @@ SockAddr sk_namelookup(const char *host, char **canonicalname) */ if (ret->family == 0) { /*debug(("Resolving \"%s\" with gethostbyname() (IPv4 only)...\n", host)); */ - if ( (h = gethostbyname(host)) ) + if ( (h = p_gethostbyname(host)) ) ret->family = AF_INET; } } /*debug(("Done resolving...(family is %d) AF_INET = %d, AF_INET6 = %d\n", ret->family, AF_INET, AF_INET6)); */ if (ret->family == 0) { - DWORD err = WSAGetLastError(); + DWORD err = p_WSAGetLastError(); ret->error = (err == WSAENETDOWN ? "Network is down" : err == WSAHOST_NOT_FOUND ? "Host does not exist" : err @@ -355,7 +449,7 @@ SockAddr sk_namelookup(const char *host, char **canonicalname) ret->family = AF_INET; strncpy(realhost, host, sizeof(realhost)); } - ret->address = ntohl(a); + ret->address = p_ntohl(a); realhost[lenof(realhost)-1] = '\0'; *canonicalname = snewn(1+strlen(realhost), char); strcpy(*canonicalname, realhost); @@ -381,8 +475,8 @@ void sk_getaddr(SockAddr addr, char *buf, int buflen) #endif if (addr->family == AF_INET) { struct in_addr a; - a.s_addr = htonl(addr->address); - strncpy(buf, inet_ntoa(a), buflen); + a.s_addr = p_htonl(addr->address); + strncpy(buf, p_inet_ntoa(a), buflen); buf[buflen-1] = '\0'; } else { assert(addr->family == AF_UNSPEC); @@ -405,7 +499,7 @@ int sk_address_is_local(SockAddr addr) #endif if (addr->family == AF_INET) { struct in_addr a; - a.s_addr = htonl(addr->address); + a.s_addr = p_htonl(addr->address); return ipv4_is_loopback(a); } else { assert(addr->family == AF_UNSPEC); @@ -432,7 +526,7 @@ void sk_addrcopy(SockAddr addr, char *buf) #endif if (addr->family == AF_INET) { struct in_addr a; - a.s_addr = htonl(addr->address); + a.s_addr = p_htonl(addr->address); memcpy(buf, (char*) &a.s_addr, 4); } } @@ -505,7 +599,7 @@ Socket sk_register(void *sock, Plug plug) ret->s = (SOCKET)sock; if (ret->s == INVALID_SOCKET) { - err = WSAGetLastError(); + err = p_WSAGetLastError(); ret->error = winsock_error_string(err); return (Socket) ret; } @@ -570,11 +664,11 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline, * Open socket. */ assert(addr->family != AF_UNSPEC); - s = socket(addr->family, SOCK_STREAM, 0); + s = p_socket(addr->family, SOCK_STREAM, 0); ret->s = s; if (s == INVALID_SOCKET) { - err = WSAGetLastError(); + err = p_WSAGetLastError(); ret->error = winsock_error_string(err); return (Socket) ret; } @@ -582,12 +676,12 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline, ret->oobinline = oobinline; if (oobinline) { BOOL b = TRUE; - setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (void *) &b, sizeof(b)); + p_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (void *) &b, sizeof(b)); } if (nodelay) { BOOL b = TRUE; - setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void *) &b, sizeof(b)); + p_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void *) &b, sizeof(b)); } /* @@ -607,28 +701,28 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline, memset(&a6, 0, sizeof(a6)); a6.sin6_family = AF_INET6; /*a6.sin6_addr = in6addr_any; *//* == 0 */ - a6.sin6_port = htons(localport); + a6.sin6_port = p_htons(localport); } else #endif { a.sin_family = AF_INET; - a.sin_addr.s_addr = htonl(INADDR_ANY); - a.sin_port = htons(localport); + a.sin_addr.s_addr = p_htonl(INADDR_ANY); + a.sin_port = p_htons(localport); } #ifdef IPV6 - retcode = bind(s, (addr->family == AF_INET6 ? + retcode = p_bind(s, (addr->family == AF_INET6 ? (struct sockaddr *) &a6 : (struct sockaddr *) &a), (addr->family == AF_INET6 ? sizeof(a6) : sizeof(a))); #else - retcode = bind(s, (struct sockaddr *) &a, sizeof(a)); + retcode = p_bind(s, (struct sockaddr *) &a, sizeof(a)); #endif if (retcode != SOCKET_ERROR) { err = 0; break; /* done */ } else { - err = WSAGetLastError(); + err = p_WSAGetLastError(); if (err != WSAEADDRINUSE) /* failed, for a bad reason */ break; } @@ -652,15 +746,15 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline, if (addr->family == AF_INET6) { memset(&a, 0, sizeof(a)); a6.sin6_family = AF_INET6; - a6.sin6_port = htons((short) port); + a6.sin6_port = p_htons((short) port); a6.sin6_addr = ((struct sockaddr_in6 *) addr->ai->ai_addr)->sin6_addr; } else #endif { a.sin_family = AF_INET; - a.sin_addr.s_addr = htonl(addr->address); - a.sin_port = htons((short) port); + a.sin_addr.s_addr = p_htonl(addr->address); + a.sin_port = p_htons((short) port); } /* Set up a select mechanism. This could be an AsyncSelect on a @@ -673,14 +767,14 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline, if (( #ifdef IPV6 - connect(s, ((addr->family == AF_INET6) ? + p_connect(s, ((addr->family == AF_INET6) ? (struct sockaddr *) &a6 : (struct sockaddr *) &a), (addr->family == AF_INET6) ? sizeof(a6) : sizeof(a)) #else - connect(s, (struct sockaddr *) &a, sizeof(a)) + p_connect(s, (struct sockaddr *) &a, sizeof(a)) #endif ) == SOCKET_ERROR) { - err = WSAGetLastError(); + err = p_WSAGetLastError(); /* * We expect a potential EWOULDBLOCK here, because the * chances are the front end has done a select for @@ -750,18 +844,18 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only) /* * Open socket. */ - s = socket(AF_INET, SOCK_STREAM, 0); + s = p_socket(AF_INET, SOCK_STREAM, 0); ret->s = s; if (s == INVALID_SOCKET) { - err = WSAGetLastError(); + err = p_WSAGetLastError(); ret->error = winsock_error_string(err); return (Socket) ret; } ret->oobinline = 0; - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on)); + p_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on)); #ifdef IPV6 if (addr->family == AF_INET6) { @@ -773,7 +867,7 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only) a6.sin6_addr = in6addr_loopback; else a6.sin6_addr = in6addr_any; - a6.sin6_port = htons(port); + a6.sin6_port = p_htons(port); } else #endif { @@ -785,7 +879,7 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only) * specified one... */ if (srcaddr) { - a.sin_addr.s_addr = inet_addr(srcaddr); + a.sin_addr.s_addr = p_inet_addr(srcaddr); if (a.sin_addr.s_addr != INADDR_NONE) { /* Override localhost_only with specified listen addr. */ ret->localhost_only = ipv4_is_loopback(a.sin_addr); @@ -798,26 +892,26 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only) */ if (!got_addr) { if (local_host_only) - a.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + a.sin_addr.s_addr = p_htonl(INADDR_LOOPBACK); else - a.sin_addr.s_addr = htonl(INADDR_ANY); + a.sin_addr.s_addr = p_htonl(INADDR_ANY); } - a.sin_port = htons((short)port); + a.sin_port = p_htons((short)port); } #ifdef IPV6 - retcode = bind(s, (addr->family == AF_INET6 ? + retcode = p_bind(s, (addr->family == AF_INET6 ? (struct sockaddr *) &a6 : (struct sockaddr *) &a), (addr->family == AF_INET6 ? sizeof(a6) : sizeof(a))); #else - retcode = bind(s, (struct sockaddr *) &a, sizeof(a)); + retcode = p_bind(s, (struct sockaddr *) &a, sizeof(a)); #endif if (retcode != SOCKET_ERROR) { err = 0; } else { - err = WSAGetLastError(); + err = p_WSAGetLastError(); } if (err) { @@ -826,8 +920,8 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only) } - if (listen(s, SOMAXCONN) == SOCKET_ERROR) { - closesocket(s); + if (p_listen(s, SOMAXCONN) == SOCKET_ERROR) { + p_closesocket(s); ret->error = winsock_error_string(err); return (Socket) ret; } @@ -852,7 +946,7 @@ static void sk_tcp_close(Socket sock) del234(sktree, s); do_select(s->s, 0); - closesocket(s->s); + p_closesocket(s->s); sfree(s); } @@ -876,10 +970,10 @@ void try_send(Actual_Socket s) urgentflag = 0; bufchain_prefix(&s->output_data, &data, &len); } - nsent = send(s->s, data, len, urgentflag); + nsent = p_send(s->s, data, len, urgentflag); noise_ultralight(nsent); if (nsent <= 0) { - err = (nsent < 0 ? WSAGetLastError() : 0); + err = (nsent < 0 ? p_WSAGetLastError() : 0); if ((err < WSABASEERR && nsent < 0) || err == WSAEWOULDBLOCK) { /* * Perfectly normal: we've sent all we can for the moment. @@ -1012,7 +1106,7 @@ int select_result(WPARAM wParam, LPARAM lParam) */ if (s->oobinline) { atmark = 1; - ioctlsocket(s->s, SIOCATMARK, &atmark); + p_ioctlsocket(s->s, SIOCATMARK, &atmark); /* * Avoid checking the return value from ioctlsocket(), * on the grounds that some WinSock wrappers don't @@ -1023,10 +1117,10 @@ int select_result(WPARAM wParam, LPARAM lParam) } else atmark = 1; - ret = recv(s->s, buf, sizeof(buf), 0); + ret = p_recv(s->s, buf, sizeof(buf), 0); noise_ultralight(ret); if (ret < 0) { - err = WSAGetLastError(); + err = p_WSAGetLastError(); if (err == WSAEWOULDBLOCK) { break; } @@ -1047,11 +1141,11 @@ int select_result(WPARAM wParam, LPARAM lParam) * and get back OOB data, which we will send to the back * end with type==2 (urgent data). */ - ret = recv(s->s, buf, sizeof(buf), MSG_OOB); + ret = p_recv(s->s, buf, sizeof(buf), MSG_OOB); noise_ultralight(ret); if (ret <= 0) { char *str = (ret == 0 ? "Internal networking trouble" : - winsock_error_string(WSAGetLastError())); + winsock_error_string(p_WSAGetLastError())); /* We're inside the Windows frontend here, so we know * that the frontend handle is unnecessary. */ logevent(NULL, str); @@ -1075,9 +1169,9 @@ int select_result(WPARAM wParam, LPARAM lParam) /* Signal a close on the socket. First read any outstanding data. */ open = 1; do { - ret = recv(s->s, buf, sizeof(buf), 0); + ret = p_recv(s->s, buf, sizeof(buf), 0); if (ret < 0) { - err = WSAGetLastError(); + err = p_WSAGetLastError(); if (err == WSAEWOULDBLOCK) break; return plug_closing(s->plug, winsock_error_string(err), @@ -1098,18 +1192,18 @@ int select_result(WPARAM wParam, LPARAM lParam) memset(&isa, 0, sizeof(struct sockaddr_in)); err = 0; - t = accept(s->s,(struct sockaddr *)&isa,&addrlen); + t = p_accept(s->s,(struct sockaddr *)&isa,&addrlen); if (t == INVALID_SOCKET) { - err = WSAGetLastError(); + err = p_WSAGetLastError(); if (err == WSATRY_AGAIN) break; } if (s->localhost_only && !ipv4_is_loopback(isa.sin_addr)) { - closesocket(t); /* dodgy WinSock let nonlocal through */ + p_closesocket(t); /* dodgy WinSock let nonlocal through */ } else if (plug_accepting(s->plug, (void*)t)) { - closesocket(t); /* denied or error */ + p_closesocket(t); /* denied or error */ } } } @@ -1194,7 +1288,7 @@ static void sk_tcp_set_frozen(Socket sock, int is_frozen) s->frozen = is_frozen; if (!is_frozen && s->frozen_readable) { char c; - recv(s->s, &c, 1, MSG_PEEK); + p_recv(s->s, &c, 1, MSG_PEEK); } s->frozen_readable = 0; } @@ -1219,9 +1313,9 @@ SOCKET next_socket(int *state) int net_service_lookup(char *service) { struct servent *se; - se = getservbyname(service, NULL); + se = p_getservbyname(service, NULL); if (se != NULL) - return ntohs(se->s_port); + return p_ntohs(se->s_port); else return 0; } diff --git a/winsftp.c b/winsftp.c index 6687210f..a399f45e 100644 --- a/winsftp.c +++ b/winsftp.c @@ -2,15 +2,6 @@ * winsftp.c: the Windows-specific parts of PSFTP and PSCP. */ -#include -#ifndef AUTO_WINSOCK -#ifdef WINSOCK_TWO -#include -#else -#include -#endif -#endif - #include "putty.h" #include "psftp.h" @@ -481,25 +472,6 @@ char *do_select(SOCKET skt, int startup) extern int select_result(WPARAM, LPARAM); /* - * Initialize the WinSock driver. - */ -static void init_winsock(void) -{ - WORD winsock_ver; - WSADATA wsadata; - - winsock_ver = MAKEWORD(1, 1); - if (WSAStartup(winsock_ver, &wsadata)) { - fprintf(stderr, "Unable to initialise WinSock"); - cleanup_exit(1); - } - if (LOBYTE(wsadata.wVersion) != 1 || HIBYTE(wsadata.wVersion) != 1) { - fprintf(stderr, "WinSock version is incompatible with 1.1"); - cleanup_exit(1); - } -} - -/* * Wait for some network data and process it. */ int ssh_sftp_loop_iteration(void) @@ -511,7 +483,7 @@ int ssh_sftp_loop_iteration(void) FD_ZERO(&readfds); FD_SET(sftp_ssh_socket, &readfds); - if (select(1, &readfds, NULL, NULL, NULL) < 0) + if (p_select(1, &readfds, NULL, NULL, NULL) < 0) return -1; /* doom */ select_result((WPARAM) sftp_ssh_socket, (LPARAM) FD_READ); @@ -525,9 +497,7 @@ int main(int argc, char *argv[]) { int ret; - init_winsock(); ret = psftp_main(argc, argv); - WSACleanup(); return ret; } diff --git a/winstore.c b/winstore.c index b6f98f5d..553f474e 100644 --- a/winstore.c +++ b/winstore.c @@ -3,7 +3,6 @@ * defined in storage.h. */ -#include #include #include #include diff --git a/winstuff.h b/winstuff.h index 61b34795..693fd42e 100644 --- a/winstuff.h +++ b/winstuff.h @@ -5,6 +5,10 @@ #ifndef PUTTY_WINSTUFF_H #define PUTTY_WINSTUFF_H +#ifndef AUTO_WINSOCK +#include +#endif +#include #include /* for FILENAME_MAX */ #include "tree234.h" @@ -130,6 +134,23 @@ GLOBAL void *logctx; "All Files (*.*)\0*\0\0\0") /* + * winnet.c dynamically loads WinSock 2 or WinSock 1 depending on + * what it can get, which means any WinSock routines used outside + * that module must be exported from it as function pointers. So + * here they are. + */ +extern int (WINAPI *p_WSAAsyncSelect) + (SOCKET s, HWND hWnd, u_int wMsg, long lEvent); +extern int (WINAPI *p_WSAEventSelect) + (SOCKET s, WSAEVENT hEventObject, long lNetworkEvents); +extern int (WINAPI *p_select) + (int nfds, fd_set FAR * readfds, fd_set FAR * writefds, + fd_set FAR *exceptfds, const struct timeval FAR * timeout); +extern int (WINAPI *p_WSAGetLastError)(void); +extern int (WINAPI *p_WSAEnumNetworkEvents) + (SOCKET s, WSAEVENT hEventObject, LPWSANETWORKEVENTS lpNetworkEvents); + +/* * Exports from winctrls.c. */ -- 2.11.0