├── win32port ├── win32helpers │ ├── strings.h │ ├── unistd.h │ ├── sys │ │ └── time.h │ ├── netdb.h │ ├── gettimeofday.h │ ├── websock-w32.h │ ├── getopt.h │ ├── gettimeofday.c │ ├── getopt.c │ └── getopt_long.c ├── zlib │ ├── inffast.h │ ├── uncompr.c │ ├── compress.c │ ├── inftrees.h │ ├── ZLib.vcxproj.filters │ ├── adler32.c │ ├── inffixed.h │ ├── inflate.h │ ├── zutil.h │ ├── trees.h │ └── zutil.c ├── client │ └── client.vcxproj.filters ├── server │ └── server.vcxproj.filters ├── libwebsocketswin32 │ └── libwebsocketswin32.vcxproj.filters └── win32port.sln ├── Makefile.am ├── test-server ├── favicon.ico ├── Makefile.am ├── test-fraggle.c ├── test-client.c ├── test.html └── test-ping.c ├── .gitignore ├── lib ├── extension-deflate-stream.h ├── extension.c ├── Makefile.am ├── extension-x-google-mux.h ├── extension-deflate-stream.c ├── base64-decode.c ├── md5.c ├── client-handshake.c ├── sha-1.c └── private-libwebsockets.h ├── libwebsockets.spec ├── configure.ac ├── config.h.in ├── README-test-server └── missing /win32port/win32helpers/strings.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /win32port/win32helpers/unistd.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | SUBDIRS=lib test-server 3 | -------------------------------------------------------------------------------- /win32port/win32helpers/sys/time.h: -------------------------------------------------------------------------------- 1 | // left blank -------------------------------------------------------------------------------- /win32port/win32helpers/netdb.h: -------------------------------------------------------------------------------- 1 | // Left blank for win32 -------------------------------------------------------------------------------- /test-server/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arteme/libwebsockets/HEAD/test-server/favicon.ico -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | output/ 2 | win32port/ipch/ 3 | win32port/Debug*/ 4 | win32port/Release*/ 5 | win32port/server/Debug*/ 6 | win32port/server/Release*/ 7 | win32port/client/Debug*/ 8 | win32port/client/Release*/ 9 | win32port/libwebsocketswin32/Debug*/ 10 | win32port/libwebsocketswin32/Release*/ 11 | win32port/zlib/Debug*/ 12 | win32port/zlib/Release*/ 13 | *.vcxproj.user 14 | *.opensdf 15 | *.sdf 16 | *.suo 17 | -------------------------------------------------------------------------------- /win32port/zlib/inffast.h: -------------------------------------------------------------------------------- 1 | /* inffast.h -- header to use inffast.c 2 | * Copyright (C) 1995-2003, 2010 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* WARNING: this file should *not* be used by applications. It is 7 | part of the implementation of the compression library and is 8 | subject to change. Applications should only use zlib.h. 9 | */ 10 | 11 | void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); 12 | -------------------------------------------------------------------------------- /lib/extension-deflate-stream.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #define DEFLATE_STREAM_CHUNK 128 5 | #define DEFLATE_STREAM_COMPRESSION_LEVEL 1 6 | 7 | struct lws_ext_deflate_stream_conn { 8 | z_stream zs_in; 9 | z_stream zs_out; 10 | unsigned char buf[2000]; 11 | }; 12 | 13 | extern int lws_extension_callback_deflate_stream( 14 | struct libwebsocket_context *context, 15 | struct libwebsocket_extension *ext, 16 | struct libwebsocket *wsi, 17 | enum libwebsocket_extension_callback_reasons reason, 18 | void *user, void *in, size_t len); 19 | -------------------------------------------------------------------------------- /lib/extension.c: -------------------------------------------------------------------------------- 1 | #include "private-libwebsockets.h" 2 | 3 | #include "extension-deflate-stream.h" 4 | #include "extension-x-google-mux.h" 5 | 6 | struct libwebsocket_extension libwebsocket_internal_extensions[] = { 7 | #ifdef LWS_EXT_GOOGLE_MUX 8 | { 9 | "x-google-mux", 10 | lws_extension_callback_x_google_mux, 11 | sizeof (struct lws_ext_x_google_mux_conn) 12 | }, 13 | #endif 14 | { 15 | "deflate-stream", 16 | lws_extension_callback_deflate_stream, 17 | sizeof (struct lws_ext_deflate_stream_conn) 18 | }, 19 | { /* terminator */ 20 | NULL, NULL, 0 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /win32port/win32helpers/gettimeofday.h: -------------------------------------------------------------------------------- 1 | #ifndef _GET_TIME_OF_DAY_H 2 | #define _GET_TIME_OF_DAY_H 3 | 4 | #include < time.h > 5 | #include //I've ommited context line. 6 | #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) 7 | #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 8 | #else 9 | #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL 10 | #endif 11 | 12 | struct timezone 13 | { 14 | int tz_minuteswest; /* minutes W of Greenwich */ 15 | int tz_dsttime; /* type of dst correction */ 16 | }; 17 | 18 | int gettimeofday(struct timeval *tv, struct timezone *tz); 19 | 20 | 21 | #endif -------------------------------------------------------------------------------- /win32port/win32helpers/websock-w32.h: -------------------------------------------------------------------------------- 1 | #ifndef __WEB_SOCK_W32_H__ 2 | #define __WEB_SOCK_W32_H__ 3 | 4 | // Windows uses _DEBUG and NDEBUG 5 | #ifdef _DEBUG 6 | #undef DEBUG 7 | #define DEBUG 1 8 | #endif 9 | 10 | #pragma warning(disable : 4996) 11 | 12 | #define bzero(b,len) (memset((b), '\0', (len)), (void) 0) 13 | 14 | #define MSG_NOSIGNAL 0 15 | #define SHUT_RDWR SD_BOTH 16 | 17 | #define SOL_TCP IPPROTO_TCP 18 | 19 | #define random rand 20 | #define usleep _sleep 21 | #define poll WSAPoll 22 | 23 | /* override configure because we are not using Makefiles */ 24 | 25 | #define LWS_NO_FORK 26 | #define DATADIR "." 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /win32port/win32helpers/getopt.h: -------------------------------------------------------------------------------- 1 | #ifndef __GETOPT_H__ 2 | #define __GETOPT_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | extern int opterr; /* if error message should be printed */ 9 | extern int optind; /* index into parent argv vector */ 10 | extern int optopt; /* character checked for validity */ 11 | extern int optreset; /* reset getopt */ 12 | extern char *optarg; /* argument associated with option */ 13 | 14 | struct option 15 | { 16 | const char *name; 17 | int has_arg; 18 | int *flag; 19 | int val; 20 | }; 21 | 22 | #define no_argument 0 23 | #define required_argument 1 24 | #define optional_argument 2 25 | 26 | int getopt(int, char**, char*); 27 | int getopt_long(int, char**, char*, struct option*, int*); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | 33 | #endif /* __GETOPT_H__ */ 34 | -------------------------------------------------------------------------------- /lib/Makefile.am: -------------------------------------------------------------------------------- 1 | lib_LTLIBRARIES=libwebsockets.la 2 | include_HEADERS=libwebsockets.h 3 | dist_libwebsockets_la_SOURCES=libwebsockets.c \ 4 | handshake.c \ 5 | parsers.c \ 6 | libwebsockets.h \ 7 | base64-decode.c \ 8 | client-handshake.c \ 9 | extension.c \ 10 | extension-deflate-stream.c \ 11 | private-libwebsockets.h 12 | 13 | if EXT_GOOGLE_MUX 14 | dist_libwebsockets_la_SOURCES += extension-x-google-mux.c 15 | endif 16 | 17 | if LIBCRYPTO 18 | else 19 | dist_libwebsockets_la_SOURCES += md5.c sha-1.c 20 | endif 21 | 22 | libwebsockets_la_CFLAGS:=-rdynamic -fPIC -Wall -Werror -std=gnu99 -pedantic -c \ 23 | -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\" 24 | libwebsockets_la_LDFLAGS=-lz -version-info 0:3 25 | 26 | all-local: 27 | ../scripts/kernel-doc -html \ 28 | libwebsockets.c \ 29 | parsers.c \ 30 | client-handshake.c \ 31 | libwebsockets.h \ 32 | > ../libwebsockets-api-doc.html 33 | 34 | -------------------------------------------------------------------------------- /win32port/win32helpers/gettimeofday.c: -------------------------------------------------------------------------------- 1 | #include < time.h > 2 | #include //I've ommited context line. 3 | #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) 4 | #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 5 | #else 6 | #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL 7 | #endif 8 | 9 | struct timezone 10 | { 11 | int tz_minuteswest; /* minutes W of Greenwich */ 12 | int tz_dsttime; /* type of dst correction */ 13 | }; 14 | 15 | int gettimeofday(struct timeval *tv, struct timezone *tz) 16 | { 17 | FILETIME ft; 18 | unsigned __int64 tmpres = 0; 19 | static int tzflag; 20 | 21 | if (NULL != tv) 22 | { 23 | GetSystemTimeAsFileTime(&ft); 24 | 25 | tmpres |= ft.dwHighDateTime; 26 | tmpres <<= 32; 27 | tmpres |= ft.dwLowDateTime; 28 | 29 | /*converting file time to unix epoch*/ 30 | tmpres -= DELTA_EPOCH_IN_MICROSECS; 31 | tmpres /= 10; /*convert into microseconds*/ 32 | tv->tv_sec = (long)(tmpres / 1000000UL); 33 | tv->tv_usec = (long)(tmpres % 1000000UL); 34 | } 35 | 36 | if (NULL != tz) 37 | { 38 | if (!tzflag) 39 | { 40 | _tzset(); 41 | tzflag++; 42 | } 43 | tz->tz_minuteswest = _timezone / 60; 44 | tz->tz_dsttime = _daylight; 45 | } 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /libwebsockets.spec: -------------------------------------------------------------------------------- 1 | Name: libwebsockets 2 | Version: 0.1 3 | Release: 45.gmaster_f1d2113d%{?dist} 4 | Summary: Websocket Server Library 5 | 6 | Group: System 7 | License: GPL 8 | URL: http://warmcat.com 9 | Source0: %{name}-%{version}.tar.gz 10 | BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) 11 | 12 | BuildRequires: openssl-devel 13 | Requires: openssl-devel 14 | 15 | %description 16 | Webserver server library 17 | 18 | %package devel 19 | Summary: Development files for libwebsockets 20 | Group: Development/Libraries 21 | Requires: %{name} = %{version}-%{release} 22 | Requires: openssl-devel 23 | 24 | %description devel 25 | Development files for libwebsockets 26 | 27 | %prep 28 | %setup -q 29 | 30 | %build 31 | ./configure --prefix=/usr --libdir=%{_libdir} --enable-openssl 32 | make 33 | 34 | 35 | %install 36 | rm -rf $RPM_BUILD_ROOT 37 | make install DESTDIR=$RPM_BUILD_ROOT 38 | 39 | 40 | %clean 41 | rm -rf $RPM_BUILD_ROOT 42 | 43 | %files 44 | %defattr(-,root,root,-) 45 | %attr(755,root,root) /usr/bin/libwebsockets-test-server 46 | %attr(755,root,root) 47 | /%{_libdir}/libwebsockets.so.0.0.3 48 | /%{_libdir}/libwebsockets.so.0 49 | /%{_libdir}/libwebsockets.so 50 | /%{_libdir}/libwebsockets.la 51 | %attr(755,root,root) /usr/share/libwebsockets-test-server 52 | %attr(755,root,root) /usr/share/libwebsockets-test-server-extpoll 53 | %attr(755,root,root) /usr/share/libwebsockets-test-client 54 | %attr(755,root,root) /usr/share/libwebsockets-test-ping 55 | %doc 56 | %files devel 57 | %defattr(-,root,root,-) 58 | /usr/include/* 59 | %attr(755,root,root) 60 | /%{_libdir}/libwebsockets.a 61 | 62 | %changelog 63 | 64 | -------------------------------------------------------------------------------- /win32port/client/client.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | -------------------------------------------------------------------------------- /win32port/server/server.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | Source Files 49 | 50 | 51 | -------------------------------------------------------------------------------- /win32port/zlib/uncompr.c: -------------------------------------------------------------------------------- 1 | /* uncompr.c -- decompress a memory buffer 2 | * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #define ZLIB_INTERNAL 9 | #include "zlib.h" 10 | 11 | /* =========================================================================== 12 | Decompresses the source buffer into the destination buffer. sourceLen is 13 | the byte length of the source buffer. Upon entry, destLen is the total 14 | size of the destination buffer, which must be large enough to hold the 15 | entire uncompressed data. (The size of the uncompressed data must have 16 | been saved previously by the compressor and transmitted to the decompressor 17 | by some mechanism outside the scope of this compression library.) 18 | Upon exit, destLen is the actual size of the compressed buffer. 19 | 20 | uncompress returns Z_OK if success, Z_MEM_ERROR if there was not 21 | enough memory, Z_BUF_ERROR if there was not enough room in the output 22 | buffer, or Z_DATA_ERROR if the input data was corrupted. 23 | */ 24 | int ZEXPORT uncompress (dest, destLen, source, sourceLen) 25 | Bytef *dest; 26 | uLongf *destLen; 27 | const Bytef *source; 28 | uLong sourceLen; 29 | { 30 | z_stream stream; 31 | int err; 32 | 33 | stream.next_in = (Bytef*)source; 34 | stream.avail_in = (uInt)sourceLen; 35 | /* Check for source > 64K on 16-bit machine: */ 36 | if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; 37 | 38 | stream.next_out = dest; 39 | stream.avail_out = (uInt)*destLen; 40 | if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; 41 | 42 | stream.zalloc = (alloc_func)0; 43 | stream.zfree = (free_func)0; 44 | 45 | err = inflateInit(&stream); 46 | if (err != Z_OK) return err; 47 | 48 | err = inflate(&stream, Z_FINISH); 49 | if (err != Z_STREAM_END) { 50 | inflateEnd(&stream); 51 | if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) 52 | return Z_DATA_ERROR; 53 | return err; 54 | } 55 | *destLen = stream.total_out; 56 | 57 | err = inflateEnd(&stream); 58 | return err; 59 | } 60 | -------------------------------------------------------------------------------- /test-server/Makefile.am: -------------------------------------------------------------------------------- 1 | bin_PROGRAMS=libwebsockets-test-server libwebsockets-test-client libwebsockets-test-server-extpoll libwebsockets-test-fraggle 2 | libwebsockets_test_server_SOURCES=test-server.c 3 | libwebsockets_test_server_LDADD=-L../lib -lwebsockets 4 | libwebsockets_test_client_SOURCES=test-client.c 5 | libwebsockets_test_client_LDADD=-L../lib -lwebsockets 6 | libwebsockets_test_server_extpoll_SOURCES=test-server-extpoll.c 7 | libwebsockets_test_server_extpoll_LDADD=-L../lib -lwebsockets 8 | libwebsockets_test_fraggle_SOURCES=test-fraggle.c 9 | libwebsockets_test_fraggle_LDADD=-L../lib -lwebsockets 10 | 11 | 12 | libwebsockets_test_server_CFLAGS:= -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\" 13 | libwebsockets_test_client_CFLAGS:= -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\" 14 | libwebsockets_test_server_extpoll_CFLAGS:= -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\" 15 | libwebsockets_test_fraggle_CFLAGS:= -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\" 16 | 17 | 18 | if NOPING 19 | else 20 | bin_PROGRAMS+=libwebsockets-test-ping 21 | libwebsockets_test_ping_SOURCES=test-ping.c 22 | libwebsockets_test_ping_LDADD=-L../lib -lwebsockets 23 | libwebsockets_test_ping_CFLAGS:= -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\" 24 | endif 25 | 26 | 27 | # 28 | # cook a random test cert and key 29 | # notice your real cert and key will want to be 0600 permissions 30 | libwebsockets-test-server.pem libwebsockets-test-server.key.pem: 31 | printf "GB\nErewhon\nAll around\nlibwebsockets-test\n\nlocalhost\nnone@invalid.org\n" | \ 32 | openssl req -new -newkey rsa:1024 -days 10000 -nodes -x509 -keyout \ 33 | ./libwebsockets-test-server.key.pem -out ./libwebsockets-test-server.pem >/dev/null 2>&1 && \ 34 | chmod 644 ./libwebsockets-test-server.key.pem \ 35 | ./libwebsockets-test-server.pem 36 | 37 | clean-local: 38 | rm -f ./libwebsockets-test-server.key.pem ./libwebsockets-test-server.pem 39 | 40 | install-data-local:libwebsockets-test-server.key.pem libwebsockets-test-server.pem 41 | mkdir -p $(DESTDIR)$(datadir)/libwebsockets-test-server 42 | cp -a test.html favicon.ico libwebsockets-test-server.key.pem libwebsockets-test-server.pem \ 43 | $(DESTDIR)$(datadir)/libwebsockets-test-server 44 | 45 | -------------------------------------------------------------------------------- /lib/extension-x-google-mux.h: -------------------------------------------------------------------------------- 1 | 2 | #if 0 3 | #ifdef WIN32 4 | static 5 | #else 6 | static inline 7 | #endif 8 | void muxdebug(const char *format, ...) 9 | { 10 | va_list ap; 11 | va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); 12 | } 13 | #else 14 | #ifdef WIN32 15 | static 16 | #else 17 | static inline 18 | #endif 19 | void muxdebug(const char *format, ...) 20 | { 21 | } 22 | #endif 23 | 24 | #define MAX_XGM_SUBCHANNELS 8192 25 | 26 | enum lws_ext_x_google_mux__parser_states { 27 | LWS_EXT_XGM_STATE__MUX_BLOCK_1, 28 | LWS_EXT_XGM_STATE__MUX_BLOCK_2, 29 | LWS_EXT_XGM_STATE__MUX_BLOCK_3, 30 | LWS_EXT_XGM_STATE__ADDCHANNEL_LEN, 31 | LWS_EXT_XGM_STATE__ADDCHANNEL_LEN16_1, 32 | LWS_EXT_XGM_STATE__ADDCHANNEL_LEN16_2, 33 | LWS_EXT_XGM_STATE__ADDCHANNEL_LEN32_1, 34 | LWS_EXT_XGM_STATE__ADDCHANNEL_LEN32_2, 35 | LWS_EXT_XGM_STATE__ADDCHANNEL_LEN32_3, 36 | LWS_EXT_XGM_STATE__ADDCHANNEL_LEN32_4, 37 | LWS_EXT_XGM_STATE__ADDCHANNEL_HEADERS, 38 | LWS_EXT_XGM_STATE__FLOWCONTROL_1, 39 | LWS_EXT_XGM_STATE__FLOWCONTROL_2, 40 | LWS_EXT_XGM_STATE__FLOWCONTROL_3, 41 | LWS_EXT_XGM_STATE__FLOWCONTROL_4, 42 | LWS_EXT_XGM_STATE__DATA, 43 | }; 44 | 45 | enum lws_ext_x_goole_mux__mux_opcodes { 46 | LWS_EXT_XGM_OPC__DATA, 47 | LWS_EXT_XGM_OPC__ADDCHANNEL, 48 | LWS_EXT_XGM_OPC__DROPCHANNEL, 49 | LWS_EXT_XGM_OPC__FLOWCONTROL, 50 | LWS_EXT_XGM_OPC__RESERVED_4, 51 | LWS_EXT_XGM_OPC__RESERVED_5, 52 | LWS_EXT_XGM_OPC__RESERVED_6, 53 | LWS_EXT_XGM_OPC__RESERVED_7, 54 | }; 55 | 56 | /* one of these per context (server or client) */ 57 | 58 | struct lws_ext_x_google_mux_context { 59 | /* 60 | * these are listing physical connections, not children sharing a 61 | * parent mux physical connection 62 | */ 63 | struct libwebsocket *wsi_muxconns[MAX_CLIENTS]; 64 | /* 65 | * when this is < 2, we do not do any mux blocks 66 | * just pure websockets 67 | */ 68 | int active_conns; 69 | }; 70 | 71 | /* one of these per connection (server or client) */ 72 | 73 | struct lws_ext_x_google_mux_conn { 74 | enum lws_ext_x_goole_mux__mux_opcodes block_subopcode; 75 | int block_subchannel; 76 | unsigned int length; 77 | enum lws_ext_x_google_mux__parser_states state; 78 | /* child points to the mux wsi using this */ 79 | struct libwebsocket *wsi_parent; 80 | int subchannel; 81 | struct libwebsocket *wsi_children[MAX_CLIENTS]; 82 | int highest_child_subchannel; 83 | char awaiting_POLLOUT; 84 | int count_children_needing_POLLOUT; 85 | int sticky_mux_used; 86 | int defeat_mux_opcode_wrapping; 87 | int original_ch1_closed; 88 | int ignore_cmd; 89 | }; 90 | 91 | extern int 92 | lws_extension_callback_x_google_mux(struct libwebsocket_context *context, 93 | struct libwebsocket_extension *ext, 94 | struct libwebsocket *wsi, 95 | enum libwebsocket_extension_callback_reasons reason, 96 | void *user, void *in, size_t len); 97 | -------------------------------------------------------------------------------- /win32port/libwebsocketswin32/libwebsocketswin32.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | 50 | 51 | Header Files 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | Header Files 61 | 62 | 63 | Source Files 64 | 65 | 66 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ([2.66]) 5 | AC_INIT(libwebsockets, 0.3, andy@warmcat.com) 6 | AC_CONFIG_SRCDIR([test-server/test-server.c]) 7 | AC_CONFIG_HEADERS([config.h]) 8 | 9 | AM_INIT_AUTOMAKE([-Wall -Werror foreign]) 10 | LT_INIT(shared) 11 | 12 | #AX_PTHREAD 13 | 14 | # Checks for programs. 15 | AC_PROG_CC 16 | AC_PROG_INSTALL 17 | AC_PROG_MAKE_SET 18 | AC_CONFIG_MACRO_DIR([m4]) 19 | 20 | 21 | # 22 | # 23 | # 24 | AC_ARG_ENABLE(openssl, 25 | [ --enable-openssl Enables https support and needs openssl libs], 26 | [ openssl=yes 27 | ]) 28 | 29 | if test "x$openssl" = "xyes" ; then 30 | AC_CHECK_LIB([ssl], [SSL_library_init]) 31 | CFLAGS="$CFLAGS -DLWS_OPENSSL_SUPPORT" 32 | fi 33 | 34 | # 35 | # 36 | # 37 | AC_ARG_ENABLE(nofork, 38 | [ --enable-nofork Disables fork-related options], 39 | [ nofork=yes 40 | ]) 41 | 42 | if test "x$nofork" = "xyes" ; then 43 | CFLAGS="$CFLAGS -DLWS_NO_FORK" 44 | else 45 | AC_FUNC_FORK 46 | fi 47 | 48 | # 49 | # 50 | # 51 | AC_ARG_ENABLE(libcrypto, 52 | [ --enable-libcrypto Use libcrypto MD5 and SHA1 implementations], 53 | [ libcrypto=yes 54 | ]) 55 | 56 | if test "x$libcrypto" = "xyes" ; then 57 | CFLAGS="$CFLAGS -DLWS_LIBCRYPTO" 58 | LDFLAGS="$LDFLAGS -lcrypto" 59 | fi 60 | AM_CONDITIONAL(LIBCRYPTO, test x$libcrypto = xyes) 61 | 62 | 63 | # 64 | # 65 | # 66 | AC_ARG_ENABLE(x-google-mux, 67 | [ --enable-x-google-mux Build experimental x-google-mux], 68 | [ x_google_mux=yes 69 | ]) 70 | if test "x$x_google_mux" = "xyes" ; then 71 | CFLAGS="$CFLAGS -DLWS_EXT_GOOGLE_MUX" 72 | fi 73 | AM_CONDITIONAL(EXT_GOOGLE_MUX, test x$x_google_mux = xyes) 74 | 75 | 76 | # 77 | # 78 | # 79 | AC_ARG_WITH([client-cert-dir], 80 | [AS_HELP_STRING([--with-client-cert-dir],[directory containing client certs, defaults to /etc/pki/tls/certs/])], 81 | [clientcertdir=$withval], 82 | [clientcertdir=/etc/pki/tls/certs/] 83 | ) 84 | AC_SUBST([clientcertdir]) 85 | 86 | AC_SUBST([CFLAGS]) 87 | 88 | 89 | # 90 | # 91 | # 92 | AC_ARG_ENABLE(noping, 93 | [ --enable-noping Do not build ping test app, which has some unixy stuff in sources], 94 | [ noping=yes 95 | ]) 96 | 97 | AM_CONDITIONAL(NOPING, test x$noping = xyes) 98 | 99 | 100 | 101 | # Checks for header files. 102 | AC_CHECK_HEADERS([zlib.h fcntl.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h]) 103 | 104 | # Checks for typedefs, structures, and compiler characteristics. 105 | AC_TYPE_SIZE_T 106 | 107 | # Checks for library functions. 108 | 109 | AC_FUNC_MALLOC 110 | AC_FUNC_REALLOC 111 | AC_CHECK_FUNCS([bzero memset socket strerror]) 112 | 113 | AC_CONFIG_FILES([Makefile 114 | lib/Makefile 115 | test-server/Makefile]) 116 | 117 | AC_OUTPUT 118 | -------------------------------------------------------------------------------- /win32port/zlib/compress.c: -------------------------------------------------------------------------------- 1 | /* compress.c -- compress a memory buffer 2 | * Copyright (C) 1995-2005 Jean-loup Gailly. 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #define ZLIB_INTERNAL 9 | #include "zlib.h" 10 | 11 | /* =========================================================================== 12 | Compresses the source buffer into the destination buffer. The level 13 | parameter has the same meaning as in deflateInit. sourceLen is the byte 14 | length of the source buffer. Upon entry, destLen is the total size of the 15 | destination buffer, which must be at least 0.1% larger than sourceLen plus 16 | 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. 17 | 18 | compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough 19 | memory, Z_BUF_ERROR if there was not enough room in the output buffer, 20 | Z_STREAM_ERROR if the level parameter is invalid. 21 | */ 22 | int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) 23 | Bytef *dest; 24 | uLongf *destLen; 25 | const Bytef *source; 26 | uLong sourceLen; 27 | int level; 28 | { 29 | z_stream stream; 30 | int err; 31 | 32 | stream.next_in = (Bytef*)source; 33 | stream.avail_in = (uInt)sourceLen; 34 | #ifdef MAXSEG_64K 35 | /* Check for source > 64K on 16-bit machine: */ 36 | if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; 37 | #endif 38 | stream.next_out = dest; 39 | stream.avail_out = (uInt)*destLen; 40 | if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; 41 | 42 | stream.zalloc = (alloc_func)0; 43 | stream.zfree = (free_func)0; 44 | stream.opaque = (voidpf)0; 45 | 46 | err = deflateInit(&stream, level); 47 | if (err != Z_OK) return err; 48 | 49 | err = deflate(&stream, Z_FINISH); 50 | if (err != Z_STREAM_END) { 51 | deflateEnd(&stream); 52 | return err == Z_OK ? Z_BUF_ERROR : err; 53 | } 54 | *destLen = stream.total_out; 55 | 56 | err = deflateEnd(&stream); 57 | return err; 58 | } 59 | 60 | /* =========================================================================== 61 | */ 62 | int ZEXPORT compress (dest, destLen, source, sourceLen) 63 | Bytef *dest; 64 | uLongf *destLen; 65 | const Bytef *source; 66 | uLong sourceLen; 67 | { 68 | return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); 69 | } 70 | 71 | /* =========================================================================== 72 | If the default memLevel or windowBits for deflateInit() is changed, then 73 | this function needs to be updated. 74 | */ 75 | uLong ZEXPORT compressBound (sourceLen) 76 | uLong sourceLen; 77 | { 78 | return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 79 | (sourceLen >> 25) + 13; 80 | } 81 | -------------------------------------------------------------------------------- /win32port/zlib/inftrees.h: -------------------------------------------------------------------------------- 1 | /* inftrees.h -- header to use inftrees.c 2 | * Copyright (C) 1995-2005, 2010 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* WARNING: this file should *not* be used by applications. It is 7 | part of the implementation of the compression library and is 8 | subject to change. Applications should only use zlib.h. 9 | */ 10 | 11 | /* Structure for decoding tables. Each entry provides either the 12 | information needed to do the operation requested by the code that 13 | indexed that table entry, or it provides a pointer to another 14 | table that indexes more bits of the code. op indicates whether 15 | the entry is a pointer to another table, a literal, a length or 16 | distance, an end-of-block, or an invalid code. For a table 17 | pointer, the low four bits of op is the number of index bits of 18 | that table. For a length or distance, the low four bits of op 19 | is the number of extra bits to get after the code. bits is 20 | the number of bits in this code or part of the code to drop off 21 | of the bit buffer. val is the actual byte to output in the case 22 | of a literal, the base length or distance, or the offset from 23 | the current table to the next table. Each entry is four bytes. */ 24 | typedef struct { 25 | unsigned char op; /* operation, extra bits, table bits */ 26 | unsigned char bits; /* bits in this part of the code */ 27 | unsigned short val; /* offset in table or code value */ 28 | } code; 29 | 30 | /* op values as set by inflate_table(): 31 | 00000000 - literal 32 | 0000tttt - table link, tttt != 0 is the number of table index bits 33 | 0001eeee - length or distance, eeee is the number of extra bits 34 | 01100000 - end of block 35 | 01000000 - invalid code 36 | */ 37 | 38 | /* Maximum size of the dynamic table. The maximum number of code structures is 39 | 1444, which is the sum of 852 for literal/length codes and 592 for distance 40 | codes. These values were found by exhaustive searches using the program 41 | examples/enough.c found in the zlib distribtution. The arguments to that 42 | program are the number of symbols, the initial root table size, and the 43 | maximum bit length of a code. "enough 286 9 15" for literal/length codes 44 | returns returns 852, and "enough 30 6 15" for distance codes returns 592. 45 | The initial root table size (9 or 6) is found in the fifth argument of the 46 | inflate_table() calls in inflate.c and infback.c. If the root table size is 47 | changed, then these maximum sizes would be need to be recalculated and 48 | updated. */ 49 | #define ENOUGH_LENS 852 50 | #define ENOUGH_DISTS 592 51 | #define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) 52 | 53 | /* Type of code to build for inflate_table() */ 54 | typedef enum { 55 | CODES, 56 | LENS, 57 | DISTS 58 | } codetype; 59 | 60 | int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, 61 | unsigned codes, code FAR * FAR *table, 62 | unsigned FAR *bits, unsigned short FAR *work)); 63 | -------------------------------------------------------------------------------- /win32port/zlib/ZLib.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {2e5deede-b2ef-40bd-950a-a7f7f0fc0413} 6 | cpp;c;cxx;rc;def;r;odl;idl;hpj;bat 7 | 8 | 9 | {85d35343-9068-43e8-875e-60b528a03c9b} 10 | h;hpp;hxx;hm;inl 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | Source Files 22 | 23 | 24 | Source Files 25 | 26 | 27 | Source Files 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | Source Files 49 | 50 | 51 | Source Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | 61 | 62 | Header Files 63 | 64 | 65 | Header Files 66 | 67 | 68 | Header Files 69 | 70 | 71 | Header Files 72 | 73 | 74 | Header Files 75 | 76 | 77 | Header Files 78 | 79 | 80 | Header Files 81 | 82 | 83 | Header Files 84 | 85 | 86 | Header Files 87 | 88 | 89 | Header Files 90 | 91 | 92 | Header Files 93 | 94 | 95 | -------------------------------------------------------------------------------- /config.h.in: -------------------------------------------------------------------------------- 1 | /* config.h.in. Generated from configure.ac by autoheader. */ 2 | 3 | /* Define to 1 if you have the `bzero' function. */ 4 | #undef HAVE_BZERO 5 | 6 | /* Define to 1 if you have the header file. */ 7 | #undef HAVE_DLFCN_H 8 | 9 | /* Define to 1 if you have the header file. */ 10 | #undef HAVE_FCNTL_H 11 | 12 | /* Define to 1 if you have the `fork' function. */ 13 | #undef HAVE_FORK 14 | 15 | /* Define to 1 if you have the header file. */ 16 | #undef HAVE_INTTYPES_H 17 | 18 | /* Define to 1 if you have the `ssl' library (-lssl). */ 19 | #undef HAVE_LIBSSL 20 | 21 | /* Define to 1 if your system has a GNU libc compatible `malloc' function, and 22 | to 0 otherwise. */ 23 | #undef HAVE_MALLOC 24 | 25 | /* Define to 1 if you have the header file. */ 26 | #undef HAVE_MEMORY_H 27 | 28 | /* Define to 1 if you have the `memset' function. */ 29 | #undef HAVE_MEMSET 30 | 31 | /* Define to 1 if you have the header file. */ 32 | #undef HAVE_NETINET_IN_H 33 | 34 | /* Define to 1 if your system has a GNU libc compatible `realloc' function, 35 | and to 0 otherwise. */ 36 | #undef HAVE_REALLOC 37 | 38 | /* Define to 1 if you have the `socket' function. */ 39 | #undef HAVE_SOCKET 40 | 41 | /* Define to 1 if you have the header file. */ 42 | #undef HAVE_STDINT_H 43 | 44 | /* Define to 1 if you have the header file. */ 45 | #undef HAVE_STDLIB_H 46 | 47 | /* Define to 1 if you have the `strerror' function. */ 48 | #undef HAVE_STRERROR 49 | 50 | /* Define to 1 if you have the header file. */ 51 | #undef HAVE_STRINGS_H 52 | 53 | /* Define to 1 if you have the header file. */ 54 | #undef HAVE_STRING_H 55 | 56 | /* Define to 1 if you have the header file. */ 57 | #undef HAVE_SYS_SOCKET_H 58 | 59 | /* Define to 1 if you have the header file. */ 60 | #undef HAVE_SYS_STAT_H 61 | 62 | /* Define to 1 if you have the header file. */ 63 | #undef HAVE_SYS_TYPES_H 64 | 65 | /* Define to 1 if you have the header file. */ 66 | #undef HAVE_UNISTD_H 67 | 68 | /* Define to 1 if you have the `vfork' function. */ 69 | #undef HAVE_VFORK 70 | 71 | /* Define to 1 if you have the header file. */ 72 | #undef HAVE_VFORK_H 73 | 74 | /* Define to 1 if `fork' works. */ 75 | #undef HAVE_WORKING_FORK 76 | 77 | /* Define to 1 if `vfork' works. */ 78 | #undef HAVE_WORKING_VFORK 79 | 80 | /* Define to 1 if you have the header file. */ 81 | #undef HAVE_ZLIB_H 82 | 83 | /* Define to the sub-directory in which libtool stores uninstalled libraries. 84 | */ 85 | #undef LT_OBJDIR 86 | 87 | /* Name of package */ 88 | #undef PACKAGE 89 | 90 | /* Define to the address where bug reports for this package should be sent. */ 91 | #undef PACKAGE_BUGREPORT 92 | 93 | /* Define to the full name of this package. */ 94 | #undef PACKAGE_NAME 95 | 96 | /* Define to the full name and version of this package. */ 97 | #undef PACKAGE_STRING 98 | 99 | /* Define to the one symbol short name of this package. */ 100 | #undef PACKAGE_TARNAME 101 | 102 | /* Define to the home page for this package. */ 103 | #undef PACKAGE_URL 104 | 105 | /* Define to the version of this package. */ 106 | #undef PACKAGE_VERSION 107 | 108 | /* Define to 1 if you have the ANSI C header files. */ 109 | #undef STDC_HEADERS 110 | 111 | /* Version number of package */ 112 | #undef VERSION 113 | 114 | /* Define to rpl_malloc if the replacement function should be used. */ 115 | #undef malloc 116 | 117 | /* Define to `int' if does not define. */ 118 | #undef pid_t 119 | 120 | /* Define to rpl_realloc if the replacement function should be used. */ 121 | #undef realloc 122 | 123 | /* Define to `unsigned int' if does not define. */ 124 | #undef size_t 125 | 126 | /* Define as `fork' if `vfork' does not work. */ 127 | #undef vfork 128 | -------------------------------------------------------------------------------- /lib/extension-deflate-stream.c: -------------------------------------------------------------------------------- 1 | #include "private-libwebsockets.h" 2 | #include "extension-deflate-stream.h" 3 | #include 4 | #include 5 | #include 6 | 7 | #define LWS_ZLIB_WINDOW_BITS 15 8 | #define LWS_ZLIB_MEMLEVEL 8 9 | 10 | int lws_extension_callback_deflate_stream( 11 | struct libwebsocket_context *context, 12 | struct libwebsocket_extension *ext, 13 | struct libwebsocket *wsi, 14 | enum libwebsocket_extension_callback_reasons reason, 15 | void *user, void *in, size_t len) 16 | { 17 | struct lws_ext_deflate_stream_conn *conn = 18 | (struct lws_ext_deflate_stream_conn *)user; 19 | int n; 20 | struct lws_tokens *eff_buf = (struct lws_tokens *)in; 21 | 22 | switch (reason) { 23 | 24 | /* 25 | * for deflate-stream, both client and server sides act the same 26 | */ 27 | 28 | case LWS_EXT_CALLBACK_CLIENT_CONSTRUCT: 29 | case LWS_EXT_CALLBACK_CONSTRUCT: 30 | conn->zs_in.zalloc = conn->zs_out.zalloc = Z_NULL; 31 | conn->zs_in.zfree = conn->zs_out.zfree = Z_NULL; 32 | conn->zs_in.opaque = conn->zs_out.opaque = Z_NULL; 33 | n = inflateInit2(&conn->zs_in, -LWS_ZLIB_WINDOW_BITS); 34 | if (n != Z_OK) { 35 | fprintf(stderr, "deflateInit returned %d\n", n); 36 | return 1; 37 | } 38 | n = deflateInit2(&conn->zs_out, 39 | DEFLATE_STREAM_COMPRESSION_LEVEL, Z_DEFLATED, 40 | -LWS_ZLIB_WINDOW_BITS, LWS_ZLIB_MEMLEVEL, 41 | Z_DEFAULT_STRATEGY); 42 | if (n != Z_OK) { 43 | fprintf(stderr, "deflateInit returned %d\n", n); 44 | return 1; 45 | } 46 | fprintf(stderr, "zlibs constructed\n"); 47 | break; 48 | 49 | case LWS_EXT_CALLBACK_DESTROY: 50 | (void)inflateEnd(&conn->zs_in); 51 | (void)deflateEnd(&conn->zs_out); 52 | fprintf(stderr, "zlibs destructed\n"); 53 | break; 54 | 55 | case LWS_EXT_CALLBACK_PACKET_RX_PREPARSE: 56 | 57 | /* 58 | * inflate the incoming compressed data 59 | * Notice, length may be 0 and pointer NULL 60 | * in the case we are flushing with nothing new coming in 61 | */ 62 | 63 | conn->zs_in.next_in = (unsigned char *)eff_buf->token; 64 | conn->zs_in.avail_in = eff_buf->token_len; 65 | 66 | conn->zs_in.next_out = conn->buf; 67 | conn->zs_in.avail_out = sizeof(conn->buf); 68 | 69 | n = inflate(&conn->zs_in, Z_SYNC_FLUSH); 70 | switch (n) { 71 | case Z_NEED_DICT: 72 | case Z_DATA_ERROR: 73 | case Z_MEM_ERROR: 74 | /* 75 | * screwed.. close the connection... we will get a 76 | * destroy callback to take care of closing nicely 77 | */ 78 | fprintf(stderr, "zlib error inflate %d\n", n); 79 | return -1; 80 | } 81 | 82 | /* rewrite the buffer pointers and length */ 83 | 84 | eff_buf->token = (char *)conn->buf; 85 | eff_buf->token_len = sizeof(conn->buf) - conn->zs_in.avail_out; 86 | 87 | /* 88 | * if we filled the output buffer, signal that we likely have 89 | * more and need to be called again 90 | */ 91 | 92 | if (eff_buf->token_len == sizeof(conn->buf)) 93 | return 1; 94 | 95 | /* we don't need calling again until new input data comes */ 96 | 97 | return 0; 98 | 99 | case LWS_EXT_CALLBACK_FLUSH_PENDING_TX: 100 | case LWS_EXT_CALLBACK_PACKET_TX_PRESEND: 101 | 102 | /* 103 | * deflate the outgoing compressed data 104 | */ 105 | 106 | conn->zs_out.next_in = (unsigned char *)eff_buf->token; 107 | conn->zs_out.avail_in = eff_buf->token_len; 108 | 109 | conn->zs_out.next_out = conn->buf; 110 | conn->zs_out.avail_out = sizeof(conn->buf); 111 | 112 | n = Z_PARTIAL_FLUSH; 113 | if (reason == LWS_EXT_CALLBACK_FLUSH_PENDING_TX) 114 | n = Z_FULL_FLUSH; 115 | 116 | n = deflate(&conn->zs_out, n); 117 | if (n == Z_STREAM_ERROR) { 118 | /* 119 | * screwed.. close the connection... we will get a 120 | * destroy callback to take care of closing nicely 121 | */ 122 | fprintf(stderr, "zlib error deflate\n"); 123 | 124 | return -1; 125 | } 126 | 127 | /* rewrite the buffer pointers and length */ 128 | 129 | eff_buf->token = (char *)conn->buf; 130 | eff_buf->token_len = sizeof(conn->buf) - conn->zs_out.avail_out; 131 | 132 | /* 133 | * if we filled the output buffer, signal that we likely have 134 | * more and need to be called again... even in deflate case 135 | * we might sometimes need to spill more than came in 136 | */ 137 | 138 | if (eff_buf->token_len == sizeof(conn->buf)) 139 | return 1; 140 | 141 | /* we don't need calling again until new input data comes */ 142 | 143 | return 0; 144 | 145 | default: 146 | break; 147 | } 148 | 149 | return 0; 150 | } 151 | -------------------------------------------------------------------------------- /win32port/win32helpers/getopt.c: -------------------------------------------------------------------------------- 1 | /* $NetBSD: getopt.c,v 1.16 1999/12/02 13:15:56 kleink Exp $ */ 2 | 3 | /* 4 | * Copyright (c) 1987, 1993, 1994 5 | * The Regents of the University of California. All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. All advertising materials mentioning features or use of this software 16 | * must display the following acknowledgement: 17 | * This product includes software developed by the University of 18 | * California, Berkeley and its contributors. 19 | * 4. Neither the name of the University nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 | * SUCH DAMAGE. 34 | */ 35 | 36 | #if 0 37 | static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; 38 | #endif 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #define __P(x) x 46 | #define _DIAGASSERT(x) assert(x) 47 | 48 | #ifdef __weak_alias 49 | __weak_alias(getopt,_getopt); 50 | #endif 51 | 52 | 53 | int opterr = 1, /* if error message should be printed */ 54 | optind = 1, /* index into parent argv vector */ 55 | optopt, /* character checked for validity */ 56 | optreset; /* reset getopt */ 57 | char *optarg; /* argument associated with option */ 58 | 59 | static char * _progname __P((char *)); 60 | int getopt_internal __P((int, char * const *, const char *)); 61 | 62 | static char * 63 | _progname(nargv0) 64 | char * nargv0; 65 | { 66 | char * tmp; 67 | 68 | _DIAGASSERT(nargv0 != NULL); 69 | 70 | tmp = strrchr(nargv0, '/'); 71 | if (tmp) 72 | tmp++; 73 | else 74 | tmp = nargv0; 75 | return(tmp); 76 | } 77 | 78 | #define BADCH (int)'?' 79 | #define BADARG (int)':' 80 | #define EMSG "" 81 | 82 | /* 83 | * getopt -- 84 | * Parse argc/argv argument vector. 85 | */ 86 | int 87 | getopt(nargc, nargv, ostr) 88 | int nargc; 89 | char * const nargv[]; 90 | const char *ostr; 91 | { 92 | static char *__progname = 0; 93 | static char *place = EMSG; /* option letter processing */ 94 | char *oli; /* option letter list index */ 95 | __progname = __progname?__progname:_progname(*nargv); 96 | 97 | _DIAGASSERT(nargv != NULL); 98 | _DIAGASSERT(ostr != NULL); 99 | 100 | if (optreset || !*place) { /* update scanning pointer */ 101 | optreset = 0; 102 | if (optind >= nargc || *(place = nargv[optind]) != '-') { 103 | place = EMSG; 104 | return (-1); 105 | } 106 | if (place[1] && *++place == '-' /* found "--" */ 107 | && place[1] == '\0') { 108 | ++optind; 109 | place = EMSG; 110 | return (-1); 111 | } 112 | } /* option letter okay? */ 113 | if ((optopt = (int)*place++) == (int)':' || 114 | !(oli = strchr(ostr, optopt))) { 115 | /* 116 | * if the user didn't specify '-' as an option, 117 | * assume it means -1. 118 | */ 119 | if (optopt == (int)'-') 120 | return (-1); 121 | if (!*place) 122 | ++optind; 123 | if (opterr && *ostr != ':') 124 | (void)fprintf(stderr, 125 | "%s: illegal option -- %c\n", __progname, optopt); 126 | return (BADCH); 127 | } 128 | if (*++oli != ':') { /* don't need argument */ 129 | optarg = NULL; 130 | if (!*place) 131 | ++optind; 132 | } 133 | else { /* need an argument */ 134 | if (*place) /* no white space */ 135 | optarg = place; 136 | else if (nargc <= ++optind) { /* no arg */ 137 | place = EMSG; 138 | if (*ostr == ':') 139 | return (BADARG); 140 | if (opterr) 141 | (void)fprintf(stderr, 142 | "%s: option requires an argument -- %c\n", 143 | __progname, optopt); 144 | return (BADCH); 145 | } 146 | else /* white space */ 147 | optarg = nargv[optind]; 148 | place = EMSG; 149 | ++optind; 150 | } 151 | return (optopt); /* dump back option letter */ 152 | } 153 | 154 | -------------------------------------------------------------------------------- /lib/base64-decode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This code originally came from here 3 | * 4 | * http://base64.sourceforge.net/b64.c 5 | * 6 | * with the following license: 7 | * 8 | * LICENCE: Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc. 9 | * 10 | * Permission is hereby granted, free of charge, to any person 11 | * obtaining a copy of this software and associated 12 | * documentation files (the "Software"), to deal in the 13 | * Software without restriction, including without limitation 14 | * the rights to use, copy, modify, merge, publish, distribute, 15 | * sublicense, and/or sell copies of the Software, and to 16 | * permit persons to whom the Software is furnished to do so, 17 | * subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall 20 | * be included in all copies or substantial portions of the 21 | * Software. 22 | * 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 24 | * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 25 | * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 26 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS 27 | * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 28 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 29 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 30 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 | * 32 | * VERSION HISTORY: 33 | * Bob Trower 08/04/01 -- Create Version 0.00.00B 34 | * 35 | * I cleaned it up quite a bit to match the (linux kernel) style of the rest 36 | * of libwebsockets; this version is under LGPL2 like the rest of libwebsockets 37 | * since he explictly allows sublicensing, but I give the URL above so you can 38 | * get the original with Bob's super-liberal terms directly if you prefer. 39 | */ 40 | 41 | 42 | #include 43 | #include 44 | 45 | static const char encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 46 | "abcdefghijklmnopqrstuvwxyz0123456789+/"; 47 | static const char decode[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW" 48 | "$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; 49 | 50 | int 51 | lws_b64_encode_string(const char *in, int in_len, char *out, int out_size) 52 | { 53 | unsigned char triple[3]; 54 | int i; 55 | int len; 56 | int line = 0; 57 | int done = 0; 58 | 59 | while (in_len) { 60 | len = 0; 61 | for (i = 0; i < 3; i++) { 62 | if (in_len) { 63 | triple[i] = *in++; 64 | len++; 65 | in_len--; 66 | } else 67 | triple[i] = 0; 68 | } 69 | if (len) { 70 | 71 | if (done + 4 >= out_size) 72 | return -1; 73 | 74 | *out++ = encode[triple[0] >> 2]; 75 | *out++ = encode[((triple[0] & 0x03) << 4) | 76 | ((triple[1] & 0xf0) >> 4)]; 77 | *out++ = (len > 1 ? encode[((triple[1] & 0x0f) << 2) | 78 | ((triple[2] & 0xc0) >> 6)] : '='); 79 | *out++ = (len > 2 ? encode[triple[2] & 0x3f] : '='); 80 | 81 | done += 4; 82 | line += 4; 83 | } 84 | #if 0 85 | if (line >= 72) { 86 | 87 | if (done + 2 >= out_size) 88 | return -1; 89 | 90 | *out++ = '\r'; 91 | *out++ = '\n'; 92 | done += 2; 93 | line = 0; 94 | } 95 | #endif 96 | } 97 | 98 | if (done + 1 >= out_size) 99 | return -1; 100 | 101 | *out++ = '\0'; 102 | 103 | return done; 104 | } 105 | 106 | /* 107 | * returns length of decoded string in out, or -1 if out was too small 108 | * according to out_size 109 | */ 110 | 111 | int 112 | lws_b64_decode_string(const char *in, char *out, int out_size) 113 | { 114 | int len; 115 | int i; 116 | int done = 0; 117 | unsigned char v; 118 | unsigned char quad[4]; 119 | 120 | while (*in) { 121 | 122 | len = 0; 123 | for (i = 0; i < 4 && *in; i++) { 124 | 125 | v = 0; 126 | while (*in && !v) { 127 | 128 | v = *in++; 129 | v = (v < 43 || v > 122) ? 0 : decode[v - 43]; 130 | if (v) 131 | v = (v == '$') ? 0 : v - 61; 132 | if (*in) { 133 | len++; 134 | if (v) 135 | quad[i] = v - 1; 136 | } else 137 | quad[i] = 0; 138 | } 139 | } 140 | if (!len) 141 | continue; 142 | 143 | if (out_size < (done + len - 1)) 144 | /* out buffer is too small */ 145 | return -1; 146 | 147 | if (len >= 2) 148 | *out++ = quad[0] << 2 | quad[1] >> 4; 149 | if (len >= 3) 150 | *out++ = quad[1] << 4 | quad[2] >> 2; 151 | if (len >= 4) 152 | *out++ = ((quad[2] << 6) & 0xc0) | quad[3]; 153 | 154 | done += len - 1; 155 | } 156 | 157 | if (done + 1 >= out_size) 158 | return -1; 159 | 160 | *out++ = '\0'; 161 | 162 | return done; 163 | } 164 | 165 | int 166 | lws_b64_selftest(void) 167 | { 168 | char buf[64]; 169 | int n; 170 | int test; 171 | static const char *plaintext[] = { 172 | "sanity check base 64" 173 | }; 174 | static const char *coded[] = { 175 | "c2FuaXR5IGNoZWNrIGJhc2UgNjQ=" 176 | }; 177 | 178 | for (test = 0; test < sizeof plaintext / sizeof(plaintext[0]); test++) { 179 | 180 | buf[sizeof(buf) - 1] = '\0'; 181 | n = lws_b64_encode_string(plaintext[test], 182 | strlen(plaintext[test]), buf, sizeof buf); 183 | if (n != strlen(coded[test]) || strcmp(buf, coded[test])) { 184 | fprintf(stderr, "Failed lws_b64 encode selftest " 185 | "%d result '%s' %d\n", test, buf, n); 186 | return -1; 187 | } 188 | 189 | buf[sizeof(buf) - 1] = '\0'; 190 | n = lws_b64_decode_string(coded[test], buf, sizeof buf); 191 | if (n != strlen(plaintext[test]) || 192 | strcmp(buf, plaintext[test])) { 193 | fprintf(stderr, "Failed lws_b64 decode selftest " 194 | "%d result '%s' %d\n", test, buf, n); 195 | return -1; 196 | } 197 | } 198 | 199 | return 0; 200 | } 201 | -------------------------------------------------------------------------------- /win32port/zlib/adler32.c: -------------------------------------------------------------------------------- 1 | /* adler32.c -- compute the Adler-32 checksum of a data stream 2 | * Copyright (C) 1995-2007 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #include "zutil.h" 9 | 10 | #define local static 11 | 12 | local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2); 13 | 14 | #define BASE 65521UL /* largest prime smaller than 65536 */ 15 | #define NMAX 5552 16 | /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ 17 | 18 | #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} 19 | #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); 20 | #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); 21 | #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); 22 | #define DO16(buf) DO8(buf,0); DO8(buf,8); 23 | 24 | /* use NO_DIVIDE if your processor does not do division in hardware */ 25 | #ifdef NO_DIVIDE 26 | # define MOD(a) \ 27 | do { \ 28 | if (a >= (BASE << 16)) a -= (BASE << 16); \ 29 | if (a >= (BASE << 15)) a -= (BASE << 15); \ 30 | if (a >= (BASE << 14)) a -= (BASE << 14); \ 31 | if (a >= (BASE << 13)) a -= (BASE << 13); \ 32 | if (a >= (BASE << 12)) a -= (BASE << 12); \ 33 | if (a >= (BASE << 11)) a -= (BASE << 11); \ 34 | if (a >= (BASE << 10)) a -= (BASE << 10); \ 35 | if (a >= (BASE << 9)) a -= (BASE << 9); \ 36 | if (a >= (BASE << 8)) a -= (BASE << 8); \ 37 | if (a >= (BASE << 7)) a -= (BASE << 7); \ 38 | if (a >= (BASE << 6)) a -= (BASE << 6); \ 39 | if (a >= (BASE << 5)) a -= (BASE << 5); \ 40 | if (a >= (BASE << 4)) a -= (BASE << 4); \ 41 | if (a >= (BASE << 3)) a -= (BASE << 3); \ 42 | if (a >= (BASE << 2)) a -= (BASE << 2); \ 43 | if (a >= (BASE << 1)) a -= (BASE << 1); \ 44 | if (a >= BASE) a -= BASE; \ 45 | } while (0) 46 | # define MOD4(a) \ 47 | do { \ 48 | if (a >= (BASE << 4)) a -= (BASE << 4); \ 49 | if (a >= (BASE << 3)) a -= (BASE << 3); \ 50 | if (a >= (BASE << 2)) a -= (BASE << 2); \ 51 | if (a >= (BASE << 1)) a -= (BASE << 1); \ 52 | if (a >= BASE) a -= BASE; \ 53 | } while (0) 54 | #else 55 | # define MOD(a) a %= BASE 56 | # define MOD4(a) a %= BASE 57 | #endif 58 | 59 | /* ========================================================================= */ 60 | uLong ZEXPORT adler32(adler, buf, len) 61 | uLong adler; 62 | const Bytef *buf; 63 | uInt len; 64 | { 65 | unsigned long sum2; 66 | unsigned n; 67 | 68 | /* split Adler-32 into component sums */ 69 | sum2 = (adler >> 16) & 0xffff; 70 | adler &= 0xffff; 71 | 72 | /* in case user likes doing a byte at a time, keep it fast */ 73 | if (len == 1) { 74 | adler += buf[0]; 75 | if (adler >= BASE) 76 | adler -= BASE; 77 | sum2 += adler; 78 | if (sum2 >= BASE) 79 | sum2 -= BASE; 80 | return adler | (sum2 << 16); 81 | } 82 | 83 | /* initial Adler-32 value (deferred check for len == 1 speed) */ 84 | if (buf == Z_NULL) 85 | return 1L; 86 | 87 | /* in case short lengths are provided, keep it somewhat fast */ 88 | if (len < 16) { 89 | while (len--) { 90 | adler += *buf++; 91 | sum2 += adler; 92 | } 93 | if (adler >= BASE) 94 | adler -= BASE; 95 | MOD4(sum2); /* only added so many BASE's */ 96 | return adler | (sum2 << 16); 97 | } 98 | 99 | /* do length NMAX blocks -- requires just one modulo operation */ 100 | while (len >= NMAX) { 101 | len -= NMAX; 102 | n = NMAX / 16; /* NMAX is divisible by 16 */ 103 | do { 104 | DO16(buf); /* 16 sums unrolled */ 105 | buf += 16; 106 | } while (--n); 107 | MOD(adler); 108 | MOD(sum2); 109 | } 110 | 111 | /* do remaining bytes (less than NMAX, still just one modulo) */ 112 | if (len) { /* avoid modulos if none remaining */ 113 | while (len >= 16) { 114 | len -= 16; 115 | DO16(buf); 116 | buf += 16; 117 | } 118 | while (len--) { 119 | adler += *buf++; 120 | sum2 += adler; 121 | } 122 | MOD(adler); 123 | MOD(sum2); 124 | } 125 | 126 | /* return recombined sums */ 127 | return adler | (sum2 << 16); 128 | } 129 | 130 | /* ========================================================================= */ 131 | local uLong adler32_combine_(adler1, adler2, len2) 132 | uLong adler1; 133 | uLong adler2; 134 | z_off64_t len2; 135 | { 136 | unsigned long sum1; 137 | unsigned long sum2; 138 | unsigned rem; 139 | 140 | /* the derivation of this formula is left as an exercise for the reader */ 141 | rem = (unsigned)(len2 % BASE); 142 | sum1 = adler1 & 0xffff; 143 | sum2 = rem * sum1; 144 | MOD(sum2); 145 | sum1 += (adler2 & 0xffff) + BASE - 1; 146 | sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; 147 | if (sum1 >= BASE) sum1 -= BASE; 148 | if (sum1 >= BASE) sum1 -= BASE; 149 | if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); 150 | if (sum2 >= BASE) sum2 -= BASE; 151 | return sum1 | (sum2 << 16); 152 | } 153 | 154 | /* ========================================================================= */ 155 | uLong ZEXPORT adler32_combine(adler1, adler2, len2) 156 | uLong adler1; 157 | uLong adler2; 158 | z_off_t len2; 159 | { 160 | return adler32_combine_(adler1, adler2, len2); 161 | } 162 | 163 | uLong ZEXPORT adler32_combine64(adler1, adler2, len2) 164 | uLong adler1; 165 | uLong adler2; 166 | z_off64_t len2; 167 | { 168 | return adler32_combine_(adler1, adler2, len2); 169 | } 170 | -------------------------------------------------------------------------------- /lib/md5.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Modified from Polarssl here 3 | * http://polarssl.org/show_source?file=md5 4 | * under GPL2 or later 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | 11 | #define GET_ULONG_LE(n, b, i) \ 12 | { \ 13 | (n) = ((unsigned long)(b)[i]) \ 14 | | ((unsigned long)(b)[(i) + 1] << 8) \ 15 | | ((unsigned long)(b)[(i) + 2] << 16) \ 16 | | ((unsigned long)(b)[(i) + 3] << 24); \ 17 | } 18 | 19 | #define PUT_ULONG_LE(n, b, i) \ 20 | { \ 21 | (b)[i] = (unsigned char)(n); \ 22 | (b)[(i) + 1] = (unsigned char)((n) >> 8); \ 23 | (b)[(i) + 2] = (unsigned char)((n) >> 16); \ 24 | (b)[(i) + 3] = (unsigned char)((n) >> 24); \ 25 | } 26 | 27 | static const unsigned char md5_padding[64] = { 28 | 0x80, 0, 0, 0, 0, 0, 0, 0, 29 | 0, 0, 0, 0, 0, 0, 0, 0, 30 | 0, 0, 0, 0, 0, 0, 0, 0, 31 | 0, 0, 0, 0, 0, 0, 0, 0, 32 | 0, 0, 0, 0, 0, 0, 0, 0, 33 | 0, 0, 0, 0, 0, 0, 0, 0, 34 | 0, 0, 0, 0, 0, 0, 0, 0, 35 | 0, 0, 0, 0, 0, 0, 0, 0, 36 | }; 37 | 38 | static const unsigned long state_init[] = { 39 | 0, 0, 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476 40 | }; 41 | 42 | static void 43 | md5_process(unsigned long *state, const unsigned char *data) 44 | { 45 | unsigned long X[16], A, B, C, D; 46 | int v; 47 | 48 | for (v = 0; v < 16; v++) 49 | GET_ULONG_LE(X[v], data, v << 2); 50 | 51 | #define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 52 | 53 | #define P(a, b, c, d, k, s, t) { a += F(b, c, d) + X[k] + t; a = S(a, s) + b; } 54 | 55 | A = state[0]; 56 | B = state[1]; 57 | C = state[2]; 58 | D = state[3]; 59 | 60 | #define F(x, y, z) (z ^ (x & (y ^ z))) 61 | 62 | P(A, B, C, D, 0, 7, 0xD76AA478); 63 | P(D, A, B, C, 1, 12, 0xE8C7B756); 64 | P(C, D, A, B, 2, 17, 0x242070DB); 65 | P(B, C, D, A, 3, 22, 0xC1BDCEEE); 66 | P(A, B, C, D, 4, 7, 0xF57C0FAF); 67 | P(D, A, B, C, 5, 12, 0x4787C62A); 68 | P(C, D, A, B, 6, 17, 0xA8304613); 69 | P(B, C, D, A, 7, 22, 0xFD469501); 70 | P(A, B, C, D, 8, 7, 0x698098D8); 71 | P(D, A, B, C, 9, 12, 0x8B44F7AF); 72 | P(C, D, A, B, 10, 17, 0xFFFF5BB1); 73 | P(B, C, D, A, 11, 22, 0x895CD7BE); 74 | P(A, B, C, D, 12, 7, 0x6B901122); 75 | P(D, A, B, C, 13, 12, 0xFD987193); 76 | P(C, D, A, B, 14, 17, 0xA679438E); 77 | P(B, C, D, A, 15, 22, 0x49B40821); 78 | 79 | #undef F 80 | 81 | #define F(x, y, z) (y ^ (z & (x ^ y))) 82 | 83 | P(A, B, C, D, 1, 5, 0xF61E2562); 84 | P(D, A, B, C, 6, 9, 0xC040B340); 85 | P(C, D, A, B, 11, 14, 0x265E5A51); 86 | P(B, C, D, A, 0, 20, 0xE9B6C7AA); 87 | P(A, B, C, D, 5, 5, 0xD62F105D); 88 | P(D, A, B, C, 10, 9, 0x02441453); 89 | P(C, D, A, B, 15, 14, 0xD8A1E681); 90 | P(B, C, D, A, 4, 20, 0xE7D3FBC8); 91 | P(A, B, C, D, 9, 5, 0x21E1CDE6); 92 | P(D, A, B, C, 14, 9, 0xC33707D6); 93 | P(C, D, A, B, 3, 14, 0xF4D50D87); 94 | P(B, C, D, A, 8, 20, 0x455A14ED); 95 | P(A, B, C, D, 13, 5, 0xA9E3E905); 96 | P(D, A, B, C, 2, 9, 0xFCEFA3F8); 97 | P(C, D, A, B, 7, 14, 0x676F02D9); 98 | P(B, C, D, A, 12, 20, 0x8D2A4C8A); 99 | 100 | #undef F 101 | 102 | #define F(x, y, z) (x ^ y ^ z) 103 | 104 | P(A, B, C, D, 5, 4, 0xFFFA3942); 105 | P(D, A, B, C, 8, 11, 0x8771F681); 106 | P(C, D, A, B, 11, 16, 0x6D9D6122); 107 | P(B, C, D, A, 14, 23, 0xFDE5380C); 108 | P(A, B, C, D, 1, 4, 0xA4BEEA44); 109 | P(D, A, B, C, 4, 11, 0x4BDECFA9); 110 | P(C, D, A, B, 7, 16, 0xF6BB4B60); 111 | P(B, C, D, A, 10, 23, 0xBEBFBC70); 112 | P(A, B, C, D, 13, 4, 0x289B7EC6); 113 | P(D, A, B, C, 0, 11, 0xEAA127FA); 114 | P(C, D, A, B, 3, 16, 0xD4EF3085); 115 | P(B, C, D, A, 6, 23, 0x04881D05); 116 | P(A, B, C, D, 9, 4, 0xD9D4D039); 117 | P(D, A, B, C, 12, 11, 0xE6DB99E5); 118 | P(C, D, A, B, 15, 16, 0x1FA27CF8); 119 | P(B, C, D, A, 2, 23, 0xC4AC5665); 120 | 121 | #undef F 122 | 123 | #define F(x, y, z) (y ^ (x | ~z)) 124 | 125 | P(A, B, C, D, 0, 6, 0xF4292244); 126 | P(D, A, B, C, 7, 10, 0x432AFF97); 127 | P(C, D, A, B, 14, 15, 0xAB9423A7); 128 | P(B, C, D, A, 5, 21, 0xFC93A039); 129 | P(A, B, C, D, 12, 6, 0x655B59C3); 130 | P(D, A, B, C, 3, 10, 0x8F0CCC92); 131 | P(C, D, A, B, 10, 15, 0xFFEFF47D); 132 | P(B, C, D, A, 1, 21, 0x85845DD1); 133 | P(A, B, C, D, 8, 6, 0x6FA87E4F); 134 | P(D, A, B, C, 15, 10, 0xFE2CE6E0); 135 | P(C, D, A, B, 6, 15, 0xA3014314); 136 | P(B, C, D, A, 13, 21, 0x4E0811A1); 137 | P(A, B, C, D, 4, 6, 0xF7537E82); 138 | P(D, A, B, C, 11, 10, 0xBD3AF235); 139 | P(C, D, A, B, 2, 15, 0x2AD7D2BB); 140 | P(B, C, D, A, 9, 21, 0xEB86D391); 141 | 142 | #undef F 143 | 144 | state[0] += A; 145 | state[1] += B; 146 | state[2] += C; 147 | state[3] += D; 148 | } 149 | 150 | static 151 | void md5_update(unsigned long *state, unsigned char *buffer, 152 | const unsigned char *input, int ilen) 153 | { 154 | int fill; 155 | unsigned long left; 156 | 157 | if (ilen <= 0) 158 | return; 159 | 160 | left = state[0] & 0x3F; 161 | fill = 64 - left; 162 | 163 | state[0] += ilen; 164 | state[0] &= 0xFFFFFFFF; 165 | 166 | if (state[0] < (unsigned long)ilen) 167 | state[1]++; 168 | 169 | if (left && ilen >= fill) { 170 | memcpy(buffer + left, input, fill); 171 | md5_process(&state[2], buffer); 172 | input += fill; 173 | ilen -= fill; 174 | left = 0; 175 | } 176 | 177 | while (ilen >= 64) { 178 | md5_process(&state[2], input); 179 | input += 64; 180 | ilen -= 64; 181 | } 182 | 183 | if (ilen > 0) 184 | memcpy(buffer + left, input, ilen); 185 | } 186 | 187 | void 188 | MD5(const unsigned char *input, int ilen, unsigned char *output) 189 | { 190 | unsigned long last, padn; 191 | unsigned long high, low; 192 | unsigned char msglen[8]; 193 | unsigned long state[6]; 194 | unsigned char buffer[64]; 195 | 196 | memcpy(&state[0], &state_init[0], sizeof(state_init)); 197 | 198 | md5_update(state, buffer, input, ilen); 199 | 200 | high = (state[0] >> 29) | (state[1] << 3); 201 | low = state[0] << 3; 202 | 203 | PUT_ULONG_LE(low, msglen, 0); 204 | PUT_ULONG_LE(high, msglen, 4); 205 | 206 | last = state[0] & 0x3F; 207 | padn = (last < 56) ? (56 - last) : (120 - last); 208 | 209 | md5_update(state, buffer, md5_padding, padn); 210 | md5_update(state, buffer, msglen, 8); 211 | 212 | PUT_ULONG_LE(state[2], output, 0); 213 | PUT_ULONG_LE(state[3], output, 4); 214 | PUT_ULONG_LE(state[4], output, 8); 215 | PUT_ULONG_LE(state[5], output, 12); 216 | } 217 | 218 | -------------------------------------------------------------------------------- /win32port/zlib/inffixed.h: -------------------------------------------------------------------------------- 1 | /* inffixed.h -- table for decoding fixed codes 2 | * Generated automatically by makefixed(). 3 | */ 4 | 5 | /* WARNING: this file should *not* be used by applications. It 6 | is part of the implementation of the compression library and 7 | is subject to change. Applications should only use zlib.h. 8 | */ 9 | 10 | static const code lenfix[512] = { 11 | {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, 12 | {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, 13 | {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, 14 | {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, 15 | {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, 16 | {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, 17 | {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, 18 | {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, 19 | {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, 20 | {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, 21 | {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, 22 | {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, 23 | {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, 24 | {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, 25 | {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, 26 | {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, 27 | {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, 28 | {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, 29 | {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, 30 | {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, 31 | {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, 32 | {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, 33 | {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, 34 | {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, 35 | {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, 36 | {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, 37 | {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, 38 | {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, 39 | {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, 40 | {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, 41 | {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, 42 | {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, 43 | {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, 44 | {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, 45 | {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, 46 | {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, 47 | {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, 48 | {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, 49 | {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, 50 | {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, 51 | {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, 52 | {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, 53 | {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, 54 | {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, 55 | {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, 56 | {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, 57 | {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, 58 | {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, 59 | {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, 60 | {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, 61 | {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, 62 | {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, 63 | {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, 64 | {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, 65 | {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, 66 | {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, 67 | {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, 68 | {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, 69 | {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, 70 | {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, 71 | {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, 72 | {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, 73 | {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, 74 | {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, 75 | {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, 76 | {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, 77 | {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, 78 | {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, 79 | {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, 80 | {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, 81 | {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, 82 | {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, 83 | {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, 84 | {0,9,255} 85 | }; 86 | 87 | static const code distfix[32] = { 88 | {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, 89 | {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, 90 | {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, 91 | {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, 92 | {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, 93 | {22,5,193},{64,5,0} 94 | }; 95 | -------------------------------------------------------------------------------- /win32port/zlib/inflate.h: -------------------------------------------------------------------------------- 1 | /* inflate.h -- internal inflate state definition 2 | * Copyright (C) 1995-2009 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* WARNING: this file should *not* be used by applications. It is 7 | part of the implementation of the compression library and is 8 | subject to change. Applications should only use zlib.h. 9 | */ 10 | 11 | /* define NO_GZIP when compiling if you want to disable gzip header and 12 | trailer decoding by inflate(). NO_GZIP would be used to avoid linking in 13 | the crc code when it is not needed. For shared libraries, gzip decoding 14 | should be left enabled. */ 15 | #ifndef NO_GZIP 16 | # define GUNZIP 17 | #endif 18 | 19 | /* Possible inflate modes between inflate() calls */ 20 | typedef enum { 21 | HEAD, /* i: waiting for magic header */ 22 | FLAGS, /* i: waiting for method and flags (gzip) */ 23 | TIME, /* i: waiting for modification time (gzip) */ 24 | OS, /* i: waiting for extra flags and operating system (gzip) */ 25 | EXLEN, /* i: waiting for extra length (gzip) */ 26 | EXTRA, /* i: waiting for extra bytes (gzip) */ 27 | NAME, /* i: waiting for end of file name (gzip) */ 28 | COMMENT, /* i: waiting for end of comment (gzip) */ 29 | HCRC, /* i: waiting for header crc (gzip) */ 30 | DICTID, /* i: waiting for dictionary check value */ 31 | DICT, /* waiting for inflateSetDictionary() call */ 32 | TYPE, /* i: waiting for type bits, including last-flag bit */ 33 | TYPEDO, /* i: same, but skip check to exit inflate on new block */ 34 | STORED, /* i: waiting for stored size (length and complement) */ 35 | COPY_, /* i/o: same as COPY below, but only first time in */ 36 | COPY, /* i/o: waiting for input or output to copy stored block */ 37 | TABLE, /* i: waiting for dynamic block table lengths */ 38 | LENLENS, /* i: waiting for code length code lengths */ 39 | CODELENS, /* i: waiting for length/lit and distance code lengths */ 40 | LEN_, /* i: same as LEN below, but only first time in */ 41 | LEN, /* i: waiting for length/lit/eob code */ 42 | LENEXT, /* i: waiting for length extra bits */ 43 | DIST, /* i: waiting for distance code */ 44 | DISTEXT, /* i: waiting for distance extra bits */ 45 | MATCH, /* o: waiting for output space to copy string */ 46 | LIT, /* o: waiting for output space to write literal */ 47 | CHECK, /* i: waiting for 32-bit check value */ 48 | LENGTH, /* i: waiting for 32-bit length (gzip) */ 49 | DONE, /* finished check, done -- remain here until reset */ 50 | BAD, /* got a data error -- remain here until reset */ 51 | MEM, /* got an inflate() memory error -- remain here until reset */ 52 | SYNC /* looking for synchronization bytes to restart inflate() */ 53 | } inflate_mode; 54 | 55 | /* 56 | State transitions between above modes - 57 | 58 | (most modes can go to BAD or MEM on error -- not shown for clarity) 59 | 60 | Process header: 61 | HEAD -> (gzip) or (zlib) or (raw) 62 | (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> 63 | HCRC -> TYPE 64 | (zlib) -> DICTID or TYPE 65 | DICTID -> DICT -> TYPE 66 | (raw) -> TYPEDO 67 | Read deflate blocks: 68 | TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK 69 | STORED -> COPY_ -> COPY -> TYPE 70 | TABLE -> LENLENS -> CODELENS -> LEN_ 71 | LEN_ -> LEN 72 | Read deflate codes in fixed or dynamic block: 73 | LEN -> LENEXT or LIT or TYPE 74 | LENEXT -> DIST -> DISTEXT -> MATCH -> LEN 75 | LIT -> LEN 76 | Process trailer: 77 | CHECK -> LENGTH -> DONE 78 | */ 79 | 80 | /* state maintained between inflate() calls. Approximately 10K bytes. */ 81 | struct inflate_state { 82 | inflate_mode mode; /* current inflate mode */ 83 | int last; /* true if processing last block */ 84 | int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ 85 | int havedict; /* true if dictionary provided */ 86 | int flags; /* gzip header method and flags (0 if zlib) */ 87 | unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ 88 | unsigned long check; /* protected copy of check value */ 89 | unsigned long total; /* protected copy of output count */ 90 | gz_headerp head; /* where to save gzip header information */ 91 | /* sliding window */ 92 | unsigned wbits; /* log base 2 of requested window size */ 93 | unsigned wsize; /* window size or zero if not using window */ 94 | unsigned whave; /* valid bytes in the window */ 95 | unsigned wnext; /* window write index */ 96 | unsigned char FAR *window; /* allocated sliding window, if needed */ 97 | /* bit accumulator */ 98 | unsigned long hold; /* input bit accumulator */ 99 | unsigned bits; /* number of bits in "in" */ 100 | /* for string and stored block copying */ 101 | unsigned length; /* literal or length of data to copy */ 102 | unsigned offset; /* distance back to copy string from */ 103 | /* for table and code decoding */ 104 | unsigned extra; /* extra bits needed */ 105 | /* fixed and dynamic code tables */ 106 | code const FAR *lencode; /* starting table for length/literal codes */ 107 | code const FAR *distcode; /* starting table for distance codes */ 108 | unsigned lenbits; /* index bits for lencode */ 109 | unsigned distbits; /* index bits for distcode */ 110 | /* dynamic table building */ 111 | unsigned ncode; /* number of code length code lengths */ 112 | unsigned nlen; /* number of length code lengths */ 113 | unsigned ndist; /* number of distance code lengths */ 114 | unsigned have; /* number of code lengths in lens[] */ 115 | code FAR *next; /* next available space in codes[] */ 116 | unsigned short lens[320]; /* temporary storage for code lengths */ 117 | unsigned short work[288]; /* work area for code table building */ 118 | code codes[ENOUGH]; /* space for code tables */ 119 | int sane; /* if false, allow invalid distance too far */ 120 | int back; /* bits back of last unprocessed length/lit */ 121 | unsigned was; /* initial length of match */ 122 | }; 123 | -------------------------------------------------------------------------------- /win32port/win32port.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual C++ Express 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server", "server\server.vcxproj", "{E585B64F-9365-4C58-9EF8-56393EB27F8B}" 5 | ProjectSection(ProjectDependencies) = postProject 6 | {332BF17E-FD30-4363-975A-AA731A827B4F} = {332BF17E-FD30-4363-975A-AA731A827B4F} 7 | EndProjectSection 8 | EndProject 9 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libwebsocketswin32", "libwebsocketswin32\libwebsocketswin32.vcxproj", "{332BF17E-FD30-4363-975A-AA731A827B4F}" 10 | ProjectSection(ProjectDependencies) = postProject 11 | {4156FC56-8443-2973-4FE2-A0BB2C621525} = {4156FC56-8443-2973-4FE2-A0BB2C621525} 12 | EndProjectSection 13 | EndProject 14 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client", "client\client.vcxproj", "{6265650C-4799-451C-A687-94DE48759A8B}" 15 | EndProject 16 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZLib", "zlib\ZLib.vcxproj", "{4156FC56-8443-2973-4FE2-A0BB2C621525}" 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug static|Win32 = Debug static|Win32 21 | Debug static|x64 = Debug static|x64 22 | Debug|Win32 = Debug|Win32 23 | Debug|x64 = Debug|x64 24 | Release DLL|Win32 = Release DLL|Win32 25 | Release DLL|x64 = Release DLL|x64 26 | Release static|Win32 = Release static|Win32 27 | Release static|x64 = Release static|x64 28 | Release|Win32 = Release|Win32 29 | Release|x64 = Release|x64 30 | EndGlobalSection 31 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 32 | {332BF17E-FD30-4363-975A-AA731A827B4F}.Debug static|Win32.ActiveCfg = Debug static|Win32 33 | {332BF17E-FD30-4363-975A-AA731A827B4F}.Debug static|Win32.Build.0 = Debug static|Win32 34 | {332BF17E-FD30-4363-975A-AA731A827B4F}.Debug static|x64.ActiveCfg = Debug static|Win32 35 | {332BF17E-FD30-4363-975A-AA731A827B4F}.Debug|Win32.ActiveCfg = Debug|Win32 36 | {332BF17E-FD30-4363-975A-AA731A827B4F}.Debug|Win32.Build.0 = Debug|Win32 37 | {332BF17E-FD30-4363-975A-AA731A827B4F}.Debug|x64.ActiveCfg = Debug|Win32 38 | {332BF17E-FD30-4363-975A-AA731A827B4F}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 39 | {332BF17E-FD30-4363-975A-AA731A827B4F}.Release DLL|Win32.Build.0 = Release DLL|Win32 40 | {332BF17E-FD30-4363-975A-AA731A827B4F}.Release DLL|x64.ActiveCfg = Release DLL|x64 41 | {332BF17E-FD30-4363-975A-AA731A827B4F}.Release DLL|x64.Build.0 = Release DLL|x64 42 | {332BF17E-FD30-4363-975A-AA731A827B4F}.Release static|Win32.ActiveCfg = Release static|Win32 43 | {332BF17E-FD30-4363-975A-AA731A827B4F}.Release static|Win32.Build.0 = Release static|Win32 44 | {332BF17E-FD30-4363-975A-AA731A827B4F}.Release static|x64.ActiveCfg = Release static|Win32 45 | {332BF17E-FD30-4363-975A-AA731A827B4F}.Release|Win32.ActiveCfg = Release|Win32 46 | {332BF17E-FD30-4363-975A-AA731A827B4F}.Release|Win32.Build.0 = Release|Win32 47 | {332BF17E-FD30-4363-975A-AA731A827B4F}.Release|x64.ActiveCfg = Release|Win32 48 | {4156FC56-8443-2973-4FE2-A0BB2C621525}.Debug static|Win32.ActiveCfg = Debug static|Win32 49 | {4156FC56-8443-2973-4FE2-A0BB2C621525}.Debug static|Win32.Build.0 = Debug static|Win32 50 | {4156FC56-8443-2973-4FE2-A0BB2C621525}.Debug static|x64.ActiveCfg = Debug static|Win32 51 | {4156FC56-8443-2973-4FE2-A0BB2C621525}.Debug|Win32.ActiveCfg = Debug|Win32 52 | {4156FC56-8443-2973-4FE2-A0BB2C621525}.Debug|Win32.Build.0 = Debug|Win32 53 | {4156FC56-8443-2973-4FE2-A0BB2C621525}.Debug|x64.ActiveCfg = Debug|Win32 54 | {4156FC56-8443-2973-4FE2-A0BB2C621525}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 55 | {4156FC56-8443-2973-4FE2-A0BB2C621525}.Release DLL|Win32.Build.0 = Release DLL|Win32 56 | {4156FC56-8443-2973-4FE2-A0BB2C621525}.Release DLL|x64.ActiveCfg = Release DLL|x64 57 | {4156FC56-8443-2973-4FE2-A0BB2C621525}.Release DLL|x64.Build.0 = Release DLL|x64 58 | {4156FC56-8443-2973-4FE2-A0BB2C621525}.Release static|Win32.ActiveCfg = Release static|Win32 59 | {4156FC56-8443-2973-4FE2-A0BB2C621525}.Release static|Win32.Build.0 = Release static|Win32 60 | {4156FC56-8443-2973-4FE2-A0BB2C621525}.Release static|x64.ActiveCfg = Release static|Win32 61 | {4156FC56-8443-2973-4FE2-A0BB2C621525}.Release|Win32.ActiveCfg = Release|Win32 62 | {4156FC56-8443-2973-4FE2-A0BB2C621525}.Release|Win32.Build.0 = Release|Win32 63 | {4156FC56-8443-2973-4FE2-A0BB2C621525}.Release|x64.ActiveCfg = Release|Win32 64 | {6265650C-4799-451C-A687-94DE48759A8B}.Debug static|Win32.ActiveCfg = Debug static|Win32 65 | {6265650C-4799-451C-A687-94DE48759A8B}.Debug static|Win32.Build.0 = Debug static|Win32 66 | {6265650C-4799-451C-A687-94DE48759A8B}.Debug static|x64.ActiveCfg = Debug static|Win32 67 | {6265650C-4799-451C-A687-94DE48759A8B}.Debug|Win32.ActiveCfg = Debug|Win32 68 | {6265650C-4799-451C-A687-94DE48759A8B}.Debug|Win32.Build.0 = Debug|Win32 69 | {6265650C-4799-451C-A687-94DE48759A8B}.Debug|x64.ActiveCfg = Debug|Win32 70 | {6265650C-4799-451C-A687-94DE48759A8B}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 71 | {6265650C-4799-451C-A687-94DE48759A8B}.Release DLL|Win32.Build.0 = Release DLL|Win32 72 | {6265650C-4799-451C-A687-94DE48759A8B}.Release DLL|x64.ActiveCfg = Release DLL|x64 73 | {6265650C-4799-451C-A687-94DE48759A8B}.Release DLL|x64.Build.0 = Release DLL|x64 74 | {6265650C-4799-451C-A687-94DE48759A8B}.Release static|Win32.ActiveCfg = Release static|Win32 75 | {6265650C-4799-451C-A687-94DE48759A8B}.Release static|Win32.Build.0 = Release static|Win32 76 | {6265650C-4799-451C-A687-94DE48759A8B}.Release static|x64.ActiveCfg = Release static|Win32 77 | {6265650C-4799-451C-A687-94DE48759A8B}.Release|Win32.ActiveCfg = Release|Win32 78 | {6265650C-4799-451C-A687-94DE48759A8B}.Release|Win32.Build.0 = Release|Win32 79 | {6265650C-4799-451C-A687-94DE48759A8B}.Release|x64.ActiveCfg = Release|Win32 80 | {E585B64F-9365-4C58-9EF8-56393EB27F8B}.Debug static|Win32.ActiveCfg = Debug static|Win32 81 | {E585B64F-9365-4C58-9EF8-56393EB27F8B}.Debug static|Win32.Build.0 = Debug static|Win32 82 | {E585B64F-9365-4C58-9EF8-56393EB27F8B}.Debug static|x64.ActiveCfg = Debug static|Win32 83 | {E585B64F-9365-4C58-9EF8-56393EB27F8B}.Debug|Win32.ActiveCfg = Debug|Win32 84 | {E585B64F-9365-4C58-9EF8-56393EB27F8B}.Debug|Win32.Build.0 = Debug|Win32 85 | {E585B64F-9365-4C58-9EF8-56393EB27F8B}.Debug|x64.ActiveCfg = Debug|Win32 86 | {E585B64F-9365-4C58-9EF8-56393EB27F8B}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 87 | {E585B64F-9365-4C58-9EF8-56393EB27F8B}.Release DLL|Win32.Build.0 = Release DLL|Win32 88 | {E585B64F-9365-4C58-9EF8-56393EB27F8B}.Release DLL|x64.ActiveCfg = Release DLL|x64 89 | {E585B64F-9365-4C58-9EF8-56393EB27F8B}.Release DLL|x64.Build.0 = Release DLL|x64 90 | {E585B64F-9365-4C58-9EF8-56393EB27F8B}.Release static|Win32.ActiveCfg = Release static|Win32 91 | {E585B64F-9365-4C58-9EF8-56393EB27F8B}.Release static|Win32.Build.0 = Release static|Win32 92 | {E585B64F-9365-4C58-9EF8-56393EB27F8B}.Release static|x64.ActiveCfg = Release static|Win32 93 | {E585B64F-9365-4C58-9EF8-56393EB27F8B}.Release|Win32.ActiveCfg = Release|Win32 94 | {E585B64F-9365-4C58-9EF8-56393EB27F8B}.Release|Win32.Build.0 = Release|Win32 95 | {E585B64F-9365-4C58-9EF8-56393EB27F8B}.Release|x64.ActiveCfg = Release|Win32 96 | EndGlobalSection 97 | GlobalSection(SolutionProperties) = preSolution 98 | HideSolutionNode = FALSE 99 | EndGlobalSection 100 | EndGlobal 101 | -------------------------------------------------------------------------------- /win32port/win32helpers/getopt_long.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (c) 1987, 1993, 1994, 1996 4 | * The Regents of the University of California. All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. All advertising materials mentioning features or use of this software 15 | * must display the following acknowledgement: 16 | * This product includes software developed by the University of 17 | * California, Berkeley and its contributors. 18 | * 4. Neither the name of the University nor the names of its contributors 19 | * may be used to endorse or promote products derived from this software 20 | * without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 | * SUCH DAMAGE. 33 | */ 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include "getopt.h" 40 | 41 | extern int opterr; /* if error message should be printed */ 42 | extern int optind; /* index into parent argv vector */ 43 | extern int optopt; /* character checked for validity */ 44 | extern int optreset; /* reset getopt */ 45 | extern char *optarg; /* argument associated with option */ 46 | 47 | #define __P(x) x 48 | #define _DIAGASSERT(x) assert(x) 49 | 50 | static char * __progname __P((char *)); 51 | int getopt_internal __P((int, char * const *, const char *)); 52 | 53 | static char * 54 | __progname(nargv0) 55 | char * nargv0; 56 | { 57 | char * tmp; 58 | 59 | _DIAGASSERT(nargv0 != NULL); 60 | 61 | tmp = strrchr(nargv0, '/'); 62 | if (tmp) 63 | tmp++; 64 | else 65 | tmp = nargv0; 66 | return(tmp); 67 | } 68 | 69 | #define BADCH (int)'?' 70 | #define BADARG (int)':' 71 | #define EMSG "" 72 | 73 | /* 74 | * getopt -- 75 | * Parse argc/argv argument vector. 76 | */ 77 | int 78 | getopt_internal(nargc, nargv, ostr) 79 | int nargc; 80 | char * const *nargv; 81 | const char *ostr; 82 | { 83 | static char *place = EMSG; /* option letter processing */ 84 | char *oli; /* option letter list index */ 85 | 86 | _DIAGASSERT(nargv != NULL); 87 | _DIAGASSERT(ostr != NULL); 88 | 89 | if (optreset || !*place) { /* update scanning pointer */ 90 | optreset = 0; 91 | if (optind >= nargc || *(place = nargv[optind]) != '-') { 92 | place = EMSG; 93 | return (-1); 94 | } 95 | if (place[1] && *++place == '-') { /* found "--" */ 96 | /* ++optind; */ 97 | place = EMSG; 98 | return (-2); 99 | } 100 | } /* option letter okay? */ 101 | if ((optopt = (int)*place++) == (int)':' || 102 | !(oli = strchr(ostr, optopt))) { 103 | /* 104 | * if the user didn't specify '-' as an option, 105 | * assume it means -1. 106 | */ 107 | if (optopt == (int)'-') 108 | return (-1); 109 | if (!*place) 110 | ++optind; 111 | if (opterr && *ostr != ':') 112 | (void)fprintf(stderr, 113 | "%s: illegal option -- %c\n", __progname(nargv[0]), optopt); 114 | return (BADCH); 115 | } 116 | if (*++oli != ':') { /* don't need argument */ 117 | optarg = NULL; 118 | if (!*place) 119 | ++optind; 120 | } else { /* need an argument */ 121 | if (*place) /* no white space */ 122 | optarg = place; 123 | else if (nargc <= ++optind) { /* no arg */ 124 | place = EMSG; 125 | if ((opterr) && (*ostr != ':')) 126 | (void)fprintf(stderr, 127 | "%s: option requires an argument -- %c\n", 128 | __progname(nargv[0]), optopt); 129 | return (BADARG); 130 | } else /* white space */ 131 | optarg = nargv[optind]; 132 | place = EMSG; 133 | ++optind; 134 | } 135 | return (optopt); /* dump back option letter */ 136 | } 137 | 138 | #if 0 139 | /* 140 | * getopt -- 141 | * Parse argc/argv argument vector. 142 | */ 143 | int 144 | getopt2(nargc, nargv, ostr) 145 | int nargc; 146 | char * const *nargv; 147 | const char *ostr; 148 | { 149 | int retval; 150 | 151 | if ((retval = getopt_internal(nargc, nargv, ostr)) == -2) { 152 | retval = -1; 153 | ++optind; 154 | } 155 | return(retval); 156 | } 157 | #endif 158 | 159 | /* 160 | * getopt_long -- 161 | * Parse argc/argv argument vector. 162 | */ 163 | int 164 | getopt_long(nargc, nargv, options, long_options, index) 165 | int nargc; 166 | char ** nargv; 167 | char * options; 168 | struct option * long_options; 169 | int * index; 170 | { 171 | int retval; 172 | 173 | _DIAGASSERT(nargv != NULL); 174 | _DIAGASSERT(options != NULL); 175 | _DIAGASSERT(long_options != NULL); 176 | /* index may be NULL */ 177 | 178 | if ((retval = getopt_internal(nargc, nargv, options)) == -2) { 179 | char *current_argv = nargv[optind++] + 2, *has_equal; 180 | int i, current_argv_len, match = -1; 181 | 182 | if (*current_argv == '\0') { 183 | return(-1); 184 | } 185 | if ((has_equal = strchr(current_argv, '=')) != NULL) { 186 | current_argv_len = has_equal - current_argv; 187 | has_equal++; 188 | } else 189 | current_argv_len = strlen(current_argv); 190 | 191 | for (i = 0; long_options[i].name; i++) { 192 | if (strncmp(current_argv, long_options[i].name, current_argv_len)) 193 | continue; 194 | 195 | if (strlen(long_options[i].name) == (unsigned)current_argv_len) { 196 | match = i; 197 | break; 198 | } 199 | if (match == -1) 200 | match = i; 201 | } 202 | if (match != -1) { 203 | if (long_options[match].has_arg == required_argument || 204 | long_options[match].has_arg == optional_argument) { 205 | if (has_equal) 206 | optarg = has_equal; 207 | else 208 | optarg = nargv[optind++]; 209 | } 210 | if ((long_options[match].has_arg == required_argument) 211 | && (optarg == NULL)) { 212 | /* 213 | * Missing argument, leading : 214 | * indicates no error should be generated 215 | */ 216 | if ((opterr) && (*options != ':')) 217 | (void)fprintf(stderr, 218 | "%s: option requires an argument -- %s\n", 219 | __progname(nargv[0]), current_argv); 220 | return (BADARG); 221 | } 222 | } else { /* No matching argument */ 223 | if ((opterr) && (*options != ':')) 224 | (void)fprintf(stderr, 225 | "%s: illegal option -- %s\n", __progname(nargv[0]), current_argv); 226 | return (BADCH); 227 | } 228 | if (long_options[match].flag) { 229 | *long_options[match].flag = long_options[match].val; 230 | retval = 0; 231 | } else 232 | retval = long_options[match].val; 233 | if (index) 234 | *index = match; 235 | } 236 | return(retval); 237 | } 238 | -------------------------------------------------------------------------------- /win32port/zlib/zutil.h: -------------------------------------------------------------------------------- 1 | /* zutil.h -- internal interface and configuration of the compression library 2 | * Copyright (C) 1995-2010 Jean-loup Gailly. 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* WARNING: this file should *not* be used by applications. It is 7 | part of the implementation of the compression library and is 8 | subject to change. Applications should only use zlib.h. 9 | */ 10 | 11 | /* @(#) $Id$ */ 12 | 13 | #ifndef ZUTIL_H 14 | #define ZUTIL_H 15 | 16 | #if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) 17 | # define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) 18 | #else 19 | # define ZLIB_INTERNAL 20 | #endif 21 | 22 | #include "zlib.h" 23 | 24 | #ifdef STDC 25 | # if !(defined(_WIN32_WCE) && defined(_MSC_VER)) 26 | # include 27 | # endif 28 | # include 29 | # include 30 | #endif 31 | 32 | #ifndef local 33 | # define local static 34 | #endif 35 | /* compile with -Dlocal if your debugger can't find static symbols */ 36 | 37 | typedef unsigned char uch; 38 | typedef uch FAR uchf; 39 | typedef unsigned short ush; 40 | typedef ush FAR ushf; 41 | typedef unsigned long ulg; 42 | 43 | extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ 44 | /* (size given to avoid silly warnings with Visual C++) */ 45 | 46 | #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] 47 | 48 | #define ERR_RETURN(strm,err) \ 49 | return (strm->msg = (char*)ERR_MSG(err), (err)) 50 | /* To be used only when the state is known to be valid */ 51 | 52 | /* common constants */ 53 | 54 | #ifndef DEF_WBITS 55 | # define DEF_WBITS MAX_WBITS 56 | #endif 57 | /* default windowBits for decompression. MAX_WBITS is for compression only */ 58 | 59 | #if MAX_MEM_LEVEL >= 8 60 | # define DEF_MEM_LEVEL 8 61 | #else 62 | # define DEF_MEM_LEVEL MAX_MEM_LEVEL 63 | #endif 64 | /* default memLevel */ 65 | 66 | #define STORED_BLOCK 0 67 | #define STATIC_TREES 1 68 | #define DYN_TREES 2 69 | /* The three kinds of block type */ 70 | 71 | #define MIN_MATCH 3 72 | #define MAX_MATCH 258 73 | /* The minimum and maximum match lengths */ 74 | 75 | #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ 76 | 77 | /* target dependencies */ 78 | 79 | #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) 80 | # define OS_CODE 0x00 81 | # if defined(__TURBOC__) || defined(__BORLANDC__) 82 | # if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) 83 | /* Allow compilation with ANSI keywords only enabled */ 84 | void _Cdecl farfree( void *block ); 85 | void *_Cdecl farmalloc( unsigned long nbytes ); 86 | # else 87 | # include 88 | # endif 89 | # else /* MSC or DJGPP */ 90 | # include 91 | # endif 92 | #endif 93 | 94 | #ifdef AMIGA 95 | # define OS_CODE 0x01 96 | #endif 97 | 98 | #if defined(VAXC) || defined(VMS) 99 | # define OS_CODE 0x02 100 | # define F_OPEN(name, mode) \ 101 | fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") 102 | #endif 103 | 104 | #if defined(ATARI) || defined(atarist) 105 | # define OS_CODE 0x05 106 | #endif 107 | 108 | #ifdef OS2 109 | # define OS_CODE 0x06 110 | # ifdef M_I86 111 | # include 112 | # endif 113 | #endif 114 | 115 | #if defined(MACOS) || defined(TARGET_OS_MAC) 116 | # define OS_CODE 0x07 117 | # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os 118 | # include /* for fdopen */ 119 | # else 120 | # ifndef fdopen 121 | # define fdopen(fd,mode) NULL /* No fdopen() */ 122 | # endif 123 | # endif 124 | #endif 125 | 126 | #ifdef TOPS20 127 | # define OS_CODE 0x0a 128 | #endif 129 | 130 | #ifdef WIN32 131 | # ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ 132 | # define OS_CODE 0x0b 133 | # endif 134 | #endif 135 | 136 | #ifdef __50SERIES /* Prime/PRIMOS */ 137 | # define OS_CODE 0x0f 138 | #endif 139 | 140 | #if defined(_BEOS_) || defined(RISCOS) 141 | # define fdopen(fd,mode) NULL /* No fdopen() */ 142 | #endif 143 | 144 | #if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX 145 | # if defined(_WIN32_WCE) 146 | # define fdopen(fd,mode) NULL /* No fdopen() */ 147 | # ifndef _PTRDIFF_T_DEFINED 148 | typedef int ptrdiff_t; 149 | # define _PTRDIFF_T_DEFINED 150 | # endif 151 | # else 152 | # define fdopen(fd,type) _fdopen(fd,type) 153 | # endif 154 | #endif 155 | 156 | #if defined(__BORLANDC__) 157 | #pragma warn -8004 158 | #pragma warn -8008 159 | #pragma warn -8066 160 | #endif 161 | 162 | /* provide prototypes for these when building zlib without LFS */ 163 | #if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 164 | ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); 165 | ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); 166 | #endif 167 | 168 | /* common defaults */ 169 | 170 | #ifndef OS_CODE 171 | # define OS_CODE 0x03 /* assume Unix */ 172 | #endif 173 | 174 | #ifndef F_OPEN 175 | # define F_OPEN(name, mode) fopen((name), (mode)) 176 | #endif 177 | 178 | /* functions */ 179 | 180 | #if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) 181 | # ifndef HAVE_VSNPRINTF 182 | # define HAVE_VSNPRINTF 183 | # endif 184 | #endif 185 | #if defined(__CYGWIN__) 186 | # ifndef HAVE_VSNPRINTF 187 | # define HAVE_VSNPRINTF 188 | # endif 189 | #endif 190 | #ifndef HAVE_VSNPRINTF 191 | # ifdef MSDOS 192 | /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), 193 | but for now we just assume it doesn't. */ 194 | # define NO_vsnprintf 195 | # endif 196 | # ifdef __TURBOC__ 197 | # define NO_vsnprintf 198 | # endif 199 | # ifdef WIN32 200 | /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ 201 | # if !defined(vsnprintf) && !defined(NO_vsnprintf) 202 | # if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) 203 | # define vsnprintf _vsnprintf 204 | # endif 205 | # endif 206 | # endif 207 | # ifdef __SASC 208 | # define NO_vsnprintf 209 | # endif 210 | #endif 211 | #ifdef VMS 212 | # define NO_vsnprintf 213 | #endif 214 | 215 | #if defined(pyr) 216 | # define NO_MEMCPY 217 | #endif 218 | #if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) 219 | /* Use our own functions for small and medium model with MSC <= 5.0. 220 | * You may have to use the same strategy for Borland C (untested). 221 | * The __SC__ check is for Symantec. 222 | */ 223 | # define NO_MEMCPY 224 | #endif 225 | #if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) 226 | # define HAVE_MEMCPY 227 | #endif 228 | #ifdef HAVE_MEMCPY 229 | # ifdef SMALL_MEDIUM /* MSDOS small or medium model */ 230 | # define zmemcpy _fmemcpy 231 | # define zmemcmp _fmemcmp 232 | # define zmemzero(dest, len) _fmemset(dest, 0, len) 233 | # else 234 | # define zmemcpy memcpy 235 | # define zmemcmp memcmp 236 | # define zmemzero(dest, len) memset(dest, 0, len) 237 | # endif 238 | #else 239 | void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); 240 | int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); 241 | void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); 242 | #endif 243 | 244 | /* Diagnostic functions */ 245 | #ifdef DEBUG 246 | # include 247 | extern int ZLIB_INTERNAL z_verbose; 248 | extern void ZLIB_INTERNAL z_error OF((char *m)); 249 | # define Assert(cond,msg) {if(!(cond)) z_error(msg);} 250 | # define Trace(x) {if (z_verbose>=0) fprintf x ;} 251 | # define Tracev(x) {if (z_verbose>0) fprintf x ;} 252 | # define Tracevv(x) {if (z_verbose>1) fprintf x ;} 253 | # define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} 254 | # define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} 255 | #else 256 | # define Assert(cond,msg) 257 | # define Trace(x) 258 | # define Tracev(x) 259 | # define Tracevv(x) 260 | # define Tracec(c,x) 261 | # define Tracecv(c,x) 262 | #endif 263 | 264 | 265 | voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, 266 | unsigned size)); 267 | void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); 268 | 269 | #define ZALLOC(strm, items, size) \ 270 | (*((strm)->zalloc))((strm)->opaque, (items), (size)) 271 | #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) 272 | #define TRY_FREE(s, p) {if (p) ZFREE(s, p);} 273 | 274 | #endif /* ZUTIL_H */ 275 | -------------------------------------------------------------------------------- /win32port/zlib/trees.h: -------------------------------------------------------------------------------- 1 | /* header created automatically with -DGEN_TREES_H */ 2 | 3 | local const ct_data static_ltree[L_CODES+2] = { 4 | {{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, 5 | {{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, 6 | {{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, 7 | {{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, 8 | {{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, 9 | {{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, 10 | {{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, 11 | {{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, 12 | {{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, 13 | {{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, 14 | {{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, 15 | {{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, 16 | {{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, 17 | {{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, 18 | {{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, 19 | {{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, 20 | {{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, 21 | {{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, 22 | {{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, 23 | {{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, 24 | {{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, 25 | {{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, 26 | {{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, 27 | {{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, 28 | {{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, 29 | {{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, 30 | {{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, 31 | {{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, 32 | {{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, 33 | {{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, 34 | {{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, 35 | {{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, 36 | {{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, 37 | {{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, 38 | {{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, 39 | {{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, 40 | {{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, 41 | {{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, 42 | {{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, 43 | {{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, 44 | {{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, 45 | {{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, 46 | {{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, 47 | {{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, 48 | {{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, 49 | {{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, 50 | {{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, 51 | {{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, 52 | {{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, 53 | {{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, 54 | {{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, 55 | {{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, 56 | {{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, 57 | {{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, 58 | {{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, 59 | {{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, 60 | {{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, 61 | {{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} 62 | }; 63 | 64 | local const ct_data static_dtree[D_CODES] = { 65 | {{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, 66 | {{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, 67 | {{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, 68 | {{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, 69 | {{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, 70 | {{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} 71 | }; 72 | 73 | const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { 74 | 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 75 | 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 76 | 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 77 | 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 78 | 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 79 | 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 80 | 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 81 | 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 82 | 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 83 | 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 84 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 85 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 86 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 87 | 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 88 | 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 89 | 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 90 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 91 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 92 | 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 93 | 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 94 | 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 95 | 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 96 | 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 97 | 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 98 | 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 99 | 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 100 | }; 101 | 102 | const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { 103 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 104 | 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 105 | 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 106 | 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 107 | 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 108 | 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 109 | 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 110 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 111 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 112 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 113 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 114 | 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 115 | 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 116 | }; 117 | 118 | local const int base_length[LENGTH_CODES] = { 119 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 120 | 64, 80, 96, 112, 128, 160, 192, 224, 0 121 | }; 122 | 123 | local const int base_dist[D_CODES] = { 124 | 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 125 | 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 126 | 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 127 | }; 128 | 129 | -------------------------------------------------------------------------------- /win32port/zlib/zutil.c: -------------------------------------------------------------------------------- 1 | /* zutil.c -- target dependent utility functions for the compression library 2 | * Copyright (C) 1995-2005, 2010 Jean-loup Gailly. 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #include "zutil.h" 9 | 10 | #ifndef NO_DUMMY_DECL 11 | struct internal_state {int dummy;}; /* for buggy compilers */ 12 | #endif 13 | 14 | const char * const z_errmsg[10] = { 15 | "need dictionary", /* Z_NEED_DICT 2 */ 16 | "stream end", /* Z_STREAM_END 1 */ 17 | "", /* Z_OK 0 */ 18 | "file error", /* Z_ERRNO (-1) */ 19 | "stream error", /* Z_STREAM_ERROR (-2) */ 20 | "data error", /* Z_DATA_ERROR (-3) */ 21 | "insufficient memory", /* Z_MEM_ERROR (-4) */ 22 | "buffer error", /* Z_BUF_ERROR (-5) */ 23 | "incompatible version",/* Z_VERSION_ERROR (-6) */ 24 | ""}; 25 | 26 | 27 | const char * ZEXPORT zlibVersion() 28 | { 29 | return ZLIB_VERSION; 30 | } 31 | 32 | uLong ZEXPORT zlibCompileFlags() 33 | { 34 | uLong flags; 35 | 36 | flags = 0; 37 | switch ((int)(sizeof(uInt))) { 38 | case 2: break; 39 | case 4: flags += 1; break; 40 | case 8: flags += 2; break; 41 | default: flags += 3; 42 | } 43 | switch ((int)(sizeof(uLong))) { 44 | case 2: break; 45 | case 4: flags += 1 << 2; break; 46 | case 8: flags += 2 << 2; break; 47 | default: flags += 3 << 2; 48 | } 49 | switch ((int)(sizeof(voidpf))) { 50 | case 2: break; 51 | case 4: flags += 1 << 4; break; 52 | case 8: flags += 2 << 4; break; 53 | default: flags += 3 << 4; 54 | } 55 | switch ((int)(sizeof(z_off_t))) { 56 | case 2: break; 57 | case 4: flags += 1 << 6; break; 58 | case 8: flags += 2 << 6; break; 59 | default: flags += 3 << 6; 60 | } 61 | #ifdef DEBUG 62 | flags += 1 << 8; 63 | #endif 64 | #if defined(ASMV) || defined(ASMINF) 65 | flags += 1 << 9; 66 | #endif 67 | #ifdef ZLIB_WINAPI 68 | flags += 1 << 10; 69 | #endif 70 | #ifdef BUILDFIXED 71 | flags += 1 << 12; 72 | #endif 73 | #ifdef DYNAMIC_CRC_TABLE 74 | flags += 1 << 13; 75 | #endif 76 | #ifdef NO_GZCOMPRESS 77 | flags += 1L << 16; 78 | #endif 79 | #ifdef NO_GZIP 80 | flags += 1L << 17; 81 | #endif 82 | #ifdef PKZIP_BUG_WORKAROUND 83 | flags += 1L << 20; 84 | #endif 85 | #ifdef FASTEST 86 | flags += 1L << 21; 87 | #endif 88 | #ifdef STDC 89 | # ifdef NO_vsnprintf 90 | flags += 1L << 25; 91 | # ifdef HAS_vsprintf_void 92 | flags += 1L << 26; 93 | # endif 94 | # else 95 | # ifdef HAS_vsnprintf_void 96 | flags += 1L << 26; 97 | # endif 98 | # endif 99 | #else 100 | flags += 1L << 24; 101 | # ifdef NO_snprintf 102 | flags += 1L << 25; 103 | # ifdef HAS_sprintf_void 104 | flags += 1L << 26; 105 | # endif 106 | # else 107 | # ifdef HAS_snprintf_void 108 | flags += 1L << 26; 109 | # endif 110 | # endif 111 | #endif 112 | return flags; 113 | } 114 | 115 | #ifdef DEBUG 116 | 117 | # ifndef verbose 118 | # define verbose 0 119 | # endif 120 | int ZLIB_INTERNAL z_verbose = verbose; 121 | 122 | void ZLIB_INTERNAL z_error (m) 123 | char *m; 124 | { 125 | fprintf(stderr, "%s\n", m); 126 | exit(1); 127 | } 128 | #endif 129 | 130 | /* exported to allow conversion of error code to string for compress() and 131 | * uncompress() 132 | */ 133 | const char * ZEXPORT zError(err) 134 | int err; 135 | { 136 | return ERR_MSG(err); 137 | } 138 | 139 | #if defined(_WIN32_WCE) 140 | /* The Microsoft C Run-Time Library for Windows CE doesn't have 141 | * errno. We define it as a global variable to simplify porting. 142 | * Its value is always 0 and should not be used. 143 | */ 144 | int errno = 0; 145 | #endif 146 | 147 | #ifndef HAVE_MEMCPY 148 | 149 | void ZLIB_INTERNAL zmemcpy(dest, source, len) 150 | Bytef* dest; 151 | const Bytef* source; 152 | uInt len; 153 | { 154 | if (len == 0) return; 155 | do { 156 | *dest++ = *source++; /* ??? to be unrolled */ 157 | } while (--len != 0); 158 | } 159 | 160 | int ZLIB_INTERNAL zmemcmp(s1, s2, len) 161 | const Bytef* s1; 162 | const Bytef* s2; 163 | uInt len; 164 | { 165 | uInt j; 166 | 167 | for (j = 0; j < len; j++) { 168 | if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; 169 | } 170 | return 0; 171 | } 172 | 173 | void ZLIB_INTERNAL zmemzero(dest, len) 174 | Bytef* dest; 175 | uInt len; 176 | { 177 | if (len == 0) return; 178 | do { 179 | *dest++ = 0; /* ??? to be unrolled */ 180 | } while (--len != 0); 181 | } 182 | #endif 183 | 184 | 185 | #ifdef SYS16BIT 186 | 187 | #ifdef __TURBOC__ 188 | /* Turbo C in 16-bit mode */ 189 | 190 | # define MY_ZCALLOC 191 | 192 | /* Turbo C malloc() does not allow dynamic allocation of 64K bytes 193 | * and farmalloc(64K) returns a pointer with an offset of 8, so we 194 | * must fix the pointer. Warning: the pointer must be put back to its 195 | * original form in order to free it, use zcfree(). 196 | */ 197 | 198 | #define MAX_PTR 10 199 | /* 10*64K = 640K */ 200 | 201 | local int next_ptr = 0; 202 | 203 | typedef struct ptr_table_s { 204 | voidpf org_ptr; 205 | voidpf new_ptr; 206 | } ptr_table; 207 | 208 | local ptr_table table[MAX_PTR]; 209 | /* This table is used to remember the original form of pointers 210 | * to large buffers (64K). Such pointers are normalized with a zero offset. 211 | * Since MSDOS is not a preemptive multitasking OS, this table is not 212 | * protected from concurrent access. This hack doesn't work anyway on 213 | * a protected system like OS/2. Use Microsoft C instead. 214 | */ 215 | 216 | voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) 217 | { 218 | voidpf buf = opaque; /* just to make some compilers happy */ 219 | ulg bsize = (ulg)items*size; 220 | 221 | /* If we allocate less than 65520 bytes, we assume that farmalloc 222 | * will return a usable pointer which doesn't have to be normalized. 223 | */ 224 | if (bsize < 65520L) { 225 | buf = farmalloc(bsize); 226 | if (*(ush*)&buf != 0) return buf; 227 | } else { 228 | buf = farmalloc(bsize + 16L); 229 | } 230 | if (buf == NULL || next_ptr >= MAX_PTR) return NULL; 231 | table[next_ptr].org_ptr = buf; 232 | 233 | /* Normalize the pointer to seg:0 */ 234 | *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; 235 | *(ush*)&buf = 0; 236 | table[next_ptr++].new_ptr = buf; 237 | return buf; 238 | } 239 | 240 | void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) 241 | { 242 | int n; 243 | if (*(ush*)&ptr != 0) { /* object < 64K */ 244 | farfree(ptr); 245 | return; 246 | } 247 | /* Find the original pointer */ 248 | for (n = 0; n < next_ptr; n++) { 249 | if (ptr != table[n].new_ptr) continue; 250 | 251 | farfree(table[n].org_ptr); 252 | while (++n < next_ptr) { 253 | table[n-1] = table[n]; 254 | } 255 | next_ptr--; 256 | return; 257 | } 258 | ptr = opaque; /* just to make some compilers happy */ 259 | Assert(0, "zcfree: ptr not found"); 260 | } 261 | 262 | #endif /* __TURBOC__ */ 263 | 264 | 265 | #ifdef M_I86 266 | /* Microsoft C in 16-bit mode */ 267 | 268 | # define MY_ZCALLOC 269 | 270 | #if (!defined(_MSC_VER) || (_MSC_VER <= 600)) 271 | # define _halloc halloc 272 | # define _hfree hfree 273 | #endif 274 | 275 | voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) 276 | { 277 | if (opaque) opaque = 0; /* to make compiler happy */ 278 | return _halloc((long)items, size); 279 | } 280 | 281 | void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) 282 | { 283 | if (opaque) opaque = 0; /* to make compiler happy */ 284 | _hfree(ptr); 285 | } 286 | 287 | #endif /* M_I86 */ 288 | 289 | #endif /* SYS16BIT */ 290 | 291 | 292 | #ifndef MY_ZCALLOC /* Any system without a special alloc function */ 293 | 294 | #ifndef STDC 295 | extern voidp malloc OF((uInt size)); 296 | extern voidp calloc OF((uInt items, uInt size)); 297 | extern void free OF((voidpf ptr)); 298 | #endif 299 | 300 | voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) 301 | voidpf opaque; 302 | unsigned items; 303 | unsigned size; 304 | { 305 | if (opaque) items += size - size; /* make compiler happy */ 306 | return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : 307 | (voidpf)calloc(items, size); 308 | } 309 | 310 | void ZLIB_INTERNAL zcfree (opaque, ptr) 311 | voidpf opaque; 312 | voidpf ptr; 313 | { 314 | free(ptr); 315 | if (opaque) return; /* make compiler happy */ 316 | } 317 | 318 | #endif /* MY_ZCALLOC */ 319 | -------------------------------------------------------------------------------- /test-server/test-fraggle.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libwebsockets-test-fraggle - random fragmentation test 3 | * 4 | * Copyright (C) 2010-2011 Andy Green 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation: 9 | * version 2.1 of the License. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19 | * MA 02110-1301 USA 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "../lib/libwebsockets.h" 30 | 31 | #define LOCAL_RESOURCE_PATH DATADIR"/libwebsockets-test-server" 32 | 33 | static int client; 34 | static int terminate; 35 | 36 | enum demo_protocols { 37 | PROTOCOL_FRAGGLE, 38 | 39 | /* always last */ 40 | DEMO_PROTOCOL_COUNT 41 | }; 42 | 43 | /* fraggle protocol */ 44 | 45 | enum fraggle_states { 46 | FRAGSTATE_START_MESSAGE, 47 | FRAGSTATE_RANDOM_PAYLOAD, 48 | FRAGSTATE_POST_PAYLOAD_SUM, 49 | }; 50 | 51 | struct per_session_data__fraggle { 52 | int packets_left; 53 | int total_message; 54 | unsigned long sum; 55 | enum fraggle_states state; 56 | }; 57 | 58 | static int 59 | callback_fraggle(struct libwebsocket_context * context, 60 | struct libwebsocket *wsi, 61 | enum libwebsocket_callback_reasons reason, 62 | void *user, void *in, size_t len) 63 | { 64 | int n; 65 | unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2048 + 66 | LWS_SEND_BUFFER_POST_PADDING]; 67 | struct per_session_data__fraggle *psf = user; 68 | int chunk; 69 | int write_mode = LWS_WRITE_CONTINUATION; 70 | unsigned long sum; 71 | unsigned char *p = (unsigned char *)in; 72 | unsigned char *bp = &buf[LWS_SEND_BUFFER_PRE_PADDING]; 73 | 74 | switch (reason) { 75 | 76 | case LWS_CALLBACK_ESTABLISHED: 77 | 78 | fprintf(stderr, "server sees client connect\n"); 79 | psf->state = FRAGSTATE_START_MESSAGE; 80 | /* start the ball rolling */ 81 | libwebsocket_callback_on_writable(context, wsi); 82 | break; 83 | 84 | case LWS_CALLBACK_CLIENT_ESTABLISHED: 85 | 86 | fprintf(stderr, "client connects to server\n"); 87 | psf->state = FRAGSTATE_START_MESSAGE; 88 | break; 89 | 90 | case LWS_CALLBACK_CLIENT_RECEIVE: 91 | 92 | switch (psf->state) { 93 | 94 | case FRAGSTATE_START_MESSAGE: 95 | 96 | psf->state = FRAGSTATE_RANDOM_PAYLOAD; 97 | psf->sum = 0; 98 | psf->total_message = 0; 99 | psf->packets_left = 0; 100 | 101 | /* fallthru */ 102 | 103 | case FRAGSTATE_RANDOM_PAYLOAD: 104 | 105 | for (n = 0; n < len; n++) 106 | psf->sum += p[n]; 107 | 108 | psf->total_message += len; 109 | psf->packets_left++; 110 | 111 | if (libwebsocket_is_final_fragment(wsi)) 112 | psf->state = FRAGSTATE_POST_PAYLOAD_SUM; 113 | break; 114 | 115 | case FRAGSTATE_POST_PAYLOAD_SUM: 116 | 117 | sum = p[0] << 24; 118 | sum |= p[1] << 16; 119 | sum |= p[2] << 8; 120 | sum |= p[3]; 121 | if (sum == psf->sum) 122 | fprintf(stderr, "EOM received %d correctly " 123 | "from %d fragments\n", 124 | psf->total_message, psf->packets_left); 125 | else 126 | fprintf(stderr, "**** ERROR at EOM: " 127 | "length %d, rx sum = 0x%lX, " 128 | "server says it sent 0x%lX\n", 129 | psf->total_message, psf->sum, sum); 130 | 131 | psf->state = FRAGSTATE_START_MESSAGE; 132 | break; 133 | } 134 | break; 135 | 136 | case LWS_CALLBACK_SERVER_WRITEABLE: 137 | 138 | switch (psf->state) { 139 | 140 | case FRAGSTATE_START_MESSAGE: 141 | 142 | psf->packets_left = (random() % 1024) + 1; 143 | fprintf(stderr, "Spamming %d random fragments\n", 144 | psf->packets_left); 145 | psf->sum = 0; 146 | psf->total_message = 0; 147 | write_mode = LWS_WRITE_BINARY; 148 | psf->state = FRAGSTATE_RANDOM_PAYLOAD; 149 | 150 | /* fallthru */ 151 | 152 | case FRAGSTATE_RANDOM_PAYLOAD: 153 | 154 | chunk = (random() % 2000) + 1; 155 | psf->total_message += chunk; 156 | 157 | libwebsockets_get_random(context, bp, chunk); 158 | for (n = 0; n < chunk; n++) 159 | psf->sum += bp[n]; 160 | 161 | psf->packets_left--; 162 | if (psf->packets_left) 163 | write_mode |= LWS_WRITE_NO_FIN; 164 | else 165 | psf->state = FRAGSTATE_POST_PAYLOAD_SUM; 166 | 167 | n = libwebsocket_write(wsi, bp, chunk, write_mode); 168 | 169 | libwebsocket_callback_on_writable(context, wsi); 170 | break; 171 | 172 | case FRAGSTATE_POST_PAYLOAD_SUM: 173 | 174 | fprintf(stderr, "Spamming session over, " 175 | "len = %d. sum = 0x%lX\n", 176 | psf->total_message, psf->sum); 177 | 178 | bp[0] = psf->sum >> 24; 179 | bp[1] = psf->sum >> 16; 180 | bp[2] = psf->sum >> 8; 181 | bp[3] = psf->sum; 182 | 183 | n = libwebsocket_write(wsi, (unsigned char *)bp, 184 | 4, LWS_WRITE_BINARY); 185 | 186 | psf->state = FRAGSTATE_START_MESSAGE; 187 | 188 | libwebsocket_callback_on_writable(context, wsi); 189 | break; 190 | } 191 | break; 192 | 193 | case LWS_CALLBACK_CLOSED: 194 | 195 | terminate = 1; 196 | break; 197 | 198 | /* because we are protocols[0] ... */ 199 | 200 | case LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED: 201 | if (strcmp(in, "deflate-stream") == 0) { 202 | fprintf(stderr, "denied deflate-stream extension\n"); 203 | return 1; 204 | } 205 | break; 206 | 207 | default: 208 | break; 209 | } 210 | 211 | return 0; 212 | } 213 | 214 | 215 | 216 | /* list of supported protocols and callbacks */ 217 | 218 | static struct libwebsocket_protocols protocols[] = { 219 | { 220 | "fraggle-protocol", 221 | callback_fraggle, 222 | sizeof(struct per_session_data__fraggle), 223 | }, 224 | { 225 | NULL, NULL, 0 /* End of list */ 226 | } 227 | }; 228 | 229 | static struct option options[] = { 230 | { "help", no_argument, NULL, 'h' }, 231 | { "port", required_argument, NULL, 'p' }, 232 | { "ssl", no_argument, NULL, 's' }, 233 | { "killmask", no_argument, NULL, 'k' }, 234 | { "interface", required_argument, NULL, 'i' }, 235 | { "client", no_argument, NULL, 'c' }, 236 | { NULL, 0, 0, 0 } 237 | }; 238 | 239 | int main(int argc, char **argv) 240 | { 241 | int n = 0; 242 | const char *cert_path = 243 | LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem"; 244 | const char *key_path = 245 | LOCAL_RESOURCE_PATH"/libwebsockets-test-server.key.pem"; 246 | int port = 7681; 247 | int use_ssl = 0; 248 | struct libwebsocket_context *context; 249 | int opts = 0; 250 | char interface_name[128] = ""; 251 | const char * interface = NULL; 252 | struct libwebsocket *wsi; 253 | const char *address; 254 | int server_port = port; 255 | 256 | fprintf(stderr, "libwebsockets test fraggle\n" 257 | "(C) Copyright 2010-2011 Andy Green " 258 | "licensed under LGPL2.1\n"); 259 | 260 | while (n >= 0) { 261 | n = getopt_long(argc, argv, "ci:khsp:", options, NULL); 262 | if (n < 0) 263 | continue; 264 | switch (n) { 265 | case 's': 266 | use_ssl = 1; 267 | break; 268 | case 'k': 269 | opts = LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK; 270 | break; 271 | case 'p': 272 | port = atoi(optarg); 273 | server_port = port; 274 | break; 275 | case 'i': 276 | strncpy(interface_name, optarg, sizeof interface_name); 277 | interface_name[(sizeof interface_name) - 1] = '\0'; 278 | interface = interface_name; 279 | break; 280 | case 'c': 281 | client = 1; 282 | fprintf(stderr, " Client mode\n"); 283 | break; 284 | case 'h': 285 | fprintf(stderr, "Usage: libwebsockets-test-fraggle " 286 | "[--port=

] [--ssl] [--client]\n"); 287 | exit(1); 288 | } 289 | } 290 | 291 | if (client) { 292 | server_port = CONTEXT_PORT_NO_LISTEN; 293 | if (optind >= argc) { 294 | fprintf(stderr, "Must give address of server\n"); 295 | return 1; 296 | } 297 | } 298 | 299 | if (!use_ssl) 300 | cert_path = key_path = NULL; 301 | 302 | context = libwebsocket_create_context(server_port, interface, protocols, 303 | libwebsocket_internal_extensions, 304 | cert_path, key_path, -1, -1, opts); 305 | if (context == NULL) { 306 | fprintf(stderr, "libwebsocket init failed\n"); 307 | return -1; 308 | } 309 | 310 | if (client) { 311 | address = argv[optind]; 312 | fprintf(stderr, "Connecting to %s:%u\n", address, port); 313 | wsi = libwebsocket_client_connect(context, address, 314 | port, use_ssl, "/", address, 315 | "origin", protocols[PROTOCOL_FRAGGLE].name, 316 | -1); 317 | if (wsi == NULL) { 318 | fprintf(stderr, "Client connect to server failed\n"); 319 | goto bail; 320 | } 321 | } 322 | 323 | n = 0; 324 | while (!n && !terminate) 325 | n = libwebsocket_service(context, 50); 326 | 327 | fprintf(stderr, "Terminating...\n"); 328 | 329 | bail: 330 | libwebsocket_context_destroy(context); 331 | 332 | return 0; 333 | } 334 | -------------------------------------------------------------------------------- /test-server/test-client.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libwebsockets-test-client - libwebsockets test implementation 3 | * 4 | * Copyright (C) 2011 Andy Green 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation: 9 | * version 2.1 of the License. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19 | * MA 02110-1301 USA 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "../lib/libwebsockets.h" 29 | 30 | static unsigned int opts; 31 | static int was_closed; 32 | static int deny_deflate; 33 | static int deny_mux; 34 | static struct libwebsocket *wsi_mirror; 35 | 36 | /* 37 | * This demo shows how to connect multiple websockets simultaneously to a 38 | * websocket server (there is no restriction on their having to be the same 39 | * server just it simplifies the demo). 40 | * 41 | * dumb-increment-protocol: we connect to the server and print the number 42 | * we are given 43 | * 44 | * lws-mirror-protocol: draws random circles, which are mirrored on to every 45 | * client (see them being drawn in every browser 46 | * session also using the test server) 47 | */ 48 | 49 | enum demo_protocols { 50 | 51 | PROTOCOL_DUMB_INCREMENT, 52 | PROTOCOL_LWS_MIRROR, 53 | 54 | /* always last */ 55 | DEMO_PROTOCOL_COUNT 56 | }; 57 | 58 | 59 | /* dumb_increment protocol */ 60 | 61 | static int 62 | callback_dumb_increment(struct libwebsocket_context * this, 63 | struct libwebsocket *wsi, 64 | enum libwebsocket_callback_reasons reason, 65 | void *user, void *in, size_t len) 66 | { 67 | switch (reason) { 68 | 69 | case LWS_CALLBACK_CLOSED: 70 | fprintf(stderr, "LWS_CALLBACK_CLOSED\n"); 71 | was_closed = 1; 72 | break; 73 | 74 | case LWS_CALLBACK_CLIENT_RECEIVE: 75 | ((char *)in)[len] = '\0'; 76 | fprintf(stderr, "rx %d '%s'\n", (int)len, (char *)in); 77 | break; 78 | 79 | /* because we are protocols[0] ... */ 80 | 81 | case LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED: 82 | if ((strcmp(in, "deflate-stream") == 0) && deny_deflate) { 83 | fprintf(stderr, "denied deflate-stream extension\n"); 84 | return 1; 85 | } 86 | if ((strcmp(in, "x-google-mux") == 0) && deny_mux) { 87 | fprintf(stderr, "denied x-google-mux extension\n"); 88 | return 1; 89 | } 90 | 91 | break; 92 | 93 | default: 94 | break; 95 | } 96 | 97 | return 0; 98 | } 99 | 100 | 101 | /* lws-mirror_protocol */ 102 | 103 | 104 | static int 105 | callback_lws_mirror(struct libwebsocket_context * this, 106 | struct libwebsocket *wsi, 107 | enum libwebsocket_callback_reasons reason, 108 | void *user, void *in, size_t len) 109 | { 110 | unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 4096 + 111 | LWS_SEND_BUFFER_POST_PADDING]; 112 | int l; 113 | 114 | switch (reason) { 115 | 116 | case LWS_CALLBACK_CLOSED: 117 | fprintf(stderr, "mirror: LWS_CALLBACK_CLOSED\n"); 118 | wsi_mirror = NULL; 119 | break; 120 | 121 | case LWS_CALLBACK_CLIENT_ESTABLISHED: 122 | 123 | /* 124 | * start the ball rolling, 125 | * LWS_CALLBACK_CLIENT_WRITEABLE will come next service 126 | */ 127 | 128 | libwebsocket_callback_on_writable(this, wsi); 129 | break; 130 | 131 | case LWS_CALLBACK_CLIENT_RECEIVE: 132 | /* fprintf(stderr, "rx %d '%s'\n", (int)len, (char *)in); */ 133 | break; 134 | 135 | case LWS_CALLBACK_CLIENT_WRITEABLE: 136 | 137 | l = sprintf((char *)&buf[LWS_SEND_BUFFER_PRE_PADDING], 138 | "c #%06X %d %d %d;", 139 | (int)random() & 0xffffff, 140 | (int)random() % 500, 141 | (int)random() % 250, 142 | (int)random() % 24); 143 | 144 | libwebsocket_write(wsi, 145 | &buf[LWS_SEND_BUFFER_PRE_PADDING], l, opts | LWS_WRITE_TEXT); 146 | 147 | /* get notified as soon as we can write again */ 148 | 149 | libwebsocket_callback_on_writable(this, wsi); 150 | 151 | /* 152 | * without at least this delay, we choke the browser 153 | * and the connection stalls, despite we now take care about 154 | * flow control 155 | */ 156 | 157 | usleep(200); 158 | break; 159 | 160 | default: 161 | break; 162 | } 163 | 164 | return 0; 165 | } 166 | 167 | 168 | /* list of supported protocols and callbacks */ 169 | 170 | static struct libwebsocket_protocols protocols[] = { 171 | { 172 | "dumb-increment-protocol", 173 | callback_dumb_increment, 174 | 0, 175 | }, 176 | { 177 | "lws-mirror-protocol", 178 | callback_lws_mirror, 179 | 0, 180 | }, 181 | { /* end of list */ 182 | NULL, 183 | NULL, 184 | 0 185 | } 186 | }; 187 | 188 | static struct option options[] = { 189 | { "help", no_argument, NULL, 'h' }, 190 | { "port", required_argument, NULL, 'p' }, 191 | { "ssl", no_argument, NULL, 's' }, 192 | { "killmask", no_argument, NULL, 'k' }, 193 | { "version", required_argument, NULL, 'v' }, 194 | { "undeflated", no_argument, NULL, 'u' }, 195 | { "nomux", no_argument, NULL, 'n' }, 196 | { NULL, 0, 0, 0 } 197 | }; 198 | 199 | 200 | int main(int argc, char **argv) 201 | { 202 | int n = 0; 203 | int port = 7681; 204 | int use_ssl = 0; 205 | struct libwebsocket_context *context; 206 | const char *address; 207 | struct libwebsocket *wsi_dumb; 208 | int ietf_version = -1; /* latest */ 209 | int mirror_lifetime = 0; 210 | 211 | fprintf(stderr, "libwebsockets test client\n" 212 | "(C) Copyright 2010 Andy Green " 213 | "licensed under LGPL2.1\n"); 214 | 215 | if (argc < 2) 216 | goto usage; 217 | 218 | while (n >= 0) { 219 | n = getopt_long(argc, argv, "nuv:khsp:", options, NULL); 220 | if (n < 0) 221 | continue; 222 | switch (n) { 223 | case 's': 224 | use_ssl = 2; /* 2 = allow selfsigned */ 225 | break; 226 | case 'p': 227 | port = atoi(optarg); 228 | break; 229 | case 'k': 230 | opts = LWS_WRITE_CLIENT_IGNORE_XOR_MASK; 231 | break; 232 | case 'v': 233 | ietf_version = atoi(optarg); 234 | break; 235 | case 'u': 236 | deny_deflate = 1; 237 | break; 238 | case 'n': 239 | deny_mux = 1; 240 | break; 241 | case 'h': 242 | goto usage; 243 | } 244 | } 245 | 246 | if (optind >= argc) 247 | goto usage; 248 | 249 | address = argv[optind]; 250 | 251 | /* 252 | * create the websockets context. This tracks open connections and 253 | * knows how to route any traffic and which protocol version to use, 254 | * and if each connection is client or server side. 255 | * 256 | * For this client-only demo, we tell it to not listen on any port. 257 | */ 258 | 259 | context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, NULL, 260 | protocols, libwebsocket_internal_extensions, 261 | NULL, NULL, -1, -1, 0); 262 | if (context == NULL) { 263 | fprintf(stderr, "Creating libwebsocket context failed\n"); 264 | return 1; 265 | } 266 | 267 | 268 | /* create a client websocket using dumb increment protocol */ 269 | 270 | wsi_dumb = libwebsocket_client_connect(context, address, port, use_ssl, 271 | "/", argv[optind], argv[optind], 272 | protocols[PROTOCOL_DUMB_INCREMENT].name, ietf_version); 273 | 274 | if (wsi_dumb == NULL) { 275 | fprintf(stderr, "libwebsocket dumb connect failed\n"); 276 | return -1; 277 | } 278 | 279 | fprintf(stderr, "Websocket connections opened\n"); 280 | 281 | /* 282 | * sit there servicing the websocket context to handle incoming 283 | * packets, and drawing random circles on the mirror protocol websocket 284 | */ 285 | 286 | n = 0; 287 | while (n >= 0 && !was_closed) { 288 | n = libwebsocket_service(context, 1000); 289 | 290 | if (wsi_mirror == NULL) { 291 | 292 | /* create a client websocket using mirror protocol */ 293 | 294 | wsi_mirror = libwebsocket_client_connect(context, address, port, 295 | use_ssl, "/", argv[optind], argv[optind], 296 | protocols[PROTOCOL_LWS_MIRROR].name, ietf_version); 297 | 298 | if (wsi_mirror == NULL) { 299 | fprintf(stderr, "libwebsocket dumb connect failed\n"); 300 | return -1; 301 | } 302 | 303 | mirror_lifetime = 10 + (random() & 1023); 304 | 305 | fprintf(stderr, "opened mirror connection with %d lifetime\n", mirror_lifetime); 306 | 307 | } else { 308 | 309 | mirror_lifetime--; 310 | if (mirror_lifetime == 0) { 311 | fprintf(stderr, "closing mirror session\n"); 312 | libwebsocket_close_and_free_session(context, 313 | wsi_mirror, LWS_CLOSE_STATUS_GOINGAWAY); 314 | 315 | /* 316 | * wsi_mirror will get set to NULL in 317 | * callback when close completes 318 | */ 319 | } 320 | } 321 | } 322 | 323 | fprintf(stderr, "Exiting\n"); 324 | 325 | libwebsocket_context_destroy(context); 326 | 327 | return 0; 328 | 329 | usage: 330 | fprintf(stderr, "Usage: libwebsockets-test-client " 331 | " [--port=

] " 332 | "[--ssl] [-k] [-v ]\n"); 333 | return 1; 334 | } 335 | -------------------------------------------------------------------------------- /lib/client-handshake.c: -------------------------------------------------------------------------------- 1 | #include "private-libwebsockets.h" 2 | #include 3 | 4 | 5 | struct libwebsocket * __libwebsocket_client_connect_2( 6 | struct libwebsocket_context *context, 7 | struct libwebsocket *wsi 8 | ) { 9 | struct pollfd pfd; 10 | struct timeval tv; 11 | struct hostent *server_hostent; 12 | struct sockaddr_in server_addr; 13 | int n; 14 | int plen = 0; 15 | char pkt[512]; 16 | int opt = 1; 17 | #if defined(__APPLE__) 18 | struct protoent* tcp_proto; 19 | #endif 20 | 21 | fprintf(stderr, "__libwebsocket_client_connect_2\n"); 22 | 23 | wsi->candidate_children_list = NULL; 24 | 25 | /* 26 | * proxy? 27 | */ 28 | 29 | if (context->http_proxy_port) { 30 | plen = sprintf(pkt, "CONNECT %s:%u HTTP/1.0\x0d\x0a" 31 | "User-agent: libwebsockets\x0d\x0a" 32 | /*Proxy-authorization: basic aGVsbG86d29ybGQ= */ 33 | "\x0d\x0a", wsi->c_address, wsi->c_port); 34 | 35 | /* OK from now on we talk via the proxy */ 36 | 37 | free(wsi->c_address); 38 | wsi->c_address = strdup(context->http_proxy_address); 39 | wsi->c_port = context->http_proxy_port; 40 | } 41 | 42 | /* 43 | * prepare the actual connection (to the proxy, if any) 44 | */ 45 | 46 | fprintf(stderr, "__libwebsocket_client_connect_2: address %s", wsi->c_address); 47 | 48 | server_hostent = gethostbyname(wsi->c_address); 49 | if (server_hostent == NULL) { 50 | fprintf(stderr, "Unable to get host name from %s\n", 51 | wsi->c_address); 52 | goto oom4; 53 | } 54 | 55 | wsi->sock = socket(AF_INET, SOCK_STREAM, 0); 56 | 57 | if (wsi->sock < 0) { 58 | fprintf(stderr, "Unable to open socket\n"); 59 | goto oom4; 60 | } 61 | 62 | server_addr.sin_family = AF_INET; 63 | server_addr.sin_port = htons(wsi->c_port); 64 | server_addr.sin_addr = *((struct in_addr *)server_hostent->h_addr); 65 | bzero(&server_addr.sin_zero, 8); 66 | 67 | /* Disable Nagle */ 68 | #if !defined(__APPLE__) 69 | setsockopt(wsi->sock, SOL_TCP, TCP_NODELAY, (const void *)&opt, sizeof(opt)); 70 | #else 71 | tcp_proto = getprotobyname("TCP"); 72 | setsockopt(wsi->sock, tcp_proto->p_proto, TCP_NODELAY, &opt, sizeof(opt)); 73 | #endif 74 | 75 | /* Set receiving timeout */ 76 | tv.tv_sec = 0; 77 | tv.tv_usec = 100 * 1000; 78 | setsockopt(wsi->sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv); 79 | 80 | if (connect(wsi->sock, (struct sockaddr *)&server_addr, 81 | sizeof(struct sockaddr)) == -1) { 82 | fprintf(stderr, "Connect failed\n"); 83 | goto oom4; 84 | } 85 | 86 | fprintf(stderr, "connected\n"); 87 | 88 | /* into fd -> wsi hashtable */ 89 | 90 | insert_wsi(context, wsi); 91 | 92 | /* into internal poll list */ 93 | 94 | context->fds[context->fds_count].fd = wsi->sock; 95 | context->fds[context->fds_count].revents = 0; 96 | context->fds[context->fds_count++].events = POLLIN; 97 | 98 | /* external POLL support via protocol 0 */ 99 | context->protocols[0].callback(context, wsi, 100 | LWS_CALLBACK_ADD_POLL_FD, 101 | (void *)(long)wsi->sock, NULL, POLLIN); 102 | 103 | /* we are connected to server, or proxy */ 104 | 105 | if (context->http_proxy_port) { 106 | 107 | n = send(wsi->sock, pkt, plen, 0); 108 | if (n < 0) { 109 | #ifdef WIN32 110 | closesocket(wsi->sock); 111 | #else 112 | close(wsi->sock); 113 | #endif 114 | fprintf(stderr, "ERROR writing to proxy socket\n"); 115 | goto bail1; 116 | } 117 | 118 | libwebsocket_set_timeout(wsi, 119 | PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE, 5); 120 | 121 | wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY; 122 | 123 | return wsi; 124 | } 125 | 126 | /* 127 | * provoke service to issue the handshake directly 128 | * we need to do it this way because in the proxy case, this is the 129 | * next state and executed only if and when we get a good proxy 130 | * response inside the state machine 131 | */ 132 | 133 | wsi->mode = LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE; 134 | pfd.fd = wsi->sock; 135 | pfd.revents = POLLIN; 136 | libwebsocket_service_fd(context, &pfd); 137 | 138 | return wsi; 139 | 140 | oom4: 141 | if (wsi->c_protocol) 142 | free(wsi->c_protocol); 143 | 144 | if (wsi->c_origin) 145 | free(wsi->c_origin); 146 | 147 | free(wsi->c_host); 148 | free(wsi->c_path); 149 | 150 | bail1: 151 | free(wsi); 152 | 153 | return NULL; 154 | } 155 | 156 | /** 157 | * libwebsocket_client_connect() - Connect to another websocket server 158 | * @context: Websocket context 159 | * @address: Remote server address, eg, "myserver.com" 160 | * @port: Port to connect to on the remote server, eg, 80 161 | * @ssl_connection: 0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self 162 | * signed certs 163 | * @path: Websocket path on server 164 | * @host: Hostname on server 165 | * @origin: Socket origin name 166 | * @protocol: Comma-separated list of protocols being asked for from 167 | * the server, or just one. The server will pick the one it 168 | * likes best. 169 | * @ietf_version_or_minus_one: -1 to ask to connect using the default, latest 170 | * protocol supported, or the specific protocol ordinal 171 | * 172 | * This function creates a connection to a remote server 173 | */ 174 | 175 | struct libwebsocket * 176 | libwebsocket_client_connect(struct libwebsocket_context *context, 177 | const char *address, 178 | int port, 179 | int ssl_connection, 180 | const char *path, 181 | const char *host, 182 | const char *origin, 183 | const char *protocol, 184 | int ietf_version_or_minus_one) 185 | { 186 | struct libwebsocket *wsi; 187 | int n; 188 | int m; 189 | struct libwebsocket_extension *ext; 190 | int handled; 191 | #ifndef LWS_OPENSSL_SUPPORT 192 | if (ssl_connection) { 193 | fprintf(stderr, "libwebsockets not configured for ssl\n"); 194 | return NULL; 195 | } 196 | #endif 197 | 198 | wsi = malloc(sizeof(struct libwebsocket)); 199 | if (wsi == NULL) 200 | goto bail1; 201 | 202 | memset(wsi, 0, sizeof *wsi); 203 | 204 | /* -1 means just use latest supported */ 205 | 206 | if (ietf_version_or_minus_one == -1) 207 | ietf_version_or_minus_one = SPEC_LATEST_SUPPORTED; 208 | 209 | wsi->ietf_spec_revision = ietf_version_or_minus_one; 210 | wsi->name_buffer_pos = 0; 211 | wsi->user_space = NULL; 212 | wsi->state = WSI_STATE_CLIENT_UNCONNECTED; 213 | wsi->pings_vs_pongs = 0; 214 | wsi->protocol = NULL; 215 | wsi->pending_timeout = NO_PENDING_TIMEOUT; 216 | wsi->count_active_extensions = 0; 217 | #ifdef LWS_OPENSSL_SUPPORT 218 | wsi->use_ssl = ssl_connection; 219 | #endif 220 | 221 | wsi->c_port = port; 222 | wsi->c_address = strdup(address); 223 | 224 | /* copy parameters over so state machine has access */ 225 | 226 | wsi->c_path = malloc(strlen(path) + 1); 227 | if (wsi->c_path == NULL) 228 | goto bail1; 229 | strcpy(wsi->c_path, path); 230 | wsi->c_host = malloc(strlen(host) + 1); 231 | if (wsi->c_host == NULL) 232 | goto oom1; 233 | strcpy(wsi->c_host, host); 234 | if (origin) { 235 | wsi->c_origin = malloc(strlen(origin) + 1); 236 | strcpy(wsi->c_origin, origin); 237 | if (wsi->c_origin == NULL) 238 | goto oom2; 239 | } else 240 | wsi->c_origin = NULL; 241 | if (protocol) { 242 | wsi->c_protocol = malloc(strlen(protocol) + 1); 243 | if (wsi->c_protocol == NULL) 244 | goto oom3; 245 | strcpy(wsi->c_protocol, protocol); 246 | } else 247 | wsi->c_protocol = NULL; 248 | 249 | 250 | /* set up appropriate masking */ 251 | 252 | wsi->xor_mask = xor_no_mask; 253 | 254 | switch (wsi->ietf_spec_revision) { 255 | case 0: 256 | break; 257 | case 4: 258 | wsi->xor_mask = xor_mask_04; 259 | break; 260 | case 5: 261 | case 6: 262 | case 7: 263 | case 8: 264 | case 13: 265 | wsi->xor_mask = xor_mask_05; 266 | break; 267 | default: 268 | fprintf(stderr, 269 | "Client ietf version %d not supported\n", 270 | wsi->ietf_spec_revision); 271 | goto oom4; 272 | } 273 | 274 | /* force no mask if he asks for that though */ 275 | 276 | if (context->options & LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK) 277 | wsi->xor_mask = xor_no_mask; 278 | 279 | for (n = 0; n < WSI_TOKEN_COUNT; n++) { 280 | wsi->utf8_token[n].token = NULL; 281 | wsi->utf8_token[n].token_len = 0; 282 | } 283 | 284 | /* 285 | * Check with each extension if it is able to route and proxy this 286 | * connection for us. For example, an extension like x-google-mux 287 | * can handle this and then we don't need an actual socket for this 288 | * connection. 289 | */ 290 | 291 | handled = 0; 292 | ext = context->extensions; 293 | n = 0; 294 | 295 | while (ext && ext->callback && !handled) { 296 | m = ext->callback(context, ext, wsi, 297 | LWS_EXT_CALLBACK_CAN_PROXY_CLIENT_CONNECTION, 298 | (void *)(long)n, (void *)address, port); 299 | if (m) 300 | handled = 1; 301 | 302 | ext++; 303 | n++; 304 | } 305 | 306 | if (handled) { 307 | fprintf(stderr, "libwebsocket_client_connect: " 308 | "ext handling conn\n"); 309 | 310 | libwebsocket_set_timeout(wsi, 311 | PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE, 5); 312 | 313 | wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT; 314 | return wsi; 315 | } 316 | 317 | fprintf(stderr, "libwebsocket_client_connect: direct conn\n"); 318 | 319 | return __libwebsocket_client_connect_2(context, wsi); 320 | 321 | 322 | oom4: 323 | if (wsi->c_protocol) 324 | free(wsi->c_protocol); 325 | 326 | oom3: 327 | if (wsi->c_origin) 328 | free(wsi->c_origin); 329 | 330 | oom2: 331 | free(wsi->c_host); 332 | 333 | oom1: 334 | free(wsi->c_path); 335 | 336 | bail1: 337 | free(wsi); 338 | 339 | return NULL; 340 | } 341 | -------------------------------------------------------------------------------- /test-server/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Minimal Websocket test app 6 | 7 | 8 | 9 |

Detected Browser:
...

10 |

libwebsockets "dumb-increment-protocol" test applet

11 | The incrementing number is coming from the server and is individual for 12 | each connection to the server... try opening a second browser window. 13 | Click the button to send the server a websocket message to 14 | reset the number.

15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
Not initialized
23 | 24 |

libwebsockets "lws-mirror-protocol" test applet

25 | Use the mouse to draw on the canvas below -- all other browser windows open 26 | on this page see your drawing in realtime and you can see any of theirs as 27 | well. 28 |

29 | The lws-mirror protocol doesn't interpret what is being sent to it, it just 30 | re-sends it to every other websocket it has a connection with using that 31 | protocol, including the guy who sent the packet. 32 |

libwebsockets-test-client spams circles on to this shared canvas when 33 | run.

34 |

35 | 36 | 37 | 38 | 46 | 47 | 48 | 49 | 50 | 51 |
Drawing color: 39 | 45 |
Not initialized
52 | 53 | 359 | 360 | 361 | 362 | -------------------------------------------------------------------------------- /README-test-server: -------------------------------------------------------------------------------- 1 | Using test-server as a quickstart 2 | --------------------------------- 3 | 4 | For a Fedora x86_86 box, the following config line was 5 | needed: 6 | 7 | ./configure --prefix=/usr --libdir=/usr/lib64 --enable-openssl 8 | 9 | For Apple systems, Christopher Baker reported that this is needed 10 | (and I was told separately enabling openssl makes trouble somehow) 11 | 12 | ./configure CC="gcc -arch i386 -arch x86_64" CXX="g++ -arch i386 -arch 13 | x86_64" CPP="gcc -E" CXXCPP="g++ -E" --enable-nofork 14 | 15 | 16 | otherwise if /usr/local/... and /usr/local/lib are OK then... 17 | 18 | $ ./configure 19 | $ make clean 20 | $ make 21 | $ sudo make install 22 | $ libwebsockets-test-server 23 | 24 | should be enough to get a test server listening on port 7861. 25 | 26 | There are a couple of other possible configure options 27 | 28 | --enable-nofork disables the fork into the background API 29 | and removes all references to fork() and 30 | pr_ctl() from the sources. Use it if your 31 | platform doesn't support forking. 32 | 33 | --enable-libcrypto by default libwebsockets uses its own 34 | built-in md5 and sha-1 implementation for 35 | simplicity. However the libcrypto ones 36 | may be faster, and in a distro context it 37 | may be highly desirable to use a common 38 | library implementation for ease of security 39 | upgrades. Give this configure option 40 | to disable the built-in ones and force use 41 | of the libcrypto (part of openssl) ones. 42 | 43 | --with-client-cert-dir=dir tells the client ssl support where to 44 | look for trust certificates to validate 45 | the remote certificate against. 46 | 47 | --enable-noping Don't try to build the ping test app 48 | It needs some unixy environment that 49 | may choke in other build contexts, this 50 | lets you cleanly stop it being built 51 | 52 | --enable-x-google-mux Enable experimental x-google-mux support 53 | in the build (see notes later in document) 54 | 55 | Testing server with a browser 56 | ----------------------------- 57 | 58 | If you point your browser (eg, Chrome) to 59 | 60 | http://127.0.0.1:7681 61 | 62 | It will fetch a script in the form of test.html, and then run the 63 | script in there on the browser to open a websocket connection. 64 | Incrementing numbers should appear in the browser display. 65 | 66 | Using SSL on the server side 67 | ---------------------------- 68 | 69 | To test it using SSL/WSS, just run the test server with 70 | 71 | $ libwebsockets-test-server --ssl 72 | 73 | and use the URL 74 | 75 | https://127.0.0.1:7681 76 | 77 | The connection will be entirely encrypted using some generated 78 | certificates that your browser will not accept, since they are 79 | not signed by any real Certificate Authority. Just accept the 80 | certificates in the browser and the connection will proceed 81 | in first https and then websocket wss, acting exactly the 82 | same. 83 | 84 | test-server.c is all that is needed to use libwebsockets for 85 | serving both the script html over http and websockets. 86 | 87 | 88 | Forkless operation 89 | ------------------ 90 | 91 | If your target device does not offer fork(), you can use 92 | libwebsockets from your own main loop instead. Use the 93 | configure option --nofork and simply call libwebsocket_service() 94 | from your own main loop as shown in the test app sources. 95 | 96 | 97 | Testing websocket client support 98 | -------------------------------- 99 | 100 | If you run the test server as described above, you can also 101 | connect to it using the test client as well as a browser. 102 | 103 | $ libwebsockets-test-client localhost 104 | 105 | will by default connect to the test server on localhost:7681 106 | and print the dumb increment number from the server at the 107 | same time as drawing random circles in the mirror protocol; 108 | if you connect to the test server using a browser at the 109 | same time you will be able to see the circles being drawn. 110 | 111 | 112 | Testing SSL on the client side 113 | ------------------------------ 114 | 115 | To test SSL/WSS client action, just run the client test with 116 | 117 | $ libwebsockets-test-client localhost --ssl 118 | 119 | By default the client test applet is set to accept selfsigned 120 | certificates used by the test server, this is indicated by the 121 | use_ssl var being set to 2. Set it to 1 to reject any server 122 | certificate that it doesn't have a trusted CA cert for. 123 | 124 | 125 | Using the websocket ping utility 126 | -------------------------------- 127 | 128 | libwebsockets-test-ping connects as a client to a remote 129 | websocket server using 04 protocol and pings it like the 130 | normal unix ping utility. 131 | 132 | $ libwebsockets-test-ping localhost 133 | handshake OK for protocol lws-mirror-protocol 134 | Websocket PING localhost.localdomain (127.0.0.1) 64 bytes of data. 135 | 64 bytes from localhost: req=1 time=0.1ms 136 | 64 bytes from localhost: req=2 time=0.1ms 137 | 64 bytes from localhost: req=3 time=0.1ms 138 | 64 bytes from localhost: req=4 time=0.2ms 139 | 64 bytes from localhost: req=5 time=0.1ms 140 | 64 bytes from localhost: req=6 time=0.2ms 141 | 64 bytes from localhost: req=7 time=0.2ms 142 | 64 bytes from localhost: req=8 time=0.1ms 143 | ^C 144 | --- localhost.localdomain websocket ping statistics --- 145 | 8 packets transmitted, 8 received, 0% packet loss, time 7458ms 146 | rtt min/avg/max = 0.110/0.185/0.218 ms 147 | $ 148 | 149 | By default it sends 64 byte payload packets using the 04 150 | PING packet opcode type. You can change the payload size 151 | using the -s= flag, up to a maximum of 125 mandated by the 152 | 04 standard. 153 | 154 | Using the lws-mirror protocol that is provided by the test 155 | server, libwebsockets-test-ping can also use larger payload 156 | sizes up to 4096 is BINARY packets; lws-mirror will copy 157 | them back to the client and they appear as a PONG. Use the 158 | -m flag to select this operation. 159 | 160 | The default interval between pings is 1s, you can use the -i= 161 | flag to set this, including fractions like -i=0.01 for 10ms 162 | interval. 163 | 164 | Before you can even use the PING opcode that is part of the 165 | standard, you must complete a handshake with a specified 166 | protocol. By default lws-mirror-protocol is used which is 167 | supported by the test server. But if you are using it on 168 | another server, you can specify the protcol to handshake with 169 | by --protocol=protocolname 170 | 171 | 172 | Fraggle test app 173 | ---------------- 174 | 175 | By default it runs in server mode 176 | 177 | $ libwebsockets-test-fraggle 178 | libwebsockets test fraggle 179 | (C) Copyright 2010-2011 Andy Green licensed under LGPL2.1 180 | Compiled with SSL support, not using it 181 | Listening on port 7681 182 | server sees client connect 183 | accepted v06 connection 184 | Spamming 360 random fragments 185 | Spamming session over, len = 371913. sum = 0x2D3C0AE 186 | Spamming 895 random fragments 187 | Spamming session over, len = 875970. sum = 0x6A74DA1 188 | ... 189 | 190 | You need to run a second session in client mode, you have to 191 | give the -c switch and the server address at least: 192 | 193 | $ libwebsockets-test-fraggle -c localhost 194 | libwebsockets test fraggle 195 | (C) Copyright 2010-2011 Andy Green licensed under LGPL2.1 196 | Client mode 197 | Connecting to localhost:7681 198 | denied deflate-stream extension 199 | handshake OK for protocol fraggle-protocol 200 | client connects to server 201 | EOM received 371913 correctly from 360 fragments 202 | EOM received 875970 correctly from 895 fragments 203 | EOM received 247140 correctly from 258 fragments 204 | EOM received 695451 correctly from 692 fragments 205 | ... 206 | 207 | The fraggle test sends a random number up to 1024 fragmented websocket frames 208 | each of a random size between 1 and 2001 bytes in a single message, then sends 209 | a checksum and starts sending a new randomly sized and fragmented message. 210 | 211 | The fraggle test client receives the same message fragments and computes the 212 | same checksum using websocket framing to see when the message has ended. It 213 | then accepts the server checksum message and compares that to its checksum. 214 | 215 | 216 | proxy support 217 | ------------- 218 | 219 | The http_proxy environment variable is respected by the client 220 | connection code for both ws:// and wss://. It doesn't support 221 | authentication yet. 222 | 223 | You use it like this 224 | 225 | export http_proxy=myproxy.com:3128 226 | libwebsockets-test-client someserver.com 227 | 228 | 229 | Websocket version supported 230 | --------------------------- 231 | 232 | The websocket client code is 04 and 05 version, the server 233 | supports 00/76 in text mode and 04 and 05 dynamically 234 | per-connection depending on the version of the 235 | client / browser. 236 | 237 | 238 | External Polling Loop support 239 | ----------------------------- 240 | 241 | libwebsockets maintains an internal poll() array for all of its 242 | sockets, but you can instead integrate the sockets into an 243 | external polling array. That's needed if libwebsockets will 244 | cooperate with an existing poll array maintained by another 245 | server. 246 | 247 | Four callbacks LWS_CALLBACK_ADD_POLL_FD, LWS_CALLBACK_DEL_POLL_FD, 248 | LWS_CALLBACK_SET_MODE_POLL_FD and LWS_CALLBACK_CLEAR_MODE_POLL_FD 249 | appear in the callback for protocol 0 and allow interface code to 250 | manage socket descriptors in other poll loops. 251 | 252 | 253 | x-google-mux support 254 | -------------------- 255 | 256 | Experimental and super-preliminary x-google-mux support is available if 257 | enabled in ./configure with --enable-x-google-mux. Note that when changing 258 | configurations, you will need to do a make distclean before, then the new 259 | configure and then make ; make install. Don't forget the necessary other 260 | flags for your platform as described at the top of the readme. 261 | 262 | It has the following notes: 263 | 264 | 1) To enable it, reconfigure with --enable-x-google-mux 265 | 266 | 2) It deviates from the google standard by sending full 267 | headers in the addchannel subcommand rather than just 268 | changed ones from original connect 269 | 270 | 3) Quota is not implemented yet 271 | 272 | However despite those caveats, in fact it can run the 273 | test client reliably over one socket (both dumb-increment 274 | and lws-mirror-protocol), you can open a browser on the 275 | same test server too and see the circles, etc. 276 | 277 | It also works compatibly with deflate-stream automatically. 278 | 279 | 2011-05-28 Andy Green 280 | 281 | -------------------------------------------------------------------------------- /lib/sha-1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the project nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | /* 30 | * FIPS pub 180-1: Secure Hash Algorithm (SHA-1) 31 | * based on: http://csrc.nist.gov/fips/fip180-1.txt 32 | * implemented by Jun-ichiro itojun Itoh 33 | */ 34 | 35 | #include 36 | #ifdef WIN32 37 | 38 | typedef unsigned char u_int8_t; 39 | typedef unsigned int u_int32_t; 40 | typedef unsigned __int64 u_int64_t; 41 | typedef void* caddr_t; 42 | 43 | #undef __P 44 | #ifndef __P 45 | #if __STDC__ 46 | #define __P(protos) protos 47 | #else 48 | #define __P(protos) () 49 | #endif 50 | #endif 51 | 52 | #define bzero(b,len) (memset((b), '\0', (len)), (void) 0) 53 | 54 | #else 55 | #include 56 | #include 57 | #endif 58 | 59 | #include 60 | 61 | struct sha1_ctxt { 62 | union { 63 | u_int8_t b8[20]; 64 | u_int32_t b32[5]; 65 | } h; 66 | union { 67 | u_int8_t b8[8]; 68 | u_int64_t b64[1]; 69 | } c; 70 | union { 71 | u_int8_t b8[64]; 72 | u_int32_t b32[16]; 73 | } m; 74 | u_int8_t count; 75 | }; 76 | 77 | /* sanity check */ 78 | #if BYTE_ORDER != BIG_ENDIAN 79 | # if BYTE_ORDER != LITTLE_ENDIAN 80 | # define unsupported 1 81 | # endif 82 | #endif 83 | 84 | #ifndef unsupported 85 | 86 | /* constant table */ 87 | static u_int32_t _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 }; 88 | #define K(t) _K[(t) / 20] 89 | 90 | #define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d))) 91 | #define F1(b, c, d) (((b) ^ (c)) ^ (d)) 92 | #define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) 93 | #define F3(b, c, d) (((b) ^ (c)) ^ (d)) 94 | 95 | #define S(n, x) (((x) << (n)) | ((x) >> (32 - n))) 96 | 97 | #define H(n) (ctxt->h.b32[(n)]) 98 | #define COUNT (ctxt->count) 99 | #define BCOUNT (ctxt->c.b64[0] / 8) 100 | #define W(n) (ctxt->m.b32[(n)]) 101 | 102 | #define PUTBYTE(x) { \ 103 | ctxt->m.b8[(COUNT % 64)] = (x); \ 104 | COUNT++; \ 105 | COUNT %= 64; \ 106 | ctxt->c.b64[0] += 8; \ 107 | if (COUNT % 64 == 0) \ 108 | sha1_step(ctxt); \ 109 | } 110 | 111 | #define PUTPAD(x) { \ 112 | ctxt->m.b8[(COUNT % 64)] = (x); \ 113 | COUNT++; \ 114 | COUNT %= 64; \ 115 | if (COUNT % 64 == 0) \ 116 | sha1_step(ctxt); \ 117 | } 118 | 119 | static void sha1_step __P((struct sha1_ctxt *)); 120 | 121 | static void 122 | sha1_step(struct sha1_ctxt *ctxt) 123 | { 124 | u_int32_t a, b, c, d, e; 125 | size_t t, s; 126 | u_int32_t tmp; 127 | 128 | #if BYTE_ORDER == LITTLE_ENDIAN 129 | struct sha1_ctxt tctxt; 130 | 131 | memcpy(&tctxt.m.b8[0], &ctxt->m.b8[0], 64); 132 | ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2]; 133 | ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0]; 134 | ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6]; 135 | ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4]; 136 | ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10]; 137 | ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8]; 138 | ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14]; 139 | ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12]; 140 | ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18]; 141 | ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16]; 142 | ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22]; 143 | ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20]; 144 | ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26]; 145 | ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24]; 146 | ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30]; 147 | ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28]; 148 | ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34]; 149 | ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32]; 150 | ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38]; 151 | ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36]; 152 | ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42]; 153 | ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40]; 154 | ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46]; 155 | ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44]; 156 | ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50]; 157 | ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48]; 158 | ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54]; 159 | ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52]; 160 | ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58]; 161 | ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56]; 162 | ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62]; 163 | ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60]; 164 | #endif 165 | 166 | a = H(0); b = H(1); c = H(2); d = H(3); e = H(4); 167 | 168 | for (t = 0; t < 20; t++) { 169 | s = t & 0x0f; 170 | if (t >= 16) 171 | W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ 172 | W((s+2) & 0x0f) ^ W(s)); 173 | 174 | tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t); 175 | e = d; d = c; c = S(30, b); b = a; a = tmp; 176 | } 177 | for (t = 20; t < 40; t++) { 178 | s = t & 0x0f; 179 | W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ 180 | W((s+2) & 0x0f) ^ W(s)); 181 | tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t); 182 | e = d; d = c; c = S(30, b); b = a; a = tmp; 183 | } 184 | for (t = 40; t < 60; t++) { 185 | s = t & 0x0f; 186 | W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ 187 | W((s+2) & 0x0f) ^ W(s)); 188 | tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t); 189 | e = d; d = c; c = S(30, b); b = a; a = tmp; 190 | } 191 | for (t = 60; t < 80; t++) { 192 | s = t & 0x0f; 193 | W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ 194 | W((s+2) & 0x0f) ^ W(s)); 195 | tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t); 196 | e = d; d = c; c = S(30, b); b = a; a = tmp; 197 | } 198 | 199 | H(0) = H(0) + a; 200 | H(1) = H(1) + b; 201 | H(2) = H(2) + c; 202 | H(3) = H(3) + d; 203 | H(4) = H(4) + e; 204 | 205 | bzero(&ctxt->m.b8[0], 64); 206 | } 207 | 208 | /*------------------------------------------------------------*/ 209 | 210 | void 211 | sha1_init(struct sha1_ctxt *ctxt) 212 | { 213 | bzero(ctxt, sizeof(struct sha1_ctxt)); 214 | H(0) = 0x67452301; 215 | H(1) = 0xefcdab89; 216 | H(2) = 0x98badcfe; 217 | H(3) = 0x10325476; 218 | H(4) = 0xc3d2e1f0; 219 | } 220 | 221 | void 222 | sha1_pad(struct sha1_ctxt *ctxt) 223 | { 224 | size_t padlen; /*pad length in bytes*/ 225 | size_t padstart; 226 | 227 | PUTPAD(0x80); 228 | 229 | padstart = COUNT % 64; 230 | padlen = 64 - padstart; 231 | if (padlen < 8) { 232 | bzero(&ctxt->m.b8[padstart], padlen); 233 | COUNT += padlen; 234 | COUNT %= 64; 235 | sha1_step(ctxt); 236 | padstart = COUNT % 64; /* should be 0 */ 237 | padlen = 64 - padstart; /* should be 64 */ 238 | } 239 | bzero(&ctxt->m.b8[padstart], padlen - 8); 240 | COUNT += (padlen - 8); 241 | COUNT %= 64; 242 | #if BYTE_ORDER == BIG_ENDIAN 243 | PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]); 244 | PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]); 245 | PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]); 246 | PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]); 247 | #else 248 | PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]); 249 | PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]); 250 | PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]); 251 | PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]); 252 | #endif 253 | } 254 | 255 | void 256 | sha1_loop(struct sha1_ctxt *ctxt, const u_int8_t *input, size_t len) 257 | { 258 | size_t gaplen; 259 | size_t gapstart; 260 | size_t off; 261 | size_t copysiz; 262 | 263 | off = 0; 264 | 265 | while (off < len) { 266 | gapstart = COUNT % 64; 267 | gaplen = 64 - gapstart; 268 | 269 | copysiz = (gaplen < len - off) ? gaplen : len - off; 270 | memcpy(&ctxt->m.b8[gapstart], &input[off], copysiz); 271 | COUNT += copysiz; 272 | COUNT %= 64; 273 | ctxt->c.b64[0] += copysiz * 8; 274 | if (COUNT % 64 == 0) 275 | sha1_step(ctxt); 276 | off += copysiz; 277 | } 278 | } 279 | 280 | void 281 | sha1_result(struct sha1_ctxt *ctxt, caddr_t digest0) 282 | { 283 | u_int8_t *digest; 284 | 285 | digest = (u_int8_t *)digest0; 286 | sha1_pad(ctxt); 287 | #if BYTE_ORDER == BIG_ENDIAN 288 | memcpy(digest, &ctxt->h.b8[0], 20); 289 | #else 290 | digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2]; 291 | digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0]; 292 | digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6]; 293 | digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4]; 294 | digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10]; 295 | digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8]; 296 | digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14]; 297 | digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12]; 298 | digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18]; 299 | digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16]; 300 | #endif 301 | } 302 | 303 | /* 304 | * This should look and work like the libcrypto implementation 305 | */ 306 | 307 | unsigned char * 308 | SHA1(const unsigned char *d, size_t n, unsigned char *md) 309 | { 310 | struct sha1_ctxt ctx; 311 | 312 | sha1_init(&ctx); 313 | sha1_loop(&ctx, d, n); 314 | sha1_result(&ctx, (caddr_t)md); 315 | 316 | return md; 317 | } 318 | 319 | #endif /*unsupported*/ 320 | 321 | -------------------------------------------------------------------------------- /lib/private-libwebsockets.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libwebsockets - small server side websockets and web server implementation 3 | * 4 | * Copyright (C) 2010 Andy Green 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation: 9 | * version 2.1 of the License. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19 | * MA 02110-1301 USA 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | 36 | #ifdef WIN32 37 | 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #else 44 | 45 | #include 46 | #include 47 | #ifndef LWS_NO_FORK 48 | #include 49 | #endif 50 | #include 51 | #include 52 | #include 53 | 54 | #include 55 | #include 56 | #include 57 | 58 | #endif 59 | 60 | #ifdef LWS_OPENSSL_SUPPORT 61 | #include 62 | #include 63 | #include 64 | #include 65 | #include 66 | #endif 67 | 68 | 69 | #include "libwebsockets.h" 70 | 71 | #if 0 72 | #define DEBUG 73 | #endif 74 | 75 | #ifdef DEBUG 76 | #ifdef WIN32 77 | static 78 | #else 79 | static inline 80 | #endif 81 | void debug(const char *format, ...) 82 | { 83 | va_list ap; 84 | va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); 85 | } 86 | #else 87 | #ifdef WIN32 88 | static 89 | #else 90 | static inline 91 | #endif 92 | void debug(const char *format, ...) 93 | { 94 | } 95 | #endif 96 | 97 | 98 | /* 99 | * Mac OSX as well as iOS do not define the MSG_NOSIGNAL flag, 100 | * but happily have something equivalent in the SO_NOSIGPIPE flag. 101 | */ 102 | #ifdef __APPLE__ 103 | #define MSG_NOSIGNAL SO_NOSIGPIPE 104 | #endif 105 | 106 | 107 | #define FD_HASHTABLE_MODULUS 32 108 | #define MAX_CLIENTS 100 109 | #define LWS_MAX_HEADER_NAME_LENGTH 64 110 | #define LWS_MAX_HEADER_LEN 4096 111 | #define LWS_INITIAL_HDR_ALLOC 256 112 | #define LWS_ADDITIONAL_HDR_ALLOC 64 113 | #define MAX_USER_RX_BUFFER 4096 114 | #define MAX_BROADCAST_PAYLOAD 2048 115 | #define LWS_MAX_PROTOCOLS 10 116 | #define LWS_MAX_EXTENSIONS_ACTIVE 10 117 | #define SPEC_LATEST_SUPPORTED 13 118 | 119 | #define MAX_WEBSOCKET_04_KEY_LEN 128 120 | #define SYSTEM_RANDOM_FILEPATH "/dev/urandom" 121 | 122 | enum lws_websocket_opcodes_04 { 123 | LWS_WS_OPCODE_04__CONTINUATION = 0, 124 | LWS_WS_OPCODE_04__CLOSE = 1, 125 | LWS_WS_OPCODE_04__PING = 2, 126 | LWS_WS_OPCODE_04__PONG = 3, 127 | LWS_WS_OPCODE_04__TEXT_FRAME = 4, 128 | LWS_WS_OPCODE_04__BINARY_FRAME = 5, 129 | 130 | LWS_WS_OPCODE_04__RESERVED_6 = 6, 131 | LWS_WS_OPCODE_04__RESERVED_7 = 7, 132 | LWS_WS_OPCODE_04__RESERVED_8 = 8, 133 | LWS_WS_OPCODE_04__RESERVED_9 = 9, 134 | LWS_WS_OPCODE_04__RESERVED_A = 0xa, 135 | LWS_WS_OPCODE_04__RESERVED_B = 0xb, 136 | LWS_WS_OPCODE_04__RESERVED_C = 0xc, 137 | LWS_WS_OPCODE_04__RESERVED_D = 0xd, 138 | LWS_WS_OPCODE_04__RESERVED_E = 0xe, 139 | LWS_WS_OPCODE_04__RESERVED_F = 0xf, 140 | }; 141 | 142 | enum lws_websocket_opcodes_07 { 143 | LWS_WS_OPCODE_07__CONTINUATION = 0, 144 | LWS_WS_OPCODE_07__TEXT_FRAME = 1, 145 | LWS_WS_OPCODE_07__BINARY_FRAME = 2, 146 | 147 | LWS_WS_OPCODE_07__NOSPEC__MUX = 7, 148 | 149 | /* control extensions 8+ */ 150 | 151 | LWS_WS_OPCODE_07__CLOSE = 8, 152 | LWS_WS_OPCODE_07__PING = 9, 153 | LWS_WS_OPCODE_07__PONG = 0xa, 154 | }; 155 | 156 | 157 | enum lws_connection_states { 158 | WSI_STATE_HTTP, 159 | WSI_STATE_HTTP_HEADERS, 160 | WSI_STATE_DEAD_SOCKET, 161 | WSI_STATE_ESTABLISHED, 162 | WSI_STATE_CLIENT_UNCONNECTED, 163 | WSI_STATE_RETURNED_CLOSE_ALREADY, 164 | WSI_STATE_AWAITING_CLOSE_ACK, 165 | }; 166 | 167 | enum lws_rx_parse_state { 168 | LWS_RXPS_NEW, 169 | 170 | LWS_RXPS_SEEN_76_FF, 171 | LWS_RXPS_PULLING_76_LENGTH, 172 | LWS_RXPS_EAT_UNTIL_76_FF, 173 | 174 | LWS_RXPS_04_MASK_NONCE_1, 175 | LWS_RXPS_04_MASK_NONCE_2, 176 | LWS_RXPS_04_MASK_NONCE_3, 177 | 178 | LWS_RXPS_04_FRAME_HDR_1, 179 | LWS_RXPS_04_FRAME_HDR_LEN, 180 | LWS_RXPS_04_FRAME_HDR_LEN16_2, 181 | LWS_RXPS_04_FRAME_HDR_LEN16_1, 182 | LWS_RXPS_04_FRAME_HDR_LEN64_8, 183 | LWS_RXPS_04_FRAME_HDR_LEN64_7, 184 | LWS_RXPS_04_FRAME_HDR_LEN64_6, 185 | LWS_RXPS_04_FRAME_HDR_LEN64_5, 186 | LWS_RXPS_04_FRAME_HDR_LEN64_4, 187 | LWS_RXPS_04_FRAME_HDR_LEN64_3, 188 | LWS_RXPS_04_FRAME_HDR_LEN64_2, 189 | LWS_RXPS_04_FRAME_HDR_LEN64_1, 190 | 191 | LWS_RXPS_07_COLLECT_FRAME_KEY_1, 192 | LWS_RXPS_07_COLLECT_FRAME_KEY_2, 193 | LWS_RXPS_07_COLLECT_FRAME_KEY_3, 194 | LWS_RXPS_07_COLLECT_FRAME_KEY_4, 195 | 196 | LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED 197 | }; 198 | 199 | 200 | enum connection_mode { 201 | LWS_CONNMODE_WS_SERVING, 202 | LWS_CONNMODE_WS_CLIENT, 203 | 204 | /* transient modes */ 205 | LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY, 206 | LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE, 207 | LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY, 208 | LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT, 209 | LWS_CONNMODE_WS_CLIENT_PENDING_CANDIDATE_CHILD, 210 | 211 | /* special internal types */ 212 | LWS_CONNMODE_SERVER_LISTENER, 213 | LWS_CONNMODE_BROADCAST_PROXY_LISTENER, 214 | LWS_CONNMODE_BROADCAST_PROXY 215 | }; 216 | 217 | 218 | #define LWS_FD_HASH(fd) ((fd ^ (fd >> 8) ^ (fd >> 16)) % FD_HASHTABLE_MODULUS) 219 | 220 | struct libwebsocket_fd_hashtable { 221 | struct libwebsocket *wsi[MAX_CLIENTS + 1]; 222 | int length; 223 | }; 224 | 225 | struct libwebsocket_protocols; 226 | 227 | struct libwebsocket_context { 228 | struct libwebsocket_fd_hashtable fd_hashtable[FD_HASHTABLE_MODULUS]; 229 | struct pollfd fds[MAX_CLIENTS * FD_HASHTABLE_MODULUS + 1]; 230 | int fds_count; 231 | int listen_port; 232 | char http_proxy_address[256]; 233 | char canonical_hostname[1024]; 234 | unsigned int http_proxy_port; 235 | unsigned int options; 236 | unsigned long last_timeout_check_s; 237 | 238 | int fd_random; 239 | 240 | #ifdef LWS_OPENSSL_SUPPORT 241 | int use_ssl; 242 | SSL_CTX *ssl_ctx; 243 | SSL_CTX *ssl_client_ctx; 244 | #endif 245 | struct libwebsocket_protocols *protocols; 246 | int count_protocols; 247 | struct libwebsocket_extension *extensions; 248 | }; 249 | 250 | 251 | enum pending_timeout { 252 | NO_PENDING_TIMEOUT = 0, 253 | PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE, 254 | PENDING_TIMEOUT_ESTABLISH_WITH_SERVER, 255 | PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE, 256 | PENDING_TIMEOUT_AWAITING_PING, 257 | PENDING_TIMEOUT_CLOSE_ACK, 258 | PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE, 259 | }; 260 | 261 | 262 | /* 263 | * This is totally opaque to code using the library. It's exported as a 264 | * forward-reference pointer-only declaration; the user can use the pointer with 265 | * other APIs to get information out of it. 266 | */ 267 | 268 | struct libwebsocket { 269 | const struct libwebsocket_protocols *protocol; 270 | struct libwebsocket_extension * 271 | active_extensions[LWS_MAX_EXTENSIONS_ACTIVE]; 272 | void * active_extensions_user[LWS_MAX_EXTENSIONS_ACTIVE]; 273 | int count_active_extensions; 274 | 275 | enum lws_connection_states state; 276 | 277 | char name_buffer[LWS_MAX_HEADER_NAME_LENGTH]; 278 | int name_buffer_pos; 279 | int current_alloc_len; 280 | enum lws_token_indexes parser_state; 281 | struct lws_tokens utf8_token[WSI_TOKEN_COUNT]; 282 | int ietf_spec_revision; 283 | char rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + MAX_USER_RX_BUFFER + 284 | LWS_SEND_BUFFER_POST_PADDING]; 285 | int rx_user_buffer_head; 286 | enum libwebsocket_write_protocol rx_frame_type; 287 | int protocol_index_for_broadcast_proxy; 288 | enum pending_timeout pending_timeout; 289 | unsigned long pending_timeout_limit; 290 | 291 | int sock; 292 | 293 | enum lws_rx_parse_state lws_rx_parse_state; 294 | char extension_data_pending; 295 | struct libwebsocket *candidate_children_list; 296 | struct libwebsocket *extension_handles; 297 | 298 | /* 04 protocol specific */ 299 | 300 | char key_b64[150]; 301 | unsigned char masking_key_04[20]; 302 | unsigned char frame_masking_nonce_04[4]; 303 | unsigned char frame_mask_04[20]; 304 | unsigned char frame_mask_index; 305 | size_t rx_packet_length; 306 | unsigned char opcode; 307 | unsigned char final; 308 | 309 | int pings_vs_pongs; 310 | unsigned char (*xor_mask)(struct libwebsocket *, unsigned char); 311 | char all_zero_nonce; 312 | 313 | enum lws_close_status close_reason; 314 | 315 | /* 07 specific */ 316 | char this_frame_masked; 317 | 318 | /* client support */ 319 | char initial_handshake_hash_base64[30]; 320 | enum connection_mode mode; 321 | char *c_path; 322 | char *c_host; 323 | char *c_origin; 324 | char *c_protocol; 325 | 326 | char *c_address; 327 | int c_port; 328 | 329 | 330 | #ifdef LWS_OPENSSL_SUPPORT 331 | SSL *ssl; 332 | BIO *client_bio; 333 | int use_ssl; 334 | #endif 335 | 336 | void *user_space; 337 | }; 338 | 339 | extern int 340 | libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c); 341 | 342 | extern int 343 | libwebsocket_parse(struct libwebsocket *wsi, unsigned char c); 344 | 345 | extern int 346 | libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi, 347 | unsigned char *buf, size_t len); 348 | 349 | extern int 350 | libwebsocket_read(struct libwebsocket_context *context, struct libwebsocket *wsi, 351 | unsigned char * buf, size_t len); 352 | 353 | extern int 354 | lws_b64_selftest(void); 355 | 356 | extern unsigned char 357 | xor_no_mask(struct libwebsocket *wsi, unsigned char c); 358 | 359 | extern unsigned char 360 | xor_mask_04(struct libwebsocket *wsi, unsigned char c); 361 | 362 | extern unsigned char 363 | xor_mask_05(struct libwebsocket *wsi, unsigned char c); 364 | 365 | extern struct libwebsocket * 366 | wsi_from_fd(struct libwebsocket_context *context, int fd); 367 | 368 | extern int 369 | insert_wsi(struct libwebsocket_context *context, struct libwebsocket *wsi); 370 | 371 | extern int 372 | delete_from_fd(struct libwebsocket_context *context, int fd); 373 | 374 | extern void 375 | libwebsocket_set_timeout(struct libwebsocket *wsi, 376 | enum pending_timeout reason, int secs); 377 | 378 | extern int 379 | lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len); 380 | 381 | 382 | extern void 383 | libwebsocket_service_timeout_check(struct libwebsocket_context *context, 384 | struct libwebsocket *wsi, unsigned int sec); 385 | 386 | extern struct libwebsocket * __libwebsocket_client_connect_2( 387 | struct libwebsocket_context *context, 388 | struct libwebsocket *wsi); 389 | 390 | extern struct libwebsocket * 391 | libwebsocket_create_new_server_wsi(struct libwebsocket_context *context); 392 | 393 | extern char * 394 | libwebsockets_generate_client_handshake(struct libwebsocket_context *context, 395 | struct libwebsocket *wsi, char *pkt); 396 | 397 | extern int 398 | lws_handle_POLLOUT_event(struct libwebsocket_context *context, 399 | struct libwebsocket *wsi, struct pollfd *pollfd); 400 | 401 | extern int 402 | lws_any_extension_handled(struct libwebsocket_context *context, 403 | struct libwebsocket *wsi, 404 | enum libwebsocket_extension_callback_reasons r, 405 | void *v, size_t len); 406 | 407 | extern void * 408 | lws_get_extension_user_matching_ext(struct libwebsocket *wsi, 409 | struct libwebsocket_extension * ext); 410 | 411 | extern int 412 | lws_client_interpret_server_handshake(struct libwebsocket_context *context, 413 | struct libwebsocket *wsi); 414 | 415 | extern int 416 | libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c); 417 | 418 | extern int 419 | lws_issue_raw_ext_access(struct libwebsocket *wsi, 420 | unsigned char *buf, size_t len); 421 | 422 | #ifndef LWS_OPENSSL_SUPPORT 423 | 424 | unsigned char * 425 | SHA1(const unsigned char *d, size_t n, unsigned char *md); 426 | 427 | void 428 | MD5(const unsigned char *input, int ilen, unsigned char *output); 429 | 430 | #endif 431 | -------------------------------------------------------------------------------- /missing: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Common stub for a few missing GNU programs while installing. 3 | 4 | scriptversion=2009-04-28.21; # UTC 5 | 6 | # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 7 | # 2008, 2009 Free Software Foundation, Inc. 8 | # Originally by Fran,cois Pinard , 1996. 9 | 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 2, or (at your option) 13 | # any later version. 14 | 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | 23 | # As a special exception to the GNU General Public License, if you 24 | # distribute this file as part of a program that contains a 25 | # configuration script generated by Autoconf, you may include it under 26 | # the same distribution terms that you use for the rest of that program. 27 | 28 | if test $# -eq 0; then 29 | echo 1>&2 "Try \`$0 --help' for more information" 30 | exit 1 31 | fi 32 | 33 | run=: 34 | sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' 35 | sed_minuso='s/.* -o \([^ ]*\).*/\1/p' 36 | 37 | # In the cases where this matters, `missing' is being run in the 38 | # srcdir already. 39 | if test -f configure.ac; then 40 | configure_ac=configure.ac 41 | else 42 | configure_ac=configure.in 43 | fi 44 | 45 | msg="missing on your system" 46 | 47 | case $1 in 48 | --run) 49 | # Try to run requested program, and just exit if it succeeds. 50 | run= 51 | shift 52 | "$@" && exit 0 53 | # Exit code 63 means version mismatch. This often happens 54 | # when the user try to use an ancient version of a tool on 55 | # a file that requires a minimum version. In this case we 56 | # we should proceed has if the program had been absent, or 57 | # if --run hadn't been passed. 58 | if test $? = 63; then 59 | run=: 60 | msg="probably too old" 61 | fi 62 | ;; 63 | 64 | -h|--h|--he|--hel|--help) 65 | echo "\ 66 | $0 [OPTION]... PROGRAM [ARGUMENT]... 67 | 68 | Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an 69 | error status if there is no known handling for PROGRAM. 70 | 71 | Options: 72 | -h, --help display this help and exit 73 | -v, --version output version information and exit 74 | --run try to run the given command, and emulate it if it fails 75 | 76 | Supported PROGRAM values: 77 | aclocal touch file \`aclocal.m4' 78 | autoconf touch file \`configure' 79 | autoheader touch file \`config.h.in' 80 | autom4te touch the output file, or create a stub one 81 | automake touch all \`Makefile.in' files 82 | bison create \`y.tab.[ch]', if possible, from existing .[ch] 83 | flex create \`lex.yy.c', if possible, from existing .c 84 | help2man touch the output file 85 | lex create \`lex.yy.c', if possible, from existing .c 86 | makeinfo touch the output file 87 | tar try tar, gnutar, gtar, then tar without non-portable flags 88 | yacc create \`y.tab.[ch]', if possible, from existing .[ch] 89 | 90 | Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and 91 | \`g' are ignored when checking the name. 92 | 93 | Send bug reports to ." 94 | exit $? 95 | ;; 96 | 97 | -v|--v|--ve|--ver|--vers|--versi|--versio|--version) 98 | echo "missing $scriptversion (GNU Automake)" 99 | exit $? 100 | ;; 101 | 102 | -*) 103 | echo 1>&2 "$0: Unknown \`$1' option" 104 | echo 1>&2 "Try \`$0 --help' for more information" 105 | exit 1 106 | ;; 107 | 108 | esac 109 | 110 | # normalize program name to check for. 111 | program=`echo "$1" | sed ' 112 | s/^gnu-//; t 113 | s/^gnu//; t 114 | s/^g//; t'` 115 | 116 | # Now exit if we have it, but it failed. Also exit now if we 117 | # don't have it and --version was passed (most likely to detect 118 | # the program). This is about non-GNU programs, so use $1 not 119 | # $program. 120 | case $1 in 121 | lex*|yacc*) 122 | # Not GNU programs, they don't have --version. 123 | ;; 124 | 125 | tar*) 126 | if test -n "$run"; then 127 | echo 1>&2 "ERROR: \`tar' requires --run" 128 | exit 1 129 | elif test "x$2" = "x--version" || test "x$2" = "x--help"; then 130 | exit 1 131 | fi 132 | ;; 133 | 134 | *) 135 | if test -z "$run" && ($1 --version) > /dev/null 2>&1; then 136 | # We have it, but it failed. 137 | exit 1 138 | elif test "x$2" = "x--version" || test "x$2" = "x--help"; then 139 | # Could not run --version or --help. This is probably someone 140 | # running `$TOOL --version' or `$TOOL --help' to check whether 141 | # $TOOL exists and not knowing $TOOL uses missing. 142 | exit 1 143 | fi 144 | ;; 145 | esac 146 | 147 | # If it does not exist, or fails to run (possibly an outdated version), 148 | # try to emulate it. 149 | case $program in 150 | aclocal*) 151 | echo 1>&2 "\ 152 | WARNING: \`$1' is $msg. You should only need it if 153 | you modified \`acinclude.m4' or \`${configure_ac}'. You might want 154 | to install the \`Automake' and \`Perl' packages. Grab them from 155 | any GNU archive site." 156 | touch aclocal.m4 157 | ;; 158 | 159 | autoconf*) 160 | echo 1>&2 "\ 161 | WARNING: \`$1' is $msg. You should only need it if 162 | you modified \`${configure_ac}'. You might want to install the 163 | \`Autoconf' and \`GNU m4' packages. Grab them from any GNU 164 | archive site." 165 | touch configure 166 | ;; 167 | 168 | autoheader*) 169 | echo 1>&2 "\ 170 | WARNING: \`$1' is $msg. You should only need it if 171 | you modified \`acconfig.h' or \`${configure_ac}'. You might want 172 | to install the \`Autoconf' and \`GNU m4' packages. Grab them 173 | from any GNU archive site." 174 | files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` 175 | test -z "$files" && files="config.h" 176 | touch_files= 177 | for f in $files; do 178 | case $f in 179 | *:*) touch_files="$touch_files "`echo "$f" | 180 | sed -e 's/^[^:]*://' -e 's/:.*//'`;; 181 | *) touch_files="$touch_files $f.in";; 182 | esac 183 | done 184 | touch $touch_files 185 | ;; 186 | 187 | automake*) 188 | echo 1>&2 "\ 189 | WARNING: \`$1' is $msg. You should only need it if 190 | you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. 191 | You might want to install the \`Automake' and \`Perl' packages. 192 | Grab them from any GNU archive site." 193 | find . -type f -name Makefile.am -print | 194 | sed 's/\.am$/.in/' | 195 | while read f; do touch "$f"; done 196 | ;; 197 | 198 | autom4te*) 199 | echo 1>&2 "\ 200 | WARNING: \`$1' is needed, but is $msg. 201 | You might have modified some files without having the 202 | proper tools for further handling them. 203 | You can get \`$1' as part of \`Autoconf' from any GNU 204 | archive site." 205 | 206 | file=`echo "$*" | sed -n "$sed_output"` 207 | test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` 208 | if test -f "$file"; then 209 | touch $file 210 | else 211 | test -z "$file" || exec >$file 212 | echo "#! /bin/sh" 213 | echo "# Created by GNU Automake missing as a replacement of" 214 | echo "# $ $@" 215 | echo "exit 0" 216 | chmod +x $file 217 | exit 1 218 | fi 219 | ;; 220 | 221 | bison*|yacc*) 222 | echo 1>&2 "\ 223 | WARNING: \`$1' $msg. You should only need it if 224 | you modified a \`.y' file. You may need the \`Bison' package 225 | in order for those modifications to take effect. You can get 226 | \`Bison' from any GNU archive site." 227 | rm -f y.tab.c y.tab.h 228 | if test $# -ne 1; then 229 | eval LASTARG="\${$#}" 230 | case $LASTARG in 231 | *.y) 232 | SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` 233 | if test -f "$SRCFILE"; then 234 | cp "$SRCFILE" y.tab.c 235 | fi 236 | SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` 237 | if test -f "$SRCFILE"; then 238 | cp "$SRCFILE" y.tab.h 239 | fi 240 | ;; 241 | esac 242 | fi 243 | if test ! -f y.tab.h; then 244 | echo >y.tab.h 245 | fi 246 | if test ! -f y.tab.c; then 247 | echo 'main() { return 0; }' >y.tab.c 248 | fi 249 | ;; 250 | 251 | lex*|flex*) 252 | echo 1>&2 "\ 253 | WARNING: \`$1' is $msg. You should only need it if 254 | you modified a \`.l' file. You may need the \`Flex' package 255 | in order for those modifications to take effect. You can get 256 | \`Flex' from any GNU archive site." 257 | rm -f lex.yy.c 258 | if test $# -ne 1; then 259 | eval LASTARG="\${$#}" 260 | case $LASTARG in 261 | *.l) 262 | SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` 263 | if test -f "$SRCFILE"; then 264 | cp "$SRCFILE" lex.yy.c 265 | fi 266 | ;; 267 | esac 268 | fi 269 | if test ! -f lex.yy.c; then 270 | echo 'main() { return 0; }' >lex.yy.c 271 | fi 272 | ;; 273 | 274 | help2man*) 275 | echo 1>&2 "\ 276 | WARNING: \`$1' is $msg. You should only need it if 277 | you modified a dependency of a manual page. You may need the 278 | \`Help2man' package in order for those modifications to take 279 | effect. You can get \`Help2man' from any GNU archive site." 280 | 281 | file=`echo "$*" | sed -n "$sed_output"` 282 | test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` 283 | if test -f "$file"; then 284 | touch $file 285 | else 286 | test -z "$file" || exec >$file 287 | echo ".ab help2man is required to generate this page" 288 | exit $? 289 | fi 290 | ;; 291 | 292 | makeinfo*) 293 | echo 1>&2 "\ 294 | WARNING: \`$1' is $msg. You should only need it if 295 | you modified a \`.texi' or \`.texinfo' file, or any other file 296 | indirectly affecting the aspect of the manual. The spurious 297 | call might also be the consequence of using a buggy \`make' (AIX, 298 | DU, IRIX). You might want to install the \`Texinfo' package or 299 | the \`GNU make' package. Grab either from any GNU archive site." 300 | # The file to touch is that specified with -o ... 301 | file=`echo "$*" | sed -n "$sed_output"` 302 | test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` 303 | if test -z "$file"; then 304 | # ... or it is the one specified with @setfilename ... 305 | infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` 306 | file=`sed -n ' 307 | /^@setfilename/{ 308 | s/.* \([^ ]*\) *$/\1/ 309 | p 310 | q 311 | }' $infile` 312 | # ... or it is derived from the source name (dir/f.texi becomes f.info) 313 | test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info 314 | fi 315 | # If the file does not exist, the user really needs makeinfo; 316 | # let's fail without touching anything. 317 | test -f $file || exit 1 318 | touch $file 319 | ;; 320 | 321 | tar*) 322 | shift 323 | 324 | # We have already tried tar in the generic part. 325 | # Look for gnutar/gtar before invocation to avoid ugly error 326 | # messages. 327 | if (gnutar --version > /dev/null 2>&1); then 328 | gnutar "$@" && exit 0 329 | fi 330 | if (gtar --version > /dev/null 2>&1); then 331 | gtar "$@" && exit 0 332 | fi 333 | firstarg="$1" 334 | if shift; then 335 | case $firstarg in 336 | *o*) 337 | firstarg=`echo "$firstarg" | sed s/o//` 338 | tar "$firstarg" "$@" && exit 0 339 | ;; 340 | esac 341 | case $firstarg in 342 | *h*) 343 | firstarg=`echo "$firstarg" | sed s/h//` 344 | tar "$firstarg" "$@" && exit 0 345 | ;; 346 | esac 347 | fi 348 | 349 | echo 1>&2 "\ 350 | WARNING: I can't seem to be able to run \`tar' with the given arguments. 351 | You may want to install GNU tar or Free paxutils, or check the 352 | command line arguments." 353 | exit 1 354 | ;; 355 | 356 | *) 357 | echo 1>&2 "\ 358 | WARNING: \`$1' is needed, and is $msg. 359 | You might have modified some files without having the 360 | proper tools for further handling them. Check the \`README' file, 361 | it often tells you about the needed prerequisites for installing 362 | this package. You may also peek at any GNU archive site, in case 363 | some other package would contain this missing \`$1' program." 364 | exit 1 365 | ;; 366 | esac 367 | 368 | exit 0 369 | 370 | # Local variables: 371 | # eval: (add-hook 'write-file-hooks 'time-stamp) 372 | # time-stamp-start: "scriptversion=" 373 | # time-stamp-format: "%:y-%02m-%02d.%02H" 374 | # time-stamp-time-zone: "UTC" 375 | # time-stamp-end: "; # UTC" 376 | # End: 377 | -------------------------------------------------------------------------------- /test-server/test-ping.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libwebsockets-test-ping - libwebsockets floodping 3 | * 4 | * Copyright (C) 2011 Andy Green 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation: 9 | * version 2.1 of the License. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19 | * MA 02110-1301 USA 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | #include "../lib/libwebsockets.h" 38 | #include 39 | 40 | /* 41 | * this is specified in the 04 standard, control frames can only have small 42 | * payload length styles 43 | */ 44 | #define MAX_PING_PAYLOAD 125 45 | #define MAX_MIRROR_PAYLOAD 4096 46 | #define MAX_PING_CLIENTS 256 47 | #define PING_RINGBUFFER_SIZE 256 48 | 49 | static struct libwebsocket *ping_wsi[MAX_PING_CLIENTS]; 50 | static unsigned int interval_us = 1000000; 51 | static unsigned int size = 64; 52 | static int flood; 53 | static const char *address; 54 | static unsigned char pingbuf[LWS_SEND_BUFFER_PRE_PADDING + MAX_MIRROR_PAYLOAD + 55 | LWS_SEND_BUFFER_POST_PADDING]; 56 | static char peer_name[128]; 57 | static unsigned long started; 58 | static int screen_width = 80; 59 | static int use_mirror; 60 | static unsigned int write_options; 61 | 62 | static unsigned long rtt_min = 100000000; 63 | static unsigned long rtt_max; 64 | static unsigned long rtt_avg; 65 | static unsigned long global_rx_count; 66 | static unsigned long global_tx_count; 67 | static int clients = 1; 68 | static unsigned long interrupted_time; 69 | 70 | struct ping { 71 | unsigned long issue_timestamp; 72 | unsigned long index; 73 | unsigned int seen; 74 | }; 75 | 76 | struct per_session_data__ping { 77 | unsigned long ping_index; 78 | 79 | struct ping ringbuffer[PING_RINGBUFFER_SIZE]; 80 | int ringbuffer_head; 81 | int ringbuffer_tail; 82 | 83 | unsigned long rx_count; 84 | }; 85 | 86 | /* 87 | * uses the ping pong protocol features to provide an equivalent for the 88 | * ping utility for 04+ websockets 89 | */ 90 | 91 | enum demo_protocols { 92 | 93 | PROTOCOL_LWS_MIRROR, 94 | 95 | /* always last */ 96 | DEMO_PROTOCOL_COUNT 97 | }; 98 | 99 | 100 | static int 101 | callback_lws_mirror(struct libwebsocket_context * this, 102 | struct libwebsocket *wsi, 103 | enum libwebsocket_callback_reasons reason, 104 | void *user, void *in, size_t len) 105 | { 106 | struct timeval tv; 107 | unsigned char *p; 108 | int shift; 109 | unsigned long l; 110 | unsigned long iv; 111 | int n; 112 | int match = 0; 113 | struct per_session_data__ping *psd = user; 114 | 115 | switch (reason) { 116 | case LWS_CALLBACK_CLOSED: 117 | 118 | fprintf(stderr, "LWS_CALLBACK_CLOSED on %p\n", (void *)wsi); 119 | 120 | /* remove closed guy */ 121 | 122 | for (n = 0; n < clients; n++) 123 | if (ping_wsi[n] == wsi) { 124 | clients--; 125 | while (n < clients) { 126 | ping_wsi[n] = ping_wsi[n + 1]; 127 | n++; 128 | } 129 | } 130 | 131 | break; 132 | 133 | case LWS_CALLBACK_CLIENT_ESTABLISHED: 134 | 135 | psd->rx_count = 0; 136 | psd->ping_index = 1; 137 | psd->ringbuffer_head = 0; 138 | psd->ringbuffer_tail = 0; 139 | 140 | /* 141 | * start the ball rolling, 142 | * LWS_CALLBACK_CLIENT_WRITEABLE will come next service 143 | */ 144 | 145 | libwebsocket_callback_on_writable(this, wsi); 146 | break; 147 | 148 | case LWS_CALLBACK_CLIENT_RECEIVE: 149 | case LWS_CALLBACK_CLIENT_RECEIVE_PONG: 150 | gettimeofday(&tv, NULL); 151 | iv = (tv.tv_sec * 1000000) + tv.tv_usec; 152 | 153 | psd->rx_count++; 154 | 155 | shift = 56; 156 | p = in; 157 | l = 0; 158 | 159 | while (shift >= 0) { 160 | l |= (*p++) << shift; 161 | shift -= 8; 162 | } 163 | 164 | /* find it in the ringbuffer, look backwards from head */ 165 | n = psd->ringbuffer_head; 166 | while (!match) { 167 | 168 | if (psd->ringbuffer[n].index == l) { 169 | psd->ringbuffer[n].seen++; 170 | match = 1; 171 | continue; 172 | } 173 | 174 | if (n == psd->ringbuffer_tail) { 175 | match = -1; 176 | continue; 177 | } 178 | 179 | if (n == 0) 180 | n = PING_RINGBUFFER_SIZE - 1; 181 | else 182 | n--; 183 | } 184 | 185 | if (match < 1) { 186 | 187 | if (!flood) 188 | fprintf(stderr, "%d bytes from %s: req=%ld " 189 | "time=(unknown)\n", (int)len, address, l); 190 | else 191 | fprintf(stderr, "\b \b"); 192 | 193 | break; 194 | } 195 | 196 | if (psd->ringbuffer[n].seen > 1) 197 | fprintf(stderr, "DUP! "); 198 | 199 | if ((iv - psd->ringbuffer[n].issue_timestamp) < rtt_min) 200 | rtt_min = iv - psd->ringbuffer[n].issue_timestamp; 201 | 202 | if ((iv - psd->ringbuffer[n].issue_timestamp) > rtt_max) 203 | rtt_max = iv - psd->ringbuffer[n].issue_timestamp; 204 | 205 | rtt_avg += iv - psd->ringbuffer[n].issue_timestamp; 206 | global_rx_count++; 207 | 208 | if (!flood) 209 | fprintf(stderr, "%d bytes from %s: req=%ld " 210 | "time=%lu.%lums\n", (int)len, address, l, 211 | (iv - psd->ringbuffer[n].issue_timestamp) / 1000, 212 | ((iv - psd->ringbuffer[n].issue_timestamp) / 100) % 10); 213 | else 214 | fprintf(stderr, "\b \b"); 215 | break; 216 | 217 | case LWS_CALLBACK_CLIENT_WRITEABLE: 218 | 219 | shift = 56; 220 | p = &pingbuf[LWS_SEND_BUFFER_PRE_PADDING]; 221 | 222 | /* 64-bit ping index in network byte order */ 223 | 224 | while (shift >= 0) { 225 | *p++ = psd->ping_index >> shift; 226 | shift -= 8; 227 | } 228 | 229 | gettimeofday(&tv, NULL); 230 | 231 | psd->ringbuffer[psd->ringbuffer_head].issue_timestamp = 232 | (tv.tv_sec * 1000000) + tv.tv_usec; 233 | psd->ringbuffer[psd->ringbuffer_head].index = psd->ping_index++; 234 | psd->ringbuffer[psd->ringbuffer_head].seen = 0; 235 | 236 | if (psd->ringbuffer_head == PING_RINGBUFFER_SIZE - 1) 237 | psd->ringbuffer_head = 0; 238 | else 239 | psd->ringbuffer_head++; 240 | 241 | /* snip any re-used tail so we keep to the ring length */ 242 | 243 | if (psd->ringbuffer_tail == psd->ringbuffer_head) { 244 | if (psd->ringbuffer_tail == PING_RINGBUFFER_SIZE - 1) 245 | psd->ringbuffer_tail = 0; 246 | else 247 | psd->ringbuffer_tail++; 248 | } 249 | 250 | global_tx_count++; 251 | 252 | if (use_mirror) 253 | libwebsocket_write(wsi, 254 | &pingbuf[LWS_SEND_BUFFER_PRE_PADDING], 255 | size, write_options | LWS_WRITE_BINARY); 256 | else 257 | libwebsocket_write(wsi, 258 | &pingbuf[LWS_SEND_BUFFER_PRE_PADDING], 259 | size, write_options | LWS_WRITE_PING); 260 | 261 | if (flood && 262 | (psd->ping_index - psd->rx_count) < (screen_width - 1)) 263 | fprintf(stderr, "."); 264 | break; 265 | 266 | default: 267 | break; 268 | } 269 | 270 | return 0; 271 | } 272 | 273 | 274 | /* list of supported protocols and callbacks */ 275 | 276 | static struct libwebsocket_protocols protocols[] = { 277 | 278 | [PROTOCOL_LWS_MIRROR] = { 279 | .name = "lws-mirror-protocol", 280 | .callback = callback_lws_mirror, 281 | .per_session_data_size = sizeof (struct per_session_data__ping), 282 | }, 283 | [DEMO_PROTOCOL_COUNT] = { /* end of list */ 284 | .callback = NULL 285 | } 286 | }; 287 | 288 | static struct option options[] = { 289 | { "help", no_argument, NULL, 'h' }, 290 | { "port", required_argument, NULL, 'p' }, 291 | { "ssl", no_argument, NULL, 't' }, 292 | { "interval", required_argument, NULL, 'i' }, 293 | { "size", required_argument, NULL, 's' }, 294 | { "protocol", required_argument, NULL, 'n' }, 295 | { "flood", no_argument, NULL, 'f' }, 296 | { "mirror", no_argument, NULL, 'm' }, 297 | { "replicate", required_argument, NULL, 'r' }, 298 | { "killmask", no_argument, NULL, 'k' }, 299 | { "version", required_argument, NULL, 'v' }, 300 | { NULL, 0, 0, 0 } 301 | }; 302 | 303 | 304 | static void 305 | signal_handler(int sig, siginfo_t *si, void *v) 306 | { 307 | struct timeval tv; 308 | 309 | gettimeofday(&tv, NULL); 310 | interrupted_time = (tv.tv_sec * 1000000) + tv.tv_usec; 311 | } 312 | 313 | 314 | int main(int argc, char **argv) 315 | { 316 | int n = 0; 317 | int port = 7681; 318 | int use_ssl = 0; 319 | struct libwebsocket_context *context; 320 | char protocol_name[256]; 321 | char ip[30]; 322 | struct sigaction sa; 323 | struct timeval tv; 324 | struct winsize w; 325 | unsigned long oldus = 0; 326 | unsigned long l; 327 | int ietf_version = -1; 328 | 329 | if (argc < 2) 330 | goto usage; 331 | 332 | address = argv[1]; 333 | optind++; 334 | 335 | while (n >= 0) { 336 | n = getopt_long(argc, argv, "v:kr:hmfts:n:i:p:", options, NULL); 337 | if (n < 0) 338 | continue; 339 | switch (n) { 340 | case 'm': 341 | use_mirror = 1; 342 | break; 343 | case 't': 344 | use_ssl = 2; /* 2 = allow selfsigned */ 345 | break; 346 | case 'p': 347 | port = atoi(optarg); 348 | break; 349 | case 'n': 350 | strncpy(protocol_name, optarg, sizeof protocol_name); 351 | protocol_name[(sizeof protocol_name) - 1] = '\0'; 352 | protocols[PROTOCOL_LWS_MIRROR].name = protocol_name; 353 | break; 354 | case 'i': 355 | interval_us = 1000000.0 * atof(optarg); 356 | break; 357 | case 's': 358 | size = atoi(optarg); 359 | break; 360 | case 'f': 361 | flood = 1; 362 | break; 363 | case 'r': 364 | clients = atoi(optarg); 365 | if (clients > MAX_PING_CLIENTS || clients < 1) { 366 | fprintf(stderr, "Max clients supportd = %d\n", 367 | MAX_PING_CLIENTS); 368 | return 1; 369 | } 370 | break; 371 | case 'k': 372 | write_options = LWS_WRITE_CLIENT_IGNORE_XOR_MASK; 373 | break; 374 | case 'v': 375 | ietf_version = atoi(optarg); 376 | break; 377 | 378 | case 'h': 379 | goto usage; 380 | } 381 | } 382 | 383 | if (!use_mirror) { 384 | if (size > MAX_PING_PAYLOAD) { 385 | fprintf(stderr, "Max ping opcode payload size %d\n", 386 | MAX_PING_PAYLOAD); 387 | return 1; 388 | } 389 | } else { 390 | if (size > MAX_MIRROR_PAYLOAD) { 391 | fprintf(stderr, "Max mirror payload size %d\n", 392 | MAX_MIRROR_PAYLOAD); 393 | return 1; 394 | } 395 | } 396 | 397 | 398 | if (isatty(STDOUT_FILENO)) 399 | if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1) 400 | if (w.ws_col > 0) 401 | screen_width = w.ws_col; 402 | 403 | context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, NULL, 404 | protocols, 405 | libwebsocket_internal_extensions, 406 | NULL, NULL, -1, -1, 0); 407 | if (context == NULL) { 408 | fprintf(stderr, "Creating libwebsocket context failed\n"); 409 | return 1; 410 | } 411 | 412 | /* create client websockets using dumb increment protocol */ 413 | 414 | for (n = 0; n < clients; n++) { 415 | ping_wsi[n] = libwebsocket_client_connect(context, address, 416 | port, use_ssl, "/", address, 417 | "origin", protocols[PROTOCOL_LWS_MIRROR].name, 418 | ietf_version); 419 | if (ping_wsi[n] == NULL) { 420 | fprintf(stderr, "client connnection %d failed to " 421 | "connect\n", n); 422 | return 1; 423 | } 424 | } 425 | 426 | libwebsockets_get_peer_addresses( 427 | libwebsocket_get_socket_fd(ping_wsi[0]), 428 | peer_name, sizeof peer_name, ip, sizeof ip); 429 | 430 | fprintf(stderr, "Websocket PING %s (%s) %d bytes of data.\n", 431 | peer_name, ip, size); 432 | 433 | /* set the ^C handler */ 434 | 435 | sa.sa_sigaction = signal_handler; 436 | sa.sa_flags = SA_SIGINFO; 437 | sigemptyset(&sa.sa_mask); 438 | sigaction(SIGINT, &sa, NULL); 439 | 440 | gettimeofday(&tv, NULL); 441 | started = (tv.tv_sec * 1000000) + tv.tv_usec; 442 | 443 | /* service loop */ 444 | 445 | n = 0; 446 | while (n >= 0) { 447 | 448 | gettimeofday(&tv, NULL); 449 | l = (tv.tv_sec * 1000000) + tv.tv_usec; 450 | 451 | /* servers can hang up on us */ 452 | 453 | if (clients == 0) { 454 | n = -1; 455 | continue; 456 | } 457 | 458 | if (!interrupted_time) { 459 | if ((l - oldus) > interval_us) { 460 | for (n = 0; n < clients; n++) 461 | libwebsocket_callback_on_writable( 462 | context, ping_wsi[n]); 463 | oldus = l; 464 | } 465 | } else 466 | 467 | /* allow time for in-flight pongs to come */ 468 | 469 | if ((l - interrupted_time) > 250000) { 470 | n = -1; 471 | continue; 472 | } 473 | 474 | if (!interval_us) 475 | n = libwebsocket_service(context, 0); 476 | else 477 | n = libwebsocket_service(context, 1); 478 | } 479 | 480 | /* stats */ 481 | 482 | fprintf(stderr, "\n--- %s websocket ping statistics " 483 | "using %d connections ---\n" 484 | "%lu packets transmitted, %lu received, " 485 | "%lu%% packet loss, time %ldms\n" 486 | "rtt min/avg/max = %0.3f/%0.3f/%0.3f ms\n" 487 | "payload bandwidth average %0.3f KiBytes/sec\n", 488 | peer_name, clients, global_tx_count, global_rx_count, 489 | ((global_tx_count - global_rx_count) * 100) / global_tx_count, 490 | (l - started) / 1000, 491 | ((double)rtt_min) / 1000.0, 492 | ((double)rtt_avg / global_rx_count) / 1000.0, 493 | ((double)rtt_max) / 1000.0, 494 | ((double)global_rx_count * (double)size) / 495 | ((double)(l - started) / 1000000.0) / 1024.0); 496 | 497 | libwebsocket_context_destroy(context); 498 | 499 | return 0; 500 | 501 | usage: 502 | fprintf(stderr, "Usage: libwebsockets-test-ping " 503 | " [--port=

] " 504 | "[--ssl] [--interval=] " 505 | "[--size=] " 506 | "[--protocol=] " 507 | "[--mirror] " 508 | "[--replicate=clients>]" 509 | "[--version ]" 510 | "\n"); 511 | return 1; 512 | } 513 | --------------------------------------------------------------------------------