Update libcurl

This commit is contained in:
Glenn Smith 2022-09-03 01:31:41 -04:00
parent 20eb0a911a
commit 01a719ee58
No known key found for this signature in database
GPG key ID: 9B71EC283F0B7A14
3439 changed files with 529259 additions and 41492 deletions

View file

@ -0,0 +1,83 @@
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 2009 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
# SPDX-License-Identifier: curl
#
###########################################################################
set(TARGET_LABEL_PREFIX "Test server ")
if(MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4306")
endif()
function(SETUP_EXECUTABLE TEST_NAME) # ARGN are the files in the test
add_executable(${TEST_NAME} EXCLUDE_FROM_ALL ${ARGN})
add_dependencies(testdeps ${TEST_NAME})
string(TOUPPER ${TEST_NAME} UPPER_TEST_NAME)
include_directories(
${CURL_SOURCE_DIR}/lib # To be able to reach "curl_setup_once.h"
${CURL_BINARY_DIR}/lib # To be able to reach "curl_config.h"
${CURL_BINARY_DIR}/include # To be able to reach "curl/curl.h"
)
if(USE_ARES)
include_directories(${CARES_INCLUDE_DIR})
endif()
target_link_libraries(${TEST_NAME} ${CURL_LIBS})
# Test servers simply are standalone programs that do not use libcurl
# library. For convenience and to ease portability of these servers,
# some source code files from the libcurl subdirectory are also used
# to build the servers. In order to achieve proper linkage of these
# files on Win32 targets it is necessary to build the test servers
# with CURL_STATICLIB defined, independently of how libcurl is built.
if(BUILD_SHARED_LIBS)
set_target_properties(${TEST_NAME} PROPERTIES
COMPILE_DEFINITIONS CURL_STATICLIB) # ${UPPER_TEST_NAME}
endif()
set_target_properties(${TEST_NAME} PROPERTIES
PROJECT_LABEL "${TARGET_LABEL_PREFIX}${TEST_NAME}")
endfunction()
transform_makefile_inc("Makefile.inc"
"${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake)
foreach(EXECUTABLE_NAME ${noinst_PROGRAMS})
setup_executable(${EXECUTABLE_NAME} ${${EXECUTABLE_NAME}_SOURCES})
endforeach()
# SET(useful
# getpart.c getpart.h
# ${CURL_SOURCE_DIR}/lib/strequal.c
# ${CURL_SOURCE_DIR}/lib/base64.c
# ${CURL_SOURCE_DIR}/lib/mprintf.c
# ${CURL_SOURCE_DIR}/lib/memdebug.c
# ${CURL_SOURCE_DIR}/lib/timeval.c
# )
# SETUP_EXECUTABLE(sws sws.c util.c util.h ${useful})
# SETUP_EXECUTABLE(resolve resolve.c util.c util.h ${useful})
# SETUP_EXECUTABLE(sockfilt sockfilt.c util.c util.h ${useful} ${CURL_SOURCE_DIR}/lib/inet_pton.c)
# SETUP_EXECUTABLE(getpart testpart.c ${useful})
# SETUP_EXECUTABLE(tftpd tftpd.c util.c util.h ${useful} tftp.h)

View file

@ -0,0 +1,62 @@
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
# SPDX-License-Identifier: curl
#
###########################################################################
AUTOMAKE_OPTIONS = foreign nostdinc
# Specify our include paths here, and do it relative to $(top_srcdir) and
# $(top_builddir), to ensure that these paths which belong to the library
# being currently built and tested are searched before the library which
# might possibly already be installed in the system.
#
# $(top_srcdir)/include is for libcurl's external include files
# $(top_builddir)/lib is for libcurl's generated lib/curl_config.h file
# $(top_srcdir)/lib for libcurl's lib/curl_setup.h and other "borrowed" files
AM_CPPFLAGS = -I$(top_srcdir)/include \
-I$(top_builddir)/lib \
-I$(top_srcdir)/lib
# Prevent LIBS from being used for all link targets
LIBS = $(BLANK_AT_MAKETIME)
if DOING_NATIVE_WINDOWS
AM_CPPFLAGS += -DCURL_STATICLIB
endif
# Makefile.inc provides neat definitions
include Makefile.inc
EXTRA_DIST = base64.pl Makefile.inc CMakeLists.txt
CHECKSRC = $(CS_$(V))
CS_0 = @echo " RUN " $@;
CS_1 =
CS_ = $(CS_0)
checksrc:
$(CHECKSRC)@PERL@ $(top_srcdir)/scripts/checksrc.pl $(srcdir)/*.[ch]
if CURLDEBUG
# for debug builds, we scan the sources on all regular make invokes
all-local: checksrc
endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,117 @@
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 2009 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
# SPDX-License-Identifier: curl
#
###########################################################################
noinst_PROGRAMS = getpart resolve rtspd sockfilt sws tftpd fake_ntlm \
socksd disabled mqttd
CURLX_SRCS = \
../../lib/mprintf.c \
../../lib/nonblock.c \
../../lib/strtoofft.c \
../../lib/warnless.c \
../../lib/timediff.c \
../../lib/curl_ctype.c \
../../lib/dynbuf.c \
../../lib/strdup.c \
../../lib/curl_multibyte.c
CURLX_HDRS = \
../../lib/curlx.h \
../../lib/nonblock.h \
../../lib/strtoofft.h \
../../lib/warnless.h \
../../lib/timediff.h \
../../lib/curl_ctype.h \
../../lib/dynbuf.h \
../../lib/strdup.h \
../../lib/curl_multibyte.h
USEFUL = \
getpart.c \
getpart.h \
server_setup.h \
../../lib/base64.c \
../../lib/curl_base64.h \
../../lib/memdebug.c \
../../lib/memdebug.h
UTIL = \
util.c \
util.h
getpart_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) \
testpart.c
getpart_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
getpart_CFLAGS = $(AM_CFLAGS)
resolve_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
resolve.c
resolve_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
resolve_CFLAGS = $(AM_CFLAGS)
rtspd_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
server_sockaddr.h \
rtspd.c
rtspd_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
rtspd_CFLAGS = $(AM_CFLAGS)
sockfilt_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
server_sockaddr.h \
sockfilt.c \
../../lib/inet_pton.c
sockfilt_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
sockfilt_CFLAGS = $(AM_CFLAGS)
socksd_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
server_sockaddr.h socksd.c \
../../lib/inet_pton.c
socksd_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
socksd_CFLAGS = $(AM_CFLAGS)
mqttd_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
server_sockaddr.h mqttd.c \
../../lib/inet_pton.c
mqttd_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
mqttd_CFLAGS = $(AM_CFLAGS)
sws_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
server_sockaddr.h \
sws.c \
../../lib/inet_pton.c
sws_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
sws_CFLAGS = $(AM_CFLAGS)
tftpd_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
server_sockaddr.h \
tftpd.c \
tftp.h
tftpd_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
tftpd_CFLAGS = $(AM_CFLAGS)
fake_ntlm_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
fake_ntlm.c
fake_ntlm_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
fake_ntlm_CFLAGS = $(AM_CFLAGS)
disabled_SOURCES = disabled.c

View file

@ -0,0 +1,32 @@
#!/usr/bin/env perl
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 2004 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
# SPDX-License-Identifier: curl
#
###########################################################################
use MIME::Base64 qw(encode_base64);
my $buf;
while(read(STDIN, $buf, 60*57)) {
my $enc = encode_base64($buf);
print "$enc";
}

View file

@ -0,0 +1,88 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
/*
* The purpose of this tool is to figure out which, if any, features that are
* disabled which should otherwise exist and work. These aren't visible in
* regular curl -V output.
*
* Disabled protocols are visible in curl_version_info() and are not included
* in this table.
*/
#include "curl_setup.h"
#include "multihandle.h" /* for ENABLE_WAKEUP */
#include <stdio.h>
static const char *disabled[]={
#ifdef CURL_DISABLE_COOKIES
"cookies",
#endif
#ifdef CURL_DISABLE_CRYPTO_AUTH
"crypto",
#endif
#ifdef CURL_DISABLE_DOH
"DoH",
#endif
#ifdef CURL_DISABLE_HTTP_AUTH
"HTTP-auth",
#endif
#ifdef CURL_DISABLE_MIME
"Mime",
#endif
#ifdef CURL_DISABLE_NETRC
"netrc",
#endif
#ifdef CURL_DISABLE_PARSEDATE
"parsedate",
#endif
#ifdef CURL_DISABLE_PROXY
"proxy",
#endif
#ifdef CURL_DISABLE_SHUFFLE_DNS
"shuffle-dns",
#endif
#ifdef CURL_DISABLE_TYPECHECK
"typecheck",
#endif
#ifdef CURL_DISABLE_VERBOSE_STRINGS
"verbose-strings",
#endif
#ifndef ENABLE_WAKEUP
"wakeup",
#endif
#ifdef CURL_DISABLE_HEADERS_API
"headers-api",
#endif
NULL
};
int main(void)
{
int i;
for(i = 0; disabled[i]; i++)
printf("%s\n", disabled[i]);
return 0;
}

View file

@ -0,0 +1,280 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2010, Mandy Wu, <mandy.wu@intel.com>
* Copyright (C) 2011 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "server_setup.h"
/*
* This is a fake ntlm_auth, which is used for testing NTLM single-sign-on.
* When DEBUGBUILD is defined, libcurl invoke this tool instead of real winbind
* daemon helper /usr/bin/ntlm_auth. This tool will accept commands and
* responses with a pre-written string saved in test case test2005.
*/
#define ENABLE_CURLX_PRINTF
#include "curlx.h" /* from the private lib dir */
#include "getpart.h"
#include "util.h"
/* include memdebug.h last */
#include "memdebug.h"
#define LOGFILE "log/fake_ntlm%ld.log"
const char *serverlogfile;
/*
* Returns an allocated buffer with printable representation of input
* buffer contents or returns NULL on out of memory condition.
*/
static char *printable(char *inbuf, size_t inlength)
{
char *outbuf;
char *newbuf;
size_t newsize;
size_t outsize;
size_t outincr = 0;
size_t i, o = 0;
#define HEX_FMT_STR "[0x%02X]"
#define HEX_STR_LEN 6
#define NOTHING_STR "[NOTHING]"
#define NOTHING_LEN 9
if(!inlength)
inlength = strlen(inbuf);
if(inlength) {
outincr = ((inlength/2) < (HEX_STR_LEN + 1)) ?
HEX_STR_LEN + 1 : inlength/2;
outsize = inlength + outincr;
}
else
outsize = NOTHING_LEN + 1;
outbuf = malloc(outsize);
if(!outbuf)
return NULL;
if(!inlength) {
msnprintf(&outbuf[0], outsize, "%s", NOTHING_STR);
return outbuf;
}
for(i = 0; i<inlength; i++) {
if(o > outsize - (HEX_STR_LEN + 1)) {
newsize = outsize + outincr;
newbuf = realloc(outbuf, newsize);
if(!newbuf) {
free(outbuf);
return NULL;
}
outbuf = newbuf;
outsize = newsize;
}
if((inbuf[i] > 0x20) && (inbuf[i] < 0x7F)) {
outbuf[o] = inbuf[i];
o++;
}
else {
msnprintf(&outbuf[o], outsize - o, HEX_FMT_STR, inbuf[i]);
o += HEX_STR_LEN;
}
}
outbuf[o] = '\0';
return outbuf;
}
int main(int argc, char *argv[])
{
char buf[1024];
char logfilename[256];
FILE *stream;
int error;
char *type1_input = NULL, *type3_input = NULL;
char *type1_output = NULL, *type3_output = NULL;
size_t size = 0;
long testnum;
const char *env;
int arg = 1;
const char *helper_user = "unknown";
const char *helper_proto = "unknown";
const char *helper_domain = "unknown";
bool use_cached_creds = FALSE;
char *msgbuf;
buf[0] = '\0';
while(argc > arg) {
if(!strcmp("--use-cached-creds", argv[arg])) {
use_cached_creds = TRUE;
arg++;
}
else if(!strcmp("--helper-protocol", argv[arg])) {
arg++;
if(argc > arg)
helper_proto = argv[arg++];
}
else if(!strcmp("--username", argv[arg])) {
arg++;
if(argc > arg)
helper_user = argv[arg++];
}
else if(!strcmp("--domain", argv[arg])) {
arg++;
if(argc > arg)
helper_domain = argv[arg++];
}
else {
puts("Usage: fake_ntlm [option]\n"
" --use-cached-creds\n"
" --helper-protocol [protocol]\n"
" --username [username]\n"
" --domain [domain]");
exit(1);
}
}
env = getenv("CURL_NTLM_AUTH_TESTNUM");
if(env) {
char *endptr;
long lnum = strtol(env, &endptr, 10);
if((endptr != env + strlen(env)) || (lnum < 1L)) {
fprintf(stderr, "Test number not valid in CURL_NTLM_AUTH_TESTNUM");
exit(1);
}
testnum = lnum;
}
else {
fprintf(stderr, "Test number not specified in CURL_NTLM_AUTH_TESTNUM");
exit(1);
}
/* logmsg cannot be used until this file name is set */
msnprintf(logfilename, sizeof(logfilename), LOGFILE, testnum);
serverlogfile = logfilename;
logmsg("fake_ntlm (user: %s) (proto: %s) (domain: %s) (cached creds: %s)",
helper_user, helper_proto, helper_domain,
(use_cached_creds) ? "yes" : "no");
env = getenv("CURL_NTLM_AUTH_SRCDIR");
if(env) {
path = env;
}
stream = test2fopen(testnum);
if(!stream) {
error = errno;
logmsg("fopen() failed with error: %d %s", error, strerror(error));
logmsg("Couldn't open test file %ld", testnum);
exit(1);
}
else {
/* get the ntlm_auth input/output */
error = getpart(&type1_input, &size, "ntlm_auth_type1", "input", stream);
fclose(stream);
if(error || size == 0) {
logmsg("getpart() type 1 input failed with error: %d", error);
exit(1);
}
}
stream = test2fopen(testnum);
if(!stream) {
error = errno;
logmsg("fopen() failed with error: %d %s", error, strerror(error));
logmsg("Couldn't open test file %ld", testnum);
}
else {
size = 0;
error = getpart(&type3_input, &size, "ntlm_auth_type3", "input", stream);
fclose(stream);
if(error || size == 0) {
logmsg("getpart() type 3 input failed with error: %d", error);
exit(1);
}
}
while(fgets(buf, sizeof(buf), stdin)) {
if(strcmp(buf, type1_input) == 0) {
stream = test2fopen(testnum);
if(!stream) {
error = errno;
logmsg("fopen() failed with error: %d %s", error, strerror(error));
logmsg("Couldn't open test file %ld", testnum);
exit(1);
}
else {
size = 0;
error = getpart(&type1_output, &size, "ntlm_auth_type1", "output",
stream);
fclose(stream);
if(error || size == 0) {
logmsg("getpart() type 1 output failed with error: %d", error);
exit(1);
}
}
printf("%s", type1_output);
fflush(stdout);
}
else if(strncmp(buf, type3_input, strlen(type3_input)) == 0) {
stream = test2fopen(testnum);
if(!stream) {
error = errno;
logmsg("fopen() failed with error: %d %s", error, strerror(error));
logmsg("Couldn't open test file %ld", testnum);
exit(1);
}
else {
size = 0;
error = getpart(&type3_output, &size, "ntlm_auth_type3", "output",
stream);
fclose(stream);
if(error || size == 0) {
logmsg("getpart() type 3 output failed with error: %d", error);
exit(1);
}
}
printf("%s", type3_output);
fflush(stdout);
}
else {
printf("Unknown request\n");
msgbuf = printable(buf, 0);
if(msgbuf) {
logmsg("invalid input: '%s'\n", msgbuf);
free(msgbuf);
}
else
logmsg("OOM formatting invalid input: '%s'\n", buf);
exit(1);
}
}
logmsg("Exit");
return 1;
}

View file

@ -0,0 +1,522 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "server_setup.h"
#include "getpart.h"
#define ENABLE_CURLX_PRINTF
/* make the curlx header define all printf() functions to use the curlx_*
versions instead */
#include "curlx.h" /* from the private lib dir */
/* just to please curl_base64.h we create a fake struct */
struct Curl_easy {
int fake;
};
#include "curl_base64.h"
#include "curl_memory.h"
/* include memdebug.h last */
#include "memdebug.h"
#define EAT_SPACE(p) while(*(p) && ISSPACE(*(p))) (p)++
#define EAT_WORD(p) while(*(p) && !ISSPACE(*(p)) && ('>' != *(p))) (p)++
#ifdef DEBUG_GETPART
#define show(x) printf x
#else
#define show(x) Curl_nop_stmt
#endif
#if defined(_MSC_VER) && defined(_DLL)
# pragma warning(disable:4232) /* MSVC extension, dllimport identity */
#endif
curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
curl_free_callback Curl_cfree = (curl_free_callback)free;
curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)strdup;
curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
#if defined(WIN32) && defined(UNICODE)
curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
#endif
#if defined(_MSC_VER) && defined(_DLL)
# pragma warning(default:4232) /* MSVC extension, dllimport identity */
#endif
/*
* Curl_convert_clone() returns a malloced copy of the source string (if
* returning CURLE_OK), with the data converted to network format. This
* function is used by base64 code in libcurl built to support data
* conversion. This is a DUMMY VERSION that returns data unmodified - for
* use by the test server only.
*/
CURLcode Curl_convert_clone(struct Curl_easy *data,
const char *indata,
size_t insize,
char **outbuf);
CURLcode Curl_convert_clone(struct Curl_easy *data,
const char *indata,
size_t insize,
char **outbuf)
{
char *convbuf;
(void)data;
convbuf = malloc(insize);
if(!convbuf)
return CURLE_OUT_OF_MEMORY;
memcpy(convbuf, indata, insize);
*outbuf = convbuf;
return CURLE_OK;
}
/*
* line_length()
*
* Counts the number of characters in a line including a new line.
* Unlike strlen() it does not stop at nul bytes.
*
*/
static size_t line_length(const char *buffer, int bytestocheck)
{
size_t length = 1;
while(*buffer != '\n' && --bytestocheck) {
length++;
buffer++;
}
if(*buffer != '\n') {
/*
* We didn't find a new line so the last byte must be a
* '\0' character inserted by fgets() which we should not
* count.
*/
length--;
}
return length;
}
/*
* readline()
*
* Reads a complete line from a file into a dynamically allocated buffer.
*
* Calling function may call this multiple times with same 'buffer'
* and 'bufsize' pointers to avoid multiple buffer allocations. Buffer
* will be reallocated and 'bufsize' increased until whole line fits in
* buffer before returning it.
*
* Calling function is responsible to free allocated buffer.
*
* This function may return:
* GPE_OUT_OF_MEMORY
* GPE_END_OF_FILE
* GPE_OK
*/
static int readline(char **buffer, size_t *bufsize, size_t *length,
FILE *stream)
{
size_t offset = 0;
char *newptr;
if(!*buffer) {
*buffer = malloc(128);
if(!*buffer)
return GPE_OUT_OF_MEMORY;
*bufsize = 128;
}
for(;;) {
int bytestoread = curlx_uztosi(*bufsize - offset);
if(!fgets(*buffer + offset, bytestoread, stream))
return (offset != 0) ? GPE_OK : GPE_END_OF_FILE;
*length = offset + line_length(*buffer + offset, bytestoread);
if(*(*buffer + *length - 1) == '\n')
break;
offset = *length;
if(*length < *bufsize - 1)
continue;
newptr = realloc(*buffer, *bufsize * 2);
if(!newptr)
return GPE_OUT_OF_MEMORY;
*buffer = newptr;
*bufsize *= 2;
}
return GPE_OK;
}
/*
* appenddata()
*
* This appends data from a given source buffer to the end of the used part of
* a destination buffer. Arguments relative to the destination buffer are, the
* address of a pointer to the destination buffer 'dst_buf', the length of data
* in destination buffer excluding potential null string termination 'dst_len',
* the allocated size of destination buffer 'dst_alloc'. All three destination
* buffer arguments may be modified by this function. Arguments relative to the
* source buffer are, a pointer to the source buffer 'src_buf' and indication
* whether the source buffer is base64 encoded or not 'src_b64'.
*
* If the source buffer is indicated to be base64 encoded, this appends the
* decoded data, binary or whatever, to the destination. The source buffer
* may not hold binary data, only a null terminated string is valid content.
*
* Destination buffer will be enlarged and relocated as needed.
*
* Calling function is responsible to provide preallocated destination
* buffer and also to deallocate it when no longer needed.
*
* This function may return:
* GPE_OUT_OF_MEMORY
* GPE_OK
*/
static int appenddata(char **dst_buf, /* dest buffer */
size_t *dst_len, /* dest buffer data length */
size_t *dst_alloc, /* dest buffer allocated size */
char *src_buf, /* source buffer */
size_t src_len, /* source buffer length */
int src_b64) /* != 0 if source is base64 encoded */
{
size_t need_alloc = 0;
if(!src_len)
return GPE_OK;
need_alloc = src_len + *dst_len + 1;
if(src_b64) {
if(src_buf[src_len - 1] == '\r')
src_len--;
if(src_buf[src_len - 1] == '\n')
src_len--;
}
/* enlarge destination buffer if required */
if(need_alloc > *dst_alloc) {
size_t newsize = need_alloc * 2;
char *newptr = realloc(*dst_buf, newsize);
if(!newptr) {
return GPE_OUT_OF_MEMORY;
}
*dst_alloc = newsize;
*dst_buf = newptr;
}
/* memcpy to support binary blobs */
memcpy(*dst_buf + *dst_len, src_buf, src_len);
*dst_len += src_len;
*(*dst_buf + *dst_len) = '\0';
return GPE_OK;
}
static int decodedata(char **buf, /* dest buffer */
size_t *len) /* dest buffer data length */
{
CURLcode error = CURLE_OK;
unsigned char *buf64 = NULL;
size_t src_len = 0;
if(!*len)
return GPE_OK;
/* base64 decode the given buffer */
error = Curl_base64_decode(*buf, &buf64, &src_len);
if(error)
return GPE_OUT_OF_MEMORY;
if(!src_len) {
/*
** currently there is no way to tell apart an OOM condition in
** Curl_base64_decode() from zero length decoded data. For now,
** let's just assume it is an OOM condition, currently we have
** no input for this function that decodes to zero length data.
*/
free(buf64);
return GPE_OUT_OF_MEMORY;
}
/* memcpy to support binary blobs */
memcpy(*buf, buf64, src_len);
*len = src_len;
*(*buf + src_len) = '\0';
free(buf64);
return GPE_OK;
}
/*
* getpart()
*
* This returns whole contents of specified XML-like section and subsection
* from the given file. This is mostly used to retrieve a specific part from
* a test definition file for consumption by test suite servers.
*
* Data is returned in a dynamically allocated buffer, a pointer to this data
* and the size of the data is stored at the addresses that caller specifies.
*
* If the returned data is a string the returned size will be the length of
* the string excluding null termination. Otherwise it will just be the size
* of the returned binary data.
*
* Calling function is responsible to free returned buffer.
*
* This function may return:
* GPE_NO_BUFFER_SPACE
* GPE_OUT_OF_MEMORY
* GPE_OK
*/
int getpart(char **outbuf, size_t *outlen,
const char *main, const char *sub, FILE *stream)
{
# define MAX_TAG_LEN 200
char couter[MAX_TAG_LEN + 1]; /* current outermost section */
char cmain[MAX_TAG_LEN + 1]; /* current main section */
char csub[MAX_TAG_LEN + 1]; /* current sub section */
char ptag[MAX_TAG_LEN + 1]; /* potential tag */
char patt[MAX_TAG_LEN + 1]; /* potential attributes */
char *buffer = NULL;
char *ptr;
char *end;
union {
ssize_t sig;
size_t uns;
} len;
size_t bufsize = 0;
size_t outalloc = 256;
size_t datalen;
int in_wanted_part = 0;
int base64 = 0;
int nonewline = 0;
int error;
enum {
STATE_OUTSIDE = 0,
STATE_OUTER = 1,
STATE_INMAIN = 2,
STATE_INSUB = 3,
STATE_ILLEGAL = 4
} state = STATE_OUTSIDE;
*outlen = 0;
*outbuf = malloc(outalloc);
if(!*outbuf)
return GPE_OUT_OF_MEMORY;
*(*outbuf) = '\0';
couter[0] = cmain[0] = csub[0] = ptag[0] = patt[0] = '\0';
while((error = readline(&buffer, &bufsize, &datalen, stream)) == GPE_OK) {
ptr = buffer;
EAT_SPACE(ptr);
if('<' != *ptr) {
if(in_wanted_part) {
show(("=> %s", buffer));
error = appenddata(outbuf, outlen, &outalloc, buffer, datalen,
base64);
if(error)
break;
}
continue;
}
ptr++;
if('/' == *ptr) {
/*
** closing section tag
*/
ptr++;
end = ptr;
EAT_WORD(end);
len.sig = end - ptr;
if(len.sig > MAX_TAG_LEN) {
error = GPE_NO_BUFFER_SPACE;
break;
}
memcpy(ptag, ptr, len.uns);
ptag[len.uns] = '\0';
if((STATE_INSUB == state) && !strcmp(csub, ptag)) {
/* end of current sub section */
state = STATE_INMAIN;
csub[0] = '\0';
if(in_wanted_part) {
/* end of wanted part */
in_wanted_part = 0;
/* Do we need to base64 decode the data? */
if(base64) {
error = decodedata(outbuf, outlen);
if(error)
return error;
}
if(nonewline)
(*outlen)--;
break;
}
}
else if((STATE_INMAIN == state) && !strcmp(cmain, ptag)) {
/* end of current main section */
state = STATE_OUTER;
cmain[0] = '\0';
if(in_wanted_part) {
/* end of wanted part */
in_wanted_part = 0;
/* Do we need to base64 decode the data? */
if(base64) {
error = decodedata(outbuf, outlen);
if(error)
return error;
}
if(nonewline)
(*outlen)--;
break;
}
}
else if((STATE_OUTER == state) && !strcmp(couter, ptag)) {
/* end of outermost file section */
state = STATE_OUTSIDE;
couter[0] = '\0';
if(in_wanted_part) {
/* end of wanted part */
in_wanted_part = 0;
break;
}
}
}
else if(!in_wanted_part) {
/*
** opening section tag
*/
/* get potential tag */
end = ptr;
EAT_WORD(end);
len.sig = end - ptr;
if(len.sig > MAX_TAG_LEN) {
error = GPE_NO_BUFFER_SPACE;
break;
}
memcpy(ptag, ptr, len.uns);
ptag[len.uns] = '\0';
/* ignore comments, doctypes and xml declarations */
if(('!' == ptag[0]) || ('?' == ptag[0])) {
show(("* ignoring (%s)", buffer));
continue;
}
/* get all potential attributes */
ptr = end;
EAT_SPACE(ptr);
end = ptr;
while(*end && ('>' != *end))
end++;
len.sig = end - ptr;
if(len.sig > MAX_TAG_LEN) {
error = GPE_NO_BUFFER_SPACE;
break;
}
memcpy(patt, ptr, len.uns);
patt[len.uns] = '\0';
if(STATE_OUTSIDE == state) {
/* outermost element (<testcase>) */
strcpy(couter, ptag);
state = STATE_OUTER;
continue;
}
else if(STATE_OUTER == state) {
/* start of a main section */
strcpy(cmain, ptag);
state = STATE_INMAIN;
continue;
}
else if(STATE_INMAIN == state) {
/* start of a sub section */
strcpy(csub, ptag);
state = STATE_INSUB;
if(!strcmp(cmain, main) && !strcmp(csub, sub)) {
/* start of wanted part */
in_wanted_part = 1;
if(strstr(patt, "base64="))
/* bit rough test, but "mostly" functional, */
/* treat wanted part data as base64 encoded */
base64 = 1;
if(strstr(patt, "nonewline=")) {
show(("* setting nonewline\n"));
nonewline = 1;
}
}
continue;
}
}
if(in_wanted_part) {
show(("=> %s", buffer));
error = appenddata(outbuf, outlen, &outalloc, buffer, datalen, base64);
if(error)
break;
}
} /* while */
free(buffer);
if(error != GPE_OK) {
if(error == GPE_END_OF_FILE)
error = GPE_OK;
else {
free(*outbuf);
*outbuf = NULL;
*outlen = 0;
}
}
return error;
}

View file

@ -0,0 +1,36 @@
#ifndef HEADER_CURL_SERVER_GETPART_H
#define HEADER_CURL_SERVER_GETPART_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "server_setup.h"
#define GPE_NO_BUFFER_SPACE -2
#define GPE_OUT_OF_MEMORY -1
#define GPE_OK 0
#define GPE_END_OF_FILE 1
int getpart(char **outbuf, size_t *outlen,
const char *main, const char *sub, FILE *stream);
#endif /* HEADER_CURL_SERVER_GETPART_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,158 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "server_setup.h"
/* Purpose
*
* Resolve the given name, using system name resolve functions (NOT any
* function provided by libcurl). Used to see if the name exists and thus if
* we can allow a test case to use it for testing.
*
* Like if 'localhost' actual exists etc.
*
*/
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef _XOPEN_SOURCE_EXTENDED
/* This define is "almost" required to build on HPUX 11 */
#include <arpa/inet.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#define ENABLE_CURLX_PRINTF
/* make the curlx header define all printf() functions to use the curlx_*
versions instead */
#include "curlx.h" /* from the private lib dir */
#include "util.h"
/* include memdebug.h last */
#include "memdebug.h"
static bool use_ipv6 = FALSE;
static const char *ipv_inuse = "IPv4";
const char *serverlogfile = ""; /* for a util.c function we don't use */
int main(int argc, char *argv[])
{
int arg = 1;
const char *host = NULL;
int rc = 0;
while(argc>arg) {
if(!strcmp("--version", argv[arg])) {
printf("resolve IPv4%s\n",
#if defined(CURLRES_IPV6)
"/IPv6"
#else
""
#endif
);
return 0;
}
else if(!strcmp("--ipv6", argv[arg])) {
ipv_inuse = "IPv6";
use_ipv6 = TRUE;
arg++;
}
else if(!strcmp("--ipv4", argv[arg])) {
/* for completeness, we support this option as well */
ipv_inuse = "IPv4";
use_ipv6 = FALSE;
arg++;
}
else {
host = argv[arg++];
}
}
if(!host) {
puts("Usage: resolve [option] <host>\n"
" --version\n"
" --ipv4"
#if defined(CURLRES_IPV6)
"\n --ipv6"
#endif
);
return 1;
}
#ifdef WIN32
win32_init();
atexit(win32_cleanup);
#endif
#if defined(CURLRES_IPV6)
if(use_ipv6) {
/* Check that the system has IPv6 enabled before checking the resolver */
curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
if(s == CURL_SOCKET_BAD)
/* an IPv6 address was requested and we can't get/use one */
rc = -1;
else {
sclose(s);
}
}
if(rc == 0) {
/* getaddrinfo() resolve */
struct addrinfo *ai;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = use_ipv6 ? PF_INET6 : PF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
/* Use parenthesis around functions to stop them from being replaced by
the macro in memdebug.h */
rc = (getaddrinfo)(host, "80", &hints, &ai);
if(rc == 0)
(freeaddrinfo)(ai);
}
#else
if(use_ipv6) {
puts("IPv6 support has been disabled in this program");
return 1;
}
else {
/* gethostbyname() resolve */
struct hostent *he;
he = gethostbyname(host);
rc = !he;
}
#endif
if(rc)
printf("Resolving %s '%s' didn't work\n", ipv_inuse, host);
return !!rc;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,31 @@
#ifndef HEADER_CURL_SERVER_SETUP_H
#define HEADER_CURL_SERVER_SETUP_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#define CURL_NO_OLDIES
#include "curl_setup.h" /* portability help from the lib directory */
#endif /* HEADER_CURL_SERVER_SETUP_H */

View file

@ -0,0 +1,43 @@
#ifndef HEADER_CURL_SERVER_SOCKADDR_H
#define HEADER_CURL_SERVER_SOCKADDR_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "server_setup.h"
#ifdef HAVE_SYS_UN_H
#include <sys/un.h> /* for sockaddr_un */
#endif
typedef union {
struct sockaddr sa;
struct sockaddr_in sa4;
#ifdef ENABLE_IPV6
struct sockaddr_in6 sa6;
#endif
#ifdef USE_UNIX_SOCKETS
struct sockaddr_un sau;
#endif
} srvr_sockaddr_union_t;
#endif /* HEADER_CURL_SERVER_SOCKADDR_H */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,51 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "server_setup.h"
#include "getpart.h"
#include "curl_printf.h"
/* include memdebug.h last */
#include "memdebug.h"
int main(int argc, char **argv)
{
char *part;
size_t partlen;
if(argc< 3) {
printf("./testpart main sub\n");
}
else {
int rc = getpart(&part, &partlen, argv[1], argv[2], stdin);
size_t i;
if(rc)
return rc;
for(i = 0; i < partlen; i++)
printf("%c", part[i]);
free(part);
}
return 0;
}

View file

@ -0,0 +1,63 @@
#ifndef HEADER_CURL_SERVER_TFTP_H
#define HEADER_CURL_SERVER_TFTP_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "server_setup.h"
/* This file is a rewrite/clone of the arpa/tftp.h file for systems without
it. */
#define SEGSIZE 512 /* data segment size */
#if defined(__GNUC__) && ((__GNUC__ >= 3) || \
((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 7)))
# define PACKED_STRUCT __attribute__((__packed__))
#else
# define PACKED_STRUCT /*NOTHING*/
#endif
/* Using a packed struct as binary in a program is begging for problems, but
the tftpd server was written like this so we have this struct here to make
things build. */
struct tftphdr {
short th_opcode; /* packet type */
unsigned short th_block; /* all sorts of things */
char th_data[1]; /* data or error string */
} PACKED_STRUCT;
#define th_stuff th_block
#define th_code th_block
#define th_msg th_data
#define EUNDEF 0
#define ENOTFOUND 1
#define EACCESS 2
#define ENOSPACE 3
#define EBADOP 4
#define EBADID 5
#define EEXISTS 6
#define ENOUSER 7
#endif /* HEADER_CURL_SERVER_TFTP_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,876 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "server_setup.h"
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef _XOPEN_SOURCE_EXTENDED
/* This define is "almost" required to build on HPUX 11 */
#include <arpa/inet.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_POLL_H
#include <poll.h>
#elif defined(HAVE_SYS_POLL_H)
#include <sys/poll.h>
#endif
#ifdef __MINGW32__
#include <w32api.h>
#endif
#define ENABLE_CURLX_PRINTF
/* make the curlx header define all printf() functions to use the curlx_*
versions instead */
#include "curlx.h" /* from the private lib dir */
#include "getpart.h"
#include "util.h"
#include "timeval.h"
#ifdef USE_WINSOCK
#undef EINTR
#define EINTR 4 /* errno.h value */
#undef EINVAL
#define EINVAL 22 /* errno.h value */
#endif
/* MinGW with w32api version < 3.6 declared in6addr_any as extern,
but lacked the definition */
#if defined(ENABLE_IPV6) && defined(__MINGW32__)
#if (__W32API_MAJOR_VERSION < 3) || \
((__W32API_MAJOR_VERSION == 3) && (__W32API_MINOR_VERSION < 6))
const struct in6_addr in6addr_any = {{ IN6ADDR_ANY_INIT }};
#endif /* w32api < 3.6 */
#endif /* ENABLE_IPV6 && __MINGW32__*/
static struct timeval tvnow(void);
/* This function returns a pointer to STATIC memory. It converts the given
* binary lump to a hex formatted string usable for output in logs or
* whatever.
*/
char *data_to_hex(char *data, size_t len)
{
static char buf[256*3];
size_t i;
char *optr = buf;
char *iptr = data;
if(len > 255)
len = 255;
for(i = 0; i < len; i++) {
if((data[i] >= 0x20) && (data[i] < 0x7f))
*optr++ = *iptr++;
else {
msnprintf(optr, 4, "%%%02x", *iptr++);
optr += 3;
}
}
*optr = 0; /* in case no sprintf was used */
return buf;
}
void logmsg(const char *msg, ...)
{
va_list ap;
char buffer[2048 + 1];
FILE *logfp;
struct timeval tv;
time_t sec;
struct tm *now;
char timebuf[20];
static time_t epoch_offset;
static int known_offset;
if(!serverlogfile) {
fprintf(stderr, "Error: serverlogfile not set\n");
return;
}
tv = tvnow();
if(!known_offset) {
epoch_offset = time(NULL) - tv.tv_sec;
known_offset = 1;
}
sec = epoch_offset + tv.tv_sec;
/* !checksrc! disable BANNEDFUNC 1 */
now = localtime(&sec); /* not thread safe but we don't care */
msnprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld",
(int)now->tm_hour, (int)now->tm_min, (int)now->tm_sec,
(long)tv.tv_usec);
va_start(ap, msg);
mvsnprintf(buffer, sizeof(buffer), msg, ap);
va_end(ap);
logfp = fopen(serverlogfile, "ab");
if(logfp) {
fprintf(logfp, "%s %s\n", timebuf, buffer);
fclose(logfp);
}
else {
int error = errno;
fprintf(stderr, "fopen() failed with error: %d %s\n",
error, strerror(error));
fprintf(stderr, "Error opening file: %s\n", serverlogfile);
fprintf(stderr, "Msg not logged: %s %s\n", timebuf, buffer);
}
}
#ifdef WIN32
/* use instead of perror() on generic windows */
void win32_perror(const char *msg)
{
char buf[512];
DWORD err = SOCKERRNO;
if(!FormatMessageA((FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
LANG_NEUTRAL, buf, sizeof(buf), NULL))
msnprintf(buf, sizeof(buf), "Unknown error %lu (%#lx)", err, err);
if(msg)
fprintf(stderr, "%s: ", msg);
fprintf(stderr, "%s\n", buf);
}
void win32_init(void)
{
#ifdef USE_WINSOCK
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if(err) {
perror("Winsock init failed");
logmsg("Error initialising winsock -- aborting");
exit(1);
}
if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) {
WSACleanup();
perror("Winsock init failed");
logmsg("No suitable winsock.dll found -- aborting");
exit(1);
}
#endif /* USE_WINSOCK */
}
void win32_cleanup(void)
{
#ifdef USE_WINSOCK
WSACleanup();
#endif /* USE_WINSOCK */
/* flush buffers of all streams regardless of their mode */
_flushall();
}
#endif /* WIN32 */
/* set by the main code to point to where the test dir is */
const char *path = ".";
FILE *test2fopen(long testno)
{
FILE *stream;
char filename[256];
/* first try the alternative, preprocessed, file */
msnprintf(filename, sizeof(filename), ALTTEST_DATA_PATH, ".", testno);
stream = fopen(filename, "rb");
if(stream)
return stream;
/* then try the source version */
msnprintf(filename, sizeof(filename), TEST_DATA_PATH, path, testno);
stream = fopen(filename, "rb");
return stream;
}
/*
* Portable function used for waiting a specific amount of ms.
* Waiting indefinitely with this function is not allowed, a
* zero or negative timeout value will return immediately.
*
* Return values:
* -1 = system call error, or invalid timeout value
* 0 = specified timeout has elapsed
*/
int wait_ms(int timeout_ms)
{
#if !defined(MSDOS) && !defined(USE_WINSOCK)
#ifndef HAVE_POLL_FINE
struct timeval pending_tv;
#endif
struct timeval initial_tv;
int pending_ms;
#endif
int r = 0;
if(!timeout_ms)
return 0;
if(timeout_ms < 0) {
errno = EINVAL;
return -1;
}
#if defined(MSDOS)
delay(timeout_ms);
#elif defined(USE_WINSOCK)
Sleep(timeout_ms);
#else
pending_ms = timeout_ms;
initial_tv = tvnow();
do {
int error;
#if defined(HAVE_POLL_FINE)
r = poll(NULL, 0, pending_ms);
#else
pending_tv.tv_sec = pending_ms / 1000;
pending_tv.tv_usec = (pending_ms % 1000) * 1000;
r = select(0, NULL, NULL, NULL, &pending_tv);
#endif /* HAVE_POLL_FINE */
if(r != -1)
break;
error = errno;
if(error && (error != EINTR))
break;
pending_ms = timeout_ms - (int)timediff(tvnow(), initial_tv);
if(pending_ms <= 0)
break;
} while(r == -1);
#endif /* USE_WINSOCK */
if(r)
r = -1;
return r;
}
curl_off_t our_getpid(void)
{
curl_off_t pid;
pid = (curl_off_t)getpid();
#if defined(WIN32) || defined(_WIN32)
/* store pid + 65536 to avoid conflict with Cygwin/msys PIDs, see also:
* - https://cygwin.com/git/?p=newlib-cygwin.git;a=commit; ↵
* h=b5e1003722cb14235c4f166be72c09acdffc62ea
* - https://cygwin.com/git/?p=newlib-cygwin.git;a=commit; ↵
* h=448cf5aa4b429d5a9cebf92a0da4ab4b5b6d23fe
*/
pid += 65536;
#endif
return pid;
}
int write_pidfile(const char *filename)
{
FILE *pidfile;
curl_off_t pid;
pid = our_getpid();
pidfile = fopen(filename, "wb");
if(!pidfile) {
logmsg("Couldn't write pid file: %s %s", filename, strerror(errno));
return 0; /* fail */
}
fprintf(pidfile, "%" CURL_FORMAT_CURL_OFF_T "\n", pid);
fclose(pidfile);
logmsg("Wrote pid %" CURL_FORMAT_CURL_OFF_T " to %s", pid, filename);
return 1; /* success */
}
/* store the used port number in a file */
int write_portfile(const char *filename, int port)
{
FILE *portfile = fopen(filename, "wb");
if(!portfile) {
logmsg("Couldn't write port file: %s %s", filename, strerror(errno));
return 0; /* fail */
}
fprintf(portfile, "%d\n", port);
fclose(portfile);
logmsg("Wrote port %d to %s", port, filename);
return 1; /* success */
}
void set_advisor_read_lock(const char *filename)
{
FILE *lockfile;
int error = 0;
int res;
do {
lockfile = fopen(filename, "wb");
} while(!lockfile && ((error = errno) == EINTR));
if(!lockfile) {
logmsg("Error creating lock file %s error: %d %s",
filename, error, strerror(error));
return;
}
do {
res = fclose(lockfile);
} while(res && ((error = errno) == EINTR));
if(res)
logmsg("Error closing lock file %s error: %d %s",
filename, error, strerror(error));
}
void clear_advisor_read_lock(const char *filename)
{
int error = 0;
int res;
/*
** Log all removal failures. Even those due to file not existing.
** This allows to detect if unexpectedly the file has already been
** removed by a process different than the one that should do this.
*/
do {
res = unlink(filename);
} while(res && ((error = errno) == EINTR));
if(res)
logmsg("Error removing lock file %s error: %d %s",
filename, error, strerror(error));
}
/* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
its behavior is altered by the current locale. */
static char raw_toupper(char in)
{
if(in >= 'a' && in <= 'z')
return (char)('A' + in - 'a');
return in;
}
int strncasecompare(const char *first, const char *second, size_t max)
{
while(*first && *second && max) {
if(raw_toupper(*first) != raw_toupper(*second)) {
break;
}
max--;
first++;
second++;
}
if(0 == max)
return 1; /* they are equal this far */
return raw_toupper(*first) == raw_toupper(*second);
}
#if defined(WIN32) && !defined(MSDOS)
static struct timeval tvnow(void)
{
/*
** GetTickCount() is available on _all_ Windows versions from W95 up
** to nowadays. Returns milliseconds elapsed since last system boot,
** increases monotonically and wraps once 49.7 days have elapsed.
**
** GetTickCount64() is available on Windows version from Windows Vista
** and Windows Server 2008 up to nowadays. The resolution of the
** function is limited to the resolution of the system timer, which
** is typically in the range of 10 milliseconds to 16 milliseconds.
*/
struct timeval now;
#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600) && \
(!defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR))
ULONGLONG milliseconds = GetTickCount64();
#else
DWORD milliseconds = GetTickCount();
#endif
now.tv_sec = (long)(milliseconds / 1000);
now.tv_usec = (long)((milliseconds % 1000) * 1000);
return now;
}
#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
static struct timeval tvnow(void)
{
/*
** clock_gettime() is granted to be increased monotonically when the
** monotonic clock is queried. Time starting point is unspecified, it
** could be the system start-up time, the Epoch, or something else,
** in any case the time starting point does not change once that the
** system has started up.
*/
struct timeval now;
struct timespec tsnow;
if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
now.tv_sec = tsnow.tv_sec;
now.tv_usec = (int)(tsnow.tv_nsec / 1000);
}
/*
** Even when the configure process has truly detected monotonic clock
** availability, it might happen that it is not actually available at
** run-time. When this occurs simply fallback to other time source.
*/
#ifdef HAVE_GETTIMEOFDAY
else
(void)gettimeofday(&now, NULL);
#else
else {
now.tv_sec = time(NULL);
now.tv_usec = 0;
}
#endif
return now;
}
#elif defined(HAVE_GETTIMEOFDAY)
static struct timeval tvnow(void)
{
/*
** gettimeofday() is not granted to be increased monotonically, due to
** clock drifting and external source time synchronization it can jump
** forward or backward in time.
*/
struct timeval now;
(void)gettimeofday(&now, NULL);
return now;
}
#else
static struct timeval tvnow(void)
{
/*
** time() returns the value of time in seconds since the Epoch.
*/
struct timeval now;
now.tv_sec = time(NULL);
now.tv_usec = 0;
return now;
}
#endif
long timediff(struct timeval newer, struct timeval older)
{
timediff_t diff = newer.tv_sec-older.tv_sec;
if(diff >= (LONG_MAX/1000))
return LONG_MAX;
else if(diff <= (LONG_MIN/1000))
return LONG_MIN;
return (long)(newer.tv_sec-older.tv_sec)*1000+
(long)(newer.tv_usec-older.tv_usec)/1000;
}
/* vars used to keep around previous signal handlers */
typedef void (*SIGHANDLER_T)(int);
#ifdef SIGHUP
static SIGHANDLER_T old_sighup_handler = SIG_ERR;
#endif
#ifdef SIGPIPE
static SIGHANDLER_T old_sigpipe_handler = SIG_ERR;
#endif
#ifdef SIGALRM
static SIGHANDLER_T old_sigalrm_handler = SIG_ERR;
#endif
#ifdef SIGINT
static SIGHANDLER_T old_sigint_handler = SIG_ERR;
#endif
#ifdef SIGTERM
static SIGHANDLER_T old_sigterm_handler = SIG_ERR;
#endif
#if defined(SIGBREAK) && defined(WIN32)
static SIGHANDLER_T old_sigbreak_handler = SIG_ERR;
#endif
#ifdef WIN32
static DWORD thread_main_id = 0;
static HANDLE thread_main_window = NULL;
static HWND hidden_main_window = NULL;
#endif
/* var which if set indicates that the program should finish execution */
volatile int got_exit_signal = 0;
/* if next is set indicates the first signal handled in exit_signal_handler */
volatile int exit_signal = 0;
#ifdef WIN32
/* event which if set indicates that the program should finish */
HANDLE exit_event = NULL;
#endif
/* signal handler that will be triggered to indicate that the program
* should finish its execution in a controlled manner as soon as possible.
* The first time this is called it will set got_exit_signal to one and
* store in exit_signal the signal that triggered its execution.
*/
static void exit_signal_handler(int signum)
{
int old_errno = errno;
logmsg("exit_signal_handler: %d", signum);
if(got_exit_signal == 0) {
got_exit_signal = 1;
exit_signal = signum;
#ifdef WIN32
if(exit_event)
(void)SetEvent(exit_event);
#endif
}
(void)signal(signum, exit_signal_handler);
errno = old_errno;
}
#ifdef WIN32
/* CTRL event handler for Windows Console applications to simulate
* SIGINT, SIGTERM and SIGBREAK on CTRL events and trigger signal handler.
*
* Background information from MSDN:
* SIGINT is not supported for any Win32 application. When a CTRL+C
* interrupt occurs, Win32 operating systems generate a new thread
* to specifically handle that interrupt. This can cause a single-thread
* application, such as one in UNIX, to become multithreaded and cause
* unexpected behavior.
* [...]
* The SIGILL and SIGTERM signals are not generated under Windows.
* They are included for ANSI compatibility. Therefore, you can set
* signal handlers for these signals by using signal, and you can also
* explicitly generate these signals by calling raise. Source:
* https://docs.microsoft.com/de-de/cpp/c-runtime-library/reference/signal
*/
static BOOL WINAPI ctrl_event_handler(DWORD dwCtrlType)
{
int signum = 0;
logmsg("ctrl_event_handler: %d", dwCtrlType);
switch(dwCtrlType) {
#ifdef SIGINT
case CTRL_C_EVENT: signum = SIGINT; break;
#endif
#ifdef SIGTERM
case CTRL_CLOSE_EVENT: signum = SIGTERM; break;
#endif
#ifdef SIGBREAK
case CTRL_BREAK_EVENT: signum = SIGBREAK; break;
#endif
default: return FALSE;
}
if(signum) {
logmsg("ctrl_event_handler: %d -> %d", dwCtrlType, signum);
raise(signum);
}
return TRUE;
}
/* Window message handler for Windows applications to add support
* for graceful process termination via taskkill (without /f) which
* sends WM_CLOSE to all Windows of a process (even hidden ones).
*
* Therefore we create and run a hidden Window in a separate thread
* to receive and handle the WM_CLOSE message as SIGTERM signal.
*/
static LRESULT CALLBACK main_window_proc(HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
int signum = 0;
if(hwnd == hidden_main_window) {
switch(uMsg) {
#ifdef SIGTERM
case WM_CLOSE: signum = SIGTERM; break;
#endif
case WM_DESTROY: PostQuitMessage(0); break;
}
if(signum) {
logmsg("main_window_proc: %d -> %d", uMsg, signum);
raise(signum);
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
/* Window message queue loop for hidden main window, details see above.
*/
static DWORD WINAPI main_window_loop(LPVOID lpParameter)
{
WNDCLASS wc;
BOOL ret;
MSG msg;
ZeroMemory(&wc, sizeof(wc));
wc.lpfnWndProc = (WNDPROC)main_window_proc;
wc.hInstance = (HINSTANCE)lpParameter;
wc.lpszClassName = TEXT("MainWClass");
if(!RegisterClass(&wc)) {
perror("RegisterClass failed");
return (DWORD)-1;
}
hidden_main_window = CreateWindowEx(0, TEXT("MainWClass"),
TEXT("Recv WM_CLOSE msg"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
(HWND)NULL, (HMENU)NULL,
wc.hInstance, (LPVOID)NULL);
if(!hidden_main_window) {
perror("CreateWindowEx failed");
return (DWORD)-1;
}
do {
ret = GetMessage(&msg, NULL, 0, 0);
if(ret == -1) {
perror("GetMessage failed");
return (DWORD)-1;
}
else if(ret) {
if(msg.message == WM_APP) {
DestroyWindow(hidden_main_window);
}
else if(msg.hwnd && !TranslateMessage(&msg)) {
DispatchMessage(&msg);
}
}
} while(ret);
hidden_main_window = NULL;
return (DWORD)msg.wParam;
}
#endif
static SIGHANDLER_T set_signal(int signum, SIGHANDLER_T handler,
bool restartable)
{
#if defined(HAVE_SIGACTION) && defined(SA_RESTART)
struct sigaction sa, oldsa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, signum);
sa.sa_flags = restartable? SA_RESTART: 0;
if(sigaction(signum, &sa, &oldsa))
return SIG_ERR;
return oldsa.sa_handler;
#else
SIGHANDLER_T oldhdlr = signal(signum, handler);
#ifdef HAVE_SIGINTERRUPT
if(oldhdlr != SIG_ERR)
siginterrupt(signum, (int) restartable);
#else
(void) restartable;
#endif
return oldhdlr;
#endif
}
void install_signal_handlers(bool keep_sigalrm)
{
#ifdef WIN32
/* setup windows exit event before any signal can trigger */
exit_event = CreateEvent(NULL, TRUE, FALSE, NULL);
if(!exit_event)
logmsg("cannot create exit event");
#endif
#ifdef SIGHUP
/* ignore SIGHUP signal */
old_sighup_handler = set_signal(SIGHUP, SIG_IGN, FALSE);
if(old_sighup_handler == SIG_ERR)
logmsg("cannot install SIGHUP handler: %s", strerror(errno));
#endif
#ifdef SIGPIPE
/* ignore SIGPIPE signal */
old_sigpipe_handler = set_signal(SIGPIPE, SIG_IGN, FALSE);
if(old_sigpipe_handler == SIG_ERR)
logmsg("cannot install SIGPIPE handler: %s", strerror(errno));
#endif
#ifdef SIGALRM
if(!keep_sigalrm) {
/* ignore SIGALRM signal */
old_sigalrm_handler = set_signal(SIGALRM, SIG_IGN, FALSE);
if(old_sigalrm_handler == SIG_ERR)
logmsg("cannot install SIGALRM handler: %s", strerror(errno));
}
#else
(void)keep_sigalrm;
#endif
#ifdef SIGINT
/* handle SIGINT signal with our exit_signal_handler */
old_sigint_handler = set_signal(SIGINT, exit_signal_handler, TRUE);
if(old_sigint_handler == SIG_ERR)
logmsg("cannot install SIGINT handler: %s", strerror(errno));
#endif
#ifdef SIGTERM
/* handle SIGTERM signal with our exit_signal_handler */
old_sigterm_handler = set_signal(SIGTERM, exit_signal_handler, TRUE);
if(old_sigterm_handler == SIG_ERR)
logmsg("cannot install SIGTERM handler: %s", strerror(errno));
#endif
#if defined(SIGBREAK) && defined(WIN32)
/* handle SIGBREAK signal with our exit_signal_handler */
old_sigbreak_handler = set_signal(SIGBREAK, exit_signal_handler, TRUE);
if(old_sigbreak_handler == SIG_ERR)
logmsg("cannot install SIGBREAK handler: %s", strerror(errno));
#endif
#ifdef WIN32
if(!SetConsoleCtrlHandler(ctrl_event_handler, TRUE))
logmsg("cannot install CTRL event handler");
thread_main_window = CreateThread(NULL, 0,
&main_window_loop,
(LPVOID)GetModuleHandle(NULL),
0, &thread_main_id);
if(!thread_main_window || !thread_main_id)
logmsg("cannot start main window loop");
#endif
}
void restore_signal_handlers(bool keep_sigalrm)
{
#ifdef SIGHUP
if(SIG_ERR != old_sighup_handler)
(void) set_signal(SIGHUP, old_sighup_handler, FALSE);
#endif
#ifdef SIGPIPE
if(SIG_ERR != old_sigpipe_handler)
(void) set_signal(SIGPIPE, old_sigpipe_handler, FALSE);
#endif
#ifdef SIGALRM
if(!keep_sigalrm) {
if(SIG_ERR != old_sigalrm_handler)
(void) set_signal(SIGALRM, old_sigalrm_handler, FALSE);
}
#else
(void)keep_sigalrm;
#endif
#ifdef SIGINT
if(SIG_ERR != old_sigint_handler)
(void) set_signal(SIGINT, old_sigint_handler, FALSE);
#endif
#ifdef SIGTERM
if(SIG_ERR != old_sigterm_handler)
(void) set_signal(SIGTERM, old_sigterm_handler, FALSE);
#endif
#if defined(SIGBREAK) && defined(WIN32)
if(SIG_ERR != old_sigbreak_handler)
(void) set_signal(SIGBREAK, old_sigbreak_handler, FALSE);
#endif
#ifdef WIN32
(void)SetConsoleCtrlHandler(ctrl_event_handler, FALSE);
if(thread_main_window && thread_main_id) {
if(PostThreadMessage(thread_main_id, WM_APP, 0, 0)) {
if(WaitForSingleObjectEx(thread_main_window, INFINITE, TRUE)) {
if(CloseHandle(thread_main_window)) {
thread_main_window = NULL;
thread_main_id = 0;
}
}
}
}
if(exit_event) {
if(CloseHandle(exit_event)) {
exit_event = NULL;
}
}
#endif
}
#ifdef USE_UNIX_SOCKETS
int bind_unix_socket(curl_socket_t sock, const char *unix_socket,
struct sockaddr_un *sau) {
int error;
int rc;
memset(sau, 0, sizeof(struct sockaddr_un));
sau->sun_family = AF_UNIX;
strncpy(sau->sun_path, unix_socket, sizeof(sau->sun_path) - 1);
rc = bind(sock, (struct sockaddr*)sau, sizeof(struct sockaddr_un));
if(0 != rc && errno == EADDRINUSE) {
struct_stat statbuf;
/* socket already exists. Perhaps it is stale? */
curl_socket_t unixfd = socket(AF_UNIX, SOCK_STREAM, 0);
if(CURL_SOCKET_BAD == unixfd) {
error = SOCKERRNO;
logmsg("Error binding socket, failed to create socket at %s: (%d) %s",
unix_socket, error, strerror(error));
return rc;
}
/* check whether the server is alive */
rc = connect(unixfd, (struct sockaddr*)sau, sizeof(struct sockaddr_un));
error = errno;
sclose(unixfd);
if(ECONNREFUSED != error) {
logmsg("Error binding socket, failed to connect to %s: (%d) %s",
unix_socket, error, strerror(error));
return rc;
}
/* socket server is not alive, now check if it was actually a socket. */
#ifdef WIN32
/* Windows does not have lstat function. */
rc = curlx_win32_stat(unix_socket, &statbuf);
#else
rc = lstat(unix_socket, &statbuf);
#endif
if(0 != rc) {
logmsg("Error binding socket, failed to stat %s: (%d) %s",
unix_socket, errno, strerror(errno));
return rc;
}
#ifdef S_IFSOCK
if((statbuf.st_mode & S_IFSOCK) != S_IFSOCK) {
logmsg("Error binding socket, failed to stat %s: (%d) %s",
unix_socket, error, strerror(error));
return rc;
}
#endif
/* dead socket, cleanup and retry bind */
rc = unlink(unix_socket);
if(0 != rc) {
logmsg("Error binding socket, failed to unlink %s: (%d) %s",
unix_socket, errno, strerror(errno));
return rc;
}
/* stale socket is gone, retry bind */
rc = bind(sock, (struct sockaddr*)sau, sizeof(struct sockaddr_un));
}
return rc;
}
#endif

View file

@ -0,0 +1,94 @@
#ifndef HEADER_CURL_SERVER_UTIL_H
#define HEADER_CURL_SERVER_UTIL_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "server_setup.h"
char *data_to_hex(char *data, size_t len);
void logmsg(const char *msg, ...);
long timediff(struct timeval newer, struct timeval older);
#define TEST_DATA_PATH "%s/data/test%ld"
#define ALTTEST_DATA_PATH "%s/log/test%ld"
#define SERVERLOGS_LOCK "log/serverlogs.lock"
/* global variable, where to find the 'data' dir */
extern const char *path;
/* global variable, log file name */
extern const char *serverlogfile;
extern const char *cmdfile;
#ifdef WIN32
#include <process.h>
#include <fcntl.h>
#define sleep(sec) Sleep ((sec)*1000)
#undef perror
#define perror(m) win32_perror(m)
void win32_perror(const char *msg);
void win32_init(void);
void win32_cleanup(void);
#endif /* WIN32 */
/* fopens the test case file */
FILE *test2fopen(long testno);
int wait_ms(int timeout_ms);
curl_off_t our_getpid(void);
int write_pidfile(const char *filename);
int write_portfile(const char *filename, int port);
void set_advisor_read_lock(const char *filename);
void clear_advisor_read_lock(const char *filename);
int strncasecompare(const char *first, const char *second, size_t max);
/* global variable which if set indicates that the program should finish */
extern volatile int got_exit_signal;
/* global variable which if set indicates the first signal handled */
extern volatile int exit_signal;
#ifdef WIN32
/* global event which if set indicates that the program should finish */
extern HANDLE exit_event;
#endif
void install_signal_handlers(bool keep_sigalrm);
void restore_signal_handlers(bool keep_sigalrm);
#ifdef USE_UNIX_SOCKETS
#ifdef HAVE_SYS_UN_H
#include <sys/un.h> /* for sockaddr_un */
#endif /* HAVE_SYS_UN_H */
int bind_unix_socket(curl_socket_t sock, const char *unix_socket,
struct sockaddr_un *sau);
#endif /* USE_UNIX_SOCKETS */
#endif /* HEADER_CURL_SERVER_UTIL_H */