From d971a4b8a96e6467d10781c07702783c7078310e Mon Sep 17 00:00:00 2001 From: artygus Date: Tue, 14 Mar 2017 22:15:44 +0000 Subject: [PATCH 1/7] add config.h include to sources --- examples/dl_client.c | 4 ++++ examples/wi_client.c | 4 ++++ examples/ws_echo1.c | 4 ++++ examples/ws_echo2.c | 4 ++++ examples/ws_echo_common.c | 4 ++++ {src => include}/validate_utf8.h | 0 src/device_listener.c | 4 ++++ src/ios_webkit_debug_proxy.c | 7 +++---- src/port_config.c | 6 +++--- src/rpc.c | 4 ++++ src/socket_manager.c | 4 ++++ src/websocket.c | 4 ++++ 12 files changed, 42 insertions(+), 7 deletions(-) rename {src => include}/validate_utf8.h (100%) diff --git a/examples/dl_client.c b/examples/dl_client.c index 24d1544f..baec0bd1 100644 --- a/examples/dl_client.c +++ b/examples/dl_client.c @@ -5,6 +5,10 @@ // An example device_listener client // +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/examples/wi_client.c b/examples/wi_client.c index 091221fd..b85bec2f 100644 --- a/examples/wi_client.c +++ b/examples/wi_client.c @@ -5,6 +5,10 @@ // A minimal webinspector client // +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/examples/ws_echo1.c b/examples/ws_echo1.c index 16e42084..acf1a154 100644 --- a/examples/ws_echo1.c +++ b/examples/ws_echo1.c @@ -5,6 +5,10 @@ // A minimal websocket "echo" server // +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/examples/ws_echo2.c b/examples/ws_echo2.c index a38a802b..148e99f3 100644 --- a/examples/ws_echo2.c +++ b/examples/ws_echo2.c @@ -5,6 +5,10 @@ // A select-based websocket "echo" server // +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/examples/ws_echo_common.c b/examples/ws_echo_common.c index e6cbd442..ee23280f 100644 --- a/examples/ws_echo_common.c +++ b/examples/ws_echo_common.c @@ -5,6 +5,10 @@ // A minimal websocket "echo" server // +#ifdef HAVE_CONFIG_H +#include +#endif + #define _GNU_SOURCE #include #include diff --git a/src/validate_utf8.h b/include/validate_utf8.h similarity index 100% rename from src/validate_utf8.h rename to include/validate_utf8.h diff --git a/src/device_listener.c b/src/device_listener.c index f53ff7a9..2c298291 100644 --- a/src/device_listener.c +++ b/src/device_listener.c @@ -1,6 +1,10 @@ // Google BSD license https://developers.google.com/google-bsd-license // Copyright 2012 Google Inc. wrightt@google.com +#ifdef HAVE_CONFIG_H +#include +#endif + #define _GNU_SOURCE #include #include diff --git a/src/ios_webkit_debug_proxy.c b/src/ios_webkit_debug_proxy.c index 7d4283b1..a20d2dce 100644 --- a/src/ios_webkit_debug_proxy.c +++ b/src/ios_webkit_debug_proxy.c @@ -1,13 +1,12 @@ // Google BSD license https://developers.google.com/google-bsd-license // Copyright 2012 Google Inc. wrightt@google.com -// -// -// +#ifdef HAVE_CONFIG_H +#include +#endif #define _GNU_SOURCE #include -//#include //apt-get install libmagic-dev #include #include #include diff --git a/src/port_config.c b/src/port_config.c index 698d8834..60feb282 100644 --- a/src/port_config.c +++ b/src/port_config.c @@ -1,9 +1,9 @@ // Google BSD license https://developers.google.com/google-bsd-license // Copyright 2012 Google Inc. wrightt@google.com -// -// -// +#ifdef HAVE_CONFIG_H +#include +#endif #include #include diff --git a/src/rpc.c b/src/rpc.c index b47c55a0..429d5dd1 100644 --- a/src/rpc.c +++ b/src/rpc.c @@ -1,6 +1,10 @@ // Google BSD license https://developers.google.com/google-bsd-license // Copyright 2014 Google Inc. wrightt@google.com +#ifdef HAVE_CONFIG_H +#include +#endif + #define _GNU_SOURCE #include #include diff --git a/src/socket_manager.c b/src/socket_manager.c index 5680f471..5615ee97 100644 --- a/src/socket_manager.c +++ b/src/socket_manager.c @@ -1,6 +1,10 @@ // Google BSD license https://developers.google.com/google-bsd-license // Copyright 2012 Google Inc. wrightt@google.com +#ifdef HAVE_CONFIG_H +#include +#endif + #define _GNU_SOURCE #include #include diff --git a/src/websocket.c b/src/websocket.c index fa5b1dfe..b2714a4e 100644 --- a/src/websocket.c +++ b/src/websocket.c @@ -1,6 +1,10 @@ // Google BSD license https://developers.google.com/google-bsd-license // Copyright 2012 Google Inc. wrightt@google.com +#ifdef HAVE_CONFIG_H +#include +#endif + #define _GNU_SOURCE #include #include From 9c3334846d8a9cb5420feef9cd47ea12cdc2027d Mon Sep 17 00:00:00 2001 From: artygus Date: Tue, 14 Mar 2017 22:34:21 +0000 Subject: [PATCH 2/7] fallback to pcre if regex.h is missing --- configure.ac | 9 +++++++++ src/Makefile.am | 4 ++-- src/ios_webkit_debug_proxy_main.c | 8 +++++++- src/port_config.c | 8 +++++++- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 08bcc215..663fe63d 100644 --- a/configure.ac +++ b/configure.ac @@ -51,6 +51,15 @@ AC_TYPE_UINT8_T # Checks for library functions. AC_FUNC_MALLOC AC_FUNC_REALLOC + +# Check for pcre presence if regex.h is absent +AC_CHECK_HEADER(regex.h, [ac_have_regex_h="yes"], [ac_have_regex_h="no"]) +if test "x$ac_have_regex_h" = "xno"; then + PKG_CHECK_MODULES(libpcreposix, libpcreposix, [], [AC_MSG_ERROR([Neither regex.h nor pcre headers were found])]) +else + AC_DEFINE(HAVE_REGEX_H, 1, [regex.h is present]) +fi + AC_CHECK_FUNCS([memmove memset regcomp select socket stpcpy strcasecmp strncasecmp strchr strdup strndup strrchr strstr strtol]) SAVE_CFLAGS=$CFLAGS diff --git a/src/Makefile.am b/src/Makefile.am index db7bae98..984633c1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,8 +3,8 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/ios-webkit-debug-proxy -AM_CFLAGS = $(GLOBAL_CFLAGS) $(libimobiledevice_CFLAGS) $(libplist_CFLAGS) -AM_LDFLAGS = $(libimobiledevice_LIBS) $(libplist_LIBS) +AM_CFLAGS = $(GLOBAL_CFLAGS) $(libimobiledevice_CFLAGS) $(libplist_CFLAGS) $(libpcreposix_CFLAGS) +AM_LDFLAGS = $(libimobiledevice_LIBS) $(libplist_LIBS) $(libpcreposix_LIBS) lib_LTLIBRARIES = libios_webkit_debug_proxy.la libios_webkit_debug_proxy_la_LIBADD = diff --git a/src/ios_webkit_debug_proxy_main.c b/src/ios_webkit_debug_proxy_main.c index 6b2eaef6..453d6594 100644 --- a/src/ios_webkit_debug_proxy_main.c +++ b/src/ios_webkit_debug_proxy_main.c @@ -12,13 +12,19 @@ #define _GNU_SOURCE #include #include -#include #include #include #include #include #include +#ifndef HAVE_REGEX_H +#include +#include +#else +#include +#endif + #include "device_listener.h" #include "hash_table.h" #include "ios_webkit_debug_proxy.h" diff --git a/src/port_config.c b/src/port_config.c index 60feb282..5de13f45 100644 --- a/src/port_config.c +++ b/src/port_config.c @@ -5,11 +5,17 @@ #include #endif -#include #include #include #include +#ifndef HAVE_REGEX_H +#include +#include +#else +#include +#endif + #include "port_config.h" From cf324032c9c843b7b6fd123ff9c86e34a1792542 Mon Sep 17 00:00:00 2001 From: artygus Date: Sat, 1 Apr 2017 22:43:05 +0100 Subject: [PATCH 3/7] configure: check for win32 platform --- configure.ac | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/configure.ac b/configure.ac index 663fe63d..66835d0a 100644 --- a/configure.ac +++ b/configure.ac @@ -52,6 +52,22 @@ AC_TYPE_UINT8_T AC_FUNC_MALLOC AC_FUNC_REALLOC +# Check for operating system +AC_MSG_CHECKING([whether to enable WIN32 build settings]) +case ${host_os} in + *mingw*|*msys*|*cygwin*) + win32=true + AC_MSG_RESULT([yes]) + AC_DEFINE(WIN32_LEAN_AND_MEAN, 1, [Define to limit the scope of windows.h]) + AC_DEFINE(__USE_MINGW_ANSI_STDIO, 1, [Define to use C99 printf/snprintf in MinGW]) + ;; + *) + win32=false + AC_MSG_RESULT([no]) + ;; +esac +AM_CONDITIONAL(WIN32, test "x$win32" = "xtrue") + # Check for pcre presence if regex.h is absent AC_CHECK_HEADER(regex.h, [ac_have_regex_h="yes"], [ac_have_regex_h="no"]) if test "x$ac_have_regex_h" = "xno"; then From a6a891edbe91521e159b16673cacce5ad7d8eced Mon Sep 17 00:00:00 2001 From: artygus Date: Sat, 1 Apr 2017 22:54:25 +0100 Subject: [PATCH 4/7] replace stpncpy with strncpy mingw64 is not POSIX.1-2008 compliant --- src/device_listener.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device_listener.c b/src/device_listener.c index 2c298291..cd393928 100644 --- a/src/device_listener.c +++ b/src/device_listener.c @@ -120,7 +120,7 @@ dl_status dl_start(dl_t self) { tail = dl_sprintf_uint32(tail, 1); // version: 1 tail = dl_sprintf_uint32(tail, TYPE_PLIST); // type: plist tail = dl_sprintf_uint32(tail, 1); // tag: 1 - tail = stpncpy(tail, xml, xml_length); + strncpy(tail, xml, xml_length); free(xml); dl_status ret = self->send_packet(self, packet, length); From 571a296ba91647cfc7f234248877236d858f3089 Mon Sep 17 00:00:00 2001 From: artygus Date: Sat, 1 Apr 2017 23:00:02 +0100 Subject: [PATCH 5/7] replace stpcpy with strcpy mingw64 is not POSIX.1-2008 compliant --- configure.ac | 2 +- src/ios_webkit_debug_proxy.c | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 66835d0a..be40b9ed 100644 --- a/configure.ac +++ b/configure.ac @@ -76,7 +76,7 @@ else AC_DEFINE(HAVE_REGEX_H, 1, [regex.h is present]) fi -AC_CHECK_FUNCS([memmove memset regcomp select socket stpcpy strcasecmp strncasecmp strchr strdup strndup strrchr strstr strtol]) +AC_CHECK_FUNCS([memmove memset regcomp select socket strcasecmp strncasecmp strchr strdup strndup strrchr strstr strtol]) SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS $libimobiledevice_CFLAGS" diff --git a/src/ios_webkit_debug_proxy.c b/src/ios_webkit_debug_proxy.c index a20d2dce..aa474724 100644 --- a/src/ios_webkit_debug_proxy.c +++ b/src/ios_webkit_debug_proxy.c @@ -1629,12 +1629,14 @@ char *iwdp_iports_to_text(iwdp_iport_t *iports, bool want_json, char *ret = (char *)calloc(length+1, sizeof(char)); if (ret) { char *tail = ret; - tail = stpcpy(tail, header); + strcpy(tail, header); + tail += strlen(header); for (item = items; *item; item++) { - tail = stpcpy(tail, *item); + strcpy(tail, *item); + tail += strlen(*item); free(*item); } - tail = stpcpy(tail, footer); + strcpy(tail, footer); } free(items); return ret; @@ -1890,12 +1892,14 @@ char *iwdp_ipages_to_text(iwdp_ipage_t *ipages, bool want_json, char *ret = (char *)calloc(length+1, sizeof(char)); if (ret) { char *tail = ret; - tail = stpcpy(tail, header); + strcpy(tail, header); + tail += strlen(header); for (item = items; *item; item++) { - tail = stpcpy(tail, *item); + strcpy(tail, *item); + tail += strlen(*item); free(*item); } - tail = stpcpy(tail, footer); + strcpy(tail, footer); } if (!want_json) { free(header); From 5a6042f848e4c370ab60f475acd1541b4ab1a3d9 Mon Sep 17 00:00:00 2001 From: artygus Date: Sun, 2 Apr 2017 10:49:58 +0100 Subject: [PATCH 6/7] strcasestr, strndup, getline replacements for systems lacking them mingw64 is not POSIX.1-2008 compliant --- configure.ac | 2 +- include/getline.h | 128 +++++++++++++++++++++++++++++++++++ include/strcasestr.h | 68 +++++++++++++++++++ include/strndup.h | 48 +++++++++++++ src/base64.c | 4 ++ src/char_buffer.c | 4 ++ src/hash_table.c | 4 ++ src/ios_webkit_debug_proxy.c | 1 + src/port_config.c | 2 + src/sha1.c | 4 ++ src/websocket.c | 2 + 11 files changed, 266 insertions(+), 1 deletion(-) create mode 100644 include/getline.h create mode 100644 include/strcasestr.h create mode 100644 include/strndup.h diff --git a/configure.ac b/configure.ac index be40b9ed..842f0086 100644 --- a/configure.ac +++ b/configure.ac @@ -76,7 +76,7 @@ else AC_DEFINE(HAVE_REGEX_H, 1, [regex.h is present]) fi -AC_CHECK_FUNCS([memmove memset regcomp select socket strcasecmp strncasecmp strchr strdup strndup strrchr strstr strtol]) +AC_CHECK_FUNCS([memmove memset regcomp select socket strcasecmp strncasecmp strchr strdup strndup strrchr strstr strtol strcasestr getline]) SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS $libimobiledevice_CFLAGS" diff --git a/include/getline.h b/include/getline.h new file mode 100644 index 00000000..57b19e9f --- /dev/null +++ b/include/getline.h @@ -0,0 +1,128 @@ +/* getline.c -- Replacement for GNU C library function getline + +Copyright (C) 1993 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. */ + +/* Written by Jan Brittenson, bson@gnu.ai.mit.edu. */ + +#ifndef __GETLINE_H +#define __GETLINE_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#ifndef HAVE_GETLINE +/* Always add at least this many bytes when extending the buffer. */ +#define GETLINE_MIN_CHUNK 256 + +static inline int getstr(char **lineptr, size_t *n, FILE *stream, + char terminator, int offset) { + int nchars_avail; /* Allocated but unused chars in *LINEPTR. */ + char *read_pos; /* Where we're reading into *LINEPTR. */ + int ret; + + if (!lineptr || !n || !stream) + { + errno = EINVAL; + return -1; + } + + if (!*lineptr) + { + *n = GETLINE_MIN_CHUNK; + *lineptr = malloc (*n); + if (!*lineptr) + { + errno = ENOMEM; + return -1; + } + } + + nchars_avail = *n - offset; + read_pos = *lineptr + offset; + + for (;;) + { + int save_errno; + register int c = getc (stream); + + save_errno = errno; + + /* We always want at least one char left in the buffer, since we + always (unless we get an error while reading the first char) + NUL-terminate the line buffer. */ + + assert((*lineptr + *n) == (read_pos + nchars_avail)); + if (nchars_avail < 2) + { + if (*n > GETLINE_MIN_CHUNK) + *n *= 2; + else + *n += GETLINE_MIN_CHUNK; + + nchars_avail = *n + *lineptr - read_pos; + *lineptr = realloc (*lineptr, *n); + if (!*lineptr) + { + errno = ENOMEM; + return -1; + } + read_pos = *n - nchars_avail + *lineptr; + assert((*lineptr + *n) == (read_pos + nchars_avail)); + } + + if (ferror (stream)) + { + /* Might like to return partial line, but there is no + place for us to store errno. And we don't want to just + lose errno. */ + errno = save_errno; + return -1; + } + + if (c == EOF) + { + /* Return partial line, if any. */ + if (read_pos == *lineptr) + return -1; + else + break; + } + + *read_pos++ = c; + nchars_avail--; + + if (c == terminator) + /* Return the line. */ + break; + } + + /* Done - NUL terminate and return the number of chars read. */ + *read_pos = '\0'; + + ret = read_pos - (*lineptr + offset); + return ret; +} + +static inline int getline(char **lineptr, size_t *n, FILE *stream) +{ + return getstr(lineptr, n, stream, '\n', 0); +} +#endif + +#endif diff --git a/include/strcasestr.h b/include/strcasestr.h new file mode 100644 index 00000000..3e935f5f --- /dev/null +++ b/include/strcasestr.h @@ -0,0 +1,68 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __STRCASESTR_H +#define __STRCASESTR_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#ifndef HAVE_STRCASESTR +static inline char* strcasestr(const char *s, const char *find) +{ + char c, sc; + size_t len; + + if ((c = *find++) != 0) { + c = tolower((unsigned char)c); + len = strlen(find); + do { + do { + if ((sc = *s++) == 0) + return (NULL); + } while ((char)tolower((unsigned char)sc) != c); + } while (strncasecmp(s, find, len) != 0); + s--; + } + return ((char *)s); +} +#endif + +#endif diff --git a/include/strndup.h b/include/strndup.h new file mode 100644 index 00000000..cd8edd54 --- /dev/null +++ b/include/strndup.h @@ -0,0 +1,48 @@ +/* Implement the strndup function. + Copyright (C) 2005 Free Software Foundation, Inc. + Written by Kaveh R. Ghazi . + + This file is part of the libiberty library. + Libiberty is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + Libiberty is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with libiberty; see the file COPYING.LIB. If + not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, + Boston, MA 02110-1301, USA. */ + +#ifndef __STRNDUP_H +#define __STRNDUP_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#ifndef HAVE_STRNDUP +static inline char* strndup(const char *s, size_t n) +{ + char *result; + size_t len = strlen (s); + + if (n < len) + len = n; + + result = (char *) malloc (len + 1); + if (!result) + return 0; + + result[len] = '\0'; + return (char *) memcpy (result, s, len); +} +#endif + +#endif diff --git a/src/base64.c b/src/base64.c index 50221c76..257e3f61 100644 --- a/src/base64.c +++ b/src/base64.c @@ -29,6 +29,10 @@ #if defined(POLARSSL_BASE64_C) +#ifdef HAVE_CONFIG_H +#include +#endif + //#include "polarssl/base64.h" #include "base64.h" #include "stdio.h" diff --git a/src/char_buffer.c b/src/char_buffer.c index d34f9602..70ea6eb2 100644 --- a/src/char_buffer.c +++ b/src/char_buffer.c @@ -1,6 +1,10 @@ // Google BSD license https://developers.google.com/google-bsd-license // Copyright 2012 Google Inc. wrightt@google.com +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/src/hash_table.c b/src/hash_table.c index 0d130aae..7e00d8e5 100644 --- a/src/hash_table.c +++ b/src/hash_table.c @@ -5,6 +5,10 @@ // A basic hash table, could be easily enhanced... // +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include diff --git a/src/ios_webkit_debug_proxy.c b/src/ios_webkit_debug_proxy.c index aa474724..adc477f0 100644 --- a/src/ios_webkit_debug_proxy.c +++ b/src/ios_webkit_debug_proxy.c @@ -24,6 +24,7 @@ #include "rpc.h" #include "webinspector.h" #include "websocket.h" +#include "strndup.h" struct iwdp_idl_struct; diff --git a/src/port_config.c b/src/port_config.c index 5de13f45..e5f0e04d 100644 --- a/src/port_config.c +++ b/src/port_config.c @@ -17,6 +17,8 @@ #endif #include "port_config.h" +#include "strndup.h" +#include "getline.h" struct pc_entry_struct; diff --git a/src/sha1.c b/src/sha1.c index 01faa772..70b9a4b6 100644 --- a/src/sha1.c +++ b/src/sha1.c @@ -35,6 +35,10 @@ #if defined(POLARSSL_SHA1_C) +#ifdef HAVE_CONFIG_H +#include +#endif + //#include "polarssl/sha1.h" #include "sha1.h" // END CHANGES diff --git a/src/websocket.c b/src/websocket.c index b2714a4e..2eb7148d 100644 --- a/src/websocket.c +++ b/src/websocket.c @@ -19,6 +19,8 @@ #include "sha1.h" #include "validate_utf8.h" +#include "strndup.h" +#include "strcasestr.h" typedef int8_t ws_state; #define STATE_ERROR 1 From 8d7f9201df5432e29c31cd7cd85775e93af45e84 Mon Sep 17 00:00:00 2001 From: artygus Date: Sun, 9 Apr 2017 12:45:29 -0700 Subject: [PATCH 7/7] win32 sockets --- src/device_listener.c | 52 ++++++++++++- src/ios_webkit_debug_proxy_main.c | 16 ++++ src/socket_manager.c | 117 ++++++++++++++++++++++++++++-- src/webinspector.c | 19 ++++- 4 files changed, 192 insertions(+), 12 deletions(-) diff --git a/src/device_listener.c b/src/device_listener.c index cd393928..f86988ea 100644 --- a/src/device_listener.c +++ b/src/device_listener.c @@ -9,16 +9,21 @@ #include #include #include -#include #include #include #include #include +#include + +#ifdef WIN32 +#include +#else +#include #include #include #include #include -#include +#endif #include @@ -34,6 +39,7 @@ // straight-forward. // +#define USBMUXD_SOCKET_PORT 27015 #define USBMUXD_FILE_PATH "/var/run/usbmuxd" #define TYPE_PLIST 8 @@ -45,8 +51,44 @@ struct dl_private { }; int dl_connect(int recv_timeout) { - const char *filename = USBMUXD_FILE_PATH; int fd = -1; +#ifdef WIN32 + fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (fd == INVALID_SOCKET) { + fprintf(stderr, "device_listener: socket function failed with\ + error %d\n", WSAGetLastError()); + return -1; + } + + struct hostent *host; + host = gethostbyname("localhost"); + if (host == NULL) { + fprintf(stderr, "device_listener: gethostbyname function failed with\ + error %d\n", WSAGetLastError()); + closesocket(fd); + return -2; + } + + struct sockaddr_in local; + local.sin_family = AF_INET; + local.sin_addr.s_addr = *(uint32_t *)host->h_addr; + local.sin_port = htons(USBMUXD_SOCKET_PORT); + + if (connect(fd, (SOCKADDR *)&local, sizeof(local)) == SOCKET_ERROR) { + fprintf(stderr, "device_listener: connect function failed with\ + error %d\n", WSAGetLastError()); + closesocket(fd); + return -2; + } + + if (recv_timeout < 0) { + u_long nb = 1; + if (ioctlsocket(fd, FIONBIO, &nb)) { + fprintf(stderr, "device_listener: could not set socket to non-blocking"); + } + } +#else + const char *filename = USBMUXD_FILE_PATH; struct stat fst; if (stat(filename, &fst) || !S_ISSOCK(fst.st_mode) || @@ -69,7 +111,9 @@ int dl_connect(int recv_timeout) { if (!opts || fcntl(fd, F_SETFL, (opts | O_NONBLOCK)) < 0) { perror("Could not set socket to non-blocking"); } - } else { + } +#endif + else { long millis = (recv_timeout > 0 ? recv_timeout : 5000); struct timeval tv; tv.tv_sec = (time_t) (millis / 1000); diff --git a/src/ios_webkit_debug_proxy_main.c b/src/ios_webkit_debug_proxy_main.c index 453d6594..ce64adc0 100644 --- a/src/ios_webkit_debug_proxy_main.c +++ b/src/ios_webkit_debug_proxy_main.c @@ -25,6 +25,10 @@ #include #endif +#ifdef WIN32 +#include +#endif + #include "device_listener.h" #include "hash_table.h" #include "ios_webkit_debug_proxy.h" @@ -61,6 +65,15 @@ int main(int argc, char** argv) { signal(SIGINT, on_signal); signal(SIGTERM, on_signal); +#ifdef WIN32 + WSADATA wsa_data; + int res = WSAStartup(MAKEWORD(2,2), &wsa_data); + if (res) { + fprintf(stderr, "WSAStartup failed with error: %d\n", res); + exit(1); + } +#endif + iwdpm_t self = iwdpm_new(); int ret = iwdpm_configure(self, argc, argv); if (ret) { @@ -84,6 +97,9 @@ int main(int argc, char** argv) { } sm->cleanup(sm); iwdpm_free(self); +#ifdef WIN32 + WSACleanup(); +#endif return ret; } // diff --git a/src/socket_manager.c b/src/socket_manager.c index 5615ee97..faf8b1ab 100644 --- a/src/socket_manager.c +++ b/src/socket_manager.c @@ -13,19 +13,24 @@ #include #include #include +#include +#include +#ifdef WIN32 +#include +#include +#else #include #include #include #include #include -#include -#include +#endif #include "char_buffer.h" #include "socket_manager.h" #include "hash_table.h" -#ifdef __MACH__ +#if defined(__MACH__) || defined(WIN32) #define SIZEOF_FD_SET sizeof(struct fd_set) #define RECV_FLAGS 0 #else @@ -73,7 +78,30 @@ void sm_sendq_free(sm_sendq_t sendq); int sm_listen(int port) { - int fd = socket(AF_INET, SOCK_STREAM, 0); + int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); +#ifdef WIN32 + if (fd == INVALID_SOCKET) { + fprintf(stderr, "socket_manager: socket function failed with\ + error %d\n", WSAGetLastError()); + return -1; + } + struct sockaddr_in local; + local.sin_family = AF_INET; + local.sin_addr.s_addr = INADDR_ANY; + local.sin_port = htons(port); + int ra = 1; + u_long nb = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&ra, + sizeof(ra)) == SOCKET_ERROR || + ioctlsocket(fd, FIONBIO, &nb) || + bind(fd, (SOCKADDR *)&local, sizeof(local)) == SOCKET_ERROR || + listen(fd, 5)) { + fprintf(stderr, "socket_manager: bind failed with\ + error %d\n", WSAGetLastError()); + closesocket(fd); + return -1; + } +#else if (fd < 0) { return -1; } @@ -92,6 +120,7 @@ int sm_listen(int port) { close(fd); return -1; } +#endif return fd; } @@ -100,6 +129,7 @@ int sm_connect(const char *hostname, int port) { memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; struct addrinfo *res0; char *port_str = NULL; if (asprintf(&port_str, "%d", port) < 0) { @@ -115,6 +145,33 @@ int sm_connect(const char *hostname, int port) { int fd = 0; struct addrinfo *res; for (res = res0; res; res = res->ai_next) { +#ifdef WIN32 + if (fd != INVALID_SOCKET) { + closesocket(fd); + } + fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (fd == INVALID_SOCKET) { + continue; + } + u_long nb = 1; + if (ioctlsocket(fd, FIONBIO, &nb) || + (connect(fd, res->ai_addr, res->ai_addrlen) == SOCKET_ERROR && + WSAGetLastError() != WSAEWOULDBLOCK && + WSAGetLastError() != WSAEINPROGRESS)) { + continue; + } + + struct timeval to; + to.tv_sec = 0; + to.tv_usec= 500*1000; + fd_set write_fds; + FD_ZERO(&write_fds); + FD_SET(fd, &write_fds); + + if (select(1, NULL, &write_fds, NULL, &to) < 1) { + continue; + } +#else if (fd > 0) { close(fd); } @@ -148,12 +205,19 @@ int sm_connect(const char *hostname, int port) { if (fcntl(fd, F_SETFL, (opts | O_NONBLOCK)) < 0) { continue; } +#endif ret = fd; break; } +#ifdef WIN32 + if (fd != INVALID_SOCKET && ret <= 0) { + closesocket(fd); + } +#else if (fd > 0 && ret <= 0) { close(fd); } +#endif freeaddrinfo(res0); return ret; } @@ -205,7 +269,11 @@ sm_status sm_remove_fd(sm_t self, int fd) { bool is_server = FD_ISSET(fd, my->server_fds); sm_on_debug(self, "ss.remove%s_fd(%d)", (is_server ? "_server" : ""), fd); sm_status ret = self->on_close(self, fd, value, is_server); +#ifdef WIN32 + closesocket(fd); +#else close(fd); +#endif FD_CLR(fd, my->all_fds); if (is_server) { FD_CLR(fd, my->server_fds); @@ -249,7 +317,11 @@ sm_status sm_send(sm_t self, int fd, const char *data, size_t length, while (1) { ssize_t sent_bytes = send(fd, (void*)head, (tail - head), 0); if (sent_bytes <= 0) { +#ifdef WIN32 + if (sent_bytes && WSAGetLastError() != WSAEWOULDBLOCK) { +#else if (sent_bytes && errno != EWOULDBLOCK) { +#endif sm_on_debug(self, "ss.failed fd=%d", fd); perror("send failed"); return SM_ERROR; @@ -294,7 +366,11 @@ void sm_accept(sm_t self, int fd) { while (1) { int new_fd = accept(fd, NULL, NULL); if (new_fd < 0) { +#ifdef WIN32 + if (WSAGetLastError() != WSAEWOULDBLOCK) { +#else if (errno != EWOULDBLOCK) { +#endif perror("accept failed"); self->remove_fd(self, fd); return; @@ -306,10 +382,18 @@ void sm_accept(sm_t self, int fd) { void *value = ht_get_value(my->fd_to_value, HT_KEY(fd)); void *new_value = NULL; if (self->on_accept(self, fd, value, new_fd, &new_value)) { - close(new_fd); +#ifdef WIN32 + closesocket(new_fd); +#else + close(new_fd); +#endif } else if (self->add_fd(self, new_fd, new_value, false)) { self->on_close(self, new_fd, new_value, false); - close(new_fd); +#ifdef WIN32 + closesocket(new_fd); +#else + close(new_fd); +#endif } } } @@ -326,8 +410,14 @@ void sm_resend(sm_t self, int fd) { while (head < tail) { ssize_t sent_bytes = send(fd, (void*)head, (tail - head), 0); if (sent_bytes <= 0) { +#ifdef WIN32 + if (sent_bytes && WSAGetLastError() != WSAEWOULDBLOCK) { + fprintf(stderr, "sendq retry failed with error: %d\n", + WSAGetLastError()); +#else if (sent_bytes && errno != EWOULDBLOCK) { perror("sendq retry failed"); +#endif self->remove_fd(self, fd); return; } @@ -381,8 +471,13 @@ void sm_recv(sm_t self, int fd) { while (1) { ssize_t read_bytes = recv(fd, my->tmp_buf, my->tmp_buf_length, RECV_FLAGS); if (read_bytes < 0) { +#ifdef WIN32 + if (WSAGetLastError() != WSAEWOULDBLOCK) { + fprintf(stderr, "recv failed with error %d\n", WSAGetLastError()); +#else if (errno != EWOULDBLOCK) { perror("recv failed"); +#endif self->remove_fd(self, fd); } break; @@ -419,11 +514,20 @@ int sm_select(sm_t self, int timeout_secs) { return 0; // timeout, select again } if (num_ready < 0) { +#ifdef WIN32 + int socket_err = WSAGetLastError(); + if (socket_err != WSAEINTR && socket_err != WSAEWOULDBLOCK) { + fprintf(stderr, "socket_manager: select failed with\ + error %d\n", WSAGetLastError()); + return -socket_err; + } +#else if (errno != EINTR && errno != EAGAIN) { // might want to sleep here? perror("select failed"); return -errno; } +#endif return 0; } @@ -570,4 +674,3 @@ void sm_free(sm_t self) { free(self); } } - diff --git a/src/webinspector.c b/src/webinspector.c index 674fb346..67f90d9c 100644 --- a/src/webinspector.c +++ b/src/webinspector.c @@ -14,10 +14,14 @@ #include #include #include +#include +#ifdef WIN32 +#include +#else #include #include #include -#include +#endif #include #include @@ -146,11 +150,18 @@ int wi_connect(const char *device_id, char **to_device_id, } if (recv_timeout < 0) { +#ifdef WIN32 + u_long nb = 1; + if (ioctlsocket(fd, FIONBIO, &nb)) { + fprintf(stderr, "webinspector: could not set socket to non-blocking"); + } +#else int opts = fcntl(fd, F_GETFL); if (!opts || fcntl(fd, F_SETFL, (opts | O_NONBLOCK)) < 0) { perror("Could not set socket to non-blocking"); goto leave_cleanup; } +#endif } else { long millis = (recv_timeout > 0 ? recv_timeout : 5000); struct timeval tv; @@ -167,9 +178,15 @@ int wi_connect(const char *device_id, char **to_device_id, ret = fd; leave_cleanup: +#ifdef WIN32 + if (ret < 0 && fd != INVALID_SOCKET) { + closesocket(fd); + } +#else if (ret < 0 && fd > 0) { close(fd); } +#endif // don't call usbmuxd_disconnect(fd)! //idevice_disconnect(connection); free(connection);