summaryrefslogtreecommitdiff
path: root/tests/libtest
diff options
context:
space:
mode:
Diffstat (limited to 'tests/libtest')
-rw-r--r--tests/libtest/.gitignore5
-rw-r--r--tests/libtest/CMakeLists.txt121
-rw-r--r--tests/libtest/Makefile.am108
-rw-r--r--tests/libtest/Makefile.inc224
-rw-r--r--tests/libtest/chkhostname.c47
-rw-r--r--tests/libtest/first.c131
-rw-r--r--tests/libtest/lib1500.c95
-rw-r--r--tests/libtest/lib1501.c126
-rw-r--r--tests/libtest/lib1502.c143
-rw-r--r--tests/libtest/lib500.c141
-rw-r--r--tests/libtest/lib501.c55
-rw-r--r--tests/libtest/lib502.c92
-rw-r--r--tests/libtest/lib503.c102
-rw-r--r--tests/libtest/lib504.c114
-rw-r--r--tests/libtest/lib505.c157
-rw-r--r--tests/libtest/lib506.c277
-rw-r--r--tests/libtest/lib507.c100
-rw-r--r--tests/libtest/lib508.c107
-rw-r--r--tests/libtest/lib510.c130
-rw-r--r--tests/libtest/lib511.c55
-rw-r--r--tests/libtest/lib512.c77
-rw-r--r--tests/libtest/lib513.c82
-rw-r--r--tests/libtest/lib514.c78
-rw-r--r--tests/libtest/lib515.c59
-rw-r--r--tests/libtest/lib516.c58
-rw-r--r--tests/libtest/lib517.c133
-rw-r--r--tests/libtest/lib518.c516
-rw-r--r--tests/libtest/lib519.c62
-rw-r--r--tests/libtest/lib520.c54
-rw-r--r--tests/libtest/lib521.c56
-rw-r--r--tests/libtest/lib523.c57
-rw-r--r--tests/libtest/lib524.c55
-rw-r--r--tests/libtest/lib525.c165
-rw-r--r--tests/libtest/lib526.c184
-rw-r--r--tests/libtest/lib530.c111
-rw-r--r--tests/libtest/lib533.c112
-rw-r--r--tests/libtest/lib536.c142
-rw-r--r--tests/libtest/lib537.c519
-rw-r--r--tests/libtest/lib539.c92
-rw-r--r--tests/libtest/lib540.c248
-rw-r--r--tests/libtest/lib541.c117
-rw-r--r--tests/libtest/lib542.c72
-rw-r--r--tests/libtest/lib543.c54
-rw-r--r--tests/libtest/lib544.c78
-rw-r--r--tests/libtest/lib547.c129
-rw-r--r--tests/libtest/lib549.c65
-rw-r--r--tests/libtest/lib552.c220
-rw-r--r--tests/libtest/lib553.c114
-rw-r--r--tests/libtest/lib554.c199
-rw-r--r--tests/libtest/lib555.c159
-rw-r--r--tests/libtest/lib556.c106
-rw-r--r--tests/libtest/lib557.c1401
-rw-r--r--tests/libtest/lib560.c113
-rw-r--r--tests/libtest/lib562.c73
-rw-r--r--tests/libtest/lib564.c93
-rw-r--r--tests/libtest/lib566.c67
-rw-r--r--tests/libtest/lib567.c69
-rw-r--r--tests/libtest/lib568.c175
-rw-r--r--tests/libtest/lib569.c129
-rw-r--r--tests/libtest/lib570.c117
-rw-r--r--tests/libtest/lib571.c212
-rw-r--r--tests/libtest/lib572.c181
-rw-r--r--tests/libtest/lib573.c113
-rw-r--r--tests/libtest/lib574.c68
-rw-r--r--tests/libtest/lib575.c114
-rw-r--r--tests/libtest/lib576.c124
-rw-r--r--tests/libtest/lib578.c102
-rw-r--r--tests/libtest/lib579.c161
-rw-r--r--tests/libtest/lib582.c366
-rw-r--r--tests/libtest/lib583.c84
-rw-r--r--tests/libtest/lib586.c246
-rw-r--r--tests/libtest/lib590.c71
-rw-r--r--tests/libtest/lib591.c149
-rw-r--r--tests/libtest/lib597.c150
-rw-r--r--tests/libtest/lib598.c72
-rw-r--r--tests/libtest/lib599.c84
-rw-r--r--tests/libtest/libauthretry.c153
-rw-r--r--tests/libtest/libntlmconnect.c275
-rwxr-xr-xtests/libtest/notexists.pl15
-rw-r--r--tests/libtest/sethostname.c41
-rw-r--r--tests/libtest/sethostname.h45
-rw-r--r--tests/libtest/test.h436
-rwxr-xr-xtests/libtest/test1013.pl50
-rwxr-xr-xtests/libtest/test1022.pl54
-rwxr-xr-xtests/libtest/test307.pl19
-rwxr-xr-xtests/libtest/test610.pl33
-rwxr-xr-xtests/libtest/test613.pl105
-rwxr-xr-xtests/libtest/test75.pl13
-rw-r--r--tests/libtest/testtrace.c146
-rw-r--r--tests/libtest/testtrace.h37
-rw-r--r--tests/libtest/testutil.c137
-rw-r--r--tests/libtest/testutil.h47
92 files changed, 12643 insertions, 0 deletions
diff --git a/tests/libtest/.gitignore b/tests/libtest/.gitignore
new file mode 100644
index 000000000..28e83c08d
--- /dev/null
+++ b/tests/libtest/.gitignore
@@ -0,0 +1,5 @@
+chkhostname
+lib5[0-9][0-9]
+lib150[0-9]
+libauthretry
+libntlmconnect
diff --git a/tests/libtest/CMakeLists.txt b/tests/libtest/CMakeLists.txt
new file mode 100644
index 000000000..896686bd8
--- /dev/null
+++ b/tests/libtest/CMakeLists.txt
@@ -0,0 +1,121 @@
+set(TARGET_LABEL_PREFIX "Test ")
+
+function(SETUP_TEST TEST_NAME) # ARGN are the files in the test
+ add_executable( ${TEST_NAME} ${ARGN} )
+ string(TOUPPER ${TEST_NAME} UPPER_TEST_NAME)
+
+ include_directories(
+ ${CURL_SOURCE_DIR}/lib # To be able to reach "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/curlbuild.h"
+ )
+ if(CURL_USE_ARES)
+ include_directories(${CARES_INCLUDE_DIR})
+ endif()
+ setup_curl_dependencies(${TEST_NAME})
+ target_link_libraries( ${TEST_NAME} libcurl )
+
+ set_target_properties(${TEST_NAME}
+ PROPERTIES COMPILE_DEFINITIONS ${UPPER_TEST_NAME})
+ set_target_properties(${TEST_NAME}
+ PROPERTIES PROJECT_LABEL "${TARGET_LABEL_PREFIX}${TEST_NAME}")
+
+ # Add the postfix to the executable since it is
+ # not added automatically as for modules and shared libraries
+ set_target_properties(${TEST_NAME}
+ PROPERTIES DEBUG_POSTFIX "${CMAKE_DEBUG_POSTFIX}")
+
+ if(MSVC)
+ if(NOT BUILD_RELEASE_DEBUG_DIRS)
+ # Ugly workaround to remove the "/debug" or "/release" in each output
+ set_target_properties(${TEST_NAME} PROPERTIES PREFIX "../")
+ set_target_properties(${TEST_NAME} PROPERTIES IMPORT_PREFIX "../")
+ endif()
+ endif()
+
+endfunction()
+
+
+transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
+include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake)
+
+foreach(TEST_NAME ${noinst_PROGRAMS})
+ setup_test(${TEST_NAME} ${${TEST_NAME}_SOURCES})
+endforeach()
+
+
+# # files used only in some libcurl test programs
+# SET(TESTUTIL testutil.c testutil.h)
+
+# # these files are used in every single test program below
+# SET(SUPPORTFILES first.c test.h)
+
+# # These are all libcurl test programs
+# SET(noinst_PROGRAMS
+# lib500 lib501 lib502 lib503 lib504 lib505 lib506
+# lib507 lib508 lib510 lib511 lib512 lib513 lib514 lib515 lib516
+# lib517 lib518 lib519 lib520 lib521 lib523 lib524 lib525 lib526
+# #lib527
+# #lib529
+# lib530
+# #lib532
+# lib533 lib536 lib537 lib540 lib541 lib542 lib543
+# lib544
+# #lib545
+# lib547
+# #lib548
+# lib549 lib552 lib553 lib554 lib555 lib556
+# lib539 lib557
+# lib560
+# )
+
+# SET(noinst_PROGRAMS_USE_TESTUTIL
+# lib502 lib503 lib504
+# lib507
+# lib525 lib526 lib527
+# lib529
+# lib530
+# lib532
+# lib533 lib536
+# lib555
+# )
+
+# MACRO(ADD_TESTUTIL_IF_NECESSARY TEST_NAME)
+# LIST(FIND noinst_PROGRAMS_USE_TESTUTIL ${TEST_NAME} USES_TESTUTIL)
+# IF(NOT ${USES_TESTUTIL} EQUAL -1)
+# LIST(APPEND SOURCE ${TESTUTIL}) # Need TestUtil
+# ENDIF()
+# ENDMACRO()
+
+# # General case
+# FOREACH(TEST_NAME ${noinst_PROGRAMS})
+# SET(SOURCE "${TEST_NAME}.c" ${SUPPORTFILES})
+# ADD_TESTUTIL_IF_NECESSARY(${TEST_NAME})
+# SETUP_TEST(${TEST_NAME} ${SOURCE})
+# ENDFOREACH()
+
+# # Special cases
+# SET(TEST_NAME lib527)
+# SET(SOURCE "lib526.c" ${SUPPORTFILES})
+# ADD_TESTUTIL_IF_NECESSARY(${TEST_NAME})
+# SETUP_TEST(${TEST_NAME} ${SOURCE})
+
+# SET(TEST_NAME lib529)
+# SET(SOURCE "lib525.c" ${SUPPORTFILES})
+# ADD_TESTUTIL_IF_NECESSARY(${TEST_NAME})
+# SETUP_TEST(${TEST_NAME} ${SOURCE})
+
+# SET(TEST_NAME lib532)
+# SET(SOURCE "lib526.c" ${SUPPORTFILES})
+# ADD_TESTUTIL_IF_NECESSARY(${TEST_NAME})
+# SETUP_TEST(${TEST_NAME} ${SOURCE})
+
+# SET(TEST_NAME lib545)
+# SET(SOURCE "lib544.c" ${SUPPORTFILES})
+# ADD_TESTUTIL_IF_NECESSARY(${TEST_NAME})
+# SETUP_TEST(${TEST_NAME} ${SOURCE})
+
+# SET(TEST_NAME lib548)
+# SET(SOURCE "lib547.c" ${SUPPORTFILES})
+# ADD_TESTUTIL_IF_NECESSARY(${TEST_NAME})
+# SETUP_TEST(${TEST_NAME} ${SOURCE})
diff --git a/tests/libtest/Makefile.am b/tests/libtest/Makefile.am
new file mode 100644
index 000000000..df13df111
--- /dev/null
+++ b/tests/libtest/Makefile.am
@@ -0,0 +1,108 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+#
+###########################################################################
+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_builddir)/include/curl for generated curlbuild.h included from curl.h
+# $(top_builddir)/include for generated curlbuild.h included from lib/setup.h
+# $(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 is for libcurl's lib/setup.h and other "borrowed" files
+# $(top_builddir)/ares is for in-tree c-ares's generated ares_build.h file
+# $(top_srcdir)/ares is for in-tree c-ares's external include files
+
+if USE_EMBEDDED_ARES
+AM_CPPFLAGS = -I$(top_builddir)/include/curl \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib \
+ -I$(top_builddir)/ares \
+ -I$(top_srcdir)/ares
+else
+AM_CPPFLAGS = -I$(top_builddir)/include/curl \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib
+endif
+
+EXTRA_DIST = test75.pl test307.pl test610.pl test613.pl test1013.pl \
+test1022.pl Makefile.inc notexists.pl
+
+CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@
+
+# Prevent LIBS from being used for all link targets
+LIBS = $(BLANK_AT_MAKETIME)
+
+if USE_EXPLICIT_LIB_DEPS
+SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@
+TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@
+else
+SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_LIBS@
+TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_AND_TIME_LIBS@
+endif
+
+# Dependencies (may need to be overriden)
+LDADD = $(SUPPORTFILES_LIBS)
+DEPENDENCIES = $(top_builddir)/lib/libcurl.la
+
+# Mostly for Windows build targets, when using static libcurl
+if USE_CPPFLAG_CURL_STATICLIB
+AM_CPPFLAGS += -DCURL_STATICLIB
+endif
+
+# Makefile.inc provides the source defines (TESTUTIL, SUPPORTFILES,
+# noinst_PROGRAMS, lib*_SOURCES, and lib*_CFLAGS)
+include Makefile.inc
+
+# Preloading of libhostname allows host name overriding,
+# this is used to make some tests machine independent.
+
+if BUILD_LIBHOSTNAME
+noinst_LTLIBRARIES = libhostname.la
+else
+noinst_LTLIBRARIES =
+endif
+
+if NO_UNDEFINED
+# The -no-undefined flag is crucial to build fine on some platforms
+UNDEF = -no-undefined
+endif
+
+libhostname_la_SOURCES = sethostname.c sethostname.h
+
+libhostname_la_LIBADD =
+libhostname_la_DEPENDENCIES =
+libhostname_la_LDFLAGS = -module -avoid-version $(UNDEF) -rpath /nowhere
+
+if DOING_CURL_SYMBOL_HIDING
+libhostname_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_HIDDEN_SYMBOLS
+libhostname_la_CFLAGS = $(AM_CFLAGS) $(CFLAG_CURL_SYMBOL_HIDING)
+else
+libhostname_la_CPPFLAGS = $(AM_CPPFLAGS)
+libhostname_la_CFLAGS = $(AM_CFLAGS)
+endif
diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc
new file mode 100644
index 000000000..c773d2b73
--- /dev/null
+++ b/tests/libtest/Makefile.inc
@@ -0,0 +1,224 @@
+# files used only in some libcurl test programs
+TESTUTIL = testutil.c testutil.h
+
+# files used only in some libcurl test programs
+TSTTRACE = testtrace.c testtrace.h
+
+# files used only in some libcurl test programs
+WARNLESS = $(top_srcdir)/lib/warnless.c $(top_srcdir)/lib/warnless.h
+
+# these files are used in every single test program below
+SUPPORTFILES = first.c test.h
+
+# These are all libcurl test programs
+noinst_PROGRAMS = chkhostname \
+ lib500 lib501 lib502 lib503 lib504 lib505 lib506 lib507 lib508 lib510 \
+ lib511 lib512 lib513 lib514 lib515 lib516 lib517 lib518 lib519 lib520 \
+ lib521 lib523 lib524 lib525 lib526 lib527 lib574 lib575 lib576 lib578 \
+ lib579 lib529 lib530 lib532 lib533 lib536 lib537 lib540 lib541 lib542 \
+ lib543 lib544 lib545 lib547 lib548 lib549 lib552 lib553 lib554 lib555 \
+ lib556 lib539 lib557 lib560 lib562 lib564 lib565 lib566 lib567 lib568 \
+ lib569 lib570 lib571 lib572 lib573 lib582 lib583 lib585 lib586 lib587 \
+ lib590 lib591 lib597 lib598 lib599 libauthretry libntlmconnect \
+ lib1500 lib1501 lib1502
+
+chkhostname_SOURCES = chkhostname.c $(top_srcdir)/lib/curl_gethostname.c
+chkhostname_LDADD = @CURL_NETWORK_LIBS@
+chkhostname_DEPENDENCIES =
+chkhostname_CFLAGS = $(AM_CFLAGS)
+
+lib500_SOURCES = lib500.c $(SUPPORTFILES) $(TESTUTIL) $(TSTTRACE)
+lib500_LDADD = $(TESTUTIL_LIBS)
+
+lib501_SOURCES = lib501.c $(SUPPORTFILES)
+
+lib502_SOURCES = lib502.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib502_LDADD = $(TESTUTIL_LIBS)
+
+lib503_SOURCES = lib503.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib503_LDADD = $(TESTUTIL_LIBS)
+
+lib504_SOURCES = lib504.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib504_LDADD = $(TESTUTIL_LIBS)
+
+lib505_SOURCES = lib505.c $(SUPPORTFILES)
+
+lib506_SOURCES = lib506.c $(SUPPORTFILES)
+
+lib507_SOURCES = lib507.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib507_LDADD = $(TESTUTIL_LIBS)
+
+lib508_SOURCES = lib508.c $(SUPPORTFILES)
+
+lib510_SOURCES = lib510.c $(SUPPORTFILES)
+
+lib511_SOURCES = lib511.c $(SUPPORTFILES)
+
+lib512_SOURCES = lib512.c $(SUPPORTFILES)
+
+lib513_SOURCES = lib513.c $(SUPPORTFILES)
+
+lib514_SOURCES = lib514.c $(SUPPORTFILES)
+
+lib515_SOURCES = lib515.c $(SUPPORTFILES)
+
+lib516_SOURCES = lib516.c $(SUPPORTFILES)
+
+lib517_SOURCES = lib517.c $(SUPPORTFILES)
+
+lib518_SOURCES = lib518.c $(SUPPORTFILES) $(WARNLESS)
+
+lib519_SOURCES = lib519.c $(SUPPORTFILES)
+
+lib520_SOURCES = lib520.c $(SUPPORTFILES)
+
+lib521_SOURCES = lib521.c $(SUPPORTFILES)
+
+lib523_SOURCES = lib523.c $(SUPPORTFILES)
+
+lib524_SOURCES = lib524.c $(SUPPORTFILES)
+
+lib525_SOURCES = lib525.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib525_LDADD = $(TESTUTIL_LIBS)
+
+lib526_SOURCES = lib526.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib526_LDADD = $(TESTUTIL_LIBS)
+lib526_CPPFLAGS = $(AM_CPPFLAGS) -DLIB526
+
+lib527_SOURCES = lib526.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib527_LDADD = $(TESTUTIL_LIBS)
+lib527_CPPFLAGS = $(AM_CPPFLAGS) -DLIB527
+
+lib529_SOURCES = lib525.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib529_LDADD = $(TESTUTIL_LIBS)
+lib529_CPPFLAGS = $(AM_CPPFLAGS) -DLIB529
+
+lib530_SOURCES = lib530.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib530_LDADD = $(TESTUTIL_LIBS)
+lib530_CPPFLAGS = $(AM_CPPFLAGS) -DLIB530
+
+lib532_SOURCES = lib526.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib532_LDADD = $(TESTUTIL_LIBS)
+lib532_CPPFLAGS = $(AM_CPPFLAGS) -DLIB532
+
+lib533_SOURCES = lib533.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib533_LDADD = $(TESTUTIL_LIBS)
+
+lib536_SOURCES = lib536.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib536_LDADD = $(TESTUTIL_LIBS)
+
+lib537_SOURCES = lib537.c $(SUPPORTFILES) $(WARNLESS)
+
+lib539_SOURCES = lib539.c $(SUPPORTFILES)
+
+lib540_SOURCES = lib540.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib540_LDADD = $(TESTUTIL_LIBS)
+
+lib541_SOURCES = lib541.c $(SUPPORTFILES)
+
+lib542_SOURCES = lib542.c $(SUPPORTFILES)
+
+lib543_SOURCES = lib543.c $(SUPPORTFILES)
+
+lib544_SOURCES = lib544.c $(SUPPORTFILES)
+
+lib545_SOURCES = lib544.c $(SUPPORTFILES)
+lib545_CPPFLAGS = $(AM_CPPFLAGS) -DLIB545
+
+lib547_SOURCES = lib547.c $(SUPPORTFILES)
+
+lib548_SOURCES = lib547.c $(SUPPORTFILES)
+lib548_CPPFLAGS = $(AM_CPPFLAGS) -DLIB548
+
+lib549_SOURCES = lib549.c $(SUPPORTFILES)
+
+lib555_SOURCES = lib555.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib555_LDADD = $(TESTUTIL_LIBS)
+
+lib552_SOURCES = lib552.c $(SUPPORTFILES) $(WARNLESS)
+
+lib553_SOURCES = lib553.c $(SUPPORTFILES)
+
+lib554_SOURCES = lib554.c $(SUPPORTFILES)
+
+lib556_SOURCES = lib556.c $(SUPPORTFILES)
+
+lib557_SOURCES = lib557.c $(SUPPORTFILES)
+
+lib560_SOURCES = lib560.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib560_LDADD = $(TESTUTIL_LIBS)
+
+lib574_SOURCES = lib574.c $(SUPPORTFILES)
+
+lib575_SOURCES = lib575.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib575_LDADD = $(TESTUTIL_LIBS)
+
+lib576_SOURCES = lib576.c $(SUPPORTFILES)
+
+lib562_SOURCES = lib562.c $(SUPPORTFILES)
+
+lib564_SOURCES = lib564.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib564_LDADD = $(TESTUTIL_LIBS)
+
+lib565_SOURCES = lib510.c $(SUPPORTFILES)
+lib565_CPPFLAGS = $(AM_CPPFLAGS) -DLIB565
+
+lib566_SOURCES = lib566.c $(SUPPORTFILES)
+
+lib567_SOURCES = lib567.c $(SUPPORTFILES)
+
+lib568_SOURCES = lib568.c $(SUPPORTFILES)
+
+lib569_SOURCES = lib569.c $(SUPPORTFILES)
+
+lib570_SOURCES = lib570.c $(SUPPORTFILES)
+
+lib571_SOURCES = lib571.c $(SUPPORTFILES) $(WARNLESS)
+
+lib572_SOURCES = lib572.c $(SUPPORTFILES)
+
+lib573_SOURCES = lib573.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) $(TSTTRACE)
+lib573_LDADD = $(TESTUTIL_LIBS)
+
+lib578_SOURCES = lib578.c $(SUPPORTFILES)
+
+lib579_SOURCES = lib579.c $(SUPPORTFILES)
+
+lib582_SOURCES = lib582.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib582_LDADD = $(TESTUTIL_LIBS)
+
+lib583_SOURCES = lib583.c $(SUPPORTFILES)
+
+lib585_SOURCES = lib500.c $(SUPPORTFILES) $(TESTUTIL) $(TSTTRACE)
+lib585_LDADD = $(TESTUTIL_LIBS)
+lib585_CPPFLAGS = $(AM_CPPFLAGS) -DLIB585
+
+lib586_SOURCES = lib586.c $(SUPPORTFILES)
+
+lib587_SOURCES = lib554.c $(SUPPORTFILES)
+lib587_CPPFLAGS = $(AM_CPPFLAGS) -DLIB587
+
+lib590_SOURCES = lib590.c $(SUPPORTFILES)
+
+lib591_SOURCES = lib591.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib591_LDADD = $(TESTUTIL_LIBS)
+
+lib597_SOURCES = lib597.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib597_LDADD = $(TESTUTIL_LIBS)
+
+lib598_SOURCES = lib598.c $(SUPPORTFILES)
+
+lib599_SOURCES = lib599.c $(SUPPORTFILES)
+
+lib1500_SOURCES = lib1500.c $(SUPPORTFILES) $(TESTUTIL)
+lib1500_LDADD = $(TESTUTIL_LIBS)
+
+lib1501_SOURCES = lib1501.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1501_LDADD = $(TESTUTIL_LIBS)
+
+lib1502_SOURCES = lib1502.c $(SUPPORTFILES)
+
+libauthretry_SOURCES = libauthretry.c $(SUPPORTFILES)
+
+libntlmconnect_SOURCES = libntlmconnect.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+libntlmconnect_LDADD = $(TESTUTIL_LIBS)
diff --git a/tests/libtest/chkhostname.c b/tests/libtest/chkhostname.c
new file mode 100644
index 000000000..a18c92e8f
--- /dev/null
+++ b/tests/libtest/chkhostname.c
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "setup.h"
+
+#include "curl_gethostname.h"
+
+#define HOSTNAME_MAX 1024
+
+int main(int argc, char *argv[])
+{
+ char buff[HOSTNAME_MAX];
+ if (argc != 2) {
+ printf("Usage: %s EXPECTED_HOSTNAME\n", argv[0]);
+ return 1;
+ }
+
+ if (Curl_gethostname(buff, HOSTNAME_MAX)) {
+ printf("Curl_gethostname() failed\n");
+ return 1;
+ }
+
+ /* compare the name returned by Curl_gethostname() with the expected one */
+ if(strncmp(buff, argv[1], HOSTNAME_MAX)) {
+ printf("got unexpected host name back, LD_PRELOAD failed\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/tests/libtest/first.c b/tests/libtest/first.c
new file mode 100644
index 000000000..253acb21d
--- /dev/null
+++ b/tests/libtest/first.c
@@ -0,0 +1,131 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h> /* for setlocale() */
+#endif
+
+#ifdef CURLDEBUG
+# define MEMDEBUG_NODEFINES
+# include "memdebug.h"
+#endif
+
+int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc,
+ struct timeval *tv)
+{
+ if(nfds < 0) {
+ SET_SOCKERRNO(EINVAL);
+ return -1;
+ }
+#ifdef USE_WINSOCK
+ /*
+ * Winsock select() requires that at least one of the three fd_set
+ * pointers is not NULL and points to a non-empty fdset. IOW Winsock
+ * select() can not be used to sleep without a single fd_set.
+ */
+ if(!nfds) {
+ Sleep(1000*tv->tv_sec + tv->tv_usec/1000);
+ return 0;
+ }
+#endif
+ return select(nfds, rd, wr, exc, tv);
+}
+
+char *libtest_arg2=NULL;
+char *libtest_arg3=NULL;
+int test_argc;
+char **test_argv;
+
+struct timeval tv_test_start; /* for test timing */
+
+#ifdef UNITTESTS
+int unitfail; /* for unittests */
+#endif
+
+#ifdef CURLDEBUG
+static void memory_tracking_init(void)
+{
+ char *env;
+ /* if CURL_MEMDEBUG is set, this starts memory tracking message logging */
+ env = curl_getenv("CURL_MEMDEBUG");
+ if(env) {
+ /* use the value as file name */
+ char fname[CURL_MT_LOGFNAME_BUFSIZE];
+ if(strlen(env) >= CURL_MT_LOGFNAME_BUFSIZE)
+ env[CURL_MT_LOGFNAME_BUFSIZE-1] = '\0';
+ strcpy(fname, env);
+ curl_free(env);
+ curl_memdebug(fname);
+ /* this weird stuff here is to make curl_free() get called
+ before curl_memdebug() as otherwise memory tracking will
+ log a free() without an alloc! */
+ }
+ /* if CURL_MEMLIMIT is set, this enables fail-on-alloc-number-N feature */
+ env = curl_getenv("CURL_MEMLIMIT");
+ if(env) {
+ char *endptr;
+ long num = strtol(env, &endptr, 10);
+ if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
+ curl_memlimit(num);
+ curl_free(env);
+ }
+}
+#else
+# define memory_tracking_init() Curl_nop_stmt
+#endif
+
+int main(int argc, char **argv)
+{
+ char *URL;
+
+ memory_tracking_init();
+
+ /*
+ * Setup proper locale from environment. This is needed to enable locale-
+ * specific behaviour by the C library in order to test for undesired side
+ * effects that could cause in libcurl.
+ */
+#ifdef HAVE_SETLOCALE
+ setlocale(LC_ALL, "");
+#endif
+
+ if(argc< 2 ) {
+ fprintf(stderr, "Pass URL as argument please\n");
+ return 1;
+ }
+
+ test_argc = argc;
+ test_argv = argv;
+
+ if(argc>2)
+ libtest_arg2=argv[2];
+
+ if(argc>3)
+ libtest_arg3=argv[3];
+
+ URL = argv[1]; /* provide this to the rest */
+
+ fprintf(stderr, "URL: %s\n", URL);
+
+ return test(URL);
+}
diff --git a/tests/libtest/lib1500.c b/tests/libtest/lib1500.c
new file mode 100644
index 000000000..784bdb2a2
--- /dev/null
+++ b/tests/libtest/lib1500.c
@@ -0,0 +1,95 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+int test(char *URL)
+{
+ CURL* curls = NULL;
+ CURLM* multi = NULL;
+ int still_running;
+ int i = -1;
+ int res = 0;
+ CURLMsg *msg;
+
+ start_test_timing();
+
+ global_init(CURL_GLOBAL_ALL);
+
+ multi_init(multi);
+
+ easy_init(curls);
+
+ easy_setopt(curls, CURLOPT_URL, URL);
+ easy_setopt(curls, CURLOPT_HEADER, 1L);
+
+ multi_add_handle(multi, curls);
+
+ multi_perform(multi, &still_running);
+
+ abort_on_test_timeout();
+
+ while(still_running) {
+ int num;
+ res = curl_multi_wait(multi, NULL, 0, TEST_HANG_TIMEOUT, &num);
+ if (res != CURLM_OK) {
+ printf("curl_multi_wait() returned %d\n", res);
+ res = -1;
+ goto test_cleanup;
+ }
+ if (num != 1) {
+ printf("curl_multi_wait() returned on %d handle(s), expected 1\n", num);
+ res = -1;
+ goto test_cleanup;
+ }
+
+ abort_on_test_timeout();
+
+ multi_perform(multi, &still_running);
+
+ abort_on_test_timeout();
+ }
+
+ msg = curl_multi_info_read(multi, &still_running);
+ if(msg)
+ /* this should now contain a result code from the easy handle,
+ get it */
+ i = msg->data.result;
+
+test_cleanup:
+
+ /* undocumented cleanup sequence - type UA */
+
+ curl_multi_cleanup(multi);
+ curl_easy_cleanup(curls);
+ curl_global_cleanup();
+
+ if(res)
+ i = res;
+
+ return i; /* return the final return code */
+}
diff --git a/tests/libtest/lib1501.c b/tests/libtest/lib1501.c
new file mode 100644
index 000000000..01a382e82
--- /dev/null
+++ b/tests/libtest/lib1501.c
@@ -0,0 +1,126 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include <fcntl.h>
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 30 * 1000
+
+/* 500 milliseconds allowed. An extreme number but lets be really conservative
+ to allow old and slow machines to run this test too */
+#define MAX_BLOCKED_TIME_US 500000
+
+/* return the number of microseconds between two time stamps */
+static int elapsed(struct timeval *before,
+ struct timeval *after)
+{
+ ssize_t result;
+
+ result = (after->tv_sec - before->tv_sec) * 1000000 +
+ after->tv_usec - before->tv_usec;
+ if (result < 0)
+ result = 0;
+
+ return curlx_sztosi(result);
+}
+
+
+int test(char *URL)
+{
+ CURL *handle = NULL;
+ CURLM *mhandle = NULL;
+ int res = 0;
+ int still_running = 0;
+
+ start_test_timing();
+
+ global_init(CURL_GLOBAL_ALL);
+
+ easy_init(handle);
+
+ easy_setopt(handle, CURLOPT_URL, URL);
+ easy_setopt(handle, CURLOPT_VERBOSE, 1L);
+
+ multi_init(mhandle);
+
+ multi_add_handle(mhandle, handle);
+
+ multi_perform(mhandle, &still_running);
+
+ abort_on_test_timeout();
+
+ while(still_running) {
+ struct timeval timeout;
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ int maxfd = -99;
+ struct timeval before;
+ struct timeval after;
+ int e;
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 100000L; /* 100 ms */
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ multi_fdset(mhandle, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ abort_on_test_timeout();
+
+ fprintf(stderr, "ping\n");
+ before = tutil_tvnow();
+
+ multi_perform(mhandle, &still_running);
+
+ abort_on_test_timeout();
+
+ after = tutil_tvnow();
+ e = elapsed(&before, &after);
+ fprintf(stderr, "pong = %d\n", e);
+
+ if(e > MAX_BLOCKED_TIME_US) {
+ res = 100;
+ break;
+ }
+ }
+
+test_cleanup:
+
+ /* undocumented cleanup sequence - type UA */
+
+ curl_multi_cleanup(mhandle);
+ curl_easy_cleanup(handle);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib1502.c b/tests/libtest/lib1502.c
new file mode 100644
index 000000000..bb008f17c
--- /dev/null
+++ b/tests/libtest/lib1502.c
@@ -0,0 +1,143 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+/*
+ * Test case converted from bug report #3575448, identifying a memory leak in
+ * the CURLOPT_RESOLVE handling with the multi interface.
+ */
+
+#include "test.h"
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+/* somewhat unix-specific */
+#include <sys/time.h>
+#include <unistd.h>
+
+int test(char *URL)
+{
+ CURL *ehandle;
+ CURLM *multi_handle;
+ char redirect[160];
+ CURLcode result = CURLE_NOT_BUILT_IN;
+ int still_running; /* keep number of running handles */
+
+ CURLMsg *msg; /* for picking up messages with the transfer status */
+ int msgs_left; /* how many messages are left */
+
+ /* DNS cache injection */
+ struct curl_slist *dns_cache_list;
+
+ sprintf(redirect, "google.com:%s:%s", libtest_arg2, libtest_arg3);
+
+ fprintf(stderr, "Redirect: %s\n", redirect);
+
+ dns_cache_list = curl_slist_append(NULL, redirect);
+
+ /* Allocate one CURL handle per transfer */
+ ehandle = curl_easy_init();
+
+ /* set the options (I left out a few, you'll get the point anyway) */
+ curl_easy_setopt(ehandle, CURLOPT_URL, URL);
+ curl_easy_setopt(ehandle, CURLOPT_HEADER, 1L);
+
+ curl_easy_setopt(ehandle, CURLOPT_RESOLVE, dns_cache_list);
+
+ /* init a multi stack */
+ multi_handle = curl_multi_init();
+
+ /* add the individual transfers */
+ curl_multi_add_handle(multi_handle, ehandle);
+
+ /* we start some action by calling perform right away */
+ curl_multi_perform(multi_handle, &still_running);
+
+ do {
+ struct timeval timeout;
+ int rc; /* select() return code */
+
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ int maxfd = -1;
+
+ long curl_timeo = -1;
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ /* set a suitable timeout to play around with */
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ curl_multi_timeout(multi_handle, &curl_timeo);
+ if(curl_timeo >= 0) {
+ int itimeout = (curl_timeo > (long)INT_MAX) ? INT_MAX : (int)curl_timeo;
+ timeout.tv_sec = itimeout / 1000;
+ if(timeout.tv_sec > 1)
+ timeout.tv_sec = 1;
+ else
+ timeout.tv_usec = (itimeout % 1000) * 1000;
+ }
+
+ /* get file descriptors from the transfers */
+ curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* In a real-world program you OF COURSE check the return code of the
+ function calls. On success, the value of maxfd is guaranteed to be
+ greater or equal than -1. We call select(maxfd + 1, ...), specially in
+ case of (maxfd == -1), we call select(0, ...), which is basically equal
+ to sleep. */
+
+ rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ switch(rc) {
+ case -1:
+ /* select error */
+ break;
+ case 0: /* timeout */
+ default: /* action */
+ curl_multi_perform(multi_handle, &still_running);
+ break;
+ }
+ } while(still_running);
+
+ /* See how the transfers went */
+ while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
+ if (msg->msg == CURLMSG_DONE)
+ result = msg->data.result;
+ }
+
+ curl_multi_cleanup(multi_handle);
+
+ /* Free the CURL handles */
+ curl_easy_cleanup(ehandle);
+
+ curl_slist_free_all(dns_cache_list);
+
+ return (int)result;
+}
diff --git a/tests/libtest/lib500.c b/tests/libtest/lib500.c
new file mode 100644
index 000000000..dda1d7f42
--- /dev/null
+++ b/tests/libtest/lib500.c
@@ -0,0 +1,141 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testtrace.h"
+#include "memdebug.h"
+
+#ifdef LIB585
+
+static int counter;
+
+static curl_socket_t tst_opensocket(void *clientp,
+ curlsocktype purpose,
+ struct curl_sockaddr *addr)
+{
+ (void)clientp;
+ (void)purpose;
+ printf("[OPEN] counter: %d\n", ++counter);
+ return socket(addr->family, addr->socktype, addr->protocol);
+}
+
+static int tst_closesocket(void *clientp, curl_socket_t sock)
+{
+ (void)clientp;
+ printf("[CLOSE] counter: %d\n", counter--);
+ return sclose(sock);
+}
+
+static void setupcallbacks(CURL *curl)
+{
+ curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, tst_opensocket);
+ curl_easy_setopt(curl, CURLOPT_CLOSESOCKETFUNCTION, tst_closesocket);
+ counter = 0;
+}
+
+#else
+#define setupcallbacks(x) Curl_nop_stmt
+#endif
+
+
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+ char *ipstr=NULL;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+
+ libtest_debug_config.nohex = 1;
+ libtest_debug_config.tracetime = 1;
+ test_setopt(curl, CURLOPT_DEBUGDATA, &libtest_debug_config);
+ test_setopt(curl, CURLOPT_DEBUGFUNCTION, libtest_debug_cb);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ if(libtest_arg3 && !strcmp(libtest_arg3, "activeftp"))
+ test_setopt(curl, CURLOPT_FTPPORT, "-");
+
+ setupcallbacks(curl);
+
+ res = curl_easy_perform(curl);
+
+ if(!res) {
+ FILE *moo;
+ res = curl_easy_getinfo(curl, CURLINFO_PRIMARY_IP, &ipstr);
+ moo = fopen(libtest_arg2, "wb");
+ if(moo) {
+ double time_namelookup;
+ double time_connect;
+ double time_pretransfer;
+ double time_starttransfer;
+ double time_total;
+ fprintf(moo, "IP: %s\n", ipstr);
+ curl_easy_getinfo(curl, CURLINFO_NAMELOOKUP_TIME, &time_namelookup);
+ curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME, &time_connect);
+ curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME, &time_pretransfer);
+ curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME,
+ &time_starttransfer);
+ curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &time_total);
+
+ /* since the timing will always vary we only compare relative differences
+ between these 5 times */
+ if(time_namelookup >= time_connect) {
+ fprintf(moo, "namelookup vs connect: %f %f\n",
+ time_namelookup, time_connect);
+ }
+ if(time_connect >= time_pretransfer) {
+ fprintf(moo, "connect vs pretransfer: %f %f\n",
+ time_connect, time_pretransfer);
+ }
+ if(time_pretransfer >= time_starttransfer) {
+ fprintf(moo, "pretransfer vs starttransfer: %f %f\n",
+ time_pretransfer, time_starttransfer);
+ }
+ if(time_starttransfer >= time_total) {
+ fprintf(moo, "starttransfer vs total: %f %f\n",
+ time_starttransfer, time_total);
+ }
+
+ fclose(moo);
+ }
+ }
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
+
diff --git a/tests/libtest/lib501.c b/tests/libtest/lib501.c
new file mode 100644
index 000000000..26275f977
--- /dev/null
+++ b/tests/libtest/lib501.c
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+
+ (void)URL; /* we don't use this */
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
+
diff --git a/tests/libtest/lib502.c b/tests/libtest/lib502.c
new file mode 100644
index 000000000..554583ae2
--- /dev/null
+++ b/tests/libtest/lib502.c
@@ -0,0 +1,92 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+/*
+ * Get a single URL without select().
+ */
+
+int test(char *URL)
+{
+ CURL *c = NULL;
+ CURLM *m = NULL;
+ int res = 0;
+ int running;
+
+ start_test_timing();
+
+ global_init(CURL_GLOBAL_ALL);
+
+ easy_init(c);
+
+ easy_setopt(c, CURLOPT_URL, URL);
+
+ multi_init(m);
+
+ multi_add_handle(m, c);
+
+ for(;;) {
+ struct timeval timeout;
+ fd_set fdread, fdwrite, fdexcep;
+ int maxfd = -99;
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 100000L; /* 100 ms */
+
+ multi_perform(m, &running);
+
+ abort_on_test_timeout();
+
+ if(!running)
+ break; /* done */
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ multi_fdset(m, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ abort_on_test_timeout();
+ }
+
+test_cleanup:
+
+ /* proper cleanup sequence - type PA */
+
+ curl_multi_remove_handle(m, c);
+ curl_multi_cleanup(m);
+ curl_easy_cleanup(c);
+ curl_global_cleanup();
+
+ return res;
+}
+
diff --git a/tests/libtest/lib503.c b/tests/libtest/lib503.c
new file mode 100644
index 000000000..50277f7d3
--- /dev/null
+++ b/tests/libtest/lib503.c
@@ -0,0 +1,102 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+/*
+ * Source code in here hugely as reported in bug report 651460 by
+ * Christopher R. Palmer.
+ *
+ * Use multi interface to get HTTPS document over proxy, and provide
+ * auth info.
+ */
+
+int test(char *URL)
+{
+ CURL *c = NULL;
+ CURLM *m = NULL;
+ int res = 0;
+ int running;
+
+ start_test_timing();
+
+ global_init(CURL_GLOBAL_ALL);
+
+ easy_init(c);
+
+ easy_setopt(c, CURLOPT_PROXY, libtest_arg2); /* set in first.c */
+ easy_setopt(c, CURLOPT_URL, URL);
+ easy_setopt(c, CURLOPT_USERPWD, "test:ing");
+ easy_setopt(c, CURLOPT_PROXYUSERPWD, "test:ing");
+ easy_setopt(c, CURLOPT_HTTPPROXYTUNNEL, 1L);
+ easy_setopt(c, CURLOPT_HEADER, 1L);
+ easy_setopt(c, CURLOPT_VERBOSE, 1L);
+
+ multi_init(m);
+
+ multi_add_handle(m, c);
+
+ for(;;) {
+ struct timeval interval;
+ fd_set rd, wr, exc;
+ int maxfd = -99;
+
+ interval.tv_sec = 1;
+ interval.tv_usec = 0;
+
+ multi_perform(m, &running);
+
+ abort_on_test_timeout();
+
+ if(!running)
+ break; /* done */
+
+ FD_ZERO(&rd);
+ FD_ZERO(&wr);
+ FD_ZERO(&exc);
+
+ multi_fdset(m, &rd, &wr, &exc, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ select_test(maxfd+1, &rd, &wr, &exc, &interval);
+
+ abort_on_test_timeout();
+ }
+
+test_cleanup:
+
+ /* proper cleanup sequence - type PA */
+
+ curl_multi_remove_handle(m, c);
+ curl_multi_cleanup(m);
+ curl_easy_cleanup(c);
+ curl_global_cleanup();
+
+ return res;
+}
+
diff --git a/tests/libtest/lib504.c b/tests/libtest/lib504.c
new file mode 100644
index 000000000..358fc98dc
--- /dev/null
+++ b/tests/libtest/lib504.c
@@ -0,0 +1,114 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+/*
+ * Source code in here hugely as reported in bug report 651464 by
+ * Christopher R. Palmer.
+ *
+ * Use multi interface to get document over proxy with bad port number.
+ * This caused the interface to "hang" in libcurl 7.10.2.
+ */
+int test(char *URL)
+{
+ CURL *c = NULL;
+ int res = 0;
+ CURLM *m = NULL;
+ fd_set rd, wr, exc;
+ int running;
+
+ start_test_timing();
+
+ global_init(CURL_GLOBAL_ALL);
+
+ easy_init(c);
+
+ /* The point here is that there must not be anything running on the given
+ proxy port */
+ if (libtest_arg2)
+ easy_setopt(c, CURLOPT_PROXY, libtest_arg2);
+ easy_setopt(c, CURLOPT_URL, URL);
+ easy_setopt(c, CURLOPT_VERBOSE, 1L);
+
+ multi_init(m);
+
+ multi_add_handle(m, c);
+
+ for(;;) {
+ struct timeval interval;
+ int maxfd = -99;
+
+ interval.tv_sec = 1;
+ interval.tv_usec = 0;
+
+ fprintf(stderr, "curl_multi_perform()\n");
+
+ multi_perform(m, &running);
+
+ abort_on_test_timeout();
+
+ if(!running) {
+ /* This is where this code is expected to reach */
+ int numleft;
+ CURLMsg *msg = curl_multi_info_read(m, &numleft);
+ fprintf(stderr, "Expected: not running\n");
+ if(msg && !numleft)
+ res = TEST_ERR_SUCCESS; /* this is where we should be */
+ else
+ res = TEST_ERR_FAILURE; /* not correct */
+ break; /* done */
+ }
+ fprintf(stderr, "running == %d\n", running);
+
+ FD_ZERO(&rd);
+ FD_ZERO(&wr);
+ FD_ZERO(&exc);
+
+ fprintf(stderr, "curl_multi_fdset()\n");
+
+ multi_fdset(m, &rd, &wr, &exc, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ select_test(maxfd+1, &rd, &wr, &exc, &interval);
+
+ abort_on_test_timeout();
+ }
+
+test_cleanup:
+
+ /* proper cleanup sequence - type PA */
+
+ curl_multi_remove_handle(m, c);
+ curl_multi_cleanup(m);
+ curl_easy_cleanup(c);
+ curl_global_cleanup();
+
+ return res;
+}
+
diff --git a/tests/libtest/lib505.c b/tests/libtest/lib505.c
new file mode 100644
index 000000000..394131ebe
--- /dev/null
+++ b/tests/libtest/lib505.c
@@ -0,0 +1,157 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "memdebug.h"
+
+/*
+ * This example shows an FTP upload, with a rename of the file just after
+ * a successful upload.
+ *
+ * Example based on source code provided by Erick Nuwendam. Thanks!
+ */
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res = CURLE_OK;
+ FILE *hd_src ;
+ int hd ;
+ struct_stat file_info;
+ struct curl_slist *hl;
+ int error;
+
+ struct curl_slist *headerlist=NULL;
+ const char *buf_1 = "RNFR 505";
+ const char *buf_2 = "RNTO 505-forreal";
+
+ if (!libtest_arg2) {
+ fprintf(stderr, "Usage: <url> <file-to-upload>\n");
+ return -1;
+ }
+
+ hd_src = fopen(libtest_arg2, "rb");
+ if(NULL == hd_src) {
+ error = ERRNO;
+ fprintf(stderr, "fopen() failed with error: %d %s\n",
+ error, strerror(error));
+ fprintf(stderr, "Error opening file: %s\n", libtest_arg2);
+ return -2; /* if this happens things are major weird */
+ }
+
+ /* get the file size of the local file */
+ hd = fstat(fileno(hd_src), &file_info);
+ if(hd == -1) {
+ /* can't open file, bail out */
+ error = ERRNO;
+ fprintf(stderr, "fstat() failed with error: %d %s\n",
+ error, strerror(error));
+ fprintf(stderr, "ERROR: cannot open file %s\n", libtest_arg2);
+ fclose(hd_src);
+ return -1;
+ }
+
+ if(! file_info.st_size) {
+ fprintf(stderr, "ERROR: file %s has zero size!\n", libtest_arg2);
+ fclose(hd_src);
+ return -4;
+ }
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ fclose(hd_src);
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* get a curl handle */
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ fclose(hd_src);
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* build a list of commands to pass to libcurl */
+
+ if ((hl = curl_slist_append(headerlist, buf_1)) == NULL) {
+ fprintf(stderr, "curl_slist_append() failed\n");
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+ fclose(hd_src);
+ return TEST_ERR_MAJOR_BAD;
+ }
+ if ((headerlist = curl_slist_append(hl, buf_2)) == NULL) {
+ fprintf(stderr, "curl_slist_append() failed\n");
+ curl_slist_free_all(hl);
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+ fclose(hd_src);
+ return TEST_ERR_MAJOR_BAD;
+ }
+ headerlist = hl;
+
+ /* enable uploading */
+ test_setopt(curl, CURLOPT_UPLOAD, 1L);
+
+ /* enable verbose */
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* specify target */
+ test_setopt(curl,CURLOPT_URL, URL);
+
+ /* pass in that last of FTP commands to run after the transfer */
+ test_setopt(curl, CURLOPT_POSTQUOTE, headerlist);
+
+ /* now specify which file to upload */
+ test_setopt(curl, CURLOPT_INFILE, hd_src);
+
+ /* and give the size of the upload (optional) */
+ test_setopt(curl, CURLOPT_INFILESIZE_LARGE,
+ (curl_off_t)file_info.st_size);
+
+ /* Now run off and do what you've been told! */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ /* clean up the FTP commands list */
+ curl_slist_free_all(headerlist);
+
+ /* close the local file */
+ fclose(hd_src);
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib506.c b/tests/libtest/lib506.c
new file mode 100644
index 000000000..4477eaa50
--- /dev/null
+++ b/tests/libtest/lib506.c
@@ -0,0 +1,277 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include <curl/mprintf.h>
+
+#include "memdebug.h"
+
+static const char *HOSTHEADER = "Host: www.host.foo.com";
+static const char *JAR = "log/jar506";
+#define THREADS 2
+
+/* struct containing data of a thread */
+struct Tdata {
+ CURLSH *share;
+ char *url;
+};
+
+struct userdata {
+ char *text;
+ int counter;
+};
+
+/* lock callback */
+static void my_lock(CURL *handle, curl_lock_data data, curl_lock_access laccess,
+ void *useptr )
+{
+ const char *what;
+ struct userdata *user = (struct userdata *)useptr;
+
+ (void)handle;
+ (void)laccess;
+
+ switch ( data ) {
+ case CURL_LOCK_DATA_SHARE:
+ what = "share";
+ break;
+ case CURL_LOCK_DATA_DNS:
+ what = "dns";
+ break;
+ case CURL_LOCK_DATA_COOKIE:
+ what = "cookie";
+ break;
+ default:
+ fprintf(stderr, "lock: no such data: %d\n", (int)data);
+ return;
+ }
+ printf("lock: %-6s [%s]: %d\n", what, user->text, user->counter);
+ user->counter++;
+}
+
+/* unlock callback */
+static void my_unlock(CURL *handle, curl_lock_data data, void *useptr )
+{
+ const char *what;
+ struct userdata *user = (struct userdata *)useptr;
+ (void)handle;
+ switch ( data ) {
+ case CURL_LOCK_DATA_SHARE:
+ what = "share";
+ break;
+ case CURL_LOCK_DATA_DNS:
+ what = "dns";
+ break;
+ case CURL_LOCK_DATA_COOKIE:
+ what = "cookie";
+ break;
+ default:
+ fprintf(stderr, "unlock: no such data: %d\n", (int)data);
+ return;
+ }
+ printf("unlock: %-6s [%s]: %d\n", what, user->text, user->counter);
+ user->counter++;
+}
+
+
+/* build host entry */
+static struct curl_slist *sethost(struct curl_slist *headers)
+{
+ (void)headers;
+ return curl_slist_append(NULL, HOSTHEADER );
+}
+
+
+/* the dummy thread function */
+static void *fire(void *ptr)
+{
+ CURLcode code;
+ struct curl_slist *headers;
+ struct Tdata *tdata = (struct Tdata*)ptr;
+ CURL *curl;
+ int i=0;
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ return NULL;
+ }
+
+ headers = sethost(NULL);
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+ curl_easy_setopt(curl, CURLOPT_URL, tdata->url);
+ printf( "CURLOPT_SHARE\n" );
+ curl_easy_setopt(curl, CURLOPT_SHARE, tdata->share);
+
+ printf( "PERFORM\n" );
+ code = curl_easy_perform(curl);
+ if( code != CURLE_OK ) {
+ fprintf(stderr, "perform url '%s' repeat %d failed, curlcode %d\n",
+ tdata->url, i, (int)code);
+ }
+
+ printf( "CLEANUP\n" );
+ curl_easy_cleanup(curl);
+ curl_slist_free_all(headers);
+
+ return NULL;
+}
+
+
+/* build request url */
+static char *suburl(const char *base, int i)
+{
+ return curl_maprintf("%s%.4d", base, i);
+}
+
+
+/* test function */
+int test(char *URL)
+{
+ int res;
+ CURLSHcode scode = CURLSHE_OK;
+ char *url;
+ struct Tdata tdata;
+ CURL *curl;
+ CURLSH *share;
+ struct curl_slist *headers;
+ int i;
+ struct userdata user;
+
+ user.text = (char *)"Pigs in space";
+ user.counter = 0;
+
+ printf( "GLOBAL_INIT\n" );
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* prepare share */
+ printf( "SHARE_INIT\n" );
+ if ((share = curl_share_init()) == NULL) {
+ fprintf(stderr, "curl_share_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ( CURLSHE_OK == scode ) {
+ printf( "CURLSHOPT_LOCKFUNC\n" );
+ scode = curl_share_setopt( share, CURLSHOPT_LOCKFUNC, my_lock);
+ }
+ if ( CURLSHE_OK == scode ) {
+ printf( "CURLSHOPT_UNLOCKFUNC\n" );
+ scode = curl_share_setopt( share, CURLSHOPT_UNLOCKFUNC, my_unlock);
+ }
+ if ( CURLSHE_OK == scode ) {
+ printf( "CURLSHOPT_USERDATA\n" );
+ scode = curl_share_setopt( share, CURLSHOPT_USERDATA, &user);
+ }
+ if ( CURLSHE_OK == scode ) {
+ printf( "CURL_LOCK_DATA_COOKIE\n" );
+ scode = curl_share_setopt( share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
+ }
+ if ( CURLSHE_OK == scode ) {
+ printf( "CURL_LOCK_DATA_DNS\n" );
+ scode = curl_share_setopt( share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
+ }
+
+ if ( CURLSHE_OK != scode ) {
+ fprintf(stderr, "curl_share_setopt() failed\n");
+ curl_share_cleanup(share);
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+
+ res = 0;
+
+ /* start treads */
+ for (i=1; i<=THREADS; i++ ) {
+
+ /* set thread data */
+ tdata.url = suburl( URL, i ); /* must be curl_free()d */
+ tdata.share = share;
+
+ /* simulate thread, direct call of "thread" function */
+ printf( "*** run %d\n",i );
+ fire( &tdata );
+
+ curl_free( tdata.url );
+
+ }
+
+
+ /* fetch a another one and save cookies */
+ printf( "*** run %d\n", i );
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_share_cleanup(share);
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ url = suburl( URL, i );
+ headers = sethost( NULL );
+ test_setopt( curl, CURLOPT_HTTPHEADER, headers );
+ test_setopt( curl, CURLOPT_URL, url );
+ printf( "CURLOPT_SHARE\n" );
+ test_setopt( curl, CURLOPT_SHARE, share );
+ printf( "CURLOPT_COOKIEJAR\n" );
+ test_setopt( curl, CURLOPT_COOKIEJAR, JAR );
+
+ printf( "PERFORM\n" );
+ curl_easy_perform( curl );
+
+ /* try to free share, expect to fail because share is in use*/
+ printf( "try SHARE_CLEANUP...\n" );
+ scode = curl_share_cleanup( share );
+ if ( scode==CURLSHE_OK )
+ {
+ fprintf(stderr, "curl_share_cleanup succeed but error expected\n");
+ share = NULL;
+ } else {
+ printf( "SHARE_CLEANUP failed, correct\n" );
+ }
+
+test_cleanup:
+
+ /* clean up last handle */
+ printf( "CLEANUP\n" );
+ curl_easy_cleanup( curl );
+ curl_slist_free_all( headers );
+
+ curl_free(url);
+
+ /* free share */
+ printf( "SHARE_CLEANUP\n" );
+ scode = curl_share_cleanup( share );
+ if ( scode!=CURLSHE_OK )
+ fprintf(stderr, "curl_share_cleanup failed, code errno %d\n",
+ (int)scode);
+
+ printf( "GLOBAL_CLEANUP\n" );
+ curl_global_cleanup();
+
+ return res;
+}
+
diff --git a/tests/libtest/lib507.c b/tests/libtest/lib507.c
new file mode 100644
index 000000000..87c21defb
--- /dev/null
+++ b/tests/libtest/lib507.c
@@ -0,0 +1,100 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+int test(char *URL)
+{
+ CURL* curls = NULL;
+ CURLM* multi = NULL;
+ int still_running;
+ int i = -1;
+ int res = 0;
+ CURLMsg *msg;
+
+ start_test_timing();
+
+ global_init(CURL_GLOBAL_ALL);
+
+ multi_init(multi);
+
+ easy_init(curls);
+
+ easy_setopt(curls, CURLOPT_URL, URL);
+ easy_setopt(curls, CURLOPT_HEADER, 1L);
+
+ multi_add_handle(multi, curls);
+
+ multi_perform(multi, &still_running);
+
+ abort_on_test_timeout();
+
+ while(still_running) {
+ struct timeval timeout;
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ int maxfd = -99;
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ abort_on_test_timeout();
+
+ multi_perform(multi, &still_running);
+
+ abort_on_test_timeout();
+ }
+
+ msg = curl_multi_info_read(multi, &still_running);
+ if(msg)
+ /* this should now contain a result code from the easy handle,
+ get it */
+ i = msg->data.result;
+
+test_cleanup:
+
+ /* undocumented cleanup sequence - type UA */
+
+ curl_multi_cleanup(multi);
+ curl_easy_cleanup(curls);
+ curl_global_cleanup();
+
+ if(res)
+ i = res;
+
+ return i; /* return the final return code */
+}
diff --git a/tests/libtest/lib508.c b/tests/libtest/lib508.c
new file mode 100644
index 000000000..1aca064e9
--- /dev/null
+++ b/tests/libtest/lib508.c
@@ -0,0 +1,107 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+static char data[]="this is what we post to the silly web server\n";
+
+struct WriteThis {
+ char *readptr;
+ size_t sizeleft;
+};
+
+static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
+{
+ struct WriteThis *pooh = (struct WriteThis *)userp;
+
+ if(size*nmemb < 1)
+ return 0;
+
+ if(pooh->sizeleft) {
+ *(char *)ptr = pooh->readptr[0]; /* copy one single byte */
+ pooh->readptr++; /* advance pointer */
+ pooh->sizeleft--; /* less data left */
+ return 1; /* we return 1 byte at a time! */
+ }
+
+ return 0; /* no more data left to deliver */
+}
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res=CURLE_OK;
+
+ struct WriteThis pooh;
+
+ pooh.readptr = data;
+ pooh.sizeleft = strlen(data);
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* First set the URL that is about to receive our POST. */
+ test_setopt(curl, CURLOPT_URL, URL);
+
+ /* Now specify we want to POST data */
+ test_setopt(curl, CURLOPT_POST, 1L);
+
+#ifdef CURL_DOES_CONVERSIONS
+ /* Convert the POST data to ASCII */
+ test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L);
+#endif
+
+ /* Set the expected POST size */
+ test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)pooh.sizeleft);
+
+ /* we want to use our own read function */
+ test_setopt(curl, CURLOPT_READFUNCTION, read_callback);
+
+ /* pointer to pass to our read function */
+ test_setopt(curl, CURLOPT_INFILE, &pooh);
+
+ /* get verbose debug output please */
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* include headers in the output */
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib510.c b/tests/libtest/lib510.c
new file mode 100644
index 000000000..8278631c1
--- /dev/null
+++ b/tests/libtest/lib510.c
@@ -0,0 +1,130 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+static const char *post[]={
+ "one",
+ "two",
+ "three",
+ "and a final longer crap: four",
+ NULL
+};
+
+
+struct WriteThis {
+ int counter;
+};
+
+static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
+{
+ struct WriteThis *pooh = (struct WriteThis *)userp;
+ const char *data;
+
+ if(size*nmemb < 1)
+ return 0;
+
+ data = post[pooh->counter];
+
+ if(data) {
+ size_t len = strlen(data);
+ memcpy(ptr, data, len);
+ pooh->counter++; /* advance pointer */
+ return len;
+ }
+ return 0; /* no more data left to deliver */
+}
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res=CURLE_OK;
+ struct curl_slist *slist = NULL;
+ struct WriteThis pooh;
+ pooh.counter = 0;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ slist = curl_slist_append(slist, "Transfer-Encoding: chunked");
+ if (slist == NULL) {
+ fprintf(stderr, "curl_slist_append() failed\n");
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* First set the URL that is about to receive our POST. */
+ test_setopt(curl, CURLOPT_URL, URL);
+
+ /* Now specify we want to POST data */
+ test_setopt(curl, CURLOPT_POST, 1L);
+
+#ifdef CURL_DOES_CONVERSIONS
+ /* Convert the POST data to ASCII */
+ test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L);
+#endif
+
+ /* we want to use our own read function */
+ test_setopt(curl, CURLOPT_READFUNCTION, read_callback);
+
+ /* pointer to pass to our read function */
+ test_setopt(curl, CURLOPT_INFILE, &pooh);
+
+ /* get verbose debug output please */
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* include headers in the output */
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+
+ /* enforce chunked transfer by setting the header */
+ test_setopt(curl, CURLOPT_HTTPHEADER, slist);
+
+#ifdef LIB565
+ test_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_DIGEST);
+ test_setopt(curl, CURLOPT_USERPWD, "foo:bar");
+#endif
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ /* clean up the headers list */
+ if(slist)
+ curl_slist_free_all(slist);
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib511.c b/tests/libtest/lib511.c
new file mode 100644
index 000000000..6be2d2f76
--- /dev/null
+++ b/tests/libtest/lib511.c
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_FILETIME, 1L);
+ test_setopt(curl, CURLOPT_NOBODY, 1L);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
diff --git a/tests/libtest/lib512.c b/tests/libtest/lib512.c
new file mode 100644
index 000000000..19da18b4f
--- /dev/null
+++ b/tests/libtest/lib512.c
@@ -0,0 +1,77 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+/* Test case code based on source in a bug report filed by James Bursa on
+ 28 Apr 2004 */
+
+int test(char *URL)
+{
+ CURLcode code;
+ CURL *curl;
+ CURL *curl2;
+ int rc = 99;
+
+ code = curl_global_init(CURL_GLOBAL_ALL);
+ if(code == CURLE_OK) {
+
+ curl = curl_easy_init();
+ if(curl) {
+
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
+
+ curl2 = curl_easy_duphandle(curl);
+ if(curl2) {
+
+ code = curl_easy_setopt(curl2, CURLOPT_URL, URL);
+ if(code == CURLE_OK) {
+
+ code = curl_easy_perform(curl2);
+ if(code == CURLE_OK)
+ rc = 0;
+ else
+ rc = 1;
+ }
+ else
+ rc = 2;
+
+ curl_easy_cleanup(curl2);
+ }
+ else
+ rc = 3;
+
+ curl_easy_cleanup(curl);
+ }
+ else
+ rc = 4;
+
+ curl_global_cleanup();
+ }
+ else
+ rc = 5;
+
+ return rc;
+}
+
diff --git a/tests/libtest/lib513.c b/tests/libtest/lib513.c
new file mode 100644
index 000000000..c013ac258
--- /dev/null
+++ b/tests/libtest/lib513.c
@@ -0,0 +1,82 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
+{
+ (void)ptr;
+ (void)size;
+ (void)nmemb;
+ (void)userp;
+ return CURL_READFUNC_ABORT;
+}
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res=CURLE_OK;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* First set the URL that is about to receive our POST. */
+ test_setopt(curl, CURLOPT_URL, URL);
+
+ /* Now specify we want to POST data */
+ test_setopt(curl, CURLOPT_POST, 1L);
+
+ /* Set the expected POST size */
+ test_setopt(curl, CURLOPT_POSTFIELDSIZE, 1L);
+
+ /* we want to use our own read function */
+ test_setopt(curl, CURLOPT_READFUNCTION, read_callback);
+
+ /* pointer to pass to our read function */
+ test_setopt(curl, CURLOPT_INFILE, NULL);
+
+ /* get verbose debug output please */
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* include headers in the output */
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
diff --git a/tests/libtest/lib514.c b/tests/libtest/lib514.c
new file mode 100644
index 000000000..953e90dff
--- /dev/null
+++ b/tests/libtest/lib514.c
@@ -0,0 +1,78 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res=CURLE_OK;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* First set the URL that is about to receive our POST. */
+ test_setopt(curl, CURLOPT_URL, URL);
+
+ /* Based on a bug report by Niels van Tongeren on June 29, 2004:
+
+ A weird situation occurs when request 1 is a POST request and the request
+ 2 is a HEAD request. For the POST request we set the CURLOPT_POSTFIELDS,
+ CURLOPT_POSTFIELDSIZE and CURLOPT_POST options. For the HEAD request we
+ set the CURLOPT_NOBODY option to '1'.
+
+ */
+
+ test_setopt(curl, CURLOPT_POSTFIELDS, "moo");
+ test_setopt(curl, CURLOPT_POSTFIELDSIZE, 3L);
+ test_setopt(curl, CURLOPT_POST, 1L);
+
+ /* this is where transfer 1 would take place, but skip that and change
+ options right away instead */
+
+ test_setopt(curl, CURLOPT_NOBODY, 1L);
+
+ test_setopt(curl, CURLOPT_VERBOSE, 1L); /* show verbose for debug */
+ test_setopt(curl, CURLOPT_HEADER, 1L); /* include header */
+
+ /* Now, we should be making a fine HEAD request */
+
+ /* Perform the request 2, res will get the return code */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
diff --git a/tests/libtest/lib515.c b/tests/libtest/lib515.c
new file mode 100644
index 000000000..4e96c4a8d
--- /dev/null
+++ b/tests/libtest/lib515.c
@@ -0,0 +1,59 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res=CURLE_OK;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* First set the URL that is about to receive our POST. */
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_POSTFIELDS, NULL);
+ test_setopt(curl, CURLOPT_POSTFIELDSIZE, 0L);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L); /* show verbose for debug */
+ test_setopt(curl, CURLOPT_HEADER, 1L); /* include header */
+
+ /* Now, we should be making a zero byte POST request */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
diff --git a/tests/libtest/lib516.c b/tests/libtest/lib516.c
new file mode 100644
index 000000000..a9590948d
--- /dev/null
+++ b/tests/libtest/lib516.c
@@ -0,0 +1,58 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res=CURLE_OK;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* First set the URL that is about to receive our POST. */
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_HTTPPOST, NULL);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L); /* show verbose for debug */
+ test_setopt(curl, CURLOPT_HEADER, 1L); /* include header */
+
+ /* Now, we should be making a zero byte POST request */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
diff --git a/tests/libtest/lib517.c b/tests/libtest/lib517.c
new file mode 100644
index 000000000..ba49ec41e
--- /dev/null
+++ b/tests/libtest/lib517.c
@@ -0,0 +1,133 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+static const char * const dates[]={
+ "Sun, 06 Nov 1994 08:49:37 GMT",
+ "Sunday, 06-Nov-94 08:49:37 GMT",
+ "Sun Nov 6 08:49:37 1994",
+ "06 Nov 1994 08:49:37 GMT",
+ "06-Nov-94 08:49:37 GMT",
+ "Nov 6 08:49:37 1994",
+ "06 Nov 1994 08:49:37",
+ "06-Nov-94 08:49:37",
+ "1994 Nov 6 08:49:37",
+ "GMT 08:49:37 06-Nov-94 Sunday",
+ "94 6 Nov 08:49:37",
+ "1994 Nov 6",
+ "06-Nov-94",
+ "Sun Nov 6 94",
+ "1994.Nov.6",
+ "Sun/Nov/6/94/GMT",
+ "Sun, 06 Nov 1994 08:49:37 CET",
+ "06 Nov 1994 08:49:37 EST",
+ "Sun, 12 Sep 2004 15:05:58 -0700",
+ "Sat, 11 Sep 2004 21:32:11 +0200",
+ "20040912 15:05:58 -0700",
+ "20040911 +0200",
+ "Thu, 01-Jan-1970 00:59:59 GMT",
+ "Thu, 01-Jan-1970 01:00:00 GMT",
+/* "2094 Nov 6", See ../data/test517 for details */
+ "Sat, 15-Apr-17 21:01:22 GMT",
+ "Thu, 19-Apr-2007 16:00:00 GMT",
+ "Wed, 25 Apr 2007 21:02:13 GMT",
+ "Thu, 19/Apr\\2007 16:00:00 GMT",
+ "Fri, 1 Jan 2010 01:01:50 GMT",
+ "Wednesday, 1-Jan-2003 00:00:00 GMT",
+ ", 1-Jan-2003 00:00:00 GMT",
+ " 1-Jan-2003 00:00:00 GMT",
+ "1-Jan-2003 00:00:00 GMT",
+ "Wed,18-Apr-07 22:50:12 GMT",
+ "WillyWonka , 18-Apr-07 22:50:12 GMT",
+ "WillyWonka , 18-Apr-07 22:50:12",
+ "WillyWonka , 18-apr-07 22:50:12",
+ "Mon, 18-Apr-1977 22:50:13 GMT",
+ "Mon, 18-Apr-77 22:50:13 GMT",
+ "\"Sat, 15-Apr-17\\\"21:01:22\\\"GMT\"",
+ "Partyday, 18- April-07 22:50:12",
+ "Partyday, 18 - Apri-07 22:50:12",
+ "Wednes, 1-Januar-2003 00:00:00 GMT",
+ "Sat, 15-Apr-17 21:01:22",
+ "Sat, 15-Apr-17 21:01:22 GMT-2",
+ "Sat, 15-Apr-17 21:01:22 GMT BLAH",
+ "Sat, 15-Apr-17 21:01:22 GMT-0400",
+ "Sat, 15-Apr-17 21:01:22 GMT-0400 (EDT)",
+ "Sat, 15-Apr-17 21:01:22 DST",
+ "Sat, 15-Apr-17 21:01:22 -0400",
+ "Sat, 15-Apr-17 21:01:22 (hello there)",
+ "Sat, 15-Apr-17 21:01:22 11:22:33",
+ "Sat, 15-Apr-17 ::00 21:01:22",
+ "Sat, 15-Apr-17 boink:z 21:01:22",
+ "Sat, 15-Apr-17 91:22:33 21:01:22",
+ "Thu Apr 18 22:50:12 2007 GMT",
+ "22:50:12 Thu Apr 18 2007 GMT",
+ "Thu 22:50:12 Apr 18 2007 GMT",
+ "Thu Apr 22:50:12 18 2007 GMT",
+ "Thu Apr 18 22:50:12 2007 GMT",
+ "Thu Apr 18 2007 22:50:12 GMT",
+ "Thu Apr 18 2007 GMT 22:50:12",
+ "Sat, 15-Apr-17 21:01:22 GMT",
+ "15-Sat, Apr-17 21:01:22 GMT",
+ "15-Sat, Apr 21:01:22 GMT 17",
+ "15-Sat, Apr 21:01:22 GMT 2017",
+ "15 Apr 21:01:22 2017",
+ "15 17 Apr 21:01:22",
+ "Apr 15 17 21:01:22",
+ "Apr 15 21:01:22 17",
+ "2017 April 15 21:01:22",
+ "15 April 2017 21:01:22",
+ "98 April 17 21:01:22",
+ "Thu, 012-Aug-2008 20:49:07 GMT",
+#if 0
+ /* leaving out these strings since they differ between 32 and 64 bit
+ archs and the test suite has no good way to support two different outputs
+ like that */
+ "Thu, 12-Aug-31841 20:49:07 GMT",
+ "Thu, 12-Aug-9999999999 20:49:07 GMT",
+#endif
+ "Thu, 999999999999-Aug-2007 20:49:07 GMT",
+ "Thu, 12-Aug-2007 20:61:99999999999 GMT",
+ "IAintNoDateFool",
+ "Thu Apr 18 22:50 2007 GMT", /* without seconds */
+ "20110623 12:34:56",
+ "20110632 12:34:56",
+ "20110623 56:34:56",
+ "20111323 12:34:56",
+ "20110623 12:34:79",
+ "Wed, 31 Dec 2008 23:59:60 GMT", /* leap second */
+ NULL
+};
+
+int test(char *URL)
+{
+ int i;
+
+ (void)URL; /* not used */
+
+ for(i=0; dates[i]; i++) {
+ printf("%d: %s => %ld\n", i, dates[i], (long)curl_getdate(dates[i], NULL));
+ }
+
+ return 0;
+}
diff --git a/tests/libtest/lib518.c b/tests/libtest/lib518.c
new file mode 100644
index 000000000..23f7f17c6
--- /dev/null
+++ b/tests/libtest/lib518.c
@@ -0,0 +1,516 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "warnless.h"
+#include "memdebug.h"
+
+#ifndef FD_SETSIZE
+#error "this test requires FD_SETSIZE"
+#endif
+
+#define SAFETY_MARGIN (16)
+#define NUM_OPEN (FD_SETSIZE + 10)
+#define NUM_NEEDED (NUM_OPEN + SAFETY_MARGIN)
+
+#if defined(WIN32) || defined(_WIN32) || defined(MSDOS)
+#define DEV_NULL "NUL"
+#else
+#define DEV_NULL "/dev/null"
+#endif
+
+#if defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT)
+
+static int *fd = NULL;
+static struct rlimit num_open;
+static char msgbuff[256];
+
+static void store_errmsg(const char *msg, int err)
+{
+ if (!err)
+ sprintf(msgbuff, "%s", msg);
+ else
+ sprintf(msgbuff, "%s, errno %d, %s", msg, err, strerror(err));
+}
+
+static void close_file_descriptors(void)
+{
+ for (num_open.rlim_cur = 0;
+ num_open.rlim_cur < num_open.rlim_max;
+ num_open.rlim_cur++)
+ if (fd[num_open.rlim_cur] > 0)
+ close(fd[num_open.rlim_cur]);
+ free(fd);
+ fd = NULL;
+}
+
+static int fopen_works(void)
+{
+ FILE *fpa[3];
+ int i;
+ int ret = 1;
+
+ for (i = 0; i < 3; i++) {
+ fpa[i] = NULL;
+ }
+ for (i = 0; i < 3; i++) {
+ fpa[i] = fopen(DEV_NULL, "r");
+ if (fpa[i] == NULL) {
+ store_errmsg("fopen() failed", ERRNO);
+ fprintf(stderr, "%s\n", msgbuff);
+ ret = 0;
+ break;
+ }
+ }
+ for (i = 0; i < 3; i++) {
+ if (fpa[i] != NULL)
+ fclose(fpa[i]);
+ }
+ return ret;
+}
+
+static int rlimit(int keep_open)
+{
+ int nitems, i;
+ int *memchunk = NULL;
+ char *fmt;
+ struct rlimit rl;
+ char strbuff[256];
+ char strbuff1[81];
+ char strbuff2[81];
+ char fmt_u[] = "%u";
+ char fmt_lu[] = "%lu";
+#ifdef HAVE_LONGLONG
+ char fmt_llu[] = "%llu";
+
+ if (sizeof(rl.rlim_max) > sizeof(long))
+ fmt = fmt_llu;
+ else
+#endif
+ fmt = (sizeof(rl.rlim_max) < sizeof(long))?fmt_u:fmt_lu;
+
+ /* get initial open file limits */
+
+ if (getrlimit(RLIMIT_NOFILE, &rl) != 0) {
+ store_errmsg("getrlimit() failed", ERRNO);
+ fprintf(stderr, "%s\n", msgbuff);
+ return -1;
+ }
+
+ /* show initial open file limits */
+
+#ifdef RLIM_INFINITY
+ if (rl.rlim_cur == RLIM_INFINITY)
+ strcpy(strbuff, "INFINITY");
+ else
+#endif
+ sprintf(strbuff, fmt, rl.rlim_cur);
+ fprintf(stderr, "initial soft limit: %s\n", strbuff);
+
+#ifdef RLIM_INFINITY
+ if (rl.rlim_max == RLIM_INFINITY)
+ strcpy(strbuff, "INFINITY");
+ else
+#endif
+ sprintf(strbuff, fmt, rl.rlim_max);
+ fprintf(stderr, "initial hard limit: %s\n", strbuff);
+
+ /* show our constants */
+
+ fprintf(stderr, "test518 FD_SETSIZE: %d\n", FD_SETSIZE);
+ fprintf(stderr, "test518 NUM_OPEN : %d\n", NUM_OPEN);
+ fprintf(stderr, "test518 NUM_NEEDED: %d\n", NUM_NEEDED);
+
+ /*
+ * if soft limit and hard limit are different we ask the
+ * system to raise soft limit all the way up to the hard
+ * limit. Due to some other system limit the soft limit
+ * might not be raised up to the hard limit. So from this
+ * point the resulting soft limit is our limit. Trying to
+ * open more than soft limit file descriptors will fail.
+ */
+
+ if (rl.rlim_cur != rl.rlim_max) {
+
+#ifdef OPEN_MAX
+ if ((rl.rlim_cur > 0) &&
+ (rl.rlim_cur < OPEN_MAX)) {
+ fprintf(stderr, "raising soft limit up to OPEN_MAX\n");
+ rl.rlim_cur = OPEN_MAX;
+ if (setrlimit(RLIMIT_NOFILE, &rl) != 0) {
+ /* on failure don't abort just issue a warning */
+ store_errmsg("setrlimit() failed", ERRNO);
+ fprintf(stderr, "%s\n", msgbuff);
+ msgbuff[0] = '\0';
+ }
+ }
+#endif
+
+ fprintf(stderr, "raising soft limit up to hard limit\n");
+ rl.rlim_cur = rl.rlim_max;
+ if (setrlimit(RLIMIT_NOFILE, &rl) != 0) {
+ /* on failure don't abort just issue a warning */
+ store_errmsg("setrlimit() failed", ERRNO);
+ fprintf(stderr, "%s\n", msgbuff);
+ msgbuff[0] = '\0';
+ }
+
+ /* get current open file limits */
+
+ if (getrlimit(RLIMIT_NOFILE, &rl) != 0) {
+ store_errmsg("getrlimit() failed", ERRNO);
+ fprintf(stderr, "%s\n", msgbuff);
+ return -3;
+ }
+
+ /* show current open file limits */
+
+#ifdef RLIM_INFINITY
+ if (rl.rlim_cur == RLIM_INFINITY)
+ strcpy(strbuff, "INFINITY");
+ else
+#endif
+ sprintf(strbuff, fmt, rl.rlim_cur);
+ fprintf(stderr, "current soft limit: %s\n", strbuff);
+
+#ifdef RLIM_INFINITY
+ if (rl.rlim_max == RLIM_INFINITY)
+ strcpy(strbuff, "INFINITY");
+ else
+#endif
+ sprintf(strbuff, fmt, rl.rlim_max);
+ fprintf(stderr, "current hard limit: %s\n", strbuff);
+
+ } /* (rl.rlim_cur != rl.rlim_max) */
+
+ /*
+ * test 518 is all about testing libcurl functionality
+ * when more than FD_SETSIZE file descriptors are open.
+ * This means that if for any reason we are not able to
+ * open more than FD_SETSIZE file descriptors then test
+ * 518 should not be run.
+ */
+
+ /*
+ * verify that soft limit is higher than NUM_NEEDED,
+ * which is the number of file descriptors we would
+ * try to open plus SAFETY_MARGIN to not exhaust the
+ * file descriptor pool
+ */
+
+ num_open.rlim_cur = NUM_NEEDED;
+
+ if ((rl.rlim_cur > 0) &&
+#ifdef RLIM_INFINITY
+ (rl.rlim_cur != RLIM_INFINITY) &&
+#endif
+ (rl.rlim_cur <= num_open.rlim_cur)) {
+ sprintf(strbuff2, fmt, rl.rlim_cur);
+ sprintf(strbuff1, fmt, num_open.rlim_cur);
+ sprintf(strbuff, "fds needed %s > system limit %s",
+ strbuff1, strbuff2);
+ store_errmsg(strbuff, 0);
+ fprintf(stderr, "%s\n", msgbuff);
+ return -4;
+ }
+
+ /*
+ * reserve a chunk of memory before opening file descriptors to
+ * avoid a low memory condition once the file descriptors are
+ * open. System conditions that could make the test fail should
+ * be addressed in the precheck phase. This chunk of memory shall
+ * be always free()ed before exiting the rlimit() function so
+ * that it becomes available to the test.
+ */
+
+ for (nitems = i = 1; nitems <= i; i *= 2)
+ nitems = i;
+ if (nitems > 0x7fff)
+ nitems = 0x40000;
+ do {
+ num_open.rlim_max = sizeof(*memchunk) * (size_t)nitems;
+ sprintf(strbuff, fmt, num_open.rlim_max);
+ fprintf(stderr, "allocating memchunk %s byte array\n", strbuff);
+ memchunk = malloc(sizeof(*memchunk) * (size_t)nitems);
+ if (!memchunk) {
+ fprintf(stderr, "memchunk, malloc() failed\n");
+ nitems /= 2;
+ }
+ } while (nitems && !memchunk);
+ if (!memchunk) {
+ store_errmsg("memchunk, malloc() failed", ERRNO);
+ fprintf(stderr, "%s\n", msgbuff);
+ return -5;
+ }
+
+ /* initialize it to fight lazy allocation */
+
+ fprintf(stderr, "initializing memchunk array\n");
+
+ for (i = 0; i < nitems; i++)
+ memchunk[i] = -1;
+
+ /* set the number of file descriptors we will try to open */
+
+ num_open.rlim_max = NUM_OPEN;
+
+ /* verify that we won't overflow size_t in malloc() */
+
+ if ((size_t)(num_open.rlim_max) > ((size_t)-1) / sizeof(*fd)) {
+ sprintf(strbuff1, fmt, num_open.rlim_max);
+ sprintf(strbuff, "unable to allocate an array for %s "
+ "file descriptors, would overflow size_t", strbuff1);
+ store_errmsg(strbuff, 0);
+ fprintf(stderr, "%s\n", msgbuff);
+ free(memchunk);
+ return -6;
+ }
+
+ /* allocate array for file descriptors */
+
+ sprintf(strbuff, fmt, num_open.rlim_max);
+ fprintf(stderr, "allocating array for %s file descriptors\n", strbuff);
+
+ fd = malloc(sizeof(*fd) * (size_t)(num_open.rlim_max));
+ if (!fd) {
+ store_errmsg("fd, malloc() failed", ERRNO);
+ fprintf(stderr, "%s\n", msgbuff);
+ free(memchunk);
+ return -7;
+ }
+
+ /* initialize it to fight lazy allocation */
+
+ fprintf(stderr, "initializing fd array\n");
+
+ for (num_open.rlim_cur = 0;
+ num_open.rlim_cur < num_open.rlim_max;
+ num_open.rlim_cur++)
+ fd[num_open.rlim_cur] = -1;
+
+ sprintf(strbuff, fmt, num_open.rlim_max);
+ fprintf(stderr, "trying to open %s file descriptors\n", strbuff);
+
+ /* open a dummy descriptor */
+
+ fd[0] = open(DEV_NULL, O_RDONLY);
+ if (fd[0] < 0) {
+ sprintf(strbuff, "opening of %s failed", DEV_NULL);
+ store_errmsg(strbuff, ERRNO);
+ fprintf(stderr, "%s\n", msgbuff);
+ free(fd);
+ fd = NULL;
+ free(memchunk);
+ return -8;
+ }
+
+ /* create a bunch of file descriptors */
+
+ for (num_open.rlim_cur = 1;
+ num_open.rlim_cur < num_open.rlim_max;
+ num_open.rlim_cur++) {
+
+ fd[num_open.rlim_cur] = dup(fd[0]);
+
+ if (fd[num_open.rlim_cur] < 0) {
+
+ fd[num_open.rlim_cur] = -1;
+
+ sprintf(strbuff1, fmt, num_open.rlim_cur);
+ sprintf(strbuff, "dup() attempt %s failed", strbuff1);
+ fprintf(stderr, "%s\n", strbuff);
+
+ sprintf(strbuff1, fmt, num_open.rlim_cur);
+ sprintf(strbuff, "fds system limit seems close to %s", strbuff1);
+ fprintf(stderr, "%s\n", strbuff);
+
+ num_open.rlim_max = NUM_NEEDED;
+
+ sprintf(strbuff2, fmt, num_open.rlim_max);
+ sprintf(strbuff1, fmt, num_open.rlim_cur);
+ sprintf(strbuff, "fds needed %s > system limit %s",
+ strbuff2, strbuff1);
+ store_errmsg(strbuff, 0);
+ fprintf(stderr, "%s\n", msgbuff);
+
+ for (num_open.rlim_cur = 0;
+ fd[num_open.rlim_cur] >= 0;
+ num_open.rlim_cur++)
+ close(fd[num_open.rlim_cur]);
+ free(fd);
+ fd = NULL;
+ free(memchunk);
+ return -9;
+
+ }
+
+ }
+
+ sprintf(strbuff, fmt, num_open.rlim_max);
+ fprintf(stderr, "%s file descriptors open\n", strbuff);
+
+#if !defined(HAVE_POLL_FINE) && \
+ !defined(USE_WINSOCK) && \
+ !defined(TPF)
+
+ /*
+ * when using select() instead of poll() we cannot test
+ * libcurl functionality with a socket number equal or
+ * greater than FD_SETSIZE. In any case, macro VERIFY_SOCK
+ * in lib/select.c enforces this check and protects libcurl
+ * from a possible crash. The effect of this protection
+ * is that test 518 will always fail, since the actual
+ * call to select() never takes place. We skip test 518
+ * with an indication that select limit would be exceeded.
+ */
+
+ num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN;
+ if (num_open.rlim_max > num_open.rlim_cur) {
+ sprintf(strbuff, "select limit is FD_SETSIZE %d", FD_SETSIZE);
+ store_errmsg(strbuff, 0);
+ fprintf(stderr, "%s\n", msgbuff);
+ close_file_descriptors();
+ free(memchunk);
+ return -10;
+ }
+
+ num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN;
+ for (rl.rlim_cur = 0;
+ rl.rlim_cur < num_open.rlim_max;
+ rl.rlim_cur++) {
+ if ((fd[rl.rlim_cur] > 0) &&
+ ((unsigned int)fd[rl.rlim_cur] > num_open.rlim_cur)) {
+ sprintf(strbuff, "select limit is FD_SETSIZE %d", FD_SETSIZE);
+ store_errmsg(strbuff, 0);
+ fprintf(stderr, "%s\n", msgbuff);
+ close_file_descriptors();
+ free(memchunk);
+ return -11;
+ }
+ }
+
+#endif /* using a FD_SETSIZE bound select() */
+
+ /*
+ * Old or 'backwards compatible' implementations of stdio do not allow
+ * handling of streams with an underlying file descriptor number greater
+ * than 255, even when allowing high numbered file descriptors for sockets.
+ * At this point we have a big number of file descriptors which have been
+ * opened using dup(), so lets test the stdio implementation and discover
+ * if it is capable of fopen()ing some additional files.
+ */
+
+ if (!fopen_works()) {
+ sprintf(strbuff1, fmt, num_open.rlim_max);
+ sprintf(strbuff, "stdio fopen() fails with %s fds open()",
+ strbuff1);
+ fprintf(stderr, "%s\n", msgbuff);
+ sprintf(strbuff, "stdio fopen() fails with lots of fds open()");
+ store_errmsg(strbuff, 0);
+ close_file_descriptors();
+ free(memchunk);
+ return -12;
+ }
+
+ /* free the chunk of memory we were reserving so that it
+ becomes becomes available to the test */
+
+ free(memchunk);
+
+ /* close file descriptors unless instructed to keep them */
+
+ if (!keep_open) {
+ close_file_descriptors();
+ }
+
+ return 0;
+}
+
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+
+ if(!strcmp(URL, "check")) {
+ /* used by the test script to ask if we can run this test or not */
+ if(rlimit(FALSE)) {
+ fprintf(stdout, "rlimit problem: %s\n", msgbuff);
+ return 1;
+ }
+ return 0; /* sure, run this! */
+ }
+
+ if (rlimit(TRUE)) {
+ /* failure */
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* run the test with the bunch of open file descriptors
+ and close them all once the test is over */
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ close_file_descriptors();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ close_file_descriptors();
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ close_file_descriptors();
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
+
+#else /* defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) */
+
+int test(char *URL)
+{
+ (void)URL;
+ printf("system lacks necessary system function(s)");
+ return 1; /* skip test */
+}
+
+#endif /* defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) */
diff --git a/tests/libtest/lib519.c b/tests/libtest/lib519.c
new file mode 100644
index 000000000..b720c8fee
--- /dev/null
+++ b/tests/libtest/lib519.c
@@ -0,0 +1,62 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_USERPWD, "monster:underbed");
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* get first page */
+ res = curl_easy_perform(curl);
+
+ test_setopt(curl, CURLOPT_USERPWD, "anothermonster:inwardrobe");
+
+ /* get second page */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
+
diff --git a/tests/libtest/lib520.c b/tests/libtest/lib520.c
new file mode 100644
index 000000000..9ffaa4f92
--- /dev/null
+++ b/tests/libtest/lib520.c
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_FILETIME, 1L);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
diff --git a/tests/libtest/lib521.c b/tests/libtest/lib521.c
new file mode 100644
index 000000000..93c306864
--- /dev/null
+++ b/tests/libtest/lib521.c
@@ -0,0 +1,56 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_PORT, strtol(libtest_arg2, NULL, 10));
+ test_setopt(curl, CURLOPT_USERPWD, "xxx:yyy");
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
+
diff --git a/tests/libtest/lib523.c b/tests/libtest/lib523.c
new file mode 100644
index 000000000..0fdc83db6
--- /dev/null
+++ b/tests/libtest/lib523.c
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_PROXY, libtest_arg2);
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_PORT, 19999L);
+ test_setopt(curl, CURLOPT_USERPWD, "xxx:yyy");
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
+
diff --git a/tests/libtest/lib524.c b/tests/libtest/lib524.c
new file mode 100644
index 000000000..6f56df9b0
--- /dev/null
+++ b/tests/libtest/lib524.c
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_UPLOAD, 1L);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
+
diff --git a/tests/libtest/lib525.c b/tests/libtest/lib525.c
new file mode 100644
index 000000000..ca128cb9c
--- /dev/null
+++ b/tests/libtest/lib525.c
@@ -0,0 +1,165 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include <fcntl.h>
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+int test(char *URL)
+{
+ int res = 0;
+ CURL *curl = NULL;
+ FILE *hd_src = NULL;
+ int hd ;
+ int error;
+ struct_stat file_info;
+ CURLM *m = NULL;
+ int running;
+
+ start_test_timing();
+
+ if(!libtest_arg2) {
+#ifdef LIB529
+ /* test 529 */
+ fprintf(stderr, "Usage: lib529 [url] [uploadfile]\n");
+#else
+ /* test 525 */
+ fprintf(stderr, "Usage: lib525 [url] [uploadfile]\n");
+#endif
+ return TEST_ERR_USAGE;
+ }
+
+ hd_src = fopen(libtest_arg2, "rb");
+ if(NULL == hd_src) {
+ error = ERRNO;
+ fprintf(stderr, "fopen() failed with error: %d (%s)\n",
+ error, strerror(error));
+ fprintf(stderr, "Error opening file: (%s)\n", libtest_arg2);
+ return TEST_ERR_FOPEN;
+ }
+
+ /* get the file size of the local file */
+ hd = fstat(fileno(hd_src), &file_info);
+ if(hd == -1) {
+ /* can't open file, bail out */
+ error = ERRNO;
+ fprintf(stderr, "fstat() failed with error: %d (%s)\n",
+ error, strerror(error));
+ fprintf(stderr, "ERROR: cannot open file (%s)\n", libtest_arg2);
+ fclose(hd_src);
+ return TEST_ERR_FSTAT;
+ }
+
+ res_global_init(CURL_GLOBAL_ALL);
+ if(res) {
+ fclose(hd_src);
+ return res;
+ }
+
+ easy_init(curl);
+
+ /* enable uploading */
+ easy_setopt(curl, CURLOPT_UPLOAD, 1L);
+
+ /* specify target */
+ easy_setopt(curl,CURLOPT_URL, URL);
+
+ /* go verbose */
+ easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* use active FTP */
+ easy_setopt(curl, CURLOPT_FTPPORT, "-");
+
+ /* now specify which file to upload */
+ easy_setopt(curl, CURLOPT_READDATA, hd_src);
+
+ /* NOTE: if you want this code to work on Windows with libcurl as a DLL, you
+ MUST also provide a read callback with CURLOPT_READFUNCTION. Failing to
+ do so will give you a crash since a DLL may not use the variable's memory
+ when passed in to it from an app like this. */
+
+ /* Set the size of the file to upload (optional). If you give a *_LARGE
+ option you MUST make sure that the type of the passed-in argument is a
+ curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must
+ make sure that to pass in a type 'long' argument. */
+ easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
+
+ multi_init(m);
+
+ multi_add_handle(m, curl);
+
+ for(;;) {
+ struct timeval interval;
+ fd_set rd, wr, exc;
+ int maxfd = -99;
+
+ interval.tv_sec = 1;
+ interval.tv_usec = 0;
+
+ multi_perform(m, &running);
+
+ abort_on_test_timeout();
+
+ if(!running)
+ break; /* done */
+
+ FD_ZERO(&rd);
+ FD_ZERO(&wr);
+ FD_ZERO(&exc);
+
+ multi_fdset(m, &rd, &wr, &exc, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ select_test(maxfd+1, &rd, &wr, &exc, &interval);
+
+ abort_on_test_timeout();
+ }
+
+test_cleanup:
+
+#ifdef LIB529
+ /* test 529 */
+ /* proper cleanup sequence - type PA */
+ curl_multi_remove_handle(m, curl);
+ curl_multi_cleanup(m);
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+#else
+ /* test 525 */
+ /* proper cleanup sequence - type PB */
+ curl_multi_remove_handle(m, curl);
+ curl_easy_cleanup(curl);
+ curl_multi_cleanup(m);
+ curl_global_cleanup();
+#endif
+
+ /* close the local file */
+ fclose(hd_src);
+
+ return res;
+}
diff --git a/tests/libtest/lib526.c b/tests/libtest/lib526.c
new file mode 100644
index 000000000..9db04dba7
--- /dev/null
+++ b/tests/libtest/lib526.c
@@ -0,0 +1,184 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+/*
+ * This code sets up multiple easy handles that transfer a single file from
+ * the same URL, in a serial manner after each other. Due to the connection
+ * sharing within the multi handle all transfers are performed on the same
+ * persistent connection.
+ *
+ * This source code is used for lib526, lib527 and lib532 with only #ifdefs
+ * controlling the small differences.
+ *
+ * - lib526 closes all easy handles after
+ * they all have transfered the file over the single connection
+ * - lib527 closes each easy handle after each single transfer.
+ * - lib532 uses only a single easy handle that is removed, reset and then
+ * re-added for each transfer
+ *
+ * Test case 526, 527 and 532 use FTP, while test 528 uses the lib526 tool but
+ * with HTTP.
+ */
+
+#include "test.h"
+
+#include <fcntl.h>
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+#define NUM_HANDLES 4
+
+int test(char *URL)
+{
+ int res = 0;
+ CURL *curl[NUM_HANDLES];
+ int running;
+ CURLM *m = NULL;
+ int current = 0;
+ int i;
+
+ for(i=0; i < NUM_HANDLES; i++)
+ curl[i] = NULL;
+
+ start_test_timing();
+
+ global_init(CURL_GLOBAL_ALL);
+
+ /* get NUM_HANDLES easy handles */
+ for(i=0; i < NUM_HANDLES; i++) {
+ easy_init(curl[i]);
+ /* specify target */
+ easy_setopt(curl[i], CURLOPT_URL, URL);
+ /* go verbose */
+ easy_setopt(curl[i], CURLOPT_VERBOSE, 1L);
+ }
+
+ multi_init(m);
+
+ multi_add_handle(m, curl[current]);
+
+ fprintf(stderr, "Start at URL 0\n");
+
+ for(;;) {
+ struct timeval interval;
+ fd_set rd, wr, exc;
+ int maxfd = -99;
+
+ interval.tv_sec = 1;
+ interval.tv_usec = 0;
+
+ multi_perform(m, &running);
+
+ abort_on_test_timeout();
+
+ if(!running) {
+#ifdef LIB527
+ /* NOTE: this code does not remove the handle from the multi handle
+ here, which would be the nice, sane and documented way of working.
+ This however tests that the API survives this abuse gracefully. */
+ curl_easy_cleanup(curl[current]);
+ curl[current] = NULL;
+#endif
+ if(++current < NUM_HANDLES) {
+ fprintf(stderr, "Advancing to URL %d\n", current);
+#ifdef LIB532
+ /* first remove the only handle we use */
+ curl_multi_remove_handle(m, curl[0]);
+
+ /* make us re-use the same handle all the time, and try resetting
+ the handle first too */
+ curl_easy_reset(curl[0]);
+ easy_setopt(curl[0], CURLOPT_URL, URL);
+ /* go verbose */
+ easy_setopt(curl[0], CURLOPT_VERBOSE, 1L);
+
+ /* re-add it */
+ multi_add_handle(m, curl[0]);
+#else
+ multi_add_handle(m, curl[current]);
+#endif
+ }
+ else {
+ break; /* done */
+ }
+ }
+
+ FD_ZERO(&rd);
+ FD_ZERO(&wr);
+ FD_ZERO(&exc);
+
+ multi_fdset(m, &rd, &wr, &exc, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ select_test(maxfd+1, &rd, &wr, &exc, &interval);
+
+ abort_on_test_timeout();
+ }
+
+test_cleanup:
+
+#if defined(LIB526)
+
+ /* test 526 and 528 */
+ /* proper cleanup sequence - type PB */
+
+ for(i=0; i < NUM_HANDLES; i++) {
+ curl_multi_remove_handle(m, curl[i]);
+ curl_easy_cleanup(curl[i]);
+ }
+ curl_multi_cleanup(m);
+ curl_global_cleanup();
+
+#elif defined(LIB527)
+
+ /* test 527 */
+
+ /* Upon non-failure test flow the easy's have already been cleanup'ed. In
+ case there is a failure we arrive here with easy's that have not been
+ cleanup'ed yet, in this case we have to cleanup them or otherwise these
+ will be leaked, let's use undocumented cleanup sequence - type UB */
+
+ if(res)
+ for(i=0; i < NUM_HANDLES; i++)
+ curl_easy_cleanup(curl[i]);
+
+ curl_multi_cleanup(m);
+ curl_global_cleanup();
+
+#elif defined(LIB532)
+
+ /* test 532 */
+ /* undocumented cleanup sequence - type UB */
+
+ for(i=0; i < NUM_HANDLES; i++)
+ curl_easy_cleanup(curl[i]);
+ curl_multi_cleanup(m);
+ curl_global_cleanup();
+
+#endif
+
+ return res;
+}
diff --git a/tests/libtest/lib530.c b/tests/libtest/lib530.c
new file mode 100644
index 000000000..ad84ff8a5
--- /dev/null
+++ b/tests/libtest/lib530.c
@@ -0,0 +1,111 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+#define NUM_HANDLES 4
+
+int test(char *URL)
+{
+ int res = 0;
+ CURL *curl[NUM_HANDLES];
+ int running;
+ CURLM *m = NULL;
+ int i;
+ char target_url[256];
+
+ for(i=0; i < NUM_HANDLES; i++)
+ curl[i] = NULL;
+
+ start_test_timing();
+
+ global_init(CURL_GLOBAL_ALL);
+
+ multi_init(m);
+
+ /* get NUM_HANDLES easy handles */
+ for(i=0; i < NUM_HANDLES; i++) {
+ /* get an easy handle */
+ easy_init(curl[i]);
+ /* specify target */
+ sprintf(target_url, "%s%04i", URL, i + 1);
+ target_url[sizeof(target_url) - 1] = '\0';
+ easy_setopt(curl[i], CURLOPT_URL, target_url);
+ /* go verbose */
+ easy_setopt(curl[i], CURLOPT_VERBOSE, 1L);
+ /* include headers */
+ easy_setopt(curl[i], CURLOPT_HEADER, 1L);
+ /* add handle to multi */
+ multi_add_handle(m, curl[i]);
+ }
+
+ multi_setopt(m, CURLMOPT_PIPELINING, 1L);
+
+ fprintf(stderr, "Start at URL 0\n");
+
+ for(;;) {
+ struct timeval interval;
+ fd_set rd, wr, exc;
+ int maxfd = -99;
+
+ interval.tv_sec = 1;
+ interval.tv_usec = 0;
+
+ multi_perform(m, &running);
+
+ abort_on_test_timeout();
+
+ if(!running)
+ break; /* done */
+
+ FD_ZERO(&rd);
+ FD_ZERO(&wr);
+ FD_ZERO(&exc);
+
+ multi_fdset(m, &rd, &wr, &exc, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ select_test(maxfd+1, &rd, &wr, &exc, &interval);
+
+ abort_on_test_timeout();
+ }
+
+test_cleanup:
+
+ /* proper cleanup sequence - type PB */
+
+ for(i=0; i < NUM_HANDLES; i++) {
+ curl_multi_remove_handle(m, curl[i]);
+ curl_easy_cleanup(curl[i]);
+ }
+
+ curl_multi_cleanup(m);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib533.c b/tests/libtest/lib533.c
new file mode 100644
index 000000000..fdc18a1eb
--- /dev/null
+++ b/tests/libtest/lib533.c
@@ -0,0 +1,112 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+/* used for test case 533, 534 and 535 */
+
+#include "test.h"
+
+#include <fcntl.h>
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+int test(char *URL)
+{
+ int res = 0;
+ CURL *curl = NULL;
+ int running;
+ CURLM *m = NULL;
+ int current=0;
+
+ start_test_timing();
+
+ global_init(CURL_GLOBAL_ALL);
+
+ easy_init(curl);
+
+ easy_setopt(curl, CURLOPT_URL, URL);
+ easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+ easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
+
+ multi_init(m);
+
+ multi_add_handle(m, curl);
+
+ fprintf(stderr, "Start at URL 0\n");
+
+ for(;;) {
+ struct timeval interval;
+ fd_set rd, wr, exc;
+ int maxfd = -99;
+
+ interval.tv_sec = 1;
+ interval.tv_usec = 0;
+
+ multi_perform(m, &running);
+
+ abort_on_test_timeout();
+
+ if(!running) {
+ if(!current++) {
+ fprintf(stderr, "Advancing to URL 1\n");
+ /* remove the handle we use */
+ curl_multi_remove_handle(m, curl);
+
+ /* make us re-use the same handle all the time, and try resetting
+ the handle first too */
+ curl_easy_reset(curl);
+ easy_setopt(curl, CURLOPT_URL, libtest_arg2);
+ easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+ easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
+
+ /* re-add it */
+ multi_add_handle(m, curl);
+ }
+ else
+ break; /* done */
+ }
+
+ FD_ZERO(&rd);
+ FD_ZERO(&wr);
+ FD_ZERO(&exc);
+
+ multi_fdset(m, &rd, &wr, &exc, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ select_test(maxfd+1, &rd, &wr, &exc, &interval);
+
+ abort_on_test_timeout();
+ }
+
+test_cleanup:
+
+ /* undocumented cleanup sequence - type UB */
+
+ curl_easy_cleanup(curl);
+ curl_multi_cleanup(m);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib536.c b/tests/libtest/lib536.c
new file mode 100644
index 000000000..e3ae402b7
--- /dev/null
+++ b/tests/libtest/lib536.c
@@ -0,0 +1,142 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include <fcntl.h>
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+static int perform(CURLM *multi)
+{
+ int handles;
+ fd_set fdread, fdwrite, fdexcep;
+ int res = 0;
+
+ for(;;) {
+ struct timeval interval;
+ int maxfd = -99;
+
+ interval.tv_sec = 0;
+ interval.tv_usec = 100000L; /* 100 ms */
+
+ res_multi_perform(multi, &handles);
+ if(res)
+ return res;
+
+ res_test_timedout();
+ if(res)
+ return res;
+
+ if(!handles)
+ break; /* done */
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ res_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
+ if(res)
+ return res;
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ res_select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &interval);
+ if(res)
+ return res;
+
+ res_test_timedout();
+ if(res)
+ return res;
+ }
+
+ return 0; /* success */
+}
+
+int test(char *URL)
+{
+ CURLM *multi = NULL;
+ CURL *easy = NULL;
+ int res = 0;
+
+ start_test_timing();
+
+ global_init(CURL_GLOBAL_ALL);
+
+ multi_init(multi);
+
+ easy_init(easy);
+
+ multi_setopt(multi, CURLMOPT_PIPELINING, 1L);
+
+ easy_setopt(easy, CURLOPT_WRITEFUNCTION, fwrite);
+ easy_setopt(easy, CURLOPT_FAILONERROR, 1L);
+ easy_setopt(easy, CURLOPT_URL, URL);
+
+ res_multi_add_handle(multi, easy);
+ if(res) {
+ printf("curl_multi_add_handle() 1 failed\n");
+ goto test_cleanup;
+ }
+
+ res = perform(multi);
+ if(res) {
+ printf("retrieve 1 failed\n");
+ goto test_cleanup;
+ }
+
+ curl_multi_remove_handle(multi, easy);
+
+ curl_easy_reset(easy);
+
+ easy_setopt(easy, CURLOPT_FAILONERROR, 1L);
+ easy_setopt(easy, CURLOPT_URL, libtest_arg2);
+
+ res_multi_add_handle(multi, easy);
+ if(res) {
+ printf("curl_multi_add_handle() 2 failed\n");
+ goto test_cleanup;
+ }
+
+ res = perform(multi);
+ if(res) {
+ printf("retrieve 2 failed\n");
+ goto test_cleanup;
+ }
+
+ curl_multi_remove_handle(multi, easy);
+
+test_cleanup:
+
+ /* undocumented cleanup sequence - type UB */
+
+ curl_easy_cleanup(easy);
+ curl_multi_cleanup(multi);
+ curl_global_cleanup();
+
+ printf("Finished!\n");
+
+ return res;
+}
diff --git a/tests/libtest/lib537.c b/tests/libtest/lib537.c
new file mode 100644
index 000000000..24d252235
--- /dev/null
+++ b/tests/libtest/lib537.c
@@ -0,0 +1,519 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "warnless.h"
+#include "memdebug.h"
+
+#if !defined(HAVE_POLL_FINE) && \
+ !defined(USE_WINSOCK) && \
+ !defined(TPF) && \
+ !defined(FD_SETSIZE)
+#error "this test requires FD_SETSIZE"
+#endif
+
+#define SAFETY_MARGIN (10)
+
+#if defined(WIN32) || defined(_WIN32) || defined(MSDOS)
+#define DEV_NULL "NUL"
+#else
+#define DEV_NULL "/dev/null"
+#endif
+
+#if defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT)
+
+static int *fd = NULL;
+static struct rlimit num_open;
+static char msgbuff[256];
+
+static void store_errmsg(const char *msg, int err)
+{
+ if (!err)
+ sprintf(msgbuff, "%s", msg);
+ else
+ sprintf(msgbuff, "%s, errno %d, %s", msg, err, strerror(err));
+}
+
+static void close_file_descriptors(void)
+{
+ for (num_open.rlim_cur = 0;
+ num_open.rlim_cur < num_open.rlim_max;
+ num_open.rlim_cur++)
+ if (fd[num_open.rlim_cur] > 0)
+ close(fd[num_open.rlim_cur]);
+ free(fd);
+ fd = NULL;
+}
+
+static int fopen_works(void)
+{
+ FILE *fpa[3];
+ int i;
+ int ret = 1;
+
+ for (i = 0; i < 3; i++) {
+ fpa[i] = NULL;
+ }
+ for (i = 0; i < 3; i++) {
+ fpa[i] = fopen(DEV_NULL, "r");
+ if (fpa[i] == NULL) {
+ store_errmsg("fopen() failed", ERRNO);
+ fprintf(stderr, "%s\n", msgbuff);
+ ret = 0;
+ break;
+ }
+ }
+ for (i = 0; i < 3; i++) {
+ if (fpa[i] != NULL)
+ fclose(fpa[i]);
+ }
+ return ret;
+}
+
+static int rlimit(int keep_open)
+{
+ int *tmpfd;
+ int nitems, i;
+ int *memchunk = NULL;
+ char *fmt;
+ struct rlimit rl;
+ char strbuff[256];
+ char strbuff1[81];
+ char fmt_u[] = "%u";
+ char fmt_lu[] = "%lu";
+#ifdef HAVE_LONGLONG
+ char fmt_llu[] = "%llu";
+
+ if (sizeof(rl.rlim_max) > sizeof(long))
+ fmt = fmt_llu;
+ else
+#endif
+ fmt = (sizeof(rl.rlim_max) < sizeof(long))?fmt_u:fmt_lu;
+
+ /* get initial open file limits */
+
+ if (getrlimit(RLIMIT_NOFILE, &rl) != 0) {
+ store_errmsg("getrlimit() failed", ERRNO);
+ fprintf(stderr, "%s\n", msgbuff);
+ return -1;
+ }
+
+ /* show initial open file limits */
+
+#ifdef RLIM_INFINITY
+ if (rl.rlim_cur == RLIM_INFINITY)
+ strcpy(strbuff, "INFINITY");
+ else
+#endif
+ sprintf(strbuff, fmt, rl.rlim_cur);
+ fprintf(stderr, "initial soft limit: %s\n", strbuff);
+
+#ifdef RLIM_INFINITY
+ if (rl.rlim_max == RLIM_INFINITY)
+ strcpy(strbuff, "INFINITY");
+ else
+#endif
+ sprintf(strbuff, fmt, rl.rlim_max);
+ fprintf(stderr, "initial hard limit: %s\n", strbuff);
+
+ /*
+ * if soft limit and hard limit are different we ask the
+ * system to raise soft limit all the way up to the hard
+ * limit. Due to some other system limit the soft limit
+ * might not be raised up to the hard limit. So from this
+ * point the resulting soft limit is our limit. Trying to
+ * open more than soft limit file descriptors will fail.
+ */
+
+ if (rl.rlim_cur != rl.rlim_max) {
+
+#ifdef OPEN_MAX
+ if ((rl.rlim_cur > 0) &&
+ (rl.rlim_cur < OPEN_MAX)) {
+ fprintf(stderr, "raising soft limit up to OPEN_MAX\n");
+ rl.rlim_cur = OPEN_MAX;
+ if (setrlimit(RLIMIT_NOFILE, &rl) != 0) {
+ /* on failure don't abort just issue a warning */
+ store_errmsg("setrlimit() failed", ERRNO);
+ fprintf(stderr, "%s\n", msgbuff);
+ msgbuff[0] = '\0';
+ }
+ }
+#endif
+
+ fprintf(stderr, "raising soft limit up to hard limit\n");
+ rl.rlim_cur = rl.rlim_max;
+ if (setrlimit(RLIMIT_NOFILE, &rl) != 0) {
+ /* on failure don't abort just issue a warning */
+ store_errmsg("setrlimit() failed", ERRNO);
+ fprintf(stderr, "%s\n", msgbuff);
+ msgbuff[0] = '\0';
+ }
+
+ /* get current open file limits */
+
+ if (getrlimit(RLIMIT_NOFILE, &rl) != 0) {
+ store_errmsg("getrlimit() failed", ERRNO);
+ fprintf(stderr, "%s\n", msgbuff);
+ return -3;
+ }
+
+ /* show current open file limits */
+
+#ifdef RLIM_INFINITY
+ if (rl.rlim_cur == RLIM_INFINITY)
+ strcpy(strbuff, "INFINITY");
+ else
+#endif
+ sprintf(strbuff, fmt, rl.rlim_cur);
+ fprintf(stderr, "current soft limit: %s\n", strbuff);
+
+#ifdef RLIM_INFINITY
+ if (rl.rlim_max == RLIM_INFINITY)
+ strcpy(strbuff, "INFINITY");
+ else
+#endif
+ sprintf(strbuff, fmt, rl.rlim_max);
+ fprintf(stderr, "current hard limit: %s\n", strbuff);
+
+ } /* (rl.rlim_cur != rl.rlim_max) */
+
+ /*
+ * test 537 is all about testing libcurl functionality
+ * when the system has nearly exhausted the number of
+ * available file descriptors. Test 537 will try to run
+ * with a very small number of file descriptors available.
+ * This implies that any file descriptor which is open
+ * when the test runs will have a number in the high range
+ * of whatever the system supports.
+ */
+
+ /*
+ * reserve a chunk of memory before opening file descriptors to
+ * avoid a low memory condition once the file descriptors are
+ * open. System conditions that could make the test fail should
+ * be addressed in the precheck phase. This chunk of memory shall
+ * be always free()ed before exiting the rlimit() function so
+ * that it becomes available to the test.
+ */
+
+ for (nitems = i = 1; nitems <= i; i *= 2)
+ nitems = i;
+ if (nitems > 0x7fff)
+ nitems = 0x40000;
+ do {
+ num_open.rlim_max = sizeof(*memchunk) * (size_t)nitems;
+ sprintf(strbuff, fmt, num_open.rlim_max);
+ fprintf(stderr, "allocating memchunk %s byte array\n", strbuff);
+ memchunk = malloc(sizeof(*memchunk) * (size_t)nitems);
+ if (!memchunk) {
+ fprintf(stderr, "memchunk, malloc() failed\n");
+ nitems /= 2;
+ }
+ } while (nitems && !memchunk);
+ if (!memchunk) {
+ store_errmsg("memchunk, malloc() failed", ERRNO);
+ fprintf(stderr, "%s\n", msgbuff);
+ return -4;
+ }
+
+ /* initialize it to fight lazy allocation */
+
+ fprintf(stderr, "initializing memchunk array\n");
+
+ for (i = 0; i < nitems; i++)
+ memchunk[i] = -1;
+
+ /* set the number of file descriptors we will try to open */
+
+#ifdef RLIM_INFINITY
+ if ((rl.rlim_cur > 0) && (rl.rlim_cur != RLIM_INFINITY)) {
+#else
+ if (rl.rlim_cur > 0) {
+#endif
+ /* soft limit minus SAFETY_MARGIN */
+ num_open.rlim_max = rl.rlim_cur - SAFETY_MARGIN;
+ }
+ else {
+ /* a huge number of file descriptors */
+ for (nitems = i = 1; nitems <= i; i *= 2)
+ nitems = i;
+ if (nitems > 0x7fff)
+ nitems = 0x40000;
+ num_open.rlim_max = nitems;
+ }
+
+ /* verify that we won't overflow size_t in malloc() */
+
+ if ((size_t)(num_open.rlim_max) > ((size_t)-1) / sizeof(*fd)) {
+ sprintf(strbuff1, fmt, num_open.rlim_max);
+ sprintf(strbuff, "unable to allocate an array for %s "
+ "file descriptors, would overflow size_t", strbuff1);
+ store_errmsg(strbuff, 0);
+ fprintf(stderr, "%s\n", msgbuff);
+ free(memchunk);
+ return -5;
+ }
+
+ /* allocate array for file descriptors */
+
+ do {
+ sprintf(strbuff, fmt, num_open.rlim_max);
+ fprintf(stderr, "allocating array for %s file descriptors\n", strbuff);
+ fd = malloc(sizeof(*fd) * (size_t)(num_open.rlim_max));
+ if (!fd) {
+ fprintf(stderr, "fd, malloc() failed\n");
+ num_open.rlim_max /= 2;
+ }
+ } while (num_open.rlim_max && !fd);
+ if (!fd) {
+ store_errmsg("fd, malloc() failed", ERRNO);
+ fprintf(stderr, "%s\n", msgbuff);
+ free(memchunk);
+ return -6;
+ }
+
+ /* initialize it to fight lazy allocation */
+
+ fprintf(stderr, "initializing fd array\n");
+
+ for (num_open.rlim_cur = 0;
+ num_open.rlim_cur < num_open.rlim_max;
+ num_open.rlim_cur++)
+ fd[num_open.rlim_cur] = -1;
+
+ sprintf(strbuff, fmt, num_open.rlim_max);
+ fprintf(stderr, "trying to open %s file descriptors\n", strbuff);
+
+ /* open a dummy descriptor */
+
+ fd[0] = open(DEV_NULL, O_RDONLY);
+ if (fd[0] < 0) {
+ sprintf(strbuff, "opening of %s failed", DEV_NULL);
+ store_errmsg(strbuff, ERRNO);
+ fprintf(stderr, "%s\n", msgbuff);
+ free(fd);
+ fd = NULL;
+ free(memchunk);
+ return -7;
+ }
+
+ /* create a bunch of file descriptors */
+
+ for (num_open.rlim_cur = 1;
+ num_open.rlim_cur < num_open.rlim_max;
+ num_open.rlim_cur++) {
+
+ fd[num_open.rlim_cur] = dup(fd[0]);
+
+ if (fd[num_open.rlim_cur] < 0) {
+
+ fd[num_open.rlim_cur] = -1;
+
+ sprintf(strbuff1, fmt, num_open.rlim_cur);
+ sprintf(strbuff, "dup() attempt %s failed", strbuff1);
+ fprintf(stderr, "%s\n", strbuff);
+
+ sprintf(strbuff1, fmt, num_open.rlim_cur);
+ sprintf(strbuff, "fds system limit seems close to %s", strbuff1);
+ fprintf(stderr, "%s\n", strbuff);
+
+ num_open.rlim_max = num_open.rlim_cur - SAFETY_MARGIN;
+
+ num_open.rlim_cur -= num_open.rlim_max;
+ sprintf(strbuff1, fmt, num_open.rlim_cur);
+ sprintf(strbuff, "closing %s file descriptors", strbuff1);
+ fprintf(stderr, "%s\n", strbuff);
+
+ for (num_open.rlim_cur = num_open.rlim_max;
+ fd[num_open.rlim_cur] >= 0;
+ num_open.rlim_cur++) {
+ close(fd[num_open.rlim_cur]);
+ fd[num_open.rlim_cur] = -1;
+ }
+
+ sprintf(strbuff, fmt, num_open.rlim_max);
+ fprintf(stderr, "shrinking array for %s file descriptors\n", strbuff);
+
+ /* we don't care if we can't shrink it */
+
+ tmpfd = realloc(fd, sizeof(*fd) * (size_t)(num_open.rlim_max));
+ if (tmpfd) {
+ fd = tmpfd;
+ tmpfd = NULL;
+ }
+
+ break;
+
+ }
+
+ }
+
+ sprintf(strbuff, fmt, num_open.rlim_max);
+ fprintf(stderr, "%s file descriptors open\n", strbuff);
+
+#if !defined(HAVE_POLL_FINE) && \
+ !defined(USE_WINSOCK) && \
+ !defined(TPF)
+
+ /*
+ * when using select() instead of poll() we cannot test
+ * libcurl functionality with a socket number equal or
+ * greater than FD_SETSIZE. In any case, macro VERIFY_SOCK
+ * in lib/select.c enforces this check and protects libcurl
+ * from a possible crash. The effect of this protection
+ * is that test 537 will always fail, since the actual
+ * call to select() never takes place. We skip test 537
+ * with an indication that select limit would be exceeded.
+ */
+
+ num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN;
+ if (num_open.rlim_max > num_open.rlim_cur) {
+ sprintf(strbuff, "select limit is FD_SETSIZE %d", FD_SETSIZE);
+ store_errmsg(strbuff, 0);
+ fprintf(stderr, "%s\n", msgbuff);
+ close_file_descriptors();
+ free(memchunk);
+ return -8;
+ }
+
+ num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN;
+ for (rl.rlim_cur = 0;
+ rl.rlim_cur < num_open.rlim_max;
+ rl.rlim_cur++) {
+ if ((fd[rl.rlim_cur] > 0) &&
+ ((unsigned int)fd[rl.rlim_cur] > num_open.rlim_cur)) {
+ sprintf(strbuff, "select limit is FD_SETSIZE %d", FD_SETSIZE);
+ store_errmsg(strbuff, 0);
+ fprintf(stderr, "%s\n", msgbuff);
+ close_file_descriptors();
+ free(memchunk);
+ return -9;
+ }
+ }
+
+#endif /* using a FD_SETSIZE bound select() */
+
+ /*
+ * Old or 'backwards compatible' implementations of stdio do not allow
+ * handling of streams with an underlying file descriptor number greater
+ * than 255, even when allowing high numbered file descriptors for sockets.
+ * At this point we have a big number of file descriptors which have been
+ * opened using dup(), so lets test the stdio implementation and discover
+ * if it is capable of fopen()ing some additional files.
+ */
+
+ if (!fopen_works()) {
+ sprintf(strbuff1, fmt, num_open.rlim_max);
+ sprintf(strbuff, "stdio fopen() fails with %s fds open()",
+ strbuff1);
+ fprintf(stderr, "%s\n", msgbuff);
+ sprintf(strbuff, "stdio fopen() fails with lots of fds open()");
+ store_errmsg(strbuff, 0);
+ close_file_descriptors();
+ free(memchunk);
+ return -10;
+ }
+
+ /* free the chunk of memory we were reserving so that it
+ becomes becomes available to the test */
+
+ free(memchunk);
+
+ /* close file descriptors unless instructed to keep them */
+
+ if (!keep_open) {
+ close_file_descriptors();
+ }
+
+ return 0;
+}
+
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+
+ if(!strcmp(URL, "check")) {
+ /* used by the test script to ask if we can run this test or not */
+ if(rlimit(FALSE)) {
+ fprintf(stdout, "rlimit problem: %s\n", msgbuff);
+ return 1;
+ }
+ return 0; /* sure, run this! */
+ }
+
+ if (rlimit(TRUE)) {
+ /* failure */
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* run the test with the bunch of open file descriptors
+ and close them all once the test is over */
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ close_file_descriptors();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ close_file_descriptors();
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ close_file_descriptors();
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
+
+#else /* defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) */
+
+int test(char *URL)
+{
+ (void)URL;
+ printf("system lacks necessary system function(s)");
+ return 1; /* skip test */
+}
+
+#endif /* defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) */
diff --git a/tests/libtest/lib539.c b/tests/libtest/lib539.c
new file mode 100644
index 000000000..923893fb2
--- /dev/null
+++ b/tests/libtest/lib539.c
@@ -0,0 +1,92 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+ char *newURL = NULL;
+ struct curl_slist *slist = NULL;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /*
+ * Begin with cURL set to use a single CWD to the URL's directory.
+ */
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+ test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_SINGLECWD);
+
+ res = curl_easy_perform(curl);
+
+ /*
+ * Change the FTP_FILEMETHOD option to use full paths rather than a CWD
+ * command. Alter the URL's path a bit, appending a "./". Use an innocuous
+ * QUOTE command, after which cURL will CWD to ftp_conn->entrypath and then
+ * (on the next call to ftp_statemach_act) find a non-zero ftpconn->dirdepth
+ * even though no directories are stored in the ftpconn->dirs array (after a
+ * call to freedirs).
+ */
+ newURL = malloc(strlen(URL) + 3);
+ if (newURL == NULL) {
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+ newURL = strcat(strcpy(newURL, URL), "./");
+
+ slist = curl_slist_append (NULL, "SYST");
+ if (slist == NULL) {
+ free(newURL);
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_URL, newURL);
+ test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_NOCWD);
+ test_setopt(curl, CURLOPT_QUOTE, slist);
+
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ curl_slist_free_all(slist);
+ if(newURL)
+ free(newURL);
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
diff --git a/tests/libtest/lib540.c b/tests/libtest/lib540.c
new file mode 100644
index 000000000..ac0ebe60b
--- /dev/null
+++ b/tests/libtest/lib540.c
@@ -0,0 +1,248 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+/* This is the 'proxyauth.c' test app posted by Shmulik Regev on the libcurl
+ * mailing list on 10 Jul 2007, converted to a test case.
+ *
+ * argv1 = URL
+ * argv2 = proxy
+ * argv3 = proxyuser:password
+ * argv4 = host name to use for the custom Host: header
+ */
+
+#include "test.h"
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+#define PROXY libtest_arg2
+#define PROXYUSERPWD libtest_arg3
+#define HOST test_argv[4]
+
+#define NUM_HANDLES 2
+
+CURL *eh[NUM_HANDLES];
+
+static int init(int num, CURLM *cm, const char* url, const char* userpwd,
+ struct curl_slist *headers)
+{
+ int res = 0;
+
+ res_easy_init(eh[num]);
+ if(res)
+ goto init_failed;
+
+ res_easy_setopt(eh[num], CURLOPT_URL, url);
+ if(res)
+ goto init_failed;
+
+ res_easy_setopt(eh[num], CURLOPT_PROXY, PROXY);
+ if(res)
+ goto init_failed;
+
+ res_easy_setopt(eh[num], CURLOPT_PROXYUSERPWD, userpwd);
+ if(res)
+ goto init_failed;
+
+ res_easy_setopt(eh[num], CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
+ if(res)
+ goto init_failed;
+
+ res_easy_setopt(eh[num], CURLOPT_VERBOSE, 1L);
+ if(res)
+ goto init_failed;
+
+ res_easy_setopt(eh[num], CURLOPT_HEADER, 1L);
+ if(res)
+ goto init_failed;
+
+ res_easy_setopt(eh[num], CURLOPT_HTTPHEADER, headers); /* custom Host: */
+ if(res)
+ goto init_failed;
+
+ res_multi_add_handle(cm, eh[num]);
+ if(res)
+ goto init_failed;
+
+ return 0; /* success */
+
+init_failed:
+
+ curl_easy_cleanup(eh[num]);
+ eh[num] = NULL;
+
+ return res; /* failure */
+}
+
+static int loop(int num, CURLM *cm, const char* url, const char* userpwd,
+ struct curl_slist *headers)
+{
+ CURLMsg *msg;
+ long L;
+ int Q, U = -1;
+ fd_set R, W, E;
+ struct timeval T;
+ int res = 0;
+
+ res = init(num, cm, url, userpwd, headers);
+ if(res)
+ return res;
+
+ while (U) {
+
+ int M = -99;
+
+ res_multi_perform(cm, &U);
+ if(res)
+ return res;
+
+ res_test_timedout();
+ if(res)
+ return res;
+
+ if (U) {
+ FD_ZERO(&R);
+ FD_ZERO(&W);
+ FD_ZERO(&E);
+
+ res_multi_fdset(cm, &R, &W, &E, &M);
+ if(res)
+ return res;
+
+ /* At this point, M is guaranteed to be greater or equal than -1. */
+
+ res_multi_timeout(cm, &L);
+ if(res)
+ return res;
+
+ /* At this point, L is guaranteed to be greater or equal than -1. */
+
+ if(L != -1) {
+ int itimeout = (L > (long)INT_MAX) ? INT_MAX : (int)L;
+ T.tv_sec = itimeout/1000;
+ T.tv_usec = (itimeout%1000)*1000;
+ }
+ else {
+ T.tv_sec = 5;
+ T.tv_usec = 0;
+ }
+
+ res_select_test(M+1, &R, &W, &E, &T);
+ if(res)
+ return res;
+ }
+
+ while((msg = curl_multi_info_read(cm, &Q)) != NULL) {
+ if(msg->msg == CURLMSG_DONE) {
+ int i;
+ CURL *e = msg->easy_handle;
+ fprintf(stderr, "R: %d - %s\n", (int)msg->data.result,
+ curl_easy_strerror(msg->data.result));
+ curl_multi_remove_handle(cm, e);
+ curl_easy_cleanup(e);
+ for(i=0; i < NUM_HANDLES; i++) {
+ if(eh[i] == e) {
+ eh[i] = NULL;
+ break;
+ }
+ }
+ }
+ else
+ fprintf(stderr, "E: CURLMsg (%d)\n", (int)msg->msg);
+ }
+
+ res_test_timedout();
+ if(res)
+ return res;
+ }
+
+ return 0; /* success */
+}
+
+int test(char *URL)
+{
+ CURLM *cm = NULL;
+ struct curl_slist *headers = NULL;
+ char buffer[246]; /* naively fixed-size */
+ int res = 0;
+ int i;
+
+ for(i=0; i < NUM_HANDLES; i++)
+ eh[i] = NULL;
+
+ start_test_timing();
+
+ if(test_argc < 4)
+ return 99;
+
+ sprintf(buffer, "Host: %s", HOST);
+
+ /* now add a custom Host: header */
+ headers = curl_slist_append(headers, buffer);
+ if(!headers) {
+ fprintf(stderr, "curl_slist_append() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ res_global_init(CURL_GLOBAL_ALL);
+ if(res) {
+ curl_slist_free_all(headers);
+ return res;
+ }
+
+ res_multi_init(cm);
+ if(res) {
+ curl_global_cleanup();
+ curl_slist_free_all(headers);
+ return res;
+ }
+
+ res = loop(0, cm, URL, PROXYUSERPWD, headers);
+ if(res)
+ goto test_cleanup;
+
+ fprintf(stderr, "lib540: now we do the request again\n");
+
+ res = loop(1, cm, URL, PROXYUSERPWD, headers);
+
+test_cleanup:
+
+ /* proper cleanup sequence - type PB */
+
+ for(i=0; i < NUM_HANDLES; i++) {
+ curl_multi_remove_handle(cm, eh[i]);
+ curl_easy_cleanup(eh[i]);
+ }
+
+ curl_multi_cleanup(cm);
+ curl_global_cleanup();
+
+ curl_slist_free_all(headers);
+
+ return res;
+}
diff --git a/tests/libtest/lib541.c b/tests/libtest/lib541.c
new file mode 100644
index 000000000..5fe8dd8ad
--- /dev/null
+++ b/tests/libtest/lib541.c
@@ -0,0 +1,117 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include "memdebug.h"
+
+/*
+ * Two FTP uploads, the second with no content sent.
+ */
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res = CURLE_OK;
+ FILE *hd_src ;
+ int hd ;
+ struct_stat file_info;
+ int error;
+
+ if (!libtest_arg2) {
+ fprintf(stderr, "Usage: <url> <file-to-upload>\n");
+ return -1;
+ }
+
+ hd_src = fopen(libtest_arg2, "rb");
+ if(NULL == hd_src) {
+ error = ERRNO;
+ fprintf(stderr, "fopen() failed with error: %d %s\n",
+ error, strerror(error));
+ fprintf(stderr, "Error opening file: %s\n", libtest_arg2);
+ return -2; /* if this happens things are major weird */
+ }
+
+ /* get the file size of the local file */
+ hd = fstat(fileno(hd_src), &file_info);
+ if(hd == -1) {
+ /* can't open file, bail out */
+ error = ERRNO;
+ fprintf(stderr, "fstat() failed with error: %d %s\n",
+ error, strerror(error));
+ fprintf(stderr, "ERROR: cannot open file %s\n", libtest_arg2);
+ fclose(hd_src);
+ return -1;
+ }
+
+ if(! file_info.st_size) {
+ fprintf(stderr, "ERROR: file %s has zero size!\n", libtest_arg2);
+ fclose(hd_src);
+ return -4;
+ }
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ fclose(hd_src);
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* get a curl handle */
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ fclose(hd_src);
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* enable uploading */
+ test_setopt(curl, CURLOPT_UPLOAD, 1L);
+
+ /* enable verbose */
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* specify target */
+ test_setopt(curl,CURLOPT_URL, URL);
+
+ /* now specify which file to upload */
+ test_setopt(curl, CURLOPT_INFILE, hd_src);
+
+ /* Now run off and do what you've been told! */
+ res = curl_easy_perform(curl);
+
+ /* and now upload the exact same again, but without rewinding so it already
+ is at end of file */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ /* close the local file */
+ fclose(hd_src);
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib542.c b/tests/libtest/lib542.c
new file mode 100644
index 000000000..84f493f3e
--- /dev/null
+++ b/tests/libtest/lib542.c
@@ -0,0 +1,72 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include "memdebug.h"
+
+/*
+ * FTP get with NOBODY but no HEADER
+ */
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res = CURLE_OK;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* get a curl handle */
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* enable verbose */
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* enable NOBODY */
+ test_setopt(curl, CURLOPT_NOBODY, 1L);
+
+ /* disable HEADER */
+ test_setopt(curl, CURLOPT_HEADER, 0L);
+
+ /* specify target */
+ test_setopt(curl,CURLOPT_URL, URL);
+
+ /* Now run off and do what you've been told! */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib543.c b/tests/libtest/lib543.c
new file mode 100644
index 000000000..08d9c4544
--- /dev/null
+++ b/tests/libtest/lib543.c
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+/* Based on Alex Fishman's bug report on September 30, 2007 */
+
+#include "test.h"
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ unsigned char a[] = {0x9c, 0x26, 0x4b, 0x3d, 0x49, 0x4, 0xa1, 0x1,
+ 0xe0, 0xd8, 0x7c, 0x20, 0xb7, 0xef, 0x53, 0x29, 0xfa,
+ 0x1d, 0x57, 0xe1};
+
+ CURL *easy;
+ int asize;
+ char *s;
+ (void)URL;
+
+ if ((easy = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ asize = (int)sizeof(a);
+
+ s = curl_easy_escape(easy, (char*)a, asize);
+
+ printf("%s\n", s);
+
+ curl_free(s);
+ curl_easy_cleanup(easy);
+
+ return 0;
+}
diff --git a/tests/libtest/lib544.c b/tests/libtest/lib544.c
new file mode 100644
index 000000000..b766187f2
--- /dev/null
+++ b/tests/libtest/lib544.c
@@ -0,0 +1,78 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+static char teststring[] =
+#ifdef CURL_DOES_CONVERSIONS
+ /* ASCII representation with escape sequences for non-ASCII platforms */
+ "\x54\x68\x69\x73\x00\x20\x69\x73\x20\x74\x65\x73\x74\x20\x62\x69\x6e\x61"
+ "\x72\x79\x20\x64\x61\x74\x61\x20\x77\x69\x74\x68\x20\x61\x6e\x20\x65\x6d"
+ "\x62\x65\x64\x64\x65\x64\x20\x4e\x55\x4c\x20\x62\x79\x74\x65\x0a";
+#else
+ "This\0 is test binary data with an embedded NUL byte\n";
+#endif
+
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res=CURLE_OK;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* First set the URL that is about to receive our POST. */
+ test_setopt(curl, CURLOPT_URL, URL);
+
+#ifdef LIB545
+ test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) sizeof teststring - 1);
+#endif
+
+ test_setopt(curl, CURLOPT_COPYPOSTFIELDS, teststring);
+
+ test_setopt(curl, CURLOPT_VERBOSE, 1L); /* show verbose for debug */
+ test_setopt(curl, CURLOPT_HEADER, 1L); /* include header */
+
+ /* Update the original data to detect non-copy. */
+ strcpy(teststring, "FAIL");
+
+ /* Now, this is a POST request with binary 0 embedded in POST data. */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
diff --git a/tests/libtest/lib547.c b/tests/libtest/lib547.c
new file mode 100644
index 000000000..c82bc3f23
--- /dev/null
+++ b/tests/libtest/lib547.c
@@ -0,0 +1,129 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+/* argv1 = URL
+ * argv2 = proxy
+ * argv3 = proxyuser:password
+ */
+
+#include "test.h"
+
+#include "memdebug.h"
+
+#ifdef CURL_DOES_CONVERSIONS
+ /* ASCII representation with escape sequences for non-ASCII platforms */
+# define UPLOADTHIS "\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x62" \
+ "\x6c\x75\x72\x62\x20\x77\x65\x20\x77\x61\x6e\x74\x20" \
+ "\x74\x6f\x20\x75\x70\x6c\x6f\x61\x64\x0a"
+#else
+# define UPLOADTHIS "this is the blurb we want to upload\n"
+#endif
+
+#ifndef LIB548
+static size_t readcallback(void *ptr,
+ size_t size,
+ size_t nmemb,
+ void *clientp)
+{
+ int *counter = (int *)clientp;
+
+ if(*counter) {
+ /* only do this once and then require a clearing of this */
+ fprintf(stderr, "READ ALREADY DONE!\n");
+ return 0;
+ }
+ (*counter)++; /* bump */
+
+ if(size * nmemb > strlen(UPLOADTHIS)) {
+ fprintf(stderr, "READ!\n");
+ strcpy(ptr, UPLOADTHIS);
+ return strlen(UPLOADTHIS);
+ }
+ fprintf(stderr, "READ NOT FINE!\n");
+ return 0;
+}
+static curlioerr ioctlcallback(CURL *handle,
+ int cmd,
+ void *clientp)
+{
+ int *counter = (int *)clientp;
+ (void)handle; /* unused */
+ if(cmd == CURLIOCMD_RESTARTREAD) {
+ fprintf(stderr, "REWIND!\n");
+ *counter = 0; /* clear counter to make the read callback restart */
+ }
+ return CURLIOE_OK;
+}
+
+
+
+#endif
+
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+#ifndef LIB548
+ int counter=0;
+#endif
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+#ifdef LIB548
+ /* set the data to POST with a mere pointer to a zero-terminated string */
+ test_setopt(curl, CURLOPT_POSTFIELDS, UPLOADTHIS);
+#else
+ /* 547 style, which means reading the POST data from a callback */
+ test_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctlcallback);
+ test_setopt(curl, CURLOPT_IOCTLDATA, &counter);
+ test_setopt(curl, CURLOPT_READFUNCTION, readcallback);
+ test_setopt(curl, CURLOPT_READDATA, &counter);
+ /* We CANNOT do the POST fine without setting the size (or choose chunked)! */
+ test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(UPLOADTHIS));
+#endif
+ test_setopt(curl, CURLOPT_POST, 1L);
+ test_setopt(curl, CURLOPT_PROXY, libtest_arg2);
+ test_setopt(curl, CURLOPT_PROXYUSERPWD, libtest_arg3);
+ test_setopt(curl, CURLOPT_PROXYAUTH,
+ (long) (CURLAUTH_NTLM | CURLAUTH_DIGEST | CURLAUTH_BASIC) );
+
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
+
diff --git a/tests/libtest/lib549.c b/tests/libtest/lib549.c
new file mode 100644
index 000000000..a1568c88f
--- /dev/null
+++ b/tests/libtest/lib549.c
@@ -0,0 +1,65 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+/* argv1 = URL
+ * argv2 = proxy
+ * argv3 = non-zero means ASCII transfer
+ */
+
+#include "test.h"
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_PROXY, libtest_arg2);
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_PROXY_TRANSFER_MODE, 1L);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+ if(libtest_arg3) {
+ /* enable ascii/text mode */
+ test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L);
+ }
+
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
+
diff --git a/tests/libtest/lib552.c b/tests/libtest/lib552.c
new file mode 100644
index 000000000..2cc942ad4
--- /dev/null
+++ b/tests/libtest/lib552.c
@@ -0,0 +1,220 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+/* argv1 = URL
+ * argv2 = proxy with embedded user+password
+ */
+
+#include "test.h"
+
+#include "warnless.h"
+#include "memdebug.h"
+
+struct data {
+ char trace_ascii; /* 1 or 0 */
+};
+
+static
+void dump(const char *text,
+ FILE *stream, unsigned char *ptr, size_t size,
+ char nohex)
+{
+ size_t i;
+ size_t c;
+
+ unsigned int width=0x10;
+
+ if(nohex)
+ /* without the hex output, we can fit more on screen */
+ width = 0x40;
+
+ fprintf(stream, "%s, %d bytes (0x%x)\n", text, (int)size, (int)size);
+
+ for(i=0; i<size; i+= width) {
+
+ fprintf(stream, "%04x: ", (int)i);
+
+ if(!nohex) {
+ /* hex not disabled, show it */
+ for(c = 0; c < width; c++)
+ if(i+c < size)
+ fprintf(stream, "%02x ", ptr[i+c]);
+ else
+ fputs(" ", stream);
+ }
+
+ for(c = 0; (c < width) && (i+c < size); c++) {
+ /* check for 0D0A; if found, skip past and start a new line of output */
+ if (nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) {
+ i+=(c+2-width);
+ break;
+ }
+ fprintf(stream, "%c",
+ (ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.');
+ /* check again for 0D0A, to avoid an extra \n if it's at width */
+ if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) {
+ i+=(c+3-width);
+ break;
+ }
+ }
+ fputc('\n', stream); /* newline */
+ }
+ fflush(stream);
+}
+
+static
+int my_trace(CURL *handle, curl_infotype type,
+ char *data, size_t size,
+ void *userp)
+{
+ struct data *config = (struct data *)userp;
+ const char *text;
+ (void)handle; /* prevent compiler warning */
+
+ switch (type) {
+ case CURLINFO_TEXT:
+ fprintf(stderr, "== Info: %s", (char *)data);
+ default: /* in case a new one is introduced to shock us */
+ return 0;
+
+ case CURLINFO_HEADER_OUT:
+ text = "=> Send header";
+ break;
+ case CURLINFO_DATA_OUT:
+ text = "=> Send data";
+ break;
+ case CURLINFO_SSL_DATA_OUT:
+ text = "=> Send SSL data";
+ break;
+ case CURLINFO_HEADER_IN:
+ text = "<= Recv header";
+ break;
+ case CURLINFO_DATA_IN:
+ text = "<= Recv data";
+ break;
+ case CURLINFO_SSL_DATA_IN:
+ text = "<= Recv SSL data";
+ break;
+ }
+
+ dump(text, stderr, (unsigned char *)data, size, config->trace_ascii);
+ return 0;
+}
+
+
+static size_t current_offset = 0;
+static char databuf[70000]; /* MUST be more than 64k OR MAX_INITIAL_POST_SIZE */
+
+static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ size_t amount = nmemb * size; /* Total bytes curl wants */
+ size_t available = sizeof(databuf) - current_offset; /* What we have to give */
+ size_t given = amount < available ? amount : available; /* What is given */
+ (void)stream;
+ memcpy(ptr, databuf + current_offset, given);
+ current_offset += given;
+ return given;
+}
+
+
+static size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ int amount = curlx_uztosi(size * nmemb);
+ printf("%.*s", amount, (char *)ptr);
+ (void)stream;
+ return size * nmemb;
+}
+
+
+static curlioerr ioctl_callback(CURL * handle, int cmd, void *clientp)
+{
+ (void)clientp;
+ if (cmd == CURLIOCMD_RESTARTREAD ) {
+ printf("APPLICATION: recieved a CURLIOCMD_RESTARTREAD request\n");
+ printf("APPLICATION: ** REWINDING! **\n");
+ current_offset = 0;
+ return CURLIOE_OK;
+ }
+ (void)handle;
+ return CURLIOE_UNKNOWNCMD;
+}
+
+
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res = CURLE_OUT_OF_MEMORY;
+ struct data config;
+ size_t i;
+ static const char fill[] = "test data";
+
+ config.trace_ascii = 1; /* enable ascii tracing */
+
+ if((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
+ test_setopt(curl, CURLOPT_DEBUGDATA, &config);
+ /* the DEBUGFUNCTION has no effect until we enable VERBOSE */
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* setup repeated data string */
+ for (i=0; i < sizeof(databuf); ++i)
+ databuf[i] = fill[i % sizeof fill];
+
+ /* Post */
+ test_setopt(curl, CURLOPT_POST, 1L);
+
+#ifdef CURL_DOES_CONVERSIONS
+ /* Convert the POST data to ASCII */
+ test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L);
+#endif
+
+ /* Setup read callback */
+ test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) sizeof(databuf));
+ test_setopt(curl, CURLOPT_READFUNCTION, read_callback);
+
+ /* Write callback */
+ test_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
+
+ /* Ioctl function */
+ test_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_callback);
+
+ test_setopt(curl, CURLOPT_PROXY, libtest_arg2);
+
+ test_setopt(curl, CURLOPT_URL, URL);
+
+ /* Accept any auth. But for this bug configure proxy with DIGEST, basic might work too, not NTLM */
+ test_setopt(curl, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
+
+ res = curl_easy_perform(curl);
+ fprintf(stderr, "curl_easy_perform = %d\n", (int)res);
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+ return (int)res;
+}
diff --git a/tests/libtest/lib553.c b/tests/libtest/lib553.c
new file mode 100644
index 000000000..cb1cefd5e
--- /dev/null
+++ b/tests/libtest/lib553.c
@@ -0,0 +1,114 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+
+/* This test case and code is based on the bug recipe Joe Malicki provided for
+ * bug report #1871269, fixed on Jan 14 2008 before the 7.18.0 release.
+ */
+
+#include "test.h"
+
+#include "memdebug.h"
+
+#define POSTLEN 40960
+
+static size_t myreadfunc(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ static size_t total=POSTLEN;
+ static char buf[1024];
+ (void)stream;
+
+ memset(buf, 'A', sizeof(buf));
+
+ size *= nmemb;
+ if (size > total)
+ size = total;
+
+ if(size > sizeof(buf))
+ size = sizeof(buf);
+
+ memcpy(ptr, buf, size);
+ total -= size;
+ return size;
+}
+
+#define NUM_HEADERS 8
+#define SIZE_HEADERS 5000
+
+static char buf[SIZE_HEADERS + 100];
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res = CURLE_FAILED_INIT;
+ int i;
+ struct curl_slist *headerlist=NULL, *hl;
+
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ for (i = 0; i < NUM_HEADERS; i++) {
+ int len = sprintf(buf, "Header%d: ", i);
+ memset(&buf[len], 'A', SIZE_HEADERS);
+ buf[len + SIZE_HEADERS]=0; /* zero terminate */
+ hl = curl_slist_append(headerlist, buf);
+ if (!hl)
+ goto test_cleanup;
+ headerlist = hl;
+ }
+
+ hl = curl_slist_append(headerlist, "Expect: ");
+ if (!hl)
+ goto test_cleanup;
+ headerlist = hl;
+
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
+ test_setopt(curl, CURLOPT_POST, 1L);
+#ifdef CURL_DOES_CONVERSIONS
+ /* Convert the POST data to ASCII */
+ test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L);
+#endif
+ test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)POSTLEN);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+ test_setopt(curl, CURLOPT_READFUNCTION, myreadfunc);
+
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+
+ curl_slist_free_all(headerlist);
+
+ curl_global_cleanup();
+
+ return (int)res;
+}
diff --git a/tests/libtest/lib554.c b/tests/libtest/lib554.c
new file mode 100644
index 000000000..0596f3ef1
--- /dev/null
+++ b/tests/libtest/lib554.c
@@ -0,0 +1,199 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+static char data[]=
+#ifdef CURL_DOES_CONVERSIONS
+ /* ASCII representation with escape sequences for non-ASCII platforms */
+ "\x74\x68\x69\x73\x20\x69\x73\x20\x77\x68\x61\x74\x20\x77\x65\x20\x70"
+ "\x6f\x73\x74\x20\x74\x6f\x20\x74\x68\x65\x20\x73\x69\x6c\x6c\x79\x20"
+ "\x77\x65\x62\x20\x73\x65\x72\x76\x65\x72\x0a";
+#else
+ "this is what we post to the silly web server\n";
+#endif
+
+struct WriteThis {
+ char *readptr;
+ size_t sizeleft;
+};
+
+static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
+{
+#ifdef LIB587
+ (void)ptr;
+ (void)size;
+ (void)nmemb;
+ (void)userp;
+ return CURL_READFUNC_ABORT;
+#else
+
+ struct WriteThis *pooh = (struct WriteThis *)userp;
+
+ if(size*nmemb < 1)
+ return 0;
+
+ if(pooh->sizeleft) {
+ *(char *)ptr = pooh->readptr[0]; /* copy one single byte */
+ pooh->readptr++; /* advance pointer */
+ pooh->sizeleft--; /* less data left */
+ return 1; /* we return 1 byte at a time! */
+ }
+
+ return 0; /* no more data left to deliver */
+#endif
+}
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res=CURLE_OK;
+ CURLFORMcode formrc;
+
+ struct curl_httppost *formpost=NULL;
+ struct curl_httppost *lastptr=NULL;
+ struct WriteThis pooh;
+ struct WriteThis pooh2;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ pooh.readptr = data;
+ pooh.sizeleft = strlen(data);
+
+ /* Fill in the file upload field */
+ formrc = curl_formadd(&formpost,
+ &lastptr,
+ CURLFORM_COPYNAME, "sendfile",
+ CURLFORM_STREAM, &pooh,
+ CURLFORM_CONTENTSLENGTH, (long)pooh.sizeleft,
+ CURLFORM_FILENAME, "postit2.c",
+ CURLFORM_END);
+
+ if(formrc)
+ printf("curl_formadd(1) = %d\n", (int)formrc);
+
+ /* Now add the same data with another name and make it not look like
+ a file upload but still using the callback */
+
+ pooh2.readptr = data;
+ pooh2.sizeleft = strlen(data);
+
+ /* Fill in the file upload field */
+ formrc = curl_formadd(&formpost,
+ &lastptr,
+ CURLFORM_COPYNAME, "callbackdata",
+ CURLFORM_STREAM, &pooh2,
+ CURLFORM_CONTENTSLENGTH, (long)pooh2.sizeleft,
+ CURLFORM_END);
+
+ if(formrc)
+ printf("curl_formadd(1) = %d\n", (int)formrc);
+
+ /* Fill in the filename field */
+ formrc = curl_formadd(&formpost,
+ &lastptr,
+ CURLFORM_COPYNAME, "filename",
+#ifdef CURL_DOES_CONVERSIONS
+ /* ASCII representation with escape
+ sequences for non-ASCII platforms */
+ CURLFORM_COPYCONTENTS,
+ "\x70\x6f\x73\x74\x69\x74\x32\x2e\x63",
+#else
+ CURLFORM_COPYCONTENTS, "postit2.c",
+#endif
+ CURLFORM_END);
+
+ if(formrc)
+ printf("curl_formadd(2) = %d\n", (int)formrc);
+
+ /* Fill in a submit field too */
+ formrc = curl_formadd(&formpost,
+ &lastptr,
+ CURLFORM_COPYNAME, "submit",
+#ifdef CURL_DOES_CONVERSIONS
+ /* ASCII representation with escape
+ sequences for non-ASCII platforms */
+ CURLFORM_COPYCONTENTS, "\x73\x65\x6e\x64",
+#else
+ CURLFORM_COPYCONTENTS, "send",
+#endif
+ CURLFORM_END);
+
+ if(formrc)
+ printf("curl_formadd(3) = %d\n", (int)formrc);
+
+ formrc = curl_formadd(&formpost, &lastptr,
+ CURLFORM_COPYNAME, "somename",
+ CURLFORM_BUFFER, "somefile.txt",
+ CURLFORM_BUFFERPTR, "blah blah",
+ CURLFORM_BUFFERLENGTH, (long)9,
+ CURLFORM_END);
+
+ if(formrc)
+ printf("curl_formadd(4) = %d\n", (int)formrc);
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_formfree(formpost);
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* First set the URL that is about to receive our POST. */
+ test_setopt(curl, CURLOPT_URL, URL);
+
+ /* Now specify we want to POST data */
+ test_setopt(curl, CURLOPT_POST, 1L);
+
+ /* Set the expected POST size */
+ test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)pooh.sizeleft);
+
+ /* we want to use our own read function */
+ test_setopt(curl, CURLOPT_READFUNCTION, read_callback);
+
+ /* send a multi-part formpost */
+ test_setopt(curl, CURLOPT_HTTPPOST, formpost);
+
+ /* get verbose debug output please */
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* include headers in the output */
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ /* now cleanup the formpost chain */
+ curl_formfree(formpost);
+
+ return res;
+}
diff --git a/tests/libtest/lib555.c b/tests/libtest/lib555.c
new file mode 100644
index 000000000..49a81bf57
--- /dev/null
+++ b/tests/libtest/lib555.c
@@ -0,0 +1,159 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+
+/* This test case is supposed to be identical to 547 except that this uses the
+ * multi interface and 547 is easy interface.
+ *
+ * argv1 = URL
+ * argv2 = proxy
+ * argv3 = proxyuser:password
+ */
+
+#include "test.h"
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+#define UPLOADTHIS "this is the blurb we want to upload\n"
+
+static size_t readcallback(void *ptr,
+ size_t size,
+ size_t nmemb,
+ void *clientp)
+{
+ int *counter = (int *)clientp;
+
+ if(*counter) {
+ /* only do this once and then require a clearing of this */
+ fprintf(stderr, "READ ALREADY DONE!\n");
+ return 0;
+ }
+ (*counter)++; /* bump */
+
+ if(size * nmemb > strlen(UPLOADTHIS)) {
+ fprintf(stderr, "READ!\n");
+ strcpy(ptr, UPLOADTHIS);
+ return strlen(UPLOADTHIS);
+ }
+ fprintf(stderr, "READ NOT FINE!\n");
+ return 0;
+}
+static curlioerr ioctlcallback(CURL *handle,
+ int cmd,
+ void *clientp)
+{
+ int *counter = (int *)clientp;
+ (void)handle; /* unused */
+ if(cmd == CURLIOCMD_RESTARTREAD) {
+ fprintf(stderr, "REWIND!\n");
+ *counter = 0; /* clear counter to make the read callback restart */
+ }
+ return CURLIOE_OK;
+}
+
+
+int test(char *URL)
+{
+ int res = 0;
+ CURL *curl = NULL;
+ int counter=0;
+ CURLM *m = NULL;
+ int running=1;
+
+ start_test_timing();
+
+ global_init(CURL_GLOBAL_ALL);
+
+ easy_init(curl);
+
+ easy_setopt(curl, CURLOPT_URL, URL);
+ easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+ easy_setopt(curl, CURLOPT_HEADER, 1L);
+
+ /* read the POST data from a callback */
+ easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctlcallback);
+ easy_setopt(curl, CURLOPT_IOCTLDATA, &counter);
+ easy_setopt(curl, CURLOPT_READFUNCTION, readcallback);
+ easy_setopt(curl, CURLOPT_READDATA, &counter);
+ /* We CANNOT do the POST fine without setting the size (or choose chunked)! */
+ easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(UPLOADTHIS));
+
+ easy_setopt(curl, CURLOPT_POST, 1L);
+#ifdef CURL_DOES_CONVERSIONS
+ /* Convert the POST data to ASCII. */
+ easy_setopt(curl, CURLOPT_TRANSFERTEXT, 1L);
+#endif
+ easy_setopt(curl, CURLOPT_PROXY, libtest_arg2);
+ easy_setopt(curl, CURLOPT_PROXYUSERPWD, libtest_arg3);
+ easy_setopt(curl, CURLOPT_PROXYAUTH,
+ (long) (CURLAUTH_NTLM | CURLAUTH_DIGEST | CURLAUTH_BASIC) );
+
+ multi_init(m);
+
+ multi_add_handle(m, curl);
+
+ while (running) {
+ struct timeval timeout;
+ fd_set fdread, fdwrite, fdexcep;
+ int maxfd = -99;
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 100000L; /* 100 ms */
+
+ multi_perform(m, &running);
+
+ abort_on_test_timeout();
+
+#ifdef TPF
+ sleep(1); /* avoid ctl-10 dump */
+#endif
+
+ if(!running)
+ break; /* done */
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ multi_fdset(m, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ abort_on_test_timeout();
+ }
+
+test_cleanup:
+
+ /* proper cleanup sequence - type PA */
+
+ curl_multi_remove_handle(m, curl);
+ curl_multi_cleanup(m);
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return res;
+}
+
diff --git a/tests/libtest/lib556.c b/tests/libtest/lib556.c
new file mode 100644
index 000000000..98062209f
--- /dev/null
+++ b/tests/libtest/lib556.c
@@ -0,0 +1,106 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+/* For Windows, mainly (may be moved in a config file?) */
+#ifndef STDIN_FILENO
+ #define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+ #define STDOUT_FILENO 1
+#endif
+#ifndef STDERR_FILENO
+ #define STDERR_FILENO 2
+#endif
+
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_CONNECT_ONLY, 1L);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ res = curl_easy_perform(curl);
+
+ if(!res) {
+ /* we are connected, now get a HTTP document the raw way */
+ const char *request =
+#ifdef CURL_DOES_CONVERSIONS
+ /* ASCII representation with escape sequences for non-ASCII platforms */
+ "\x47\x45\x54\x20\x2f\x35\x35\x36\x20\x48\x54\x54\x50\x2f\x31\x2e"
+ "\x32\x0d\x0a\x48\x6f\x73\x74\x3a\x20\x6e\x69\x6e\x6a\x61\x0d\x0a"
+ "\x0d\x0a";
+#else
+ "GET /556 HTTP/1.2\r\n"
+ "Host: ninja\r\n\r\n";
+#endif
+ size_t iolen;
+ char buf[1024];
+
+ res = curl_easy_send(curl, request, strlen(request), &iolen);
+
+ if(!res) {
+ /* we assume that sending always work */
+ size_t total=0;
+
+ do {
+ /* busy-read like crazy */
+ res = curl_easy_recv(curl, buf, 1024, &iolen);
+
+#ifdef TPF
+ sleep(1); /* avoid ctl-10 dump */
+#endif
+
+ if(iolen) {
+ /* send received stuff to stdout */
+ if(!write(STDOUT_FILENO, buf, iolen))
+ break;
+ }
+ total += iolen;
+
+ } while(((res == CURLE_OK) || (res == CURLE_AGAIN)) && (total < 129));
+ }
+ }
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
+
diff --git a/tests/libtest/lib557.c b/tests/libtest/lib557.c
new file mode 100644
index 000000000..dc3bcae86
--- /dev/null
+++ b/tests/libtest/lib557.c
@@ -0,0 +1,1401 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+
+/*
+ * The purpose of this test is to minimally exercise libcurl's internal
+ * curl_m*printf formatting capabilities and handling of some data types.
+ */
+
+#include "test.h"
+
+#include <curl/mprintf.h>
+
+#include "memdebug.h"
+
+
+#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
+# define MPRNT_SUFFIX_CURL_OFF_T LL
+#else
+# define MPRNT_SUFFIX_CURL_OFF_T L
+#endif
+
+
+#ifdef CURL_ISOCPP
+# define MPRNT_OFF_T_C_HELPER2(Val,Suffix) Val ## Suffix
+#else
+# define MPRNT_OFF_T_C_HELPER2(Val,Suffix) Val/**/Suffix
+#endif
+#define MPRNT_OFF_T_C_HELPER1(Val,Suffix) MPRNT_OFF_T_C_HELPER2(Val,Suffix)
+#define MPRNT_OFF_T_C(Val) MPRNT_OFF_T_C_HELPER1(Val,MPRNT_SUFFIX_CURL_OFF_T)
+
+
+#define BUFSZ 256
+#define USHORT_TESTS_ARRSZ 1 + 100
+#define SSHORT_TESTS_ARRSZ 1 + 100
+#define UINT_TESTS_ARRSZ 1 + 100
+#define SINT_TESTS_ARRSZ 1 + 100
+#define ULONG_TESTS_ARRSZ 1 + 100
+#define SLONG_TESTS_ARRSZ 1 + 100
+#define COFFT_TESTS_ARRSZ 1 + 100
+
+
+struct unsshort_st {
+ unsigned short num; /* unsigned short */
+ const char *expected; /* expected string */
+ char result[BUFSZ]; /* result string */
+};
+
+
+struct sigshort_st {
+ short num; /* signed short */
+ const char *expected; /* expected string */
+ char result[BUFSZ]; /* result string */
+};
+
+
+struct unsint_st {
+ unsigned int num; /* unsigned int */
+ const char *expected; /* expected string */
+ char result[BUFSZ]; /* result string */
+};
+
+
+struct sigint_st {
+ int num; /* signed int */
+ const char *expected; /* expected string */
+ char result[BUFSZ]; /* result string */
+};
+
+
+struct unslong_st {
+ unsigned long num; /* unsigned long */
+ const char *expected; /* expected string */
+ char result[BUFSZ]; /* result string */
+};
+
+
+struct siglong_st {
+ long num; /* signed long */
+ const char *expected; /* expected string */
+ char result[BUFSZ]; /* result string */
+};
+
+
+struct curloff_st {
+ curl_off_t num; /* curl_off_t */
+ const char *expected; /* expected string */
+ char result[BUFSZ]; /* result string */
+};
+
+
+static struct unsshort_st us_test[USHORT_TESTS_ARRSZ];
+static struct sigshort_st ss_test[SSHORT_TESTS_ARRSZ];
+static struct unsint_st ui_test[UINT_TESTS_ARRSZ];
+static struct sigint_st si_test[SINT_TESTS_ARRSZ];
+static struct unslong_st ul_test[ULONG_TESTS_ARRSZ];
+static struct siglong_st sl_test[SLONG_TESTS_ARRSZ];
+static struct curloff_st co_test[COFFT_TESTS_ARRSZ];
+
+
+static int test_unsigned_short_formatting(void)
+{
+ int i, j;
+ int num_ushort_tests;
+ int failed = 0;
+
+#if (SIZEOF_SHORT == 1)
+
+ i=1; us_test[i].num = 0xFFU; us_test[i].expected = "256";
+ i++; us_test[i].num = 0xF0U; us_test[i].expected = "240";
+ i++; us_test[i].num = 0x0FU; us_test[i].expected = "15";
+
+ i++; us_test[i].num = 0xE0U; us_test[i].expected = "224";
+ i++; us_test[i].num = 0x0EU; us_test[i].expected = "14";
+
+ i++; us_test[i].num = 0xC0U; us_test[i].expected = "192";
+ i++; us_test[i].num = 0x0CU; us_test[i].expected = "12";
+
+ i++; us_test[i].num = 0x01U; us_test[i].expected = "1";
+ i++; us_test[i].num = 0x00U; us_test[i].expected = "0";
+
+ num_ushort_tests = i;
+
+#elif (SIZEOF_SHORT == 2)
+
+ i=1; us_test[i].num = 0xFFFFU; us_test[i].expected = "65535";
+ i++; us_test[i].num = 0xFF00U; us_test[i].expected = "65280";
+ i++; us_test[i].num = 0x00FFU; us_test[i].expected = "255";
+
+ i++; us_test[i].num = 0xF000U; us_test[i].expected = "61440";
+ i++; us_test[i].num = 0x0F00U; us_test[i].expected = "3840";
+ i++; us_test[i].num = 0x00F0U; us_test[i].expected = "240";
+ i++; us_test[i].num = 0x000FU; us_test[i].expected = "15";
+
+ i++; us_test[i].num = 0xC000U; us_test[i].expected = "49152";
+ i++; us_test[i].num = 0x0C00U; us_test[i].expected = "3072";
+ i++; us_test[i].num = 0x00C0U; us_test[i].expected = "192";
+ i++; us_test[i].num = 0x000CU; us_test[i].expected = "12";
+
+ i++; us_test[i].num = 0x0001U; us_test[i].expected = "1";
+ i++; us_test[i].num = 0x0000U; us_test[i].expected = "0";
+
+ num_ushort_tests = i;
+
+#elif (SIZEOF_SHORT == 4)
+
+ i=1; us_test[i].num = 0xFFFFFFFFU; us_test[i].expected = "4294967295";
+ i++; us_test[i].num = 0xFFFF0000U; us_test[i].expected = "4294901760";
+ i++; us_test[i].num = 0x0000FFFFU; us_test[i].expected = "65535";
+
+ i++; us_test[i].num = 0xFF000000U; us_test[i].expected = "4278190080";
+ i++; us_test[i].num = 0x00FF0000U; us_test[i].expected = "16711680";
+ i++; us_test[i].num = 0x0000FF00U; us_test[i].expected = "65280";
+ i++; us_test[i].num = 0x000000FFU; us_test[i].expected = "255";
+
+ i++; us_test[i].num = 0xF0000000U; us_test[i].expected = "4026531840";
+ i++; us_test[i].num = 0x0F000000U; us_test[i].expected = "251658240";
+ i++; us_test[i].num = 0x00F00000U; us_test[i].expected = "15728640";
+ i++; us_test[i].num = 0x000F0000U; us_test[i].expected = "983040";
+ i++; us_test[i].num = 0x0000F000U; us_test[i].expected = "61440";
+ i++; us_test[i].num = 0x00000F00U; us_test[i].expected = "3840";
+ i++; us_test[i].num = 0x000000F0U; us_test[i].expected = "240";
+ i++; us_test[i].num = 0x0000000FU; us_test[i].expected = "15";
+
+ i++; us_test[i].num = 0xC0000000U; us_test[i].expected = "3221225472";
+ i++; us_test[i].num = 0x0C000000U; us_test[i].expected = "201326592";
+ i++; us_test[i].num = 0x00C00000U; us_test[i].expected = "12582912";
+ i++; us_test[i].num = 0x000C0000U; us_test[i].expected = "786432";
+ i++; us_test[i].num = 0x0000C000U; us_test[i].expected = "49152";
+ i++; us_test[i].num = 0x00000C00U; us_test[i].expected = "3072";
+ i++; us_test[i].num = 0x000000C0U; us_test[i].expected = "192";
+ i++; us_test[i].num = 0x0000000CU; us_test[i].expected = "12";
+
+ i++; us_test[i].num = 0x00000001U; us_test[i].expected = "1";
+ i++; us_test[i].num = 0x00000000U; us_test[i].expected = "0";
+
+ num_ushort_tests = i;
+
+#endif
+
+ for(i=1; i<=num_ushort_tests; i++) {
+
+ for(j=0; j<BUFSZ; j++)
+ us_test[i].result[j] = 'X';
+ us_test[i].result[BUFSZ-1] = '\0';
+
+ (void)curl_msprintf(us_test[i].result, "%hu", us_test[i].num);
+
+ if(memcmp(us_test[i].result,
+ us_test[i].expected,
+ strlen(us_test[i].expected))) {
+ printf("unsigned short test #%.2d: Failed (Expected: %s Got: %s)\n",
+ i, us_test[i].expected, us_test[i].result);
+ failed++;
+ }
+
+ }
+
+ if(!failed)
+ printf("All curl_mprintf() unsigned short tests OK!\n");
+ else
+ printf("Some curl_mprintf() unsigned short tests Failed!\n");
+
+ return failed;
+}
+
+
+static int test_signed_short_formatting(void)
+{
+ int i, j;
+ int num_sshort_tests;
+ int failed = 0;
+
+#if (SIZEOF_SHORT == 1)
+
+ i=1; ss_test[i].num = 0x7F; ss_test[i].expected = "127";
+
+ i++; ss_test[i].num = 0x70; ss_test[i].expected = "112";
+ i++; ss_test[i].num = 0x07; ss_test[i].expected = "7";
+
+ i++; ss_test[i].num = 0x50; ss_test[i].expected = "80";
+ i++; ss_test[i].num = 0x05; ss_test[i].expected = "5";
+
+ i++; ss_test[i].num = 0x01; ss_test[i].expected = "1";
+ i++; ss_test[i].num = 0x00; ss_test[i].expected = "0";
+
+ i++; ss_test[i].num = -0x7F -1; ss_test[i].expected = "-128";
+
+ i++; ss_test[i].num = -0x70 -1; ss_test[i].expected = "-113";
+ i++; ss_test[i].num = -0x07 -1; ss_test[i].expected = "-8";
+
+ i++; ss_test[i].num = -0x50 -1; ss_test[i].expected = "-81";
+ i++; ss_test[i].num = -0x05 -1; ss_test[i].expected = "-6";
+
+ i++; ss_test[i].num = 0x00 -1; ss_test[i].expected = "-1";
+
+ num_sshort_tests = i;
+
+#elif (SIZEOF_SHORT == 2)
+
+ i=1; ss_test[i].num = 0x7FFF; ss_test[i].expected = "32767";
+ i++; ss_test[i].num = 0x7FFE; ss_test[i].expected = "32766";
+ i++; ss_test[i].num = 0x7FFD; ss_test[i].expected = "32765";
+ i++; ss_test[i].num = 0x7F00; ss_test[i].expected = "32512";
+ i++; ss_test[i].num = 0x07F0; ss_test[i].expected = "2032";
+ i++; ss_test[i].num = 0x007F; ss_test[i].expected = "127";
+
+ i++; ss_test[i].num = 0x7000; ss_test[i].expected = "28672";
+ i++; ss_test[i].num = 0x0700; ss_test[i].expected = "1792";
+ i++; ss_test[i].num = 0x0070; ss_test[i].expected = "112";
+ i++; ss_test[i].num = 0x0007; ss_test[i].expected = "7";
+
+ i++; ss_test[i].num = 0x5000; ss_test[i].expected = "20480";
+ i++; ss_test[i].num = 0x0500; ss_test[i].expected = "1280";
+ i++; ss_test[i].num = 0x0050; ss_test[i].expected = "80";
+ i++; ss_test[i].num = 0x0005; ss_test[i].expected = "5";
+
+ i++; ss_test[i].num = 0x0001; ss_test[i].expected = "1";
+ i++; ss_test[i].num = 0x0000; ss_test[i].expected = "0";
+
+ i++; ss_test[i].num = -0x7FFF -1; ss_test[i].expected = "-32768";
+ i++; ss_test[i].num = -0x7FFE -1; ss_test[i].expected = "-32767";
+ i++; ss_test[i].num = -0x7FFD -1; ss_test[i].expected = "-32766";
+ i++; ss_test[i].num = -0x7F00 -1; ss_test[i].expected = "-32513";
+ i++; ss_test[i].num = -0x07F0 -1; ss_test[i].expected = "-2033";
+ i++; ss_test[i].num = -0x007F -1; ss_test[i].expected = "-128";
+
+ i++; ss_test[i].num = -0x7000 -1; ss_test[i].expected = "-28673";
+ i++; ss_test[i].num = -0x0700 -1; ss_test[i].expected = "-1793";
+ i++; ss_test[i].num = -0x0070 -1; ss_test[i].expected = "-113";
+ i++; ss_test[i].num = -0x0007 -1; ss_test[i].expected = "-8";
+
+ i++; ss_test[i].num = -0x5000 -1; ss_test[i].expected = "-20481";
+ i++; ss_test[i].num = -0x0500 -1; ss_test[i].expected = "-1281";
+ i++; ss_test[i].num = -0x0050 -1; ss_test[i].expected = "-81";
+ i++; ss_test[i].num = -0x0005 -1; ss_test[i].expected = "-6";
+
+ i++; ss_test[i].num = 0x0000 -1; ss_test[i].expected = "-1";
+
+ num_sshort_tests = i;
+
+#elif (SIZEOF_SHORT == 4)
+
+ i=1; ss_test[i].num = 0x7FFFFFFF; ss_test[i].expected = "2147483647";
+ i++; ss_test[i].num = 0x7FFFFFFE; ss_test[i].expected = "2147483646";
+ i++; ss_test[i].num = 0x7FFFFFFD; ss_test[i].expected = "2147483645";
+ i++; ss_test[i].num = 0x7FFF0000; ss_test[i].expected = "2147418112";
+ i++; ss_test[i].num = 0x00007FFF; ss_test[i].expected = "32767";
+
+ i++; ss_test[i].num = 0x7F000000; ss_test[i].expected = "2130706432";
+ i++; ss_test[i].num = 0x007F0000; ss_test[i].expected = "8323072";
+ i++; ss_test[i].num = 0x00007F00; ss_test[i].expected = "32512";
+ i++; ss_test[i].num = 0x0000007F; ss_test[i].expected = "127";
+
+ i++; ss_test[i].num = 0x70000000; ss_test[i].expected = "1879048192";
+ i++; ss_test[i].num = 0x07000000; ss_test[i].expected = "117440512";
+ i++; ss_test[i].num = 0x00700000; ss_test[i].expected = "7340032";
+ i++; ss_test[i].num = 0x00070000; ss_test[i].expected = "458752";
+ i++; ss_test[i].num = 0x00007000; ss_test[i].expected = "28672";
+ i++; ss_test[i].num = 0x00000700; ss_test[i].expected = "1792";
+ i++; ss_test[i].num = 0x00000070; ss_test[i].expected = "112";
+ i++; ss_test[i].num = 0x00000007; ss_test[i].expected = "7";
+
+ i++; ss_test[i].num = 0x50000000; ss_test[i].expected = "1342177280";
+ i++; ss_test[i].num = 0x05000000; ss_test[i].expected = "83886080";
+ i++; ss_test[i].num = 0x00500000; ss_test[i].expected = "5242880";
+ i++; ss_test[i].num = 0x00050000; ss_test[i].expected = "327680";
+ i++; ss_test[i].num = 0x00005000; ss_test[i].expected = "20480";
+ i++; ss_test[i].num = 0x00000500; ss_test[i].expected = "1280";
+ i++; ss_test[i].num = 0x00000050; ss_test[i].expected = "80";
+ i++; ss_test[i].num = 0x00000005; ss_test[i].expected = "5";
+
+ i++; ss_test[i].num = 0x00000001; ss_test[i].expected = "1";
+ i++; ss_test[i].num = 0x00000000; ss_test[i].expected = "0";
+
+ i++; ss_test[i].num = -0x7FFFFFFF -1; ss_test[i].expected = "-2147483648";
+ i++; ss_test[i].num = -0x7FFFFFFE -1; ss_test[i].expected = "-2147483647";
+ i++; ss_test[i].num = -0x7FFFFFFD -1; ss_test[i].expected = "-2147483646";
+ i++; ss_test[i].num = -0x7FFF0000 -1; ss_test[i].expected = "-2147418113";
+ i++; ss_test[i].num = -0x00007FFF -1; ss_test[i].expected = "-32768";
+
+ i++; ss_test[i].num = -0x7F000000 -1; ss_test[i].expected = "-2130706433";
+ i++; ss_test[i].num = -0x007F0000 -1; ss_test[i].expected = "-8323073";
+ i++; ss_test[i].num = -0x00007F00 -1; ss_test[i].expected = "-32513";
+ i++; ss_test[i].num = -0x0000007F -1; ss_test[i].expected = "-128";
+
+ i++; ss_test[i].num = -0x70000000 -1; ss_test[i].expected = "-1879048193";
+ i++; ss_test[i].num = -0x07000000 -1; ss_test[i].expected = "-117440513";
+ i++; ss_test[i].num = -0x00700000 -1; ss_test[i].expected = "-7340033";
+ i++; ss_test[i].num = -0x00070000 -1; ss_test[i].expected = "-458753";
+ i++; ss_test[i].num = -0x00007000 -1; ss_test[i].expected = "-28673";
+ i++; ss_test[i].num = -0x00000700 -1; ss_test[i].expected = "-1793";
+ i++; ss_test[i].num = -0x00000070 -1; ss_test[i].expected = "-113";
+ i++; ss_test[i].num = -0x00000007 -1; ss_test[i].expected = "-8";
+
+ i++; ss_test[i].num = -0x50000000 -1; ss_test[i].expected = "-1342177281";
+ i++; ss_test[i].num = -0x05000000 -1; ss_test[i].expected = "-83886081";
+ i++; ss_test[i].num = -0x00500000 -1; ss_test[i].expected = "-5242881";
+ i++; ss_test[i].num = -0x00050000 -1; ss_test[i].expected = "-327681";
+ i++; ss_test[i].num = -0x00005000 -1; ss_test[i].expected = "-20481";
+ i++; ss_test[i].num = -0x00000500 -1; ss_test[i].expected = "-1281";
+ i++; ss_test[i].num = -0x00000050 -1; ss_test[i].expected = "-81";
+ i++; ss_test[i].num = -0x00000005 -1; ss_test[i].expected = "-6";
+
+ i++; ss_test[i].num = 0x00000000 -1; ss_test[i].expected = "-1";
+
+ num_sshort_tests = i;
+
+#endif
+
+ for(i=1; i<=num_sshort_tests; i++) {
+
+ for(j=0; j<BUFSZ; j++)
+ ss_test[i].result[j] = 'X';
+ ss_test[i].result[BUFSZ-1] = '\0';
+
+ (void)curl_msprintf(ss_test[i].result, "%hd", ss_test[i].num);
+
+ if(memcmp(ss_test[i].result,
+ ss_test[i].expected,
+ strlen(ss_test[i].expected))) {
+ printf("signed short test #%.2d: Failed (Expected: %s Got: %s)\n",
+ i, ss_test[i].expected, ss_test[i].result);
+ failed++;
+ }
+
+ }
+
+ if(!failed)
+ printf("All curl_mprintf() signed short tests OK!\n");
+ else
+ printf("Some curl_mprintf() signed short tests Failed!\n");
+
+ return failed;
+}
+
+
+static int test_unsigned_int_formatting(void)
+{
+ int i, j;
+ int num_uint_tests;
+ int failed = 0;
+
+#if (SIZEOF_INT == 2)
+
+ i=1; ui_test[i].num = 0xFFFFU; ui_test[i].expected = "65535";
+ i++; ui_test[i].num = 0xFF00U; ui_test[i].expected = "65280";
+ i++; ui_test[i].num = 0x00FFU; ui_test[i].expected = "255";
+
+ i++; ui_test[i].num = 0xF000U; ui_test[i].expected = "61440";
+ i++; ui_test[i].num = 0x0F00U; ui_test[i].expected = "3840";
+ i++; ui_test[i].num = 0x00F0U; ui_test[i].expected = "240";
+ i++; ui_test[i].num = 0x000FU; ui_test[i].expected = "15";
+
+ i++; ui_test[i].num = 0xC000U; ui_test[i].expected = "49152";
+ i++; ui_test[i].num = 0x0C00U; ui_test[i].expected = "3072";
+ i++; ui_test[i].num = 0x00C0U; ui_test[i].expected = "192";
+ i++; ui_test[i].num = 0x000CU; ui_test[i].expected = "12";
+
+ i++; ui_test[i].num = 0x0001U; ui_test[i].expected = "1";
+ i++; ui_test[i].num = 0x0000U; ui_test[i].expected = "0";
+
+ num_uint_tests = i;
+
+#elif (SIZEOF_INT == 4)
+
+ i=1; ui_test[i].num = 0xFFFFFFFFU; ui_test[i].expected = "4294967295";
+ i++; ui_test[i].num = 0xFFFF0000U; ui_test[i].expected = "4294901760";
+ i++; ui_test[i].num = 0x0000FFFFU; ui_test[i].expected = "65535";
+
+ i++; ui_test[i].num = 0xFF000000U; ui_test[i].expected = "4278190080";
+ i++; ui_test[i].num = 0x00FF0000U; ui_test[i].expected = "16711680";
+ i++; ui_test[i].num = 0x0000FF00U; ui_test[i].expected = "65280";
+ i++; ui_test[i].num = 0x000000FFU; ui_test[i].expected = "255";
+
+ i++; ui_test[i].num = 0xF0000000U; ui_test[i].expected = "4026531840";
+ i++; ui_test[i].num = 0x0F000000U; ui_test[i].expected = "251658240";
+ i++; ui_test[i].num = 0x00F00000U; ui_test[i].expected = "15728640";
+ i++; ui_test[i].num = 0x000F0000U; ui_test[i].expected = "983040";
+ i++; ui_test[i].num = 0x0000F000U; ui_test[i].expected = "61440";
+ i++; ui_test[i].num = 0x00000F00U; ui_test[i].expected = "3840";
+ i++; ui_test[i].num = 0x000000F0U; ui_test[i].expected = "240";
+ i++; ui_test[i].num = 0x0000000FU; ui_test[i].expected = "15";
+
+ i++; ui_test[i].num = 0xC0000000U; ui_test[i].expected = "3221225472";
+ i++; ui_test[i].num = 0x0C000000U; ui_test[i].expected = "201326592";
+ i++; ui_test[i].num = 0x00C00000U; ui_test[i].expected = "12582912";
+ i++; ui_test[i].num = 0x000C0000U; ui_test[i].expected = "786432";
+ i++; ui_test[i].num = 0x0000C000U; ui_test[i].expected = "49152";
+ i++; ui_test[i].num = 0x00000C00U; ui_test[i].expected = "3072";
+ i++; ui_test[i].num = 0x000000C0U; ui_test[i].expected = "192";
+ i++; ui_test[i].num = 0x0000000CU; ui_test[i].expected = "12";
+
+ i++; ui_test[i].num = 0x00000001U; ui_test[i].expected = "1";
+ i++; ui_test[i].num = 0x00000000U; ui_test[i].expected = "0";
+
+ num_uint_tests = i;
+
+#elif (SIZEOF_INT == 8)
+
+ i=1; ui_test[i].num = 0xFFFFFFFFFFFFFFFFU; ui_test[i].expected = "18446744073709551615";
+ i++; ui_test[i].num = 0xFFFFFFFF00000000U; ui_test[i].expected = "18446744069414584320";
+ i++; ui_test[i].num = 0x00000000FFFFFFFFU; ui_test[i].expected = "4294967295";
+
+ i++; ui_test[i].num = 0xFFFF000000000000U; ui_test[i].expected = "18446462598732840960";
+ i++; ui_test[i].num = 0x0000FFFF00000000U; ui_test[i].expected = "281470681743360";
+ i++; ui_test[i].num = 0x00000000FFFF0000U; ui_test[i].expected = "4294901760";
+ i++; ui_test[i].num = 0x000000000000FFFFU; ui_test[i].expected = "65535";
+
+ i++; ui_test[i].num = 0xFF00000000000000U; ui_test[i].expected = "18374686479671623680";
+ i++; ui_test[i].num = 0x00FF000000000000U; ui_test[i].expected = "71776119061217280";
+ i++; ui_test[i].num = 0x0000FF0000000000U; ui_test[i].expected = "280375465082880";
+ i++; ui_test[i].num = 0x000000FF00000000U; ui_test[i].expected = "1095216660480";
+ i++; ui_test[i].num = 0x00000000FF000000U; ui_test[i].expected = "4278190080";
+ i++; ui_test[i].num = 0x0000000000FF0000U; ui_test[i].expected = "16711680";
+ i++; ui_test[i].num = 0x000000000000FF00U; ui_test[i].expected = "65280";
+ i++; ui_test[i].num = 0x00000000000000FFU; ui_test[i].expected = "255";
+
+ i++; ui_test[i].num = 0xF000000000000000U; ui_test[i].expected = "17293822569102704640";
+ i++; ui_test[i].num = 0x0F00000000000000U; ui_test[i].expected = "1080863910568919040";
+ i++; ui_test[i].num = 0x00F0000000000000U; ui_test[i].expected = "67553994410557440";
+ i++; ui_test[i].num = 0x000F000000000000U; ui_test[i].expected = "4222124650659840";
+ i++; ui_test[i].num = 0x0000F00000000000U; ui_test[i].expected = "263882790666240";
+ i++; ui_test[i].num = 0x00000F0000000000U; ui_test[i].expected = "16492674416640";
+ i++; ui_test[i].num = 0x000000F000000000U; ui_test[i].expected = "1030792151040";
+ i++; ui_test[i].num = 0x0000000F00000000U; ui_test[i].expected = "64424509440";
+ i++; ui_test[i].num = 0x00000000F0000000U; ui_test[i].expected = "4026531840";
+ i++; ui_test[i].num = 0x000000000F000000U; ui_test[i].expected = "251658240";
+ i++; ui_test[i].num = 0x0000000000F00000U; ui_test[i].expected = "15728640";
+ i++; ui_test[i].num = 0x00000000000F0000U; ui_test[i].expected = "983040";
+ i++; ui_test[i].num = 0x000000000000F000U; ui_test[i].expected = "61440";
+ i++; ui_test[i].num = 0x0000000000000F00U; ui_test[i].expected = "3840";
+ i++; ui_test[i].num = 0x00000000000000F0U; ui_test[i].expected = "240";
+ i++; ui_test[i].num = 0x000000000000000FU; ui_test[i].expected = "15";
+
+ i++; ui_test[i].num = 0xC000000000000000U; ui_test[i].expected = "13835058055282163712";
+ i++; ui_test[i].num = 0x0C00000000000000U; ui_test[i].expected = "864691128455135232";
+ i++; ui_test[i].num = 0x00C0000000000000U; ui_test[i].expected = "54043195528445952";
+ i++; ui_test[i].num = 0x000C000000000000U; ui_test[i].expected = "3377699720527872";
+ i++; ui_test[i].num = 0x0000C00000000000U; ui_test[i].expected = "211106232532992";
+ i++; ui_test[i].num = 0x00000C0000000000U; ui_test[i].expected = "13194139533312";
+ i++; ui_test[i].num = 0x000000C000000000U; ui_test[i].expected = "824633720832";
+ i++; ui_test[i].num = 0x0000000C00000000U; ui_test[i].expected = "51539607552";
+ i++; ui_test[i].num = 0x00000000C0000000U; ui_test[i].expected = "3221225472";
+ i++; ui_test[i].num = 0x000000000C000000U; ui_test[i].expected = "201326592";
+ i++; ui_test[i].num = 0x0000000000C00000U; ui_test[i].expected = "12582912";
+ i++; ui_test[i].num = 0x00000000000C0000U; ui_test[i].expected = "786432";
+ i++; ui_test[i].num = 0x000000000000C000U; ui_test[i].expected = "49152";
+ i++; ui_test[i].num = 0x0000000000000C00U; ui_test[i].expected = "3072";
+ i++; ui_test[i].num = 0x00000000000000C0U; ui_test[i].expected = "192";
+ i++; ui_test[i].num = 0x000000000000000CU; ui_test[i].expected = "12";
+
+ i++; ui_test[i].num = 0x00000001U; ui_test[i].expected = "1";
+ i++; ui_test[i].num = 0x00000000U; ui_test[i].expected = "0";
+
+ num_uint_tests = i;
+
+#endif
+
+ for(i=1; i<=num_uint_tests; i++) {
+
+ for(j=0; j<BUFSZ; j++)
+ ui_test[i].result[j] = 'X';
+ ui_test[i].result[BUFSZ-1] = '\0';
+
+ (void)curl_msprintf(ui_test[i].result, "%u", ui_test[i].num);
+
+ if(memcmp(ui_test[i].result,
+ ui_test[i].expected,
+ strlen(ui_test[i].expected))) {
+ printf("unsigned int test #%.2d: Failed (Expected: %s Got: %s)\n",
+ i, ui_test[i].expected, ui_test[i].result);
+ failed++;
+ }
+
+ }
+
+ if(!failed)
+ printf("All curl_mprintf() unsigned int tests OK!\n");
+ else
+ printf("Some curl_mprintf() unsigned int tests Failed!\n");
+
+ return failed;
+}
+
+
+static int test_signed_int_formatting(void)
+{
+ int i, j;
+ int num_sint_tests;
+ int failed = 0;
+
+#if (SIZEOF_INT == 2)
+
+ i=1; si_test[i].num = 0x7FFF; si_test[i].expected = "32767";
+ i++; si_test[i].num = 0x7FFE; si_test[i].expected = "32766";
+ i++; si_test[i].num = 0x7FFD; si_test[i].expected = "32765";
+ i++; si_test[i].num = 0x7F00; si_test[i].expected = "32512";
+ i++; si_test[i].num = 0x07F0; si_test[i].expected = "2032";
+ i++; si_test[i].num = 0x007F; si_test[i].expected = "127";
+
+ i++; si_test[i].num = 0x7000; si_test[i].expected = "28672";
+ i++; si_test[i].num = 0x0700; si_test[i].expected = "1792";
+ i++; si_test[i].num = 0x0070; si_test[i].expected = "112";
+ i++; si_test[i].num = 0x0007; si_test[i].expected = "7";
+
+ i++; si_test[i].num = 0x5000; si_test[i].expected = "20480";
+ i++; si_test[i].num = 0x0500; si_test[i].expected = "1280";
+ i++; si_test[i].num = 0x0050; si_test[i].expected = "80";
+ i++; si_test[i].num = 0x0005; si_test[i].expected = "5";
+
+ i++; si_test[i].num = 0x0001; si_test[i].expected = "1";
+ i++; si_test[i].num = 0x0000; si_test[i].expected = "0";
+
+ i++; si_test[i].num = -0x7FFF -1; si_test[i].expected = "-32768";
+ i++; si_test[i].num = -0x7FFE -1; si_test[i].expected = "-32767";
+ i++; si_test[i].num = -0x7FFD -1; si_test[i].expected = "-32766";
+ i++; si_test[i].num = -0x7F00 -1; si_test[i].expected = "-32513";
+ i++; si_test[i].num = -0x07F0 -1; si_test[i].expected = "-2033";
+ i++; si_test[i].num = -0x007F -1; si_test[i].expected = "-128";
+
+ i++; si_test[i].num = -0x7000 -1; si_test[i].expected = "-28673";
+ i++; si_test[i].num = -0x0700 -1; si_test[i].expected = "-1793";
+ i++; si_test[i].num = -0x0070 -1; si_test[i].expected = "-113";
+ i++; si_test[i].num = -0x0007 -1; si_test[i].expected = "-8";
+
+ i++; si_test[i].num = -0x5000 -1; si_test[i].expected = "-20481";
+ i++; si_test[i].num = -0x0500 -1; si_test[i].expected = "-1281";
+ i++; si_test[i].num = -0x0050 -1; si_test[i].expected = "-81";
+ i++; si_test[i].num = -0x0005 -1; si_test[i].expected = "-6";
+
+ i++; si_test[i].num = 0x0000 -1; si_test[i].expected = "-1";
+
+ num_sint_tests = i;
+
+#elif (SIZEOF_INT == 4)
+
+ i=1; si_test[i].num = 0x7FFFFFFF; si_test[i].expected = "2147483647";
+ i++; si_test[i].num = 0x7FFFFFFE; si_test[i].expected = "2147483646";
+ i++; si_test[i].num = 0x7FFFFFFD; si_test[i].expected = "2147483645";
+ i++; si_test[i].num = 0x7FFF0000; si_test[i].expected = "2147418112";
+ i++; si_test[i].num = 0x00007FFF; si_test[i].expected = "32767";
+
+ i++; si_test[i].num = 0x7F000000; si_test[i].expected = "2130706432";
+ i++; si_test[i].num = 0x007F0000; si_test[i].expected = "8323072";
+ i++; si_test[i].num = 0x00007F00; si_test[i].expected = "32512";
+ i++; si_test[i].num = 0x0000007F; si_test[i].expected = "127";
+
+ i++; si_test[i].num = 0x70000000; si_test[i].expected = "1879048192";
+ i++; si_test[i].num = 0x07000000; si_test[i].expected = "117440512";
+ i++; si_test[i].num = 0x00700000; si_test[i].expected = "7340032";
+ i++; si_test[i].num = 0x00070000; si_test[i].expected = "458752";
+ i++; si_test[i].num = 0x00007000; si_test[i].expected = "28672";
+ i++; si_test[i].num = 0x00000700; si_test[i].expected = "1792";
+ i++; si_test[i].num = 0x00000070; si_test[i].expected = "112";
+ i++; si_test[i].num = 0x00000007; si_test[i].expected = "7";
+
+ i++; si_test[i].num = 0x50000000; si_test[i].expected = "1342177280";
+ i++; si_test[i].num = 0x05000000; si_test[i].expected = "83886080";
+ i++; si_test[i].num = 0x00500000; si_test[i].expected = "5242880";
+ i++; si_test[i].num = 0x00050000; si_test[i].expected = "327680";
+ i++; si_test[i].num = 0x00005000; si_test[i].expected = "20480";
+ i++; si_test[i].num = 0x00000500; si_test[i].expected = "1280";
+ i++; si_test[i].num = 0x00000050; si_test[i].expected = "80";
+ i++; si_test[i].num = 0x00000005; si_test[i].expected = "5";
+
+ i++; si_test[i].num = 0x00000001; si_test[i].expected = "1";
+ i++; si_test[i].num = 0x00000000; si_test[i].expected = "0";
+
+ i++; si_test[i].num = -0x7FFFFFFF -1; si_test[i].expected = "-2147483648";
+ i++; si_test[i].num = -0x7FFFFFFE -1; si_test[i].expected = "-2147483647";
+ i++; si_test[i].num = -0x7FFFFFFD -1; si_test[i].expected = "-2147483646";
+ i++; si_test[i].num = -0x7FFF0000 -1; si_test[i].expected = "-2147418113";
+ i++; si_test[i].num = -0x00007FFF -1; si_test[i].expected = "-32768";
+
+ i++; si_test[i].num = -0x7F000000 -1; si_test[i].expected = "-2130706433";
+ i++; si_test[i].num = -0x007F0000 -1; si_test[i].expected = "-8323073";
+ i++; si_test[i].num = -0x00007F00 -1; si_test[i].expected = "-32513";
+ i++; si_test[i].num = -0x0000007F -1; si_test[i].expected = "-128";
+
+ i++; si_test[i].num = -0x70000000 -1; si_test[i].expected = "-1879048193";
+ i++; si_test[i].num = -0x07000000 -1; si_test[i].expected = "-117440513";
+ i++; si_test[i].num = -0x00700000 -1; si_test[i].expected = "-7340033";
+ i++; si_test[i].num = -0x00070000 -1; si_test[i].expected = "-458753";
+ i++; si_test[i].num = -0x00007000 -1; si_test[i].expected = "-28673";
+ i++; si_test[i].num = -0x00000700 -1; si_test[i].expected = "-1793";
+ i++; si_test[i].num = -0x00000070 -1; si_test[i].expected = "-113";
+ i++; si_test[i].num = -0x00000007 -1; si_test[i].expected = "-8";
+
+ i++; si_test[i].num = -0x50000000 -1; si_test[i].expected = "-1342177281";
+ i++; si_test[i].num = -0x05000000 -1; si_test[i].expected = "-83886081";
+ i++; si_test[i].num = -0x00500000 -1; si_test[i].expected = "-5242881";
+ i++; si_test[i].num = -0x00050000 -1; si_test[i].expected = "-327681";
+ i++; si_test[i].num = -0x00005000 -1; si_test[i].expected = "-20481";
+ i++; si_test[i].num = -0x00000500 -1; si_test[i].expected = "-1281";
+ i++; si_test[i].num = -0x00000050 -1; si_test[i].expected = "-81";
+ i++; si_test[i].num = -0x00000005 -1; si_test[i].expected = "-6";
+
+ i++; si_test[i].num = 0x00000000 -1; si_test[i].expected = "-1";
+
+ num_sint_tests = i;
+
+#elif (SIZEOF_INT == 8)
+
+ i=1; si_test[i].num = 0x7FFFFFFFFFFFFFFF; si_test[i].expected = "9223372036854775807";
+ i++; si_test[i].num = 0x7FFFFFFFFFFFFFFE; si_test[i].expected = "9223372036854775806";
+ i++; si_test[i].num = 0x7FFFFFFFFFFFFFFD; si_test[i].expected = "9223372036854775805";
+ i++; si_test[i].num = 0x7FFFFFFF00000000; si_test[i].expected = "9223372032559808512";
+ i++; si_test[i].num = 0x000000007FFFFFFF; si_test[i].expected = "2147483647";
+
+ i++; si_test[i].num = 0x7FFF000000000000; si_test[i].expected = "9223090561878065152";
+ i++; si_test[i].num = 0x00007FFF00000000; si_test[i].expected = "140733193388032";
+ i++; si_test[i].num = 0x000000007FFF0000; si_test[i].expected = "2147418112";
+ i++; si_test[i].num = 0x0000000000007FFF; si_test[i].expected = "32767";
+
+ i++; si_test[i].num = 0x7F00000000000000; si_test[i].expected = "9151314442816847872";
+ i++; si_test[i].num = 0x007F000000000000; si_test[i].expected = "35747322042253312";
+ i++; si_test[i].num = 0x00007F0000000000; si_test[i].expected = "139637976727552";
+ i++; si_test[i].num = 0x0000007F00000000; si_test[i].expected = "545460846592";
+ i++; si_test[i].num = 0x000000007F000000; si_test[i].expected = "2130706432";
+ i++; si_test[i].num = 0x00000000007F0000; si_test[i].expected = "8323072";
+ i++; si_test[i].num = 0x0000000000007F00; si_test[i].expected = "32512";
+ i++; si_test[i].num = 0x000000000000007F; si_test[i].expected = "127";
+
+ i++; si_test[i].num = 0x7000000000000000; si_test[i].expected = "8070450532247928832";
+ i++; si_test[i].num = 0x0700000000000000; si_test[i].expected = "504403158265495552";
+ i++; si_test[i].num = 0x0070000000000000; si_test[i].expected = "31525197391593472";
+ i++; si_test[i].num = 0x0007000000000000; si_test[i].expected = "1970324836974592";
+ i++; si_test[i].num = 0x0000700000000000; si_test[i].expected = "123145302310912";
+ i++; si_test[i].num = 0x0000070000000000; si_test[i].expected = "7696581394432";
+ i++; si_test[i].num = 0x0000007000000000; si_test[i].expected = "481036337152";
+ i++; si_test[i].num = 0x0000000700000000; si_test[i].expected = "30064771072";
+ i++; si_test[i].num = 0x0000000070000000; si_test[i].expected = "1879048192";
+ i++; si_test[i].num = 0x0000000007000000; si_test[i].expected = "117440512";
+ i++; si_test[i].num = 0x0000000000700000; si_test[i].expected = "7340032";
+ i++; si_test[i].num = 0x0000000000070000; si_test[i].expected = "458752";
+ i++; si_test[i].num = 0x0000000000007000; si_test[i].expected = "28672";
+ i++; si_test[i].num = 0x0000000000000700; si_test[i].expected = "1792";
+ i++; si_test[i].num = 0x0000000000000070; si_test[i].expected = "112";
+ i++; si_test[i].num = 0x0000000000000007; si_test[i].expected = "7";
+
+ i++; si_test[i].num = 0x0000000000000001; si_test[i].expected = "1";
+ i++; si_test[i].num = 0x0000000000000000; si_test[i].expected = "0";
+
+ i++; si_test[i].num = -0x7FFFFFFFFFFFFFFF -1; si_test[i].expected = "-9223372036854775808";
+ i++; si_test[i].num = -0x7FFFFFFFFFFFFFFE -1; si_test[i].expected = "-9223372036854775807";
+ i++; si_test[i].num = -0x7FFFFFFFFFFFFFFD -1; si_test[i].expected = "-9223372036854775806";
+ i++; si_test[i].num = -0x7FFFFFFF00000000 -1; si_test[i].expected = "-9223372032559808513";
+ i++; si_test[i].num = -0x000000007FFFFFFF -1; si_test[i].expected = "-2147483648";
+
+ i++; si_test[i].num = -0x7FFF000000000000 -1; si_test[i].expected = "-9223090561878065153";
+ i++; si_test[i].num = -0x00007FFF00000000 -1; si_test[i].expected = "-140733193388033";
+ i++; si_test[i].num = -0x000000007FFF0000 -1; si_test[i].expected = "-2147418113";
+ i++; si_test[i].num = -0x0000000000007FFF -1; si_test[i].expected = "-32768";
+
+ i++; si_test[i].num = -0x7F00000000000000 -1; si_test[i].expected = "-9151314442816847873";
+ i++; si_test[i].num = -0x007F000000000000 -1; si_test[i].expected = "-35747322042253313";
+ i++; si_test[i].num = -0x00007F0000000000 -1; si_test[i].expected = "-139637976727553";
+ i++; si_test[i].num = -0x0000007F00000000 -1; si_test[i].expected = "-545460846593";
+ i++; si_test[i].num = -0x000000007F000000 -1; si_test[i].expected = "-2130706433";
+ i++; si_test[i].num = -0x00000000007F0000 -1; si_test[i].expected = "-8323073";
+ i++; si_test[i].num = -0x0000000000007F00 -1; si_test[i].expected = "-32513";
+ i++; si_test[i].num = -0x000000000000007F -1; si_test[i].expected = "-128";
+
+ i++; si_test[i].num = -0x7000000000000000 -1; si_test[i].expected = "-8070450532247928833";
+ i++; si_test[i].num = -0x0700000000000000 -1; si_test[i].expected = "-504403158265495553";
+ i++; si_test[i].num = -0x0070000000000000 -1; si_test[i].expected = "-31525197391593473";
+ i++; si_test[i].num = -0x0007000000000000 -1; si_test[i].expected = "-1970324836974593";
+ i++; si_test[i].num = -0x0000700000000000 -1; si_test[i].expected = "-123145302310913";
+ i++; si_test[i].num = -0x0000070000000000 -1; si_test[i].expected = "-7696581394433";
+ i++; si_test[i].num = -0x0000007000000000 -1; si_test[i].expected = "-481036337153";
+ i++; si_test[i].num = -0x0000000700000000 -1; si_test[i].expected = "-30064771073";
+ i++; si_test[i].num = -0x0000000070000000 -1; si_test[i].expected = "-1879048193";
+ i++; si_test[i].num = -0x0000000007000000 -1; si_test[i].expected = "-117440513";
+ i++; si_test[i].num = -0x0000000000700000 -1; si_test[i].expected = "-7340033";
+ i++; si_test[i].num = -0x0000000000070000 -1; si_test[i].expected = "-458753";
+ i++; si_test[i].num = -0x0000000000007000 -1; si_test[i].expected = "-28673";
+ i++; si_test[i].num = -0x0000000000000700 -1; si_test[i].expected = "-1793";
+ i++; si_test[i].num = -0x0000000000000070 -1; si_test[i].expected = "-113";
+ i++; si_test[i].num = -0x0000000000000007 -1; si_test[i].expected = "-8";
+
+ i++; si_test[i].num = 0x0000000000000000 -1; si_test[i].expected = "-1";
+
+ num_sint_tests = i;
+
+#endif
+
+ for(i=1; i<=num_sint_tests; i++) {
+
+ for(j=0; j<BUFSZ; j++)
+ si_test[i].result[j] = 'X';
+ si_test[i].result[BUFSZ-1] = '\0';
+
+ (void)curl_msprintf(si_test[i].result, "%d", si_test[i].num);
+
+ if(memcmp(si_test[i].result,
+ si_test[i].expected,
+ strlen(si_test[i].expected))) {
+ printf("signed int test #%.2d: Failed (Expected: %s Got: %s)\n",
+ i, si_test[i].expected, si_test[i].result);
+ failed++;
+ }
+
+ }
+
+ if(!failed)
+ printf("All curl_mprintf() signed int tests OK!\n");
+ else
+ printf("Some curl_mprintf() signed int tests Failed!\n");
+
+ return failed;
+}
+
+
+static int test_unsigned_long_formatting(void)
+{
+ int i, j;
+ int num_ulong_tests;
+ int failed = 0;
+
+#if (CURL_SIZEOF_LONG == 2)
+
+ i=1; ul_test[i].num = 0xFFFFUL; ul_test[i].expected = "65535";
+ i++; ul_test[i].num = 0xFF00UL; ul_test[i].expected = "65280";
+ i++; ul_test[i].num = 0x00FFUL; ul_test[i].expected = "255";
+
+ i++; ul_test[i].num = 0xF000UL; ul_test[i].expected = "61440";
+ i++; ul_test[i].num = 0x0F00UL; ul_test[i].expected = "3840";
+ i++; ul_test[i].num = 0x00F0UL; ul_test[i].expected = "240";
+ i++; ul_test[i].num = 0x000FUL; ul_test[i].expected = "15";
+
+ i++; ul_test[i].num = 0xC000UL; ul_test[i].expected = "49152";
+ i++; ul_test[i].num = 0x0C00UL; ul_test[i].expected = "3072";
+ i++; ul_test[i].num = 0x00C0UL; ul_test[i].expected = "192";
+ i++; ul_test[i].num = 0x000CUL; ul_test[i].expected = "12";
+
+ i++; ul_test[i].num = 0x0001UL; ul_test[i].expected = "1";
+ i++; ul_test[i].num = 0x0000UL; ul_test[i].expected = "0";
+
+ num_ulong_tests = i;
+
+#elif (CURL_SIZEOF_LONG == 4)
+
+ i=1; ul_test[i].num = 0xFFFFFFFFUL; ul_test[i].expected = "4294967295";
+ i++; ul_test[i].num = 0xFFFF0000UL; ul_test[i].expected = "4294901760";
+ i++; ul_test[i].num = 0x0000FFFFUL; ul_test[i].expected = "65535";
+
+ i++; ul_test[i].num = 0xFF000000UL; ul_test[i].expected = "4278190080";
+ i++; ul_test[i].num = 0x00FF0000UL; ul_test[i].expected = "16711680";
+ i++; ul_test[i].num = 0x0000FF00UL; ul_test[i].expected = "65280";
+ i++; ul_test[i].num = 0x000000FFUL; ul_test[i].expected = "255";
+
+ i++; ul_test[i].num = 0xF0000000UL; ul_test[i].expected = "4026531840";
+ i++; ul_test[i].num = 0x0F000000UL; ul_test[i].expected = "251658240";
+ i++; ul_test[i].num = 0x00F00000UL; ul_test[i].expected = "15728640";
+ i++; ul_test[i].num = 0x000F0000UL; ul_test[i].expected = "983040";
+ i++; ul_test[i].num = 0x0000F000UL; ul_test[i].expected = "61440";
+ i++; ul_test[i].num = 0x00000F00UL; ul_test[i].expected = "3840";
+ i++; ul_test[i].num = 0x000000F0UL; ul_test[i].expected = "240";
+ i++; ul_test[i].num = 0x0000000FUL; ul_test[i].expected = "15";
+
+ i++; ul_test[i].num = 0xC0000000UL; ul_test[i].expected = "3221225472";
+ i++; ul_test[i].num = 0x0C000000UL; ul_test[i].expected = "201326592";
+ i++; ul_test[i].num = 0x00C00000UL; ul_test[i].expected = "12582912";
+ i++; ul_test[i].num = 0x000C0000UL; ul_test[i].expected = "786432";
+ i++; ul_test[i].num = 0x0000C000UL; ul_test[i].expected = "49152";
+ i++; ul_test[i].num = 0x00000C00UL; ul_test[i].expected = "3072";
+ i++; ul_test[i].num = 0x000000C0UL; ul_test[i].expected = "192";
+ i++; ul_test[i].num = 0x0000000CUL; ul_test[i].expected = "12";
+
+ i++; ul_test[i].num = 0x00000001UL; ul_test[i].expected = "1";
+ i++; ul_test[i].num = 0x00000000UL; ul_test[i].expected = "0";
+
+ num_ulong_tests = i;
+
+#elif (CURL_SIZEOF_LONG == 8)
+
+ i=1; ul_test[i].num = 0xFFFFFFFFFFFFFFFFUL; ul_test[i].expected = "18446744073709551615";
+ i++; ul_test[i].num = 0xFFFFFFFF00000000UL; ul_test[i].expected = "18446744069414584320";
+ i++; ul_test[i].num = 0x00000000FFFFFFFFUL; ul_test[i].expected = "4294967295";
+
+ i++; ul_test[i].num = 0xFFFF000000000000UL; ul_test[i].expected = "18446462598732840960";
+ i++; ul_test[i].num = 0x0000FFFF00000000UL; ul_test[i].expected = "281470681743360";
+ i++; ul_test[i].num = 0x00000000FFFF0000UL; ul_test[i].expected = "4294901760";
+ i++; ul_test[i].num = 0x000000000000FFFFUL; ul_test[i].expected = "65535";
+
+ i++; ul_test[i].num = 0xFF00000000000000UL; ul_test[i].expected = "18374686479671623680";
+ i++; ul_test[i].num = 0x00FF000000000000UL; ul_test[i].expected = "71776119061217280";
+ i++; ul_test[i].num = 0x0000FF0000000000UL; ul_test[i].expected = "280375465082880";
+ i++; ul_test[i].num = 0x000000FF00000000UL; ul_test[i].expected = "1095216660480";
+ i++; ul_test[i].num = 0x00000000FF000000UL; ul_test[i].expected = "4278190080";
+ i++; ul_test[i].num = 0x0000000000FF0000UL; ul_test[i].expected = "16711680";
+ i++; ul_test[i].num = 0x000000000000FF00UL; ul_test[i].expected = "65280";
+ i++; ul_test[i].num = 0x00000000000000FFUL; ul_test[i].expected = "255";
+
+ i++; ul_test[i].num = 0xF000000000000000UL; ul_test[i].expected = "17293822569102704640";
+ i++; ul_test[i].num = 0x0F00000000000000UL; ul_test[i].expected = "1080863910568919040";
+ i++; ul_test[i].num = 0x00F0000000000000UL; ul_test[i].expected = "67553994410557440";
+ i++; ul_test[i].num = 0x000F000000000000UL; ul_test[i].expected = "4222124650659840";
+ i++; ul_test[i].num = 0x0000F00000000000UL; ul_test[i].expected = "263882790666240";
+ i++; ul_test[i].num = 0x00000F0000000000UL; ul_test[i].expected = "16492674416640";
+ i++; ul_test[i].num = 0x000000F000000000UL; ul_test[i].expected = "1030792151040";
+ i++; ul_test[i].num = 0x0000000F00000000UL; ul_test[i].expected = "64424509440";
+ i++; ul_test[i].num = 0x00000000F0000000UL; ul_test[i].expected = "4026531840";
+ i++; ul_test[i].num = 0x000000000F000000UL; ul_test[i].expected = "251658240";
+ i++; ul_test[i].num = 0x0000000000F00000UL; ul_test[i].expected = "15728640";
+ i++; ul_test[i].num = 0x00000000000F0000UL; ul_test[i].expected = "983040";
+ i++; ul_test[i].num = 0x000000000000F000UL; ul_test[i].expected = "61440";
+ i++; ul_test[i].num = 0x0000000000000F00UL; ul_test[i].expected = "3840";
+ i++; ul_test[i].num = 0x00000000000000F0UL; ul_test[i].expected = "240";
+ i++; ul_test[i].num = 0x000000000000000FUL; ul_test[i].expected = "15";
+
+ i++; ul_test[i].num = 0xC000000000000000UL; ul_test[i].expected = "13835058055282163712";
+ i++; ul_test[i].num = 0x0C00000000000000UL; ul_test[i].expected = "864691128455135232";
+ i++; ul_test[i].num = 0x00C0000000000000UL; ul_test[i].expected = "54043195528445952";
+ i++; ul_test[i].num = 0x000C000000000000UL; ul_test[i].expected = "3377699720527872";
+ i++; ul_test[i].num = 0x0000C00000000000UL; ul_test[i].expected = "211106232532992";
+ i++; ul_test[i].num = 0x00000C0000000000UL; ul_test[i].expected = "13194139533312";
+ i++; ul_test[i].num = 0x000000C000000000UL; ul_test[i].expected = "824633720832";
+ i++; ul_test[i].num = 0x0000000C00000000UL; ul_test[i].expected = "51539607552";
+ i++; ul_test[i].num = 0x00000000C0000000UL; ul_test[i].expected = "3221225472";
+ i++; ul_test[i].num = 0x000000000C000000UL; ul_test[i].expected = "201326592";
+ i++; ul_test[i].num = 0x0000000000C00000UL; ul_test[i].expected = "12582912";
+ i++; ul_test[i].num = 0x00000000000C0000UL; ul_test[i].expected = "786432";
+ i++; ul_test[i].num = 0x000000000000C000UL; ul_test[i].expected = "49152";
+ i++; ul_test[i].num = 0x0000000000000C00UL; ul_test[i].expected = "3072";
+ i++; ul_test[i].num = 0x00000000000000C0UL; ul_test[i].expected = "192";
+ i++; ul_test[i].num = 0x000000000000000CUL; ul_test[i].expected = "12";
+
+ i++; ul_test[i].num = 0x00000001UL; ul_test[i].expected = "1";
+ i++; ul_test[i].num = 0x00000000UL; ul_test[i].expected = "0";
+
+ num_ulong_tests = i;
+
+#endif
+
+ for(i=1; i<=num_ulong_tests; i++) {
+
+ for(j=0; j<BUFSZ; j++)
+ ul_test[i].result[j] = 'X';
+ ul_test[i].result[BUFSZ-1] = '\0';
+
+ (void)curl_msprintf(ul_test[i].result, "%lu", ul_test[i].num);
+
+ if(memcmp(ul_test[i].result,
+ ul_test[i].expected,
+ strlen(ul_test[i].expected))) {
+ printf("unsigned long test #%.2d: Failed (Expected: %s Got: %s)\n",
+ i, ul_test[i].expected, ul_test[i].result);
+ failed++;
+ }
+
+ }
+
+ if(!failed)
+ printf("All curl_mprintf() unsigned long tests OK!\n");
+ else
+ printf("Some curl_mprintf() unsigned long tests Failed!\n");
+
+ return failed;
+}
+
+
+static int test_signed_long_formatting(void)
+{
+ int i, j;
+ int num_slong_tests;
+ int failed = 0;
+
+#if (CURL_SIZEOF_LONG == 2)
+
+ i=1; sl_test[i].num = 0x7FFFL; sl_test[i].expected = "32767";
+ i++; sl_test[i].num = 0x7FFEL; sl_test[i].expected = "32766";
+ i++; sl_test[i].num = 0x7FFDL; sl_test[i].expected = "32765";
+ i++; sl_test[i].num = 0x7F00L; sl_test[i].expected = "32512";
+ i++; sl_test[i].num = 0x07F0L; sl_test[i].expected = "2032";
+ i++; sl_test[i].num = 0x007FL; sl_test[i].expected = "127";
+
+ i++; sl_test[i].num = 0x7000L; sl_test[i].expected = "28672";
+ i++; sl_test[i].num = 0x0700L; sl_test[i].expected = "1792";
+ i++; sl_test[i].num = 0x0070L; sl_test[i].expected = "112";
+ i++; sl_test[i].num = 0x0007L; sl_test[i].expected = "7";
+
+ i++; sl_test[i].num = 0x5000L; sl_test[i].expected = "20480";
+ i++; sl_test[i].num = 0x0500L; sl_test[i].expected = "1280";
+ i++; sl_test[i].num = 0x0050L; sl_test[i].expected = "80";
+ i++; sl_test[i].num = 0x0005L; sl_test[i].expected = "5";
+
+ i++; sl_test[i].num = 0x0001L; sl_test[i].expected = "1";
+ i++; sl_test[i].num = 0x0000L; sl_test[i].expected = "0";
+
+ i++; sl_test[i].num = -0x7FFFL -1L; sl_test[i].expected = "-32768";
+ i++; sl_test[i].num = -0x7FFEL -1L; sl_test[i].expected = "-32767";
+ i++; sl_test[i].num = -0x7FFDL -1L; sl_test[i].expected = "-32766";
+ i++; sl_test[i].num = -0x7F00L -1L; sl_test[i].expected = "-32513";
+ i++; sl_test[i].num = -0x07F0L -1L; sl_test[i].expected = "-2033";
+ i++; sl_test[i].num = -0x007FL -1L; sl_test[i].expected = "-128";
+
+ i++; sl_test[i].num = -0x7000L -1L; sl_test[i].expected = "-28673";
+ i++; sl_test[i].num = -0x0700L -1L; sl_test[i].expected = "-1793";
+ i++; sl_test[i].num = -0x0070L -1L; sl_test[i].expected = "-113";
+ i++; sl_test[i].num = -0x0007L -1L; sl_test[i].expected = "-8";
+
+ i++; sl_test[i].num = -0x5000L -1L; sl_test[i].expected = "-20481";
+ i++; sl_test[i].num = -0x0500L -1L; sl_test[i].expected = "-1281";
+ i++; sl_test[i].num = -0x0050L -1L; sl_test[i].expected = "-81";
+ i++; sl_test[i].num = -0x0005L -1L; sl_test[i].expected = "-6";
+
+ i++; sl_test[i].num = 0x0000L -1L; sl_test[i].expected = "-1";
+
+ num_slong_tests = i;
+
+#elif (CURL_SIZEOF_LONG == 4)
+
+ i=1; sl_test[i].num = 0x7FFFFFFFL; sl_test[i].expected = "2147483647";
+ i++; sl_test[i].num = 0x7FFFFFFEL; sl_test[i].expected = "2147483646";
+ i++; sl_test[i].num = 0x7FFFFFFDL; sl_test[i].expected = "2147483645";
+ i++; sl_test[i].num = 0x7FFF0000L; sl_test[i].expected = "2147418112";
+ i++; sl_test[i].num = 0x00007FFFL; sl_test[i].expected = "32767";
+
+ i++; sl_test[i].num = 0x7F000000L; sl_test[i].expected = "2130706432";
+ i++; sl_test[i].num = 0x007F0000L; sl_test[i].expected = "8323072";
+ i++; sl_test[i].num = 0x00007F00L; sl_test[i].expected = "32512";
+ i++; sl_test[i].num = 0x0000007FL; sl_test[i].expected = "127";
+
+ i++; sl_test[i].num = 0x70000000L; sl_test[i].expected = "1879048192";
+ i++; sl_test[i].num = 0x07000000L; sl_test[i].expected = "117440512";
+ i++; sl_test[i].num = 0x00700000L; sl_test[i].expected = "7340032";
+ i++; sl_test[i].num = 0x00070000L; sl_test[i].expected = "458752";
+ i++; sl_test[i].num = 0x00007000L; sl_test[i].expected = "28672";
+ i++; sl_test[i].num = 0x00000700L; sl_test[i].expected = "1792";
+ i++; sl_test[i].num = 0x00000070L; sl_test[i].expected = "112";
+ i++; sl_test[i].num = 0x00000007L; sl_test[i].expected = "7";
+
+ i++; sl_test[i].num = 0x50000000L; sl_test[i].expected = "1342177280";
+ i++; sl_test[i].num = 0x05000000L; sl_test[i].expected = "83886080";
+ i++; sl_test[i].num = 0x00500000L; sl_test[i].expected = "5242880";
+ i++; sl_test[i].num = 0x00050000L; sl_test[i].expected = "327680";
+ i++; sl_test[i].num = 0x00005000L; sl_test[i].expected = "20480";
+ i++; sl_test[i].num = 0x00000500L; sl_test[i].expected = "1280";
+ i++; sl_test[i].num = 0x00000050L; sl_test[i].expected = "80";
+ i++; sl_test[i].num = 0x00000005L; sl_test[i].expected = "5";
+
+ i++; sl_test[i].num = 0x00000001L; sl_test[i].expected = "1";
+ i++; sl_test[i].num = 0x00000000L; sl_test[i].expected = "0";
+
+ i++; sl_test[i].num = -0x7FFFFFFFL -1L; sl_test[i].expected = "-2147483648";
+ i++; sl_test[i].num = -0x7FFFFFFEL -1L; sl_test[i].expected = "-2147483647";
+ i++; sl_test[i].num = -0x7FFFFFFDL -1L; sl_test[i].expected = "-2147483646";
+ i++; sl_test[i].num = -0x7FFF0000L -1L; sl_test[i].expected = "-2147418113";
+ i++; sl_test[i].num = -0x00007FFFL -1L; sl_test[i].expected = "-32768";
+
+ i++; sl_test[i].num = -0x7F000000L -1L; sl_test[i].expected = "-2130706433";
+ i++; sl_test[i].num = -0x007F0000L -1L; sl_test[i].expected = "-8323073";
+ i++; sl_test[i].num = -0x00007F00L -1L; sl_test[i].expected = "-32513";
+ i++; sl_test[i].num = -0x0000007FL -1L; sl_test[i].expected = "-128";
+
+ i++; sl_test[i].num = -0x70000000L -1L; sl_test[i].expected = "-1879048193";
+ i++; sl_test[i].num = -0x07000000L -1L; sl_test[i].expected = "-117440513";
+ i++; sl_test[i].num = -0x00700000L -1L; sl_test[i].expected = "-7340033";
+ i++; sl_test[i].num = -0x00070000L -1L; sl_test[i].expected = "-458753";
+ i++; sl_test[i].num = -0x00007000L -1L; sl_test[i].expected = "-28673";
+ i++; sl_test[i].num = -0x00000700L -1L; sl_test[i].expected = "-1793";
+ i++; sl_test[i].num = -0x00000070L -1L; sl_test[i].expected = "-113";
+ i++; sl_test[i].num = -0x00000007L -1L; sl_test[i].expected = "-8";
+
+ i++; sl_test[i].num = -0x50000000L -1L; sl_test[i].expected = "-1342177281";
+ i++; sl_test[i].num = -0x05000000L -1L; sl_test[i].expected = "-83886081";
+ i++; sl_test[i].num = -0x00500000L -1L; sl_test[i].expected = "-5242881";
+ i++; sl_test[i].num = -0x00050000L -1L; sl_test[i].expected = "-327681";
+ i++; sl_test[i].num = -0x00005000L -1L; sl_test[i].expected = "-20481";
+ i++; sl_test[i].num = -0x00000500L -1L; sl_test[i].expected = "-1281";
+ i++; sl_test[i].num = -0x00000050L -1L; sl_test[i].expected = "-81";
+ i++; sl_test[i].num = -0x00000005L -1L; sl_test[i].expected = "-6";
+
+ i++; sl_test[i].num = 0x00000000L -1L; sl_test[i].expected = "-1";
+
+ num_slong_tests = i;
+
+#elif (CURL_SIZEOF_LONG == 8)
+
+ i=1; sl_test[i].num = 0x7FFFFFFFFFFFFFFFL; sl_test[i].expected = "9223372036854775807";
+ i++; sl_test[i].num = 0x7FFFFFFFFFFFFFFEL; sl_test[i].expected = "9223372036854775806";
+ i++; sl_test[i].num = 0x7FFFFFFFFFFFFFFDL; sl_test[i].expected = "9223372036854775805";
+ i++; sl_test[i].num = 0x7FFFFFFF00000000L; sl_test[i].expected = "9223372032559808512";
+ i++; sl_test[i].num = 0x000000007FFFFFFFL; sl_test[i].expected = "2147483647";
+
+ i++; sl_test[i].num = 0x7FFF000000000000L; sl_test[i].expected = "9223090561878065152";
+ i++; sl_test[i].num = 0x00007FFF00000000L; sl_test[i].expected = "140733193388032";
+ i++; sl_test[i].num = 0x000000007FFF0000L; sl_test[i].expected = "2147418112";
+ i++; sl_test[i].num = 0x0000000000007FFFL; sl_test[i].expected = "32767";
+
+ i++; sl_test[i].num = 0x7F00000000000000L; sl_test[i].expected = "9151314442816847872";
+ i++; sl_test[i].num = 0x007F000000000000L; sl_test[i].expected = "35747322042253312";
+ i++; sl_test[i].num = 0x00007F0000000000L; sl_test[i].expected = "139637976727552";
+ i++; sl_test[i].num = 0x0000007F00000000L; sl_test[i].expected = "545460846592";
+ i++; sl_test[i].num = 0x000000007F000000L; sl_test[i].expected = "2130706432";
+ i++; sl_test[i].num = 0x00000000007F0000L; sl_test[i].expected = "8323072";
+ i++; sl_test[i].num = 0x0000000000007F00L; sl_test[i].expected = "32512";
+ i++; sl_test[i].num = 0x000000000000007FL; sl_test[i].expected = "127";
+
+ i++; sl_test[i].num = 0x7000000000000000L; sl_test[i].expected = "8070450532247928832";
+ i++; sl_test[i].num = 0x0700000000000000L; sl_test[i].expected = "504403158265495552";
+ i++; sl_test[i].num = 0x0070000000000000L; sl_test[i].expected = "31525197391593472";
+ i++; sl_test[i].num = 0x0007000000000000L; sl_test[i].expected = "1970324836974592";
+ i++; sl_test[i].num = 0x0000700000000000L; sl_test[i].expected = "123145302310912";
+ i++; sl_test[i].num = 0x0000070000000000L; sl_test[i].expected = "7696581394432";
+ i++; sl_test[i].num = 0x0000007000000000L; sl_test[i].expected = "481036337152";
+ i++; sl_test[i].num = 0x0000000700000000L; sl_test[i].expected = "30064771072";
+ i++; sl_test[i].num = 0x0000000070000000L; sl_test[i].expected = "1879048192";
+ i++; sl_test[i].num = 0x0000000007000000L; sl_test[i].expected = "117440512";
+ i++; sl_test[i].num = 0x0000000000700000L; sl_test[i].expected = "7340032";
+ i++; sl_test[i].num = 0x0000000000070000L; sl_test[i].expected = "458752";
+ i++; sl_test[i].num = 0x0000000000007000L; sl_test[i].expected = "28672";
+ i++; sl_test[i].num = 0x0000000000000700L; sl_test[i].expected = "1792";
+ i++; sl_test[i].num = 0x0000000000000070L; sl_test[i].expected = "112";
+ i++; sl_test[i].num = 0x0000000000000007L; sl_test[i].expected = "7";
+
+ i++; sl_test[i].num = 0x0000000000000001L; sl_test[i].expected = "1";
+ i++; sl_test[i].num = 0x0000000000000000L; sl_test[i].expected = "0";
+
+ i++; sl_test[i].num = -0x7FFFFFFFFFFFFFFFL -1L; sl_test[i].expected = "-9223372036854775808";
+ i++; sl_test[i].num = -0x7FFFFFFFFFFFFFFEL -1L; sl_test[i].expected = "-9223372036854775807";
+ i++; sl_test[i].num = -0x7FFFFFFFFFFFFFFDL -1L; sl_test[i].expected = "-9223372036854775806";
+ i++; sl_test[i].num = -0x7FFFFFFF00000000L -1L; sl_test[i].expected = "-9223372032559808513";
+ i++; sl_test[i].num = -0x000000007FFFFFFFL -1L; sl_test[i].expected = "-2147483648";
+
+ i++; sl_test[i].num = -0x7FFF000000000000L -1L; sl_test[i].expected = "-9223090561878065153";
+ i++; sl_test[i].num = -0x00007FFF00000000L -1L; sl_test[i].expected = "-140733193388033";
+ i++; sl_test[i].num = -0x000000007FFF0000L -1L; sl_test[i].expected = "-2147418113";
+ i++; sl_test[i].num = -0x0000000000007FFFL -1L; sl_test[i].expected = "-32768";
+
+ i++; sl_test[i].num = -0x7F00000000000000L -1L; sl_test[i].expected = "-9151314442816847873";
+ i++; sl_test[i].num = -0x007F000000000000L -1L; sl_test[i].expected = "-35747322042253313";
+ i++; sl_test[i].num = -0x00007F0000000000L -1L; sl_test[i].expected = "-139637976727553";
+ i++; sl_test[i].num = -0x0000007F00000000L -1L; sl_test[i].expected = "-545460846593";
+ i++; sl_test[i].num = -0x000000007F000000L -1L; sl_test[i].expected = "-2130706433";
+ i++; sl_test[i].num = -0x00000000007F0000L -1L; sl_test[i].expected = "-8323073";
+ i++; sl_test[i].num = -0x0000000000007F00L -1L; sl_test[i].expected = "-32513";
+ i++; sl_test[i].num = -0x000000000000007FL -1L; sl_test[i].expected = "-128";
+
+ i++; sl_test[i].num = -0x7000000000000000L -1L; sl_test[i].expected = "-8070450532247928833";
+ i++; sl_test[i].num = -0x0700000000000000L -1L; sl_test[i].expected = "-504403158265495553";
+ i++; sl_test[i].num = -0x0070000000000000L -1L; sl_test[i].expected = "-31525197391593473";
+ i++; sl_test[i].num = -0x0007000000000000L -1L; sl_test[i].expected = "-1970324836974593";
+ i++; sl_test[i].num = -0x0000700000000000L -1L; sl_test[i].expected = "-123145302310913";
+ i++; sl_test[i].num = -0x0000070000000000L -1L; sl_test[i].expected = "-7696581394433";
+ i++; sl_test[i].num = -0x0000007000000000L -1L; sl_test[i].expected = "-481036337153";
+ i++; sl_test[i].num = -0x0000000700000000L -1L; sl_test[i].expected = "-30064771073";
+ i++; sl_test[i].num = -0x0000000070000000L -1L; sl_test[i].expected = "-1879048193";
+ i++; sl_test[i].num = -0x0000000007000000L -1L; sl_test[i].expected = "-117440513";
+ i++; sl_test[i].num = -0x0000000000700000L -1L; sl_test[i].expected = "-7340033";
+ i++; sl_test[i].num = -0x0000000000070000L -1L; sl_test[i].expected = "-458753";
+ i++; sl_test[i].num = -0x0000000000007000L -1L; sl_test[i].expected = "-28673";
+ i++; sl_test[i].num = -0x0000000000000700L -1L; sl_test[i].expected = "-1793";
+ i++; sl_test[i].num = -0x0000000000000070L -1L; sl_test[i].expected = "-113";
+ i++; sl_test[i].num = -0x0000000000000007L -1L; sl_test[i].expected = "-8";
+
+ i++; sl_test[i].num = 0x0000000000000000L -1L; sl_test[i].expected = "-1";
+
+ num_slong_tests = i;
+
+#endif
+
+ for(i=1; i<=num_slong_tests; i++) {
+
+ for(j=0; j<BUFSZ; j++)
+ sl_test[i].result[j] = 'X';
+ sl_test[i].result[BUFSZ-1] = '\0';
+
+ (void)curl_msprintf(sl_test[i].result, "%ld", sl_test[i].num);
+
+ if(memcmp(sl_test[i].result,
+ sl_test[i].expected,
+ strlen(sl_test[i].expected))) {
+ printf("signed long test #%.2d: Failed (Expected: %s Got: %s)\n",
+ i, sl_test[i].expected, sl_test[i].result);
+ failed++;
+ }
+
+ }
+
+ if(!failed)
+ printf("All curl_mprintf() signed long tests OK!\n");
+ else
+ printf("Some curl_mprintf() signed long tests Failed!\n");
+
+ return failed;
+}
+
+
+static int test_curl_off_t_formatting(void)
+{
+ int i, j;
+ int num_cofft_tests;
+ int failed = 0;
+
+#if (CURL_SIZEOF_CURL_OFF_T == 2)
+
+ i=1; co_test[i].num = MPRNT_OFF_T_C(0x7FFF); co_test[i].expected = "32767";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFE); co_test[i].expected = "32766";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFD); co_test[i].expected = "32765";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x7F00); co_test[i].expected = "32512";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x07F0); co_test[i].expected = "2032";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x007F); co_test[i].expected = "127";
+
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x7000); co_test[i].expected = "28672";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0700); co_test[i].expected = "1792";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0070); co_test[i].expected = "112";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0007); co_test[i].expected = "7";
+
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x5000); co_test[i].expected = "20480";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0500); co_test[i].expected = "1280";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0050); co_test[i].expected = "80";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0005); co_test[i].expected = "5";
+
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0001); co_test[i].expected = "1";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000); co_test[i].expected = "0";
+
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFF) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32768";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFE) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32767";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFD) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32766";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x7F00) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32513";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x07F0) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2033";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x007F) -MPRNT_OFF_T_C(1); co_test[i].expected = "-128";
+
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x7000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-28673";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0700) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1793";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0070) -MPRNT_OFF_T_C(1); co_test[i].expected = "-113";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0007) -MPRNT_OFF_T_C(1); co_test[i].expected = "-8";
+
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x5000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-20481";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0500) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1281";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0050) -MPRNT_OFF_T_C(1); co_test[i].expected = "-81";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0005) -MPRNT_OFF_T_C(1); co_test[i].expected = "-6";
+
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1";
+
+ num_cofft_tests = i;
+
+#elif (CURL_SIZEOF_CURL_OFF_T == 4)
+
+ i=1; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFF); co_test[i].expected = "2147483647";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFE); co_test[i].expected = "2147483646";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFD); co_test[i].expected = "2147483645";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFF0000); co_test[i].expected = "2147418112";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00007FFF); co_test[i].expected = "32767";
+
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x7F000000); co_test[i].expected = "2130706432";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x007F0000); co_test[i].expected = "8323072";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00007F00); co_test[i].expected = "32512";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000007F); co_test[i].expected = "127";
+
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x70000000); co_test[i].expected = "1879048192";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x07000000); co_test[i].expected = "117440512";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00700000); co_test[i].expected = "7340032";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00070000); co_test[i].expected = "458752";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00007000); co_test[i].expected = "28672";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00000700); co_test[i].expected = "1792";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00000070); co_test[i].expected = "112";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00000007); co_test[i].expected = "7";
+
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x50000000); co_test[i].expected = "1342177280";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x05000000); co_test[i].expected = "83886080";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00500000); co_test[i].expected = "5242880";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00050000); co_test[i].expected = "327680";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00005000); co_test[i].expected = "20480";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00000500); co_test[i].expected = "1280";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00000050); co_test[i].expected = "80";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00000005); co_test[i].expected = "5";
+
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00000001); co_test[i].expected = "1";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00000000); co_test[i].expected = "0";
+
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFF) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2147483648";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFE) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2147483647";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFD) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2147483646";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFF0000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2147418113";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x00007FFF) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32768";
+
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x7F000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2130706433";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x007F0000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-8323073";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x00007F00) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32513";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000007F) -MPRNT_OFF_T_C(1); co_test[i].expected = "-128";
+
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x70000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1879048193";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x07000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-117440513";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x00700000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-7340033";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x00070000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-458753";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x00007000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-28673";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x00000700) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1793";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x00000070) -MPRNT_OFF_T_C(1); co_test[i].expected = "-113";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x00000007) -MPRNT_OFF_T_C(1); co_test[i].expected = "-8";
+
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x50000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1342177281";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x05000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-83886081";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x00500000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-5242881";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x00050000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-327681";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x00005000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-20481";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x00000500) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1281";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x00000050) -MPRNT_OFF_T_C(1); co_test[i].expected = "-81";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x00000005) -MPRNT_OFF_T_C(1); co_test[i].expected = "-6";
+
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1";
+
+ num_cofft_tests = i;
+
+#elif (CURL_SIZEOF_CURL_OFF_T == 8)
+
+ i=1; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFF); co_test[i].expected = "9223372036854775807";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFE); co_test[i].expected = "9223372036854775806";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFD); co_test[i].expected = "9223372036854775805";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFF00000000); co_test[i].expected = "9223372032559808512";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x000000007FFFFFFF); co_test[i].expected = "2147483647";
+
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFF000000000000); co_test[i].expected = "9223090561878065152";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00007FFF00000000); co_test[i].expected = "140733193388032";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x000000007FFF0000); co_test[i].expected = "2147418112";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000007FFF); co_test[i].expected = "32767";
+
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x7F00000000000000); co_test[i].expected = "9151314442816847872";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x007F000000000000); co_test[i].expected = "35747322042253312";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00007F0000000000); co_test[i].expected = "139637976727552";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000007F00000000); co_test[i].expected = "545460846592";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x000000007F000000); co_test[i].expected = "2130706432";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x00000000007F0000); co_test[i].expected = "8323072";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000007F00); co_test[i].expected = "32512";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x000000000000007F); co_test[i].expected = "127";
+
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x7000000000000000); co_test[i].expected = "8070450532247928832";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0700000000000000); co_test[i].expected = "504403158265495552";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0070000000000000); co_test[i].expected = "31525197391593472";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0007000000000000); co_test[i].expected = "1970324836974592";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000700000000000); co_test[i].expected = "123145302310912";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000070000000000); co_test[i].expected = "7696581394432";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000007000000000); co_test[i].expected = "481036337152";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000700000000); co_test[i].expected = "30064771072";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000070000000); co_test[i].expected = "1879048192";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000007000000); co_test[i].expected = "117440512";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000700000); co_test[i].expected = "7340032";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000070000); co_test[i].expected = "458752";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000007000); co_test[i].expected = "28672";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000700); co_test[i].expected = "1792";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000070); co_test[i].expected = "112";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000007); co_test[i].expected = "7";
+
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000001); co_test[i].expected = "1";
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000000); co_test[i].expected = "0";
+
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFF) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9223372036854775808";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFE) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9223372036854775807";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFD) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9223372036854775806";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFF00000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9223372032559808513";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x000000007FFFFFFF) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2147483648";
+
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFF000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9223090561878065153";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x00007FFF00000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-140733193388033";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x000000007FFF0000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2147418113";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000007FFF) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32768";
+
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x7F00000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9151314442816847873";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x007F000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-35747322042253313";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x00007F0000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-139637976727553";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000007F00000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-545460846593";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x000000007F000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2130706433";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x00000000007F0000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-8323073";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000007F00) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32513";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x000000000000007F) -MPRNT_OFF_T_C(1); co_test[i].expected = "-128";
+
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x7000000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-8070450532247928833";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0700000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-504403158265495553";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0070000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-31525197391593473";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0007000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1970324836974593";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000700000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-123145302310913";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000070000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-7696581394433";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000007000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-481036337153";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000700000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-30064771073";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000070000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1879048193";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000007000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-117440513";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000700000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-7340033";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000070000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-458753";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000007000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-28673";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000000700) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1793";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000000070) -MPRNT_OFF_T_C(1); co_test[i].expected = "-113";
+ i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000000007) -MPRNT_OFF_T_C(1); co_test[i].expected = "-8";
+
+ i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1";
+
+ num_cofft_tests = i;
+
+#endif
+
+ for(i=1; i<=num_cofft_tests; i++) {
+
+ for(j=0; j<BUFSZ; j++)
+ co_test[i].result[j] = 'X';
+ co_test[i].result[BUFSZ-1] = '\0';
+
+ (void)curl_msprintf(co_test[i].result, "%" FORMAT_OFF_T, co_test[i].num);
+
+ if(memcmp(co_test[i].result,
+ co_test[i].expected,
+ strlen(co_test[i].expected))) {
+ printf("curl_off_t test #%.2d: Failed (Expected: %s Got: %s)\n",
+ i, co_test[i].expected, co_test[i].result);
+ failed++;
+ }
+
+ }
+
+ if(!failed)
+ printf("All curl_mprintf() curl_off_t tests OK!\n");
+ else
+ printf("Some curl_mprintf() curl_off_t tests Failed!\n");
+
+ return failed;
+}
+
+
+int test(char *URL)
+{
+ int errors = 0;
+ (void)URL; /* not used */
+
+ errors += test_unsigned_short_formatting();
+
+ errors += test_signed_short_formatting();
+
+ errors += test_unsigned_int_formatting();
+
+ errors += test_signed_int_formatting();
+
+ errors += test_unsigned_long_formatting();
+
+ errors += test_signed_long_formatting();
+
+ errors += test_curl_off_t_formatting();
+
+ if(errors)
+ return TEST_ERR_MAJOR_BAD;
+ else
+ return 0;
+}
diff --git a/tests/libtest/lib560.c b/tests/libtest/lib560.c
new file mode 100644
index 000000000..e8be1c7bd
--- /dev/null
+++ b/tests/libtest/lib560.c
@@ -0,0 +1,113 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+/*
+ * Simply download a HTTPS file!
+ *
+ * This test was added after the HTTPS-using-multi-interface with OpenSSL
+ * regression of 7.19.1 to hopefully prevent this embarassing mistake from
+ * appearing again... Unfortunately the bug wasn't triggered by this test,
+ * which presumably is because the connect to a local server is too
+ * fast/different compared to the real/distant servers we saw the bug happen
+ * with.
+ */
+int test(char *URL)
+{
+ CURL *http_handle = NULL;
+ CURLM *multi_handle = NULL;
+ int res = 0;
+
+ int still_running; /* keep number of running handles */
+
+ start_test_timing();
+
+ /*
+ ** curl_global_init called indirectly from curl_easy_init.
+ */
+
+ easy_init(http_handle);
+
+ /* set options */
+ easy_setopt(http_handle, CURLOPT_URL, URL);
+ easy_setopt(http_handle, CURLOPT_HEADER, 1L);
+ easy_setopt(http_handle, CURLOPT_SSL_VERIFYPEER, 0L);
+ easy_setopt(http_handle, CURLOPT_SSL_VERIFYHOST, 0L);
+
+ /* init a multi stack */
+ multi_init(multi_handle);
+
+ /* add the individual transfers */
+ multi_add_handle(multi_handle, http_handle);
+
+ /* we start some action by calling perform right away */
+ multi_perform(multi_handle, &still_running);
+
+ abort_on_test_timeout();
+
+ while(still_running) {
+ struct timeval timeout;
+
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ int maxfd = -99;
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ /* set a suitable timeout to play around with */
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ /* get file descriptors from the transfers */
+ multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ abort_on_test_timeout();
+
+ /* timeout or readable/writable sockets */
+ multi_perform(multi_handle, &still_running);
+
+ abort_on_test_timeout();
+ }
+
+test_cleanup:
+
+ /* undocumented cleanup sequence - type UA */
+
+ curl_multi_cleanup(multi_handle);
+ curl_easy_cleanup(http_handle);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib562.c b/tests/libtest/lib562.c
new file mode 100644
index 000000000..a5f0ea534
--- /dev/null
+++ b/tests/libtest/lib562.c
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include "memdebug.h"
+
+/*
+ * From "KNOWN_BUGS" April 2009:
+
+ 59. If the CURLOPT_PORT option is used on an FTP URL like
+ "ftp://example.com/file;type=A" the ";type=A" is stripped off.
+
+ */
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res = CURLE_OK;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* get a curl handle */
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* enable verbose */
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* set port number */
+ test_setopt(curl, CURLOPT_PORT, strtol(libtest_arg2, NULL, 10));
+
+ /* specify target */
+ test_setopt(curl,CURLOPT_URL, URL);
+
+ /* Now run off and do what you've been told! */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib564.c b/tests/libtest/lib564.c
new file mode 100644
index 000000000..ed00e1bf6
--- /dev/null
+++ b/tests/libtest/lib564.c
@@ -0,0 +1,93 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include <fcntl.h>
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+int test(char *URL)
+{
+ int res = 0;
+ CURL *curl = NULL;
+ int running;
+ CURLM *m = NULL;
+
+ start_test_timing();
+
+ global_init(CURL_GLOBAL_ALL);
+
+ easy_init(curl);
+
+ easy_setopt(curl, CURLOPT_URL, URL);
+ easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+ easy_setopt(curl, CURLOPT_PROXY, libtest_arg2);
+ easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
+
+ multi_init(m);
+
+ multi_add_handle(m, curl);
+
+ fprintf(stderr, "Start at URL 0\n");
+
+ for(;;) {
+ struct timeval interval;
+ fd_set rd, wr, exc;
+ int maxfd = -99;
+
+ interval.tv_sec = 1;
+ interval.tv_usec = 0;
+
+ multi_perform(m, &running);
+
+ abort_on_test_timeout();
+
+ if(!running)
+ break; /* done */
+
+ FD_ZERO(&rd);
+ FD_ZERO(&wr);
+ FD_ZERO(&exc);
+
+ multi_fdset(m, &rd, &wr, &exc, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ select_test(maxfd+1, &rd, &wr, &exc, &interval);
+
+ abort_on_test_timeout();
+ }
+
+test_cleanup:
+
+ /* undocumented cleanup sequence - type UB */
+
+ curl_easy_cleanup(curl);
+ curl_multi_cleanup(m);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib566.c b/tests/libtest/lib566.c
new file mode 100644
index 000000000..ba839d65f
--- /dev/null
+++ b/tests/libtest/lib566.c
@@ -0,0 +1,67 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+
+ double content_length = 3;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+
+ res = curl_easy_perform(curl);
+
+ if(!res) {
+ FILE *moo;
+ res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD,
+ &content_length);
+ moo = fopen(libtest_arg2, "wb");
+ if(moo) {
+ fprintf(moo, "CL: %.0f\n", content_length);
+ fclose(moo);
+ }
+ }
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
+
diff --git a/tests/libtest/lib567.c b/tests/libtest/lib567.c
new file mode 100644
index 000000000..573529cd8
--- /dev/null
+++ b/tests/libtest/lib567.c
@@ -0,0 +1,69 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+/*
+ * Test a simple OPTIONS request with a custom header
+ */
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+ struct curl_slist *custom_headers=NULL;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* Dump data to stdout for protocol verification */
+ test_setopt(curl, CURLOPT_HEADERDATA, stdout);
+ test_setopt(curl, CURLOPT_WRITEDATA, stdout);
+
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, URL);
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS);
+ test_setopt(curl, CURLOPT_USERAGENT, "test567");
+
+ custom_headers = curl_slist_append(custom_headers, "Test-Number: 567");
+ test_setopt(curl, CURLOPT_RTSPHEADER, custom_headers);
+
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ if(custom_headers)
+ curl_slist_free_all(custom_headers);
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
+
diff --git a/tests/libtest/lib568.c b/tests/libtest/lib568.c
new file mode 100644
index 000000000..4b15821f2
--- /dev/null
+++ b/tests/libtest/lib568.c
@@ -0,0 +1,175 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include <curl/mprintf.h>
+
+#include "memdebug.h"
+
+/* build request url */
+static char *suburl(const char *base, int i)
+{
+ return curl_maprintf("%s%.4d", base, i);
+}
+
+/*
+ * Test the Client->Server ANNOUNCE functionality (PUT style)
+ */
+int test(char *URL)
+{
+ int res;
+ CURL *curl;
+ int sdp;
+ FILE *sdpf = NULL;
+ struct_stat file_info;
+ char *stream_uri = NULL;
+ int request=1;
+ struct curl_slist *custom_headers=NULL;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_HEADERDATA, stdout);
+ test_setopt(curl, CURLOPT_WRITEDATA, stdout);
+
+ test_setopt(curl, CURLOPT_URL, URL);
+
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ sdp = open("log/file568.txt", O_RDONLY);
+ fstat(sdp, &file_info);
+ close(sdp);
+
+ sdpf = fopen("log/file568.txt", "rb");
+ if(sdpf == NULL) {
+ fprintf(stderr, "can't open log/file568.txt\n");
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_ANNOUNCE);
+
+ test_setopt(curl, CURLOPT_READDATA, sdpf);
+ test_setopt(curl, CURLOPT_UPLOAD, 1L);
+ test_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t) file_info.st_size);
+
+ /* Do the ANNOUNCE */
+ res = curl_easy_perform(curl);
+ if(res)
+ goto test_cleanup;
+
+ test_setopt(curl, CURLOPT_UPLOAD, 0L);
+ fclose(sdpf);
+ sdpf = NULL;
+
+ /* Make sure we can do a normal request now */
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_DESCRIBE);
+ res = curl_easy_perform(curl);
+ if(res)
+ goto test_cleanup;
+
+ /* Now do a POST style one */
+
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ custom_headers = curl_slist_append(custom_headers,
+ "Content-Type: posty goodness");
+ if(!custom_headers) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSPHEADER, custom_headers);
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_ANNOUNCE);
+ test_setopt(curl, CURLOPT_POSTFIELDS, "postyfield=postystuff&project=curl\n");
+
+ res = curl_easy_perform(curl);
+ if(res)
+ goto test_cleanup;
+
+ test_setopt(curl, CURLOPT_POSTFIELDS, NULL);
+ test_setopt(curl, CURLOPT_RTSPHEADER, NULL);
+ curl_slist_free_all(custom_headers);
+ custom_headers = NULL;
+
+ /* Make sure we can do a normal request now */
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS);
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ if(sdpf)
+ fclose(sdpf);
+
+ if(stream_uri)
+ free(stream_uri);
+
+ if(custom_headers)
+ curl_slist_free_all(custom_headers);
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return res;
+}
+
diff --git a/tests/libtest/lib569.c b/tests/libtest/lib569.c
new file mode 100644
index 000000000..a434d7459
--- /dev/null
+++ b/tests/libtest/lib569.c
@@ -0,0 +1,129 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include <curl/mprintf.h>
+
+#include "memdebug.h"
+
+/* build request url */
+static char *suburl(const char *base, int i)
+{
+ return curl_maprintf("%s%.4d", base, i);
+}
+
+/*
+ * Test Session ID capture
+ */
+int test(char *URL)
+{
+ int res;
+ CURL *curl;
+ char *stream_uri = NULL;
+ char *rtsp_session_id;
+ int request=1;
+ int i;
+ FILE *idfile = NULL;
+
+ idfile = fopen(libtest_arg2, "wb");
+ if(idfile == NULL) {
+ fprintf(stderr, "couldn't open the Session ID File\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ fclose(idfile);
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ fclose(idfile);
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_HEADERDATA, stdout);
+ test_setopt(curl, CURLOPT_WRITEDATA, stdout);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ test_setopt(curl, CURLOPT_URL, URL);
+
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP);
+ res = curl_easy_perform(curl);
+ if(res != (int)CURLE_BAD_FUNCTION_ARGUMENT) {
+ fprintf(stderr, "This should have failed. "
+ "Cannot setup without a Transport: header");
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+
+ /* Go through the various Session IDs */
+ for(i = 0; i < 3; i++) {
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP);
+ test_setopt(curl, CURLOPT_RTSP_TRANSPORT, "Fake/NotReal/JustATest;foo=baz");
+ res = curl_easy_perform(curl);
+ if(res)
+ goto test_cleanup;
+
+ curl_easy_getinfo(curl, CURLINFO_RTSP_SESSION_ID, &rtsp_session_id);
+ fprintf(idfile, "Got Session ID: [%s]\n", rtsp_session_id);
+ rtsp_session_id = NULL;
+
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_TEARDOWN);
+ res = curl_easy_perform(curl);
+
+ /* Clear for the next go-round */
+ test_setopt(curl, CURLOPT_RTSP_SESSION_ID, NULL);
+ }
+
+test_cleanup:
+
+ if(idfile)
+ fclose(idfile);
+
+ if(stream_uri)
+ free(stream_uri);
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return res;
+}
+
diff --git a/tests/libtest/lib570.c b/tests/libtest/lib570.c
new file mode 100644
index 000000000..a9fac9915
--- /dev/null
+++ b/tests/libtest/lib570.c
@@ -0,0 +1,117 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include <curl/mprintf.h>
+
+#include "memdebug.h"
+
+/* build request url */
+static char *suburl(const char *base, int i)
+{
+ return curl_maprintf("%s%.4d", base, i);
+}
+
+int test(char *URL)
+{
+ int res;
+ CURL *curl;
+ int request=1;
+ char *stream_uri = NULL;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_HEADERDATA, stdout);
+ test_setopt(curl, CURLOPT_WRITEDATA, stdout);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ test_setopt(curl, CURLOPT_URL, URL);
+
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS);
+
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ res = curl_easy_perform(curl);
+ if(res != (int)CURLE_RTSP_CSEQ_ERROR) {
+ fprintf(stderr, "Failed to detect CSeq mismatch");
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+
+ test_setopt(curl, CURLOPT_RTSP_CLIENT_CSEQ, 999);
+ test_setopt(curl, CURLOPT_RTSP_TRANSPORT,
+ "RAW/RAW/UDP;unicast;client_port=3056-3057");
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP);
+
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ res = curl_easy_perform(curl);
+ if(res)
+ goto test_cleanup;
+
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_PLAY);
+
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ res = curl_easy_perform(curl);
+ if(res != CURLE_RTSP_SESSION_ERROR) {
+ fprintf(stderr, "Failed to detect a Session ID mismatch");
+ }
+
+test_cleanup:
+
+ if(stream_uri)
+ free(stream_uri);
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return res;
+}
+
diff --git a/tests/libtest/lib571.c b/tests/libtest/lib571.c
new file mode 100644
index 000000000..ba0aa1ce4
--- /dev/null
+++ b/tests/libtest/lib571.c
@@ -0,0 +1,212 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#include <curl/mprintf.h>
+
+#include "warnless.h"
+#include "memdebug.h"
+
+#define RTP_PKT_CHANNEL(p) ((int)((unsigned char)((p)[1])))
+
+#define RTP_PKT_LENGTH(p) ((((int)((unsigned char)((p)[2]))) << 8) | \
+ ((int)((unsigned char)((p)[3]))))
+
+#define RTP_DATA_SIZE 12
+static const char *RTP_DATA = "$_1234\n\0asdf";
+
+static int rtp_packet_count = 0;
+
+static size_t rtp_write(void *ptr, size_t size, size_t nmemb, void *stream) {
+ char *data = (char *)ptr;
+ int channel = RTP_PKT_CHANNEL(data);
+ int message_size;
+ int coded_size = RTP_PKT_LENGTH(data);
+ size_t failure = (size * nmemb) ? 0 : 1;
+ int i;
+ (void)stream;
+
+ message_size = curlx_uztosi(size * nmemb) - 4;
+
+ printf("RTP: message size %d, channel %d\n", message_size, channel);
+ if(message_size != coded_size) {
+ printf("RTP embedded size (%d) does not match the write size (%d).\n",
+ coded_size, message_size);
+ return failure;
+ }
+
+ data += 4;
+ for(i = 0; i < message_size; i+= RTP_DATA_SIZE) {
+ if(message_size - i > RTP_DATA_SIZE) {
+ if(memcmp(RTP_DATA, data + i, RTP_DATA_SIZE) != 0) {
+ printf("RTP PAYLOAD CORRUPTED [%s]\n", data + i);
+ return failure;
+ }
+ } else {
+ if (memcmp(RTP_DATA, data + i, message_size - i) != 0) {
+ printf("RTP PAYLOAD END CORRUPTED (%d), [%s]\n",
+ message_size - i, data + i);
+ return failure;
+ }
+ }
+ }
+
+ rtp_packet_count++;
+ fprintf(stderr, "packet count is %d\n", rtp_packet_count);
+
+ return size * nmemb;
+}
+
+/* build request url */
+static char *suburl(const char *base, int i)
+{
+ return curl_maprintf("%s%.4d", base, i);
+}
+
+int test(char *URL)
+{
+ int res;
+ CURL *curl;
+ char *stream_uri = NULL;
+ int request=1;
+ FILE *protofile = NULL;
+
+ protofile = fopen(libtest_arg2, "wb");
+ if(protofile == NULL) {
+ fprintf(stderr, "Couldn't open the protocol dump file\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ fclose(protofile);
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ fclose(protofile);
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+ test_setopt(curl, CURLOPT_URL, URL);
+
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ test_setopt(curl, CURLOPT_INTERLEAVEFUNCTION, rtp_write);
+ test_setopt(curl, CURLOPT_TIMEOUT, 3);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+ test_setopt(curl, CURLOPT_WRITEDATA, protofile);
+
+ test_setopt(curl, CURLOPT_RTSP_TRANSPORT, "RTP/AVP/TCP;interleaved=0-1");
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP);
+
+ res = curl_easy_perform(curl);
+ if(res)
+ goto test_cleanup;
+
+ /* This PLAY starts the interleave */
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_PLAY);
+
+ res = curl_easy_perform(curl);
+ if(res)
+ goto test_cleanup;
+
+ /* The DESCRIBE request will try to consume data after the Content */
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_DESCRIBE);
+
+ res = curl_easy_perform(curl);
+ if(res)
+ goto test_cleanup;
+
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_PLAY);
+
+ res = curl_easy_perform(curl);
+ if(res)
+ goto test_cleanup;
+
+ fprintf(stderr, "PLAY COMPLETE\n");
+
+ /* Use Receive to get the rest of the data */
+ while(!res && rtp_packet_count < 13) {
+ fprintf(stderr, "LOOPY LOOP!\n");
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_RECEIVE);
+ res = curl_easy_perform(curl);
+ }
+
+test_cleanup:
+
+ if(stream_uri)
+ free(stream_uri);
+
+ if(protofile)
+ fclose(protofile);
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return res;
+}
+
diff --git a/tests/libtest/lib572.c b/tests/libtest/lib572.c
new file mode 100644
index 000000000..3df4d036a
--- /dev/null
+++ b/tests/libtest/lib572.c
@@ -0,0 +1,181 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include <curl/mprintf.h>
+
+#include "memdebug.h"
+
+/* build request url */
+static char *suburl(const char *base, int i)
+{
+ return curl_maprintf("%s%.4d", base, i);
+}
+
+/*
+ * Test GET_PARAMETER: PUT, HEARTBEAT, and POST
+ */
+int test(char *URL)
+{
+ int res;
+ CURL *curl;
+ int params;
+ FILE *paramsf = NULL;
+ struct_stat file_info;
+ char *stream_uri = NULL;
+ int request=1;
+ struct curl_slist *custom_headers=NULL;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+
+ test_setopt(curl, CURLOPT_HEADERDATA, stdout);
+ test_setopt(curl, CURLOPT_WRITEDATA, stdout);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ test_setopt(curl, CURLOPT_URL, URL);
+
+ /* SETUP */
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ test_setopt(curl, CURLOPT_RTSP_TRANSPORT, "Planes/Trains/Automobiles");
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP);
+ res = curl_easy_perform(curl);
+ if(res)
+ goto test_cleanup;
+
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ /* PUT style GET_PARAMETERS */
+ params = open("log/file572.txt", O_RDONLY);
+ fstat(params, &file_info);
+ close(params);
+
+ paramsf = fopen("log/file572.txt", "rb");
+ if(paramsf == NULL) {
+ fprintf(stderr, "can't open log/file572.txt\n");
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_GET_PARAMETER);
+
+ test_setopt(curl, CURLOPT_READDATA, paramsf);
+ test_setopt(curl, CURLOPT_UPLOAD, 1L);
+ test_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t) file_info.st_size);
+
+ res = curl_easy_perform(curl);
+ if(res)
+ goto test_cleanup;
+
+ test_setopt(curl, CURLOPT_UPLOAD, 0L);
+ fclose(paramsf);
+ paramsf = NULL;
+
+ /* Heartbeat GET_PARAMETERS */
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ res = curl_easy_perform(curl);
+ if(res)
+ goto test_cleanup;
+
+ /* POST GET_PARAMETERS */
+
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_GET_PARAMETER);
+ test_setopt(curl, CURLOPT_POSTFIELDS, "packets_received\njitter\n");
+
+ res = curl_easy_perform(curl);
+ if(res)
+ goto test_cleanup;
+
+ test_setopt(curl, CURLOPT_POSTFIELDS, NULL);
+
+ /* Make sure we can do a normal request now */
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS);
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ if(paramsf)
+ fclose(paramsf);
+
+ if(stream_uri)
+ free(stream_uri);
+
+ if(custom_headers)
+ curl_slist_free_all(custom_headers);
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return res;
+}
+
diff --git a/tests/libtest/lib573.c b/tests/libtest/lib573.c
new file mode 100644
index 000000000..b49d26a5d
--- /dev/null
+++ b/tests/libtest/lib573.c
@@ -0,0 +1,113 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testtrace.h"
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+/*
+ * Get a single URL without select().
+ */
+
+int test(char *URL)
+{
+ CURL *c = NULL;
+ CURLM *m = NULL;
+ int res = 0;
+ int running = 1;
+ double connect_time = 0.0;
+ double dbl_epsilon;
+
+ dbl_epsilon = 1.0;
+ do {
+ dbl_epsilon /= 2.0;
+ } while ((double)(1.0 + (dbl_epsilon/2.0)) > (double)1.0);
+
+ start_test_timing();
+
+ global_init(CURL_GLOBAL_ALL);
+
+ easy_init(c);
+
+ easy_setopt(c, CURLOPT_HEADER, 1L);
+ easy_setopt(c, CURLOPT_URL, URL);
+
+ libtest_debug_config.nohex = 1;
+ libtest_debug_config.tracetime = 1;
+ easy_setopt(c, CURLOPT_DEBUGDATA, &libtest_debug_config);
+ easy_setopt(c, CURLOPT_DEBUGFUNCTION, libtest_debug_cb);
+ easy_setopt(c, CURLOPT_VERBOSE, 1L);
+
+ multi_init(m);
+
+ multi_add_handle(m, c);
+
+ while (running) {
+ struct timeval timeout;
+ fd_set fdread, fdwrite, fdexcep;
+ int maxfd = -99;
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 100000L; /* 100 ms */
+
+ multi_perform(m, &running);
+
+ abort_on_test_timeout();
+
+ if(!running)
+ break; /* done */
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ multi_fdset(m, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ abort_on_test_timeout();
+ }
+
+ curl_easy_getinfo(c, CURLINFO_CONNECT_TIME, &connect_time);
+ if (connect_time < dbl_epsilon) {
+ fprintf(stderr, "connect time is < epsilon\n");
+ res = TEST_ERR_MAJOR_BAD;
+ }
+
+test_cleanup:
+
+ /* proper cleanup sequence - type PA */
+
+ curl_multi_remove_handle(m, c);
+ curl_multi_cleanup(m);
+ curl_easy_cleanup(c);
+ curl_global_cleanup();
+
+ return res;
+}
+
diff --git a/tests/libtest/lib574.c b/tests/libtest/lib574.c
new file mode 100644
index 000000000..afb2bceae
--- /dev/null
+++ b/tests/libtest/lib574.c
@@ -0,0 +1,68 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+static int new_fnmatch(const char *pattern, const char *string)
+{
+ (void)pattern;
+ (void)string;
+ return CURL_FNMATCHFUNC_MATCH;
+}
+
+int test(char *URL)
+{
+ int res;
+ CURL *curl;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_WILDCARDMATCH, 1L);
+ test_setopt(curl, CURLOPT_FNMATCH_FUNCTION, new_fnmatch);
+
+ res = curl_easy_perform(curl);
+ if(res) {
+ fprintf(stderr, "curl_easy_perform() failed %d\n", res);
+ goto test_cleanup;
+ }
+ res = curl_easy_perform(curl);
+ if(res) {
+ fprintf(stderr, "curl_easy_perform() failed %d\n", res);
+ goto test_cleanup;
+ }
+
+test_cleanup:
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+ return res;
+}
diff --git a/tests/libtest/lib575.c b/tests/libtest/lib575.c
new file mode 100644
index 000000000..942df68c5
--- /dev/null
+++ b/tests/libtest/lib575.c
@@ -0,0 +1,114 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include <fcntl.h>
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+/* 3x download!
+ * 1. normal
+ * 2. dup handle
+ * 3. with multi interface
+ */
+
+int test(char *URL)
+{
+ CURL *handle = NULL;
+ CURL *duphandle = NULL;
+ CURLM *mhandle = NULL;
+ int res = 0;
+ int still_running = 0;
+
+ start_test_timing();
+
+ global_init(CURL_GLOBAL_ALL);
+
+ easy_init(handle);
+
+ easy_setopt(handle, CURLOPT_URL, URL);
+ easy_setopt(handle, CURLOPT_WILDCARDMATCH, 1L);
+ easy_setopt(handle, CURLOPT_VERBOSE, 1L);
+
+ res = curl_easy_perform(handle);
+ if(res)
+ goto test_cleanup;
+
+ res = curl_easy_perform(handle);
+ if(res)
+ goto test_cleanup;
+
+ duphandle = curl_easy_duphandle(handle);
+ if(!duphandle)
+ goto test_cleanup;
+ curl_easy_cleanup(handle);
+ handle = duphandle;
+
+ multi_init(mhandle);
+
+ multi_add_handle(mhandle, handle);
+
+ multi_perform(mhandle, &still_running);
+
+ abort_on_test_timeout();
+
+ while(still_running) {
+ struct timeval timeout;
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ int maxfd = -99;
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 100000L; /* 100 ms */
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ multi_fdset(mhandle, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ abort_on_test_timeout();
+
+ multi_perform(mhandle, &still_running);
+
+ abort_on_test_timeout();
+ }
+
+test_cleanup:
+
+ /* undocumented cleanup sequence - type UA */
+
+ curl_multi_cleanup(mhandle);
+ curl_easy_cleanup(handle);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib576.c b/tests/libtest/lib576.c
new file mode 100644
index 000000000..61bb61325
--- /dev/null
+++ b/tests/libtest/lib576.c
@@ -0,0 +1,124 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testutil.h"
+#include "memdebug.h"
+
+typedef struct {
+ int remains;
+ int print_content;
+} chunk_data_t;
+
+static
+long chunk_bgn(const struct curl_fileinfo *finfo, void *ptr, int remains);
+static
+long chunk_end(void *ptr);
+
+static
+long chunk_bgn(const struct curl_fileinfo *finfo, void *ptr, int remains)
+{
+ chunk_data_t *ch_d = ptr;
+ ch_d->remains = remains;
+
+ printf("=============================================================\n");
+ printf("Remains: %d\n", remains);
+ printf("Filename: %s\n", finfo->filename);
+ if(finfo->strings.perm) {
+ printf("Permissions: %s", finfo->strings.perm);
+ if(finfo->flags & CURLFINFOFLAG_KNOWN_PERM)
+ printf(" (parsed => %o)", finfo->perm);
+ printf("\n");
+ }
+ printf("Size: %ldB\n", (long)finfo->size);
+ if(finfo->strings.user)
+ printf("User: %s\n", finfo->strings.user);
+ if(finfo->strings.group)
+ printf("Group: %s\n", finfo->strings.group);
+ if(finfo->strings.time)
+ printf("Time: %s\n", finfo->strings.time);
+ printf("Filetype: ");
+ switch(finfo->filetype) {
+ case CURLFILETYPE_FILE:
+ printf("regular file\n");
+ break;
+ case CURLFILETYPE_DIRECTORY:
+ printf("directory\n");
+ break;
+ case CURLFILETYPE_SYMLINK:
+ printf("symlink\n");
+ printf("Target: %s\n", finfo->strings.target);
+ break;
+ default:
+ printf("other type\n");
+ break;
+ }
+ if(finfo->filetype == CURLFILETYPE_FILE) {
+ ch_d->print_content = 1;
+ printf("Content:\n-------------------------------------------------------------\n");
+ }
+ if(strcmp(finfo->filename, "someothertext.txt") == 0) {
+ printf("# THIS CONTENT WAS SKIPPED IN CHUNK_BGN CALLBACK #\n");
+ return CURL_CHUNK_BGN_FUNC_SKIP;
+ }
+ return CURL_CHUNK_BGN_FUNC_OK;
+}
+
+static
+long chunk_end(void *ptr)
+{
+ chunk_data_t *ch_d = ptr;
+ if(ch_d->print_content) {
+ ch_d->print_content = 0;
+ printf("-------------------------------------------------------------\n");
+ }
+ if(ch_d->remains == 1)
+ printf("=============================================================\n");
+ return CURL_CHUNK_END_FUNC_OK;
+}
+
+int test(char *URL)
+{
+ CURL *handle = NULL;
+ CURLcode res = CURLE_OK;
+ chunk_data_t chunk_data = {0,0};
+ curl_global_init(CURL_GLOBAL_ALL);
+ handle = curl_easy_init();
+ if(!handle) {
+ res = CURLE_OUT_OF_MEMORY;
+ goto test_cleanup;
+ }
+
+ test_setopt(handle, CURLOPT_URL, URL);
+ test_setopt(handle, CURLOPT_WILDCARDMATCH, 1L);
+ test_setopt(handle, CURLOPT_CHUNK_BGN_FUNCTION, chunk_bgn);
+ test_setopt(handle, CURLOPT_CHUNK_END_FUNCTION, chunk_end);
+ test_setopt(handle, CURLOPT_CHUNK_DATA, &chunk_data);
+
+ res = curl_easy_perform(handle);
+
+test_cleanup:
+ if(handle)
+ curl_easy_cleanup(handle);
+ curl_global_cleanup();
+ return res;
+}
diff --git a/tests/libtest/lib578.c b/tests/libtest/lib578.c
new file mode 100644
index 000000000..a39b31772
--- /dev/null
+++ b/tests/libtest/lib578.c
@@ -0,0 +1,102 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+/* The size of data should be kept below MAX_INITIAL_POST_SIZE! */
+static char data[]="this is a short string.\n";
+
+static size_t data_size = sizeof(data) / sizeof(char);
+
+static int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
+{
+ FILE *moo = fopen(libtest_arg2, "wb");
+
+ (void)clientp; /* UNUSED */
+ (void)dltotal; /* UNUSED */
+ (void)dlnow; /* UNUSED */
+
+ if(moo) {
+ if ((size_t)ultotal == data_size && (size_t)ulnow == data_size)
+ fprintf(moo, "PASSED, UL data matched data size\n");
+ else
+ fprintf(moo, "Progress callback called with UL %f out of %f\n", ulnow, ultotal);
+ fclose(moo);
+ }
+ return 0;
+}
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res=CURLE_OK;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* First set the URL that is about to receive our POST. */
+ test_setopt(curl, CURLOPT_URL, URL);
+
+ /* Now specify we want to POST data */
+ test_setopt(curl, CURLOPT_POST, 1L);
+
+#ifdef CURL_DOES_CONVERSIONS
+ /* Convert the POST data to ASCII */
+ test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L);
+#endif
+
+ /* Set the expected POST size */
+ test_setopt(curl, CURLOPT_POSTFIELDSIZE, data_size);
+ test_setopt(curl, CURLOPT_POSTFIELDS, data);
+
+ /* we want to use our own progress function */
+ test_setopt(curl, CURLOPT_NOPROGRESS, 0L);
+ test_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
+
+ /* pointer to pass to our read function */
+
+ /* get verbose debug output please */
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* include headers in the output */
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib579.c b/tests/libtest/lib579.c
new file mode 100644
index 000000000..c5cf603bb
--- /dev/null
+++ b/tests/libtest/lib579.c
@@ -0,0 +1,161 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+static const char * const post[]={
+ "one",
+ "two",
+ "three",
+ "and a final longer crap: four",
+ NULL
+};
+
+
+struct WriteThis {
+ int counter;
+};
+
+static int progress_callback(void *clientp, double dltotal, double dlnow,
+ double ultotal, double ulnow)
+{
+ FILE *moo;
+ static int prev_ultotal = -1;
+ static int prev_ulnow = -1;
+ (void)clientp; /* UNUSED */
+ (void)dltotal; /* UNUSED */
+ (void)dlnow; /* UNUSED */
+
+ /* to avoid depending on timing, which will cause this progress function to
+ get called a different number of times depending on circumstances, we
+ only log these lines if the numbers are different from the previous
+ invoke */
+ if((prev_ultotal != (int)ultotal) ||
+ (prev_ulnow != (int)ulnow)) {
+
+ moo = fopen(libtest_arg2, "ab");
+ if(moo) {
+ fprintf(moo, "Progress callback called with UL %d out of %d\n",
+ (int)ulnow, (int)ultotal);
+ fclose(moo);
+ }
+ prev_ulnow = (int) ulnow;
+ prev_ultotal = (int) ultotal;
+ }
+ return 0;
+}
+
+static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
+{
+ struct WriteThis *pooh = (struct WriteThis *)userp;
+ const char *data;
+
+ if(size*nmemb < 1)
+ return 0;
+
+ data = post[pooh->counter];
+
+ if(data) {
+ size_t len = strlen(data);
+ memcpy(ptr, data, len);
+ pooh->counter++; /* advance pointer */
+ return len;
+ }
+ return 0; /* no more data left to deliver */
+}
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res=CURLE_OK;
+ struct curl_slist *slist = NULL;
+ struct WriteThis pooh;
+ pooh.counter = 0;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ slist = curl_slist_append(slist, "Transfer-Encoding: chunked");
+ if (slist == NULL) {
+ fprintf(stderr, "curl_slist_append() failed\n");
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* First set the URL that is about to receive our POST. */
+ test_setopt(curl, CURLOPT_URL, URL);
+
+ /* Now specify we want to POST data */
+ test_setopt(curl, CURLOPT_POST, 1L);
+
+#ifdef CURL_DOES_CONVERSIONS
+ /* Convert the POST data to ASCII */
+ test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L);
+#endif
+
+ /* we want to use our own read function */
+ test_setopt(curl, CURLOPT_READFUNCTION, read_callback);
+
+ /* pointer to pass to our read function */
+ test_setopt(curl, CURLOPT_INFILE, &pooh);
+
+ /* get verbose debug output please */
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* include headers in the output */
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+
+ /* enforce chunked transfer by setting the header */
+ test_setopt(curl, CURLOPT_HTTPHEADER, slist);
+
+ test_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_DIGEST);
+ test_setopt(curl, CURLOPT_USERPWD, "foo:bar");
+
+ /* we want to use our own progress function */
+ test_setopt(curl, CURLOPT_NOPROGRESS, 0L);
+ test_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ /* clean up the headers list */
+ if(slist)
+ curl_slist_free_all(slist);
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib582.c b/tests/libtest/lib582.c
new file mode 100644
index 000000000..952efb4ed
--- /dev/null
+++ b/tests/libtest/lib582.c
@@ -0,0 +1,366 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include <fcntl.h>
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+struct Sockets
+{
+ curl_socket_t *sockets;
+ int count; /* number of sockets actually stored in array */
+ int max_count; /* max number of sockets that fit in allocated array */
+};
+
+struct ReadWriteSockets
+{
+ struct Sockets read, write;
+};
+
+/**
+ * Remove a file descriptor from a sockets array.
+ */
+static void removeFd(struct Sockets* sockets, curl_socket_t fd, int mention)
+{
+ int i;
+
+ if(mention)
+ fprintf(stderr, "Remove socket fd %d\n", (int) fd);
+
+ for (i = 0; i < sockets->count; ++i) {
+ if (sockets->sockets[i] == fd) {
+ if (i < sockets->count - 1)
+ memmove(&sockets->sockets[i], &sockets->sockets[i + 1],
+ sizeof(curl_socket_t) * (sockets->count - (i + 1)));
+ --sockets->count;
+ }
+ }
+}
+
+/**
+ * Add a file descriptor to a sockets array.
+ */
+static void addFd(struct Sockets* sockets, curl_socket_t fd, const char *what)
+{
+ /**
+ * To ensure we only have each file descriptor once, we remove it then add
+ * it again.
+ */
+ fprintf(stderr, "Add socket fd %d for %s\n", (int) fd, what);
+ removeFd(sockets, fd, 0);
+ /*
+ * Allocate array storage when required.
+ */
+ if(!sockets->sockets) {
+ sockets->sockets = malloc(sizeof(curl_socket_t) * 20U);
+ if(!sockets->sockets)
+ return;
+ sockets->max_count = 20;
+ }
+ else if(sockets->count + 1 > sockets->max_count) {
+ curl_socket_t *oldptr = sockets->sockets;
+ sockets->sockets = realloc(oldptr, sizeof(curl_socket_t) *
+ (sockets->max_count + 20));
+ if(!sockets->sockets) {
+ /* cleanup in test_cleanup */
+ sockets->sockets = oldptr;
+ return;
+ }
+ sockets->max_count += 20;
+ }
+ /*
+ * Add file descriptor to array.
+ */
+ sockets->sockets[sockets->count] = fd;
+ ++sockets->count;
+}
+
+/**
+ * Callback invoked by curl to poll reading / writing of a socket.
+ */
+static int curlSocketCallback(CURL *easy, curl_socket_t s, int action,
+ void *userp, void *socketp)
+{
+ struct ReadWriteSockets* sockets = userp;
+
+ (void)easy; /* unused */
+ (void)socketp; /* unused */
+
+ if (action == CURL_POLL_IN || action == CURL_POLL_INOUT)
+ addFd(&sockets->read, s, "read");
+
+ if (action == CURL_POLL_OUT || action == CURL_POLL_INOUT)
+ addFd(&sockets->write, s, "write");
+
+ if(action == CURL_POLL_REMOVE) {
+ removeFd(&sockets->read, s, 1);
+ removeFd(&sockets->write, s, 0);
+ }
+
+ return 0;
+}
+
+/**
+ * Callback invoked by curl to set a timeout.
+ */
+static int curlTimerCallback(CURLM *multi, long timeout_ms, void *userp)
+{
+ struct timeval* timeout = userp;
+
+ (void)multi; /* unused */
+ if (timeout_ms != -1) {
+ *timeout = tutil_tvnow();
+ timeout->tv_usec += timeout_ms * 1000;
+ }
+ else {
+ timeout->tv_sec = -1;
+ }
+ return 0;
+}
+
+/**
+ * Check for curl completion.
+ */
+static int checkForCompletion(CURLM* curl, int* success)
+{
+ int numMessages;
+ CURLMsg* message;
+ int result = 0;
+ *success = 0;
+ while ((message = curl_multi_info_read(curl, &numMessages)) != NULL) {
+ if (message->msg == CURLMSG_DONE) {
+ result = 1;
+ if (message->data.result == CURLE_OK)
+ *success = 1;
+ else
+ *success = 0;
+ }
+ else {
+ fprintf(stderr, "Got an unexpected message from curl: %i\n",
+ (int)message->msg);
+ result = 1;
+ *success = 0;
+ }
+ }
+ return result;
+}
+
+static int getMicroSecondTimeout(struct timeval* timeout)
+{
+ struct timeval now;
+ ssize_t result;
+ now = tutil_tvnow();
+ result = (timeout->tv_sec - now.tv_sec) * 1000000 +
+ timeout->tv_usec - now.tv_usec;
+ if (result < 0)
+ result = 0;
+
+ return curlx_sztosi(result);
+}
+
+/**
+ * Update a fd_set with all of the sockets in use.
+ */
+static void updateFdSet(struct Sockets* sockets, fd_set* fdset,
+ curl_socket_t *maxFd)
+{
+ int i;
+ for (i = 0; i < sockets->count; ++i) {
+ FD_SET(sockets->sockets[i], fdset);
+ if (*maxFd < sockets->sockets[i] + 1) {
+ *maxFd = sockets->sockets[i] + 1;
+ }
+ }
+}
+
+static void notifyCurl(CURLM *curl, curl_socket_t s, int evBitmask,
+ const char *info)
+{
+ int numhandles = 0;
+ CURLMcode result = curl_multi_socket_action(curl, s, evBitmask, &numhandles);
+ if (result != CURLM_OK) {
+ fprintf(stderr, "Curl error on %s: %i (%s)\n",
+ info, result, curl_multi_strerror(result));
+ }
+}
+
+/**
+ * Invoke curl when a file descriptor is set.
+ */
+static void checkFdSet(CURLM *curl, struct Sockets *sockets, fd_set *fdset,
+ int evBitmask, const char *name)
+{
+ int i;
+ for (i = 0; i < sockets->count; ++i) {
+ if (FD_ISSET(sockets->sockets[i], fdset)) {
+ notifyCurl(curl, sockets->sockets[i], evBitmask, name);
+ }
+ }
+}
+
+int test(char *URL)
+{
+ int res = 0;
+ CURL *curl = NULL;
+ FILE *hd_src = NULL;
+ int hd ;
+ int error;
+ struct_stat file_info;
+ CURLM *m = NULL;
+ struct ReadWriteSockets sockets = {{NULL, 0, 0}, {NULL, 0, 0}};
+ struct timeval timeout = {-1, 0};
+ int success = 0;
+
+ start_test_timing();
+
+ if (!libtest_arg3) {
+ fprintf(stderr, "Usage: lib582 [url] [filename] [username]\n");
+ return TEST_ERR_USAGE;
+ }
+
+ hd_src = fopen(libtest_arg2, "rb");
+ if(NULL == hd_src) {
+ error = ERRNO;
+ fprintf(stderr, "fopen() failed with error: %d (%s)\n",
+ error, strerror(error));
+ fprintf(stderr, "Error opening file: (%s)\n", libtest_arg2);
+ return TEST_ERR_FOPEN;
+ }
+
+ /* get the file size of the local file */
+ hd = fstat(fileno(hd_src), &file_info);
+ if(hd == -1) {
+ /* can't open file, bail out */
+ error = ERRNO;
+ fprintf(stderr, "fstat() failed with error: %d (%s)\n",
+ error, strerror(error));
+ fprintf(stderr, "ERROR: cannot open file (%s)\n", libtest_arg2);
+ fclose(hd_src);
+ return TEST_ERR_FSTAT;
+ }
+ fprintf(stderr, "Set to upload %d bytes\n", (int)file_info.st_size);
+
+ res_global_init(CURL_GLOBAL_ALL);
+ if(res) {
+ fclose(hd_src);
+ return res;
+ }
+
+ easy_init(curl);
+
+ /* enable uploading */
+ easy_setopt(curl, CURLOPT_UPLOAD, 1L);
+
+ /* specify target */
+ easy_setopt(curl,CURLOPT_URL, URL);
+
+ /* go verbose */
+ easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* now specify which file to upload */
+ easy_setopt(curl, CURLOPT_READDATA, hd_src);
+
+ easy_setopt(curl, CURLOPT_USERPWD, libtest_arg3);
+ easy_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, "curl_client_key.pub");
+ easy_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, "curl_client_key");
+
+ easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
+
+ multi_init(m);
+
+ multi_setopt(m, CURLMOPT_SOCKETFUNCTION, curlSocketCallback);
+ multi_setopt(m, CURLMOPT_SOCKETDATA, &sockets);
+
+ multi_setopt(m, CURLMOPT_TIMERFUNCTION, curlTimerCallback);
+ multi_setopt(m, CURLMOPT_TIMERDATA, &timeout);
+
+ multi_add_handle(m, curl);
+
+ while (!checkForCompletion(m, &success))
+ {
+ fd_set readSet, writeSet;
+ curl_socket_t maxFd = 0;
+ struct timeval tv = {10, 0};
+
+ FD_ZERO(&readSet);
+ FD_ZERO(&writeSet);
+ updateFdSet(&sockets.read, &readSet, &maxFd);
+ updateFdSet(&sockets.write, &writeSet, &maxFd);
+
+ if (timeout.tv_sec != -1)
+ {
+ int usTimeout = getMicroSecondTimeout(&timeout);
+ tv.tv_sec = usTimeout / 1000000;
+ tv.tv_usec = usTimeout % 1000000;
+ }
+ else if (maxFd <= 0)
+ {
+ tv.tv_sec = 0;
+ tv.tv_usec = 100000;
+ }
+
+ select_test(maxFd, &readSet, &writeSet, NULL, &tv);
+
+ /* Check the sockets for reading / writing */
+ checkFdSet(m, &sockets.read, &readSet, CURL_CSELECT_IN, "read");
+ checkFdSet(m, &sockets.write, &writeSet, CURL_CSELECT_OUT, "write");
+
+ if (timeout.tv_sec != -1 && getMicroSecondTimeout(&timeout) == 0)
+ {
+ /* Curl's timer has elapsed. */
+ notifyCurl(m, CURL_SOCKET_TIMEOUT, 0, "timeout");
+ }
+
+ abort_on_test_timeout();
+ }
+
+ if (!success)
+ {
+ fprintf(stderr, "Error uploading file.\n");
+ res = TEST_ERR_MAJOR_BAD;
+ }
+
+test_cleanup:
+
+ /* proper cleanup sequence - type PB */
+
+ curl_multi_remove_handle(m, curl);
+ curl_easy_cleanup(curl);
+ curl_multi_cleanup(m);
+ curl_global_cleanup();
+
+ /* close the local file */
+ fclose(hd_src);
+
+ /* free local memory */
+ if(sockets.read.sockets)
+ free(sockets.read.sockets);
+ if(sockets.write.sockets)
+ free(sockets.write.sockets);
+
+ return res;
+}
diff --git a/tests/libtest/lib583.c b/tests/libtest/lib583.c
new file mode 100644
index 000000000..ad5a5cea7
--- /dev/null
+++ b/tests/libtest/lib583.c
@@ -0,0 +1,84 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+/*
+ * This test case is based on the sample code provided by Saqib Ali
+ * http://curl.haxx.se/mail/lib-2011-03/0066.html
+ */
+
+#include "test.h"
+
+#include <sys/stat.h>
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ int stillRunning;
+ CURLM* multiHandle = NULL;
+ CURL* curl = NULL;
+ int res = 0;
+
+ global_init(CURL_GLOBAL_ALL);
+
+ multi_init(multiHandle);
+
+ easy_init(curl);
+
+ easy_setopt(curl, CURLOPT_USERPWD, libtest_arg2);
+ easy_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, "curl_client_key.pub");
+ easy_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, "curl_client_key");
+
+ easy_setopt(curl, CURLOPT_UPLOAD, 1L);
+ easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ easy_setopt(curl, CURLOPT_URL, URL);
+ easy_setopt(curl, CURLOPT_INFILESIZE, (long)5);
+
+ multi_add_handle(multiHandle, curl);
+
+ /* this tests if removing an easy handle immediately after multi
+ perform has been called succeeds or not. */
+
+ fprintf(stderr, "curl_multi_perform()...\n");
+
+ multi_perform(multiHandle, &stillRunning);
+
+ fprintf(stderr, "curl_multi_perform() succeeded\n");
+
+ fprintf(stderr, "curl_multi_remove_handle()...\n");
+ res = (int) curl_multi_remove_handle(multiHandle, curl);
+ if(res)
+ fprintf(stderr, "curl_multi_remove_handle() failed, "
+ "with code %d\n", res);
+ else
+ fprintf(stderr, "curl_multi_remove_handle() succeeded\n");
+
+test_cleanup:
+
+ /* undocumented cleanup sequence - type UB */
+
+ curl_easy_cleanup(curl);
+ curl_multi_cleanup(multiHandle);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib586.c b/tests/libtest/lib586.c
new file mode 100644
index 000000000..2cf04fe85
--- /dev/null
+++ b/tests/libtest/lib586.c
@@ -0,0 +1,246 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include <curl/mprintf.h>
+
+#include "memdebug.h"
+
+#define THREADS 2
+
+/* struct containing data of a thread */
+struct Tdata {
+ CURLSH *share;
+ char *url;
+};
+
+struct userdata {
+ char *text;
+ int counter;
+};
+
+/* lock callback */
+static void my_lock(CURL *handle, curl_lock_data data, curl_lock_access laccess,
+ void *useptr )
+{
+ const char *what;
+ struct userdata *user = (struct userdata *)useptr;
+
+ (void)handle;
+ (void)laccess;
+
+ switch ( data ) {
+ case CURL_LOCK_DATA_SHARE:
+ what = "share";
+ break;
+ case CURL_LOCK_DATA_DNS:
+ what = "dns";
+ break;
+ case CURL_LOCK_DATA_COOKIE:
+ what = "cookie";
+ break;
+ case CURL_LOCK_DATA_SSL_SESSION:
+ what = "ssl_session";
+ break;
+ default:
+ fprintf(stderr, "lock: no such data: %d\n", (int)data);
+ return;
+ }
+ printf("lock: %-6s [%s]: %d\n", what, user->text, user->counter);
+ user->counter++;
+}
+
+/* unlock callback */
+static void my_unlock(CURL *handle, curl_lock_data data, void *useptr )
+{
+ const char *what;
+ struct userdata *user = (struct userdata *)useptr;
+ (void)handle;
+ switch ( data ) {
+ case CURL_LOCK_DATA_SHARE:
+ what = "share";
+ break;
+ case CURL_LOCK_DATA_DNS:
+ what = "dns";
+ break;
+ case CURL_LOCK_DATA_COOKIE:
+ what = "cookie";
+ break;
+ case CURL_LOCK_DATA_SSL_SESSION:
+ what = "ssl_session";
+ break;
+ default:
+ fprintf(stderr, "unlock: no such data: %d\n", (int)data);
+ return;
+ }
+ printf("unlock: %-6s [%s]: %d\n", what, user->text, user->counter);
+ user->counter++;
+}
+
+/* the dummy thread function */
+static void *fire(void *ptr)
+{
+ CURLcode code;
+ struct Tdata *tdata = (struct Tdata*)ptr;
+ CURL *curl;
+ int i=0;
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ return NULL;
+ }
+
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(curl, CURLOPT_URL, tdata->url);
+ printf( "CURLOPT_SHARE\n" );
+ curl_easy_setopt(curl, CURLOPT_SHARE, tdata->share);
+
+ printf( "PERFORM\n" );
+ code = curl_easy_perform(curl);
+ if( code != CURLE_OK ) {
+ fprintf(stderr, "perform url '%s' repeat %d failed, curlcode %d\n",
+ tdata->url, i, (int)code);
+ }
+
+ printf( "CLEANUP\n" );
+ curl_easy_cleanup(curl);
+
+ return NULL;
+}
+
+/* test function */
+int test(char *URL)
+{
+ int res;
+ CURLSHcode scode = CURLSHE_OK;
+ char *url;
+ struct Tdata tdata;
+ CURL *curl;
+ CURLSH *share;
+ int i;
+ struct userdata user;
+
+ user.text = (char *)"Pigs in space";
+ user.counter = 0;
+
+ printf( "GLOBAL_INIT\n" );
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* prepare share */
+ printf( "SHARE_INIT\n" );
+ if ((share = curl_share_init()) == NULL) {
+ fprintf(stderr, "curl_share_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ( CURLSHE_OK == scode ) {
+ printf( "CURLSHOPT_LOCKFUNC\n" );
+ scode = curl_share_setopt( share, CURLSHOPT_LOCKFUNC, my_lock);
+ }
+ if ( CURLSHE_OK == scode ) {
+ printf( "CURLSHOPT_UNLOCKFUNC\n" );
+ scode = curl_share_setopt( share, CURLSHOPT_UNLOCKFUNC, my_unlock);
+ }
+ if ( CURLSHE_OK == scode ) {
+ printf( "CURLSHOPT_USERDATA\n" );
+ scode = curl_share_setopt( share, CURLSHOPT_USERDATA, &user);
+ }
+ if ( CURLSHE_OK == scode ) {
+ printf( "CURL_LOCK_DATA_SSL_SESSION\n" );
+ scode = curl_share_setopt( share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
+ }
+
+ if ( CURLSHE_OK != scode ) {
+ fprintf(stderr, "curl_share_setopt() failed\n");
+ curl_share_cleanup(share);
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+
+ res = 0;
+
+ /* start treads */
+ for (i=1; i<=THREADS; i++ ) {
+
+ /* set thread data */
+ tdata.url = URL;
+ tdata.share = share;
+
+ /* simulate thread, direct call of "thread" function */
+ printf( "*** run %d\n",i );
+ fire( &tdata );
+ }
+
+
+ /* fetch a another one */
+ printf( "*** run %d\n", i );
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_share_cleanup(share);
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ url = URL;
+ test_setopt( curl, CURLOPT_URL, url );
+ printf( "CURLOPT_SHARE\n" );
+ test_setopt( curl, CURLOPT_SHARE, share );
+
+ printf( "PERFORM\n" );
+ curl_easy_perform( curl );
+
+ /* try to free share, expect to fail because share is in use*/
+ printf( "try SHARE_CLEANUP...\n" );
+ scode = curl_share_cleanup( share );
+ if ( scode==CURLSHE_OK )
+ {
+ fprintf(stderr, "curl_share_cleanup succeed but error expected\n");
+ share = NULL;
+ } else {
+ printf( "SHARE_CLEANUP failed, correct\n" );
+ }
+
+test_cleanup:
+
+ /* clean up last handle */
+ printf( "CLEANUP\n" );
+ curl_easy_cleanup( curl );
+
+ /* free share */
+ printf( "SHARE_CLEANUP\n" );
+ scode = curl_share_cleanup( share );
+ if ( scode!=CURLSHE_OK )
+ fprintf(stderr, "curl_share_cleanup failed, code errno %d\n",
+ (int)scode);
+
+ printf( "GLOBAL_CLEANUP\n" );
+ curl_global_cleanup();
+
+ return res;
+}
+
diff --git a/tests/libtest/lib590.c b/tests/libtest/lib590.c
new file mode 100644
index 000000000..68603c65e
--- /dev/null
+++ b/tests/libtest/lib590.c
@@ -0,0 +1,71 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+/*
+ Based on a bug report recipe by Rene Bernhardt in
+ http://curl.haxx.se/mail/lib-2011-10/0323.html
+
+ It is reproducible by the following steps:
+
+ - Use a proxy that offers NTLM and Negotiate ( CURLOPT_PROXY and
+ CURLOPT_PROXYPORT )
+ - Tell libcurl NOT to use Negotiate CURL_EASY_SETOPT(CURLOPT_PROXYAUTH,
+ CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_NTLM )
+ - Start the request
+*/
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+ test_setopt(curl, CURLOPT_PROXYAUTH,
+ (long) (CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_NTLM));
+ test_setopt(curl, CURLOPT_PROXY, libtest_arg2); /* set in first.c */
+ test_setopt(curl, CURLOPT_PROXYUSERPWD, "me:password");
+
+ res = curl_easy_perform(curl);
+
+ test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
+
diff --git a/tests/libtest/lib591.c b/tests/libtest/lib591.c
new file mode 100644
index 000000000..5cd4644e3
--- /dev/null
+++ b/tests/libtest/lib591.c
@@ -0,0 +1,149 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+/* lib591 is used for test cases 591, 592, 593 and 594 */
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include <fcntl.h>
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+int test(char *URL)
+{
+ CURL *easy = NULL;
+ CURLM *multi = NULL;
+ int res = 0;
+ int running;
+ int msgs_left;
+ CURLMsg *msg;
+ FILE *upload = NULL;
+ int error;
+
+ start_test_timing();
+
+ upload = fopen(libtest_arg3, "rb");
+ if(!upload) {
+ error = ERRNO;
+ fprintf(stderr, "fopen() failed with error: %d (%s)\n",
+ error, strerror(error));
+ fprintf(stderr, "Error opening file: (%s)\n", libtest_arg3);
+ return TEST_ERR_FOPEN;
+ }
+
+ res_global_init(CURL_GLOBAL_ALL);
+ if(res) {
+ fclose(upload);
+ return res;
+ }
+
+ easy_init(easy);
+
+ /* go verbose */
+ easy_setopt(easy, CURLOPT_VERBOSE, 1L);
+
+ /* specify target */
+ easy_setopt(easy, CURLOPT_URL, URL);
+
+ /* enable uploading */
+ easy_setopt(easy, CURLOPT_UPLOAD, 1L);
+
+ /* data pointer for the file read function */
+ easy_setopt(easy, CURLOPT_READDATA, upload);
+
+ /* use active mode FTP */
+ easy_setopt(easy, CURLOPT_FTPPORT, "-");
+
+ /* server connection timeout */
+ easy_setopt(easy, CURLOPT_ACCEPTTIMEOUT_MS,
+ strtol(libtest_arg2, NULL, 10)*1000);
+
+ multi_init(multi);
+
+ multi_add_handle(multi, easy);
+
+ for(;;) {
+ struct timeval interval;
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ long timeout = -99;
+ int maxfd = -99;
+
+ multi_perform(multi, &running);
+
+ abort_on_test_timeout();
+
+ if(!running)
+ break; /* done */
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ multi_timeout(multi, &timeout);
+
+ /* At this point, timeout is guaranteed to be greater or equal than -1. */
+
+ if(timeout != -1L) {
+ int itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout;
+ interval.tv_sec = itimeout/1000;
+ interval.tv_usec = (itimeout%1000)*1000;
+ }
+ else {
+ interval.tv_sec = 0;
+ interval.tv_usec = 100000L; /* 100 ms */
+ }
+
+ select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &interval);
+
+ abort_on_test_timeout();
+ }
+
+ msg = curl_multi_info_read(multi, &msgs_left);
+ if(msg)
+ res = msg->data.result;
+
+test_cleanup:
+
+ /* undocumented cleanup sequence - type UA */
+
+ curl_multi_cleanup(multi);
+ curl_easy_cleanup(easy);
+ curl_global_cleanup();
+
+ /* close the local file */
+ fclose(upload);
+
+ return res;
+}
diff --git a/tests/libtest/lib597.c b/tests/libtest/lib597.c
new file mode 100644
index 000000000..a27cefd5b
--- /dev/null
+++ b/tests/libtest/lib597.c
@@ -0,0 +1,150 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 5 * 1000
+
+/*
+ * Test case for below scenario:
+ * - Connect to an FTP server using CONNECT_ONLY option
+ * - transfer some files with re-using the connection (omitted in test case)
+ * - Disconnect from FTP server with sending QUIT command
+ *
+ * The test case originated for verifying CONNECT_ONLY option shall not
+ * block after protocol connect is done, but it returns the message
+ * with function curl_multi_info_read().
+ */
+
+enum {
+ CONNECT_ONLY_PHASE = 0,
+ QUIT_PHASE,
+ LAST_PHASE
+};
+
+int test(char *URL)
+{
+ CURL *easy = NULL;
+ CURLM *multi = NULL;
+ int res = 0;
+ int running;
+ int msgs_left;
+ int phase;
+ CURLMsg *msg;
+
+ start_test_timing();
+
+ res_global_init(CURL_GLOBAL_ALL);
+ if(res) {
+ return res;
+ }
+
+ easy_init(easy);
+
+ multi_init(multi);
+
+ for (phase = CONNECT_ONLY_PHASE; phase < LAST_PHASE; ++phase) {
+ /* go verbose */
+ easy_setopt(easy, CURLOPT_VERBOSE, 1L);
+
+ /* specify target */
+ easy_setopt(easy, CURLOPT_URL, URL);
+
+ /* enable 'CONNECT_ONLY' option when in connect phase */
+ if (phase == CONNECT_ONLY_PHASE)
+ easy_setopt(easy, CURLOPT_CONNECT_ONLY, 1L);
+
+ /* enable 'NOBODY' option to send 'QUIT' command in quit phase */
+ if (phase == QUIT_PHASE) {
+ easy_setopt(easy, CURLOPT_CONNECT_ONLY, 0L);
+ easy_setopt(easy, CURLOPT_NOBODY, 1L);
+ easy_setopt(easy, CURLOPT_FORBID_REUSE, 1L);
+ }
+
+ multi_add_handle(multi, easy);
+
+ for(;;) {
+ struct timeval interval;
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ long timeout = -99;
+ int maxfd = -99;
+
+ multi_perform(multi, &running);
+
+ abort_on_test_timeout();
+
+ if(!running)
+ break; /* done */
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ multi_timeout(multi, &timeout);
+
+ /* At this point, timeout is guaranteed to be greater or equal than -1. */
+
+ if(timeout != -1L) {
+ int itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout;
+ interval.tv_sec = itimeout/1000;
+ interval.tv_usec = (itimeout%1000)*1000;
+ }
+ else {
+ interval.tv_sec = TEST_HANG_TIMEOUT/1000+1;
+ interval.tv_usec = 0;
+ }
+
+ select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &interval);
+
+ abort_on_test_timeout();
+ }
+
+ msg = curl_multi_info_read(multi, &msgs_left);
+ if(msg)
+ res = msg->data.result;
+
+ multi_remove_handle(multi, easy);
+ }
+
+test_cleanup:
+
+ /* undocumented cleanup sequence - type UA */
+
+ curl_multi_cleanup(multi);
+ curl_easy_cleanup(easy);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib598.c b/tests/libtest/lib598.c
new file mode 100644
index 000000000..e9c1ad776
--- /dev/null
+++ b/tests/libtest/lib598.c
@@ -0,0 +1,72 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURLcode res;
+ CURL *curl;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+ test_setopt(curl, CURLOPT_REFERER, "http://example.com/the-moo");
+ test_setopt(curl, CURLOPT_USERAGENT, "the-moo agent next generation");
+ test_setopt(curl, CURLOPT_COOKIE, "name=moo");
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ res = curl_easy_perform(curl);
+ if(res) {
+ fprintf(stderr, "retrieve 1 failed\n");
+ goto test_cleanup;
+ }
+
+ curl_easy_reset(curl);
+
+ test_setopt(curl, CURLOPT_URL, URL);
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ res = curl_easy_perform(curl);
+ if(res)
+ fprintf(stderr, "retrieve 2 failed\n");
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
+
diff --git a/tests/libtest/lib599.c b/tests/libtest/lib599.c
new file mode 100644
index 000000000..6b092677a
--- /dev/null
+++ b/tests/libtest/lib599.c
@@ -0,0 +1,84 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+static int progress_callback(void *clientp, double dltotal,
+ double dlnow, double ultotal, double ulnow)
+{
+ (void)clientp;
+ (void)ulnow;
+ (void)ultotal;
+
+ if((dltotal > 0.0) && (dlnow > dltotal)) {
+ /* this should not happen with test case 599 */
+ printf("%.0f > %.0f !!\n", dltotal, dlnow);
+ return -1;
+ }
+
+ return 0;
+}
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res=CURLE_OK;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* First set the URL that is about to receive our POST. */
+ test_setopt(curl, CURLOPT_URL, URL);
+
+ /* we want to use our own progress function */
+ test_setopt(curl, CURLOPT_NOPROGRESS, 0L);
+ test_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
+
+ /* get verbose debug output please */
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* follow redirects */
+ test_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+
+ /* include headers in the output */
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/libauthretry.c b/tests/libtest/libauthretry.c
new file mode 100644
index 000000000..95761325a
--- /dev/null
+++ b/tests/libtest/libauthretry.c
@@ -0,0 +1,153 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+/* argv1 = URL
+ * argv2 = main auth type
+ * argv3 = second auth type
+ */
+
+#include "test.h"
+#include "strequal.h"
+#include "memdebug.h"
+
+static CURLcode send_request(CURL *curl, const char *url, int seq,
+ long auth_scheme, const char *userpwd)
+{
+ CURLcode res;
+ char* full_url = malloc(strlen(url) + 4 + 1);
+ if (!full_url) {
+ fprintf(stderr, "Not enough memory for full url\n");
+ res = CURLE_OUT_OF_MEMORY;
+ goto test_cleanup;
+ }
+
+ sprintf(full_url, "%s%04d", url, seq);
+ fprintf(stderr, "Sending new request %d to %s with credential %s "
+ "(auth %ld)\n", seq, full_url, userpwd, auth_scheme);
+ test_setopt(curl, CURLOPT_URL, full_url);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+ test_setopt(curl, CURLOPT_HTTPGET, 1L);
+ test_setopt(curl, CURLOPT_USERPWD, userpwd);
+ test_setopt(curl, CURLOPT_HTTPAUTH, auth_scheme);
+
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+ free(full_url);
+ return res;
+}
+
+static CURLcode send_wrong_password(CURL *curl, const char *url, int seq,
+ long auth_scheme)
+{
+ return send_request(curl, url, seq, auth_scheme, "testuser:wrongpass");
+}
+
+static CURLcode send_right_password(CURL *curl, const char *url, int seq,
+ long auth_scheme)
+{
+ return send_request(curl, url, seq, auth_scheme, "testuser:testpass");
+}
+
+static long parse_auth_name(const char *arg)
+{
+ if (!arg)
+ return CURLAUTH_NONE;
+ if (strequal(arg, "basic"))
+ return CURLAUTH_BASIC;
+ if (strequal(arg, "digest"))
+ return CURLAUTH_DIGEST;
+ if (strequal(arg, "ntlm"))
+ return CURLAUTH_NTLM;
+ return CURLAUTH_NONE;
+}
+
+int test(char *url)
+{
+ CURLcode res;
+ CURL *curl = NULL;
+
+ long main_auth_scheme = parse_auth_name(libtest_arg2);
+ long fallback_auth_scheme = parse_auth_name(libtest_arg3);
+
+ if (main_auth_scheme == CURLAUTH_NONE ||
+ fallback_auth_scheme == CURLAUTH_NONE) {
+ fprintf(stderr, "auth schemes not found on commandline\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* Send wrong password, then right password */
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ res = send_wrong_password(curl, url, 100, main_auth_scheme);
+ if (res != CURLE_OK)
+ goto test_cleanup;
+ curl_easy_reset(curl);
+
+ res = send_right_password(curl, url, 200, fallback_auth_scheme);
+ if (res != CURLE_OK)
+ goto test_cleanup;
+ curl_easy_reset(curl);
+
+ curl_easy_cleanup(curl);
+
+ /* Send wrong password twice, then right password */
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ res = send_wrong_password(curl, url, 300, main_auth_scheme);
+ if (res != CURLE_OK)
+ goto test_cleanup;
+ curl_easy_reset(curl);
+
+ res = send_wrong_password(curl, url, 400, fallback_auth_scheme);
+ if (res != CURLE_OK)
+ goto test_cleanup;
+ curl_easy_reset(curl);
+
+ res = send_right_password(curl, url, 500, fallback_auth_scheme);
+ if (res != CURLE_OK)
+ goto test_cleanup;
+ curl_easy_reset(curl);
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
+
diff --git a/tests/libtest/libntlmconnect.c b/tests/libtest/libntlmconnect.c
new file mode 100644
index 000000000..66d09e936
--- /dev/null
+++ b/tests/libtest/libntlmconnect.c
@@ -0,0 +1,275 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#include <assert.h>
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 5 * 1000
+#define MAX_EASY_HANDLES 3
+
+/* On Windows INVALID_SOCKET represents an invalid socket, not -1:
+ http://msdn.microsoft.com/en-us/library/windows/desktop/ms740516.aspx */
+#ifndef INVALID_SOCKET
+#define INVALID_SOCKET -1
+#endif
+
+CURL *easy[MAX_EASY_HANDLES];
+curl_socket_t sockets[MAX_EASY_HANDLES];
+int res = 0;
+
+static size_t callback(char* ptr, size_t size, size_t nmemb, void* data)
+{
+ ssize_t idx = ((CURL **) data) - easy;
+ curl_socket_t sock;
+ long lastsock;
+
+ char *output = malloc(size * nmemb + 1);
+ memcpy(output, ptr, size * nmemb);
+ output[size * nmemb] = '\0';
+ fprintf(stdout, "%s", output);
+ free(output);
+
+ res = curl_easy_getinfo(easy[idx], CURLINFO_LASTSOCKET, &lastsock);
+ if (CURLE_OK != res) {
+ fprintf(stderr, "Error reading CURLINFO_LASTSOCKET\n");
+ return 0;
+ }
+ if (lastsock == -1) {
+ sock = INVALID_SOCKET;
+ }
+ else {
+ sock = (curl_socket_t)lastsock;
+ }
+ /* sock will only be set for NTLM requests; for others it is -1 */
+ if (sock != INVALID_SOCKET) {
+ if (sockets[idx] == INVALID_SOCKET) {
+ /* Data was written for this request before the socket was detected by
+ multi_fdset. Record the socket now. */
+ sockets[idx] = sock;
+ }
+ else if (sock != sockets[idx]) {
+ fprintf(stderr, "Handle %d started on socket %d and moved to %d\n",
+ curlx_sztosi(idx), (int)sockets[idx], (int)sock);
+ res = TEST_ERR_MAJOR_BAD;
+ return 0;
+ }
+ }
+ return size * nmemb;
+}
+
+enum HandleState {
+ ReadyForNewHandle,
+ NeedSocketForNewHandle,
+ NoMoreHandles
+};
+
+int test(char *url)
+{
+ CURLM *multi = NULL;
+ int running;
+ int i, j;
+ int num_handles = 0;
+ enum HandleState state = ReadyForNewHandle;
+ char* full_url = malloc(strlen(url) + 4 + 1);
+
+ start_test_timing();
+
+ if (!full_url) {
+ fprintf(stderr, "Not enough memory for full url\n");
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ for (i = 0; i < MAX_EASY_HANDLES; ++i) {
+ easy[i] = NULL;
+ sockets[i] = -1;
+ }
+
+ res = 0;
+ res_global_init(CURL_GLOBAL_ALL);
+ if(res) {
+ return res;
+ }
+
+ multi_init(multi);
+
+ for(;;) {
+ struct timeval interval;
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ long timeout = -99;
+ curl_socket_t curfd, maxfd = INVALID_SOCKET;
+ bool found_new_socket = FALSE;
+
+ /* Start a new handle if we aren't at the max */
+ if (state == ReadyForNewHandle) {
+ easy_init(easy[num_handles]);
+
+ if (num_handles % 3 == 2) {
+ sprintf(full_url, "%s0200", url);
+ easy_setopt(easy[num_handles], CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
+ } else {
+ sprintf(full_url, "%s0100", url);
+ easy_setopt(easy[num_handles], CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
+ }
+ easy_setopt(easy[num_handles], CURLOPT_FRESH_CONNECT, 1L);
+ easy_setopt(easy[num_handles], CURLOPT_URL, full_url);
+ easy_setopt(easy[num_handles], CURLOPT_VERBOSE, 1L);
+ easy_setopt(easy[num_handles], CURLOPT_HTTPGET, 1L);
+ easy_setopt(easy[num_handles], CURLOPT_USERPWD, "testuser:testpass");
+ easy_setopt(easy[num_handles], CURLOPT_WRITEFUNCTION, callback);
+ easy_setopt(easy[num_handles], CURLOPT_WRITEDATA, easy + num_handles);
+ easy_setopt(easy[num_handles], CURLOPT_HEADER, 1L);
+
+ multi_add_handle(multi, easy[num_handles]);
+ num_handles += 1;
+ state = NeedSocketForNewHandle;
+ }
+
+ multi_perform(multi, &running);
+ if (0 != res)
+ break;
+
+ abort_on_test_timeout();
+
+ if(!running && state == NoMoreHandles)
+ break; /* done */
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ multi_fdset(multi, &fdread, &fdwrite, &fdexcep, (int *)&maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ /* Any socket which is new in fdread is associated with the new handle */
+ for (curfd = 0; curfd <= maxfd; ++curfd) {
+ bool socket_exists = FALSE;
+ if (!FD_ISSET(curfd, &fdread)) {
+ continue;
+ }
+
+ /* Check if this socket was already detected for an earlier handle (or
+ for this handle, num_handles-1, in the callback */
+ for (j = 0; j < num_handles; ++j) {
+ if (sockets[j] == curfd) {
+ socket_exists = TRUE;
+ break;
+ }
+ }
+ if (socket_exists) {
+ continue;
+ }
+
+ if (found_new_socket || state != NeedSocketForNewHandle) {
+ fprintf(stderr, "Unexpected new socket\n");
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+
+ /* Now we know the socket is for the most recent handle, num_handles-1 */
+ if (sockets[num_handles-1] != INVALID_SOCKET) {
+ /* A socket for this handle was already detected in the callback; if it
+ matched socket_exists should be true and we would never get here */
+ assert(curfd != sockets[num_handles-1]);
+ fprintf(stderr, "Handle %d wrote to socket %d then detected on %d\n",
+ num_handles-1, (int)sockets[num_handles-1], (int)curfd);
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ else {
+ sockets[num_handles-1] = curfd;
+ found_new_socket = TRUE;
+ /* continue to make sure there's only one new handle */
+ }
+ }
+
+ if (state == NeedSocketForNewHandle) {
+ if(maxfd != -1 && !found_new_socket) {
+ fprintf(stderr, "Warning: socket did not open immediately for new "
+ "handle (trying again)\n");
+ continue;
+ }
+ state = num_handles < MAX_EASY_HANDLES ? ReadyForNewHandle
+ : NoMoreHandles;
+ }
+
+ multi_timeout(multi, &timeout);
+
+ /* At this point, timeout is guaranteed to be greater or equal than -1. */
+
+ fprintf(stderr, "%s:%d num_handles %d timeout %ld\n",
+ __FILE__, __LINE__, num_handles, timeout);
+
+ if(timeout != -1L) {
+ int itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout;
+ interval.tv_sec = itimeout/1000;
+ interval.tv_usec = (itimeout%1000)*1000;
+ }
+ else {
+ interval.tv_sec = TEST_HANG_TIMEOUT/1000+1;
+ interval.tv_usec = 0;
+
+ /* if there's no timeout and we get here on the last handle, we may
+ already have read the last part of the stream so waiting makes no
+ sense */
+ if(!running && num_handles == MAX_EASY_HANDLES) {
+ break;
+ }
+ }
+
+ select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &interval);
+
+ abort_on_test_timeout();
+ }
+
+test_cleanup:
+
+ for (i = 0; i < MAX_EASY_HANDLES; ++i) {
+ if (easy[i]) {
+ if (multi) {
+ curl_multi_remove_handle(multi, easy[i]);
+ }
+ curl_easy_cleanup(easy[i]);
+ }
+ }
+
+ if (multi) {
+ curl_multi_cleanup(multi);
+ }
+
+ curl_global_cleanup();
+
+ if (full_url) {
+ free(full_url);
+ }
+
+ return res;
+}
diff --git a/tests/libtest/notexists.pl b/tests/libtest/notexists.pl
new file mode 100755
index 000000000..31b9851ec
--- /dev/null
+++ b/tests/libtest/notexists.pl
@@ -0,0 +1,15 @@
+#!/usr/bin/env perl
+# Check that given arguments do not exist on filesystem.
+my $code = 0;
+if ($#ARGV < 0) {
+ print "Usage: $0 file1 [fileN]\n";
+ exit 2;
+}
+while (@ARGV) {
+ my $fname = shift @ARGV;
+ if (-e $fname) {
+ print "Found '$fname' when not supposed to exist.\n";
+ $code = 1;
+ }
+}
+exit $code;
diff --git a/tests/libtest/sethostname.c b/tests/libtest/sethostname.c
new file mode 100644
index 000000000..f131fe9fb
--- /dev/null
+++ b/tests/libtest/sethostname.c
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "setup.h"
+
+#include "sethostname.h"
+
+/*
+ * we force our own host name, in order to make some tests machine independent
+ */
+
+int gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen)
+{
+ const char *force_hostname = getenv("CURL_GETHOSTNAME");
+ if(force_hostname) {
+ strncpy(name, force_hostname, namelen);
+ name[namelen-1] = '\0';
+ return 0;
+ }
+
+ /* LD_PRELOAD used, but no hostname set, we'll just return a failure */
+ return -1;
+}
diff --git a/tests/libtest/sethostname.h b/tests/libtest/sethostname.h
new file mode 100644
index 000000000..e2633dd7f
--- /dev/null
+++ b/tests/libtest/sethostname.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+
+#if (defined(WIN32) || defined(__SYMBIAN32__)) && !defined(CURL_STATICLIB)
+# if defined(BUILDING_LIBCURL)
+# define LIBHOSTNAME_EXTERN __declspec(dllexport)
+# else
+# define LIBHOSTNAME_EXTERN __declspec(dllimport)
+# endif
+#else
+# ifdef CURL_HIDDEN_SYMBOLS
+# define LIBHOSTNAME_EXTERN CURL_EXTERN_SYMBOL
+# else
+# define LIBHOSTNAME_EXTERN
+# endif
+#endif
+
+#ifdef USE_WINSOCK
+# define FUNCALLCONV __stdcall
+#else
+# define FUNCALLCONV
+#endif
+
+LIBHOSTNAME_EXTERN int FUNCALLCONV
+ gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen);
+
diff --git a/tests/libtest/test.h b/tests/libtest/test.h
new file mode 100644
index 000000000..ffa4be166
--- /dev/null
+++ b/tests/libtest/test.h
@@ -0,0 +1,436 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+
+/* Now include the setup.h file from libcurl's private libdir (the source
+ version, but that might include "curl_config.h" from the build dir so we
+ need both of them in the include path), so that we get good in-depth
+ knowledge about the system we're building this on */
+
+#define CURL_NO_OLDIES
+
+#include "setup.h"
+
+#include <curl/curl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+/* since so many tests use select(), we can just as well include it here */
+#include <sys/select.h>
+#endif
+#ifdef HAVE_UNISTD_H
+/* at least somewhat oldish FreeBSD systems need this for select() */
+#include <unistd.h>
+#endif
+
+#ifdef TPF
+# include "select.h"
+#endif
+
+#define test_setopt(A,B,C) \
+ if((res = curl_easy_setopt((A),(B),(C))) != CURLE_OK) goto test_cleanup
+
+#define test_multi_setopt(A,B,C) \
+ if((res = curl_multi_setopt((A),(B),(C))) != CURLE_OK) goto test_cleanup
+
+extern char *libtest_arg2; /* set by first.c to the argv[2] or NULL */
+extern char *libtest_arg3; /* set by first.c to the argv[3] or NULL */
+
+/* argc and argv as passed in to the main() function */
+extern int test_argc;
+extern char **test_argv;
+
+extern struct timeval tv_test_start; /* for test timing */
+
+extern int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc,
+ struct timeval *tv);
+
+extern int test(char *URL); /* the actual test function provided by each
+ individual libXXX.c file */
+
+#ifdef UNITTESTS
+extern int unitfail;
+#endif
+
+/*
+** TEST_ERR_* values must be greater than CURL_LAST CURLcode in order
+** to avoid confusion with any CURLcode or CURLMcode. These TEST_ERR_*
+** codes are returned to signal test specific situations and should
+** not get mixed with CURLcode or CURLMcode values.
+**
+** For portability reasons TEST_ERR_* values should be less than 127.
+*/
+
+#define TEST_ERR_MAJOR_BAD 126
+#define TEST_ERR_RUNS_FOREVER 125
+#define TEST_ERR_EASY_INIT 124
+#define TEST_ERR_MULTI_INIT 123
+#define TEST_ERR_NUM_HANDLES 122
+#define TEST_ERR_SELECT 121
+#define TEST_ERR_SUCCESS 120
+#define TEST_ERR_FAILURE 119
+#define TEST_ERR_USAGE 118
+#define TEST_ERR_FOPEN 117
+#define TEST_ERR_FSTAT 116
+#define TEST_ERR_BAD_TIMEOUT 115
+
+/*
+** Macros for test source code readability/maintainability.
+**
+** All of the following macros require that an int data type 'res' variable
+** exists in scope where macro is used, and that it has been initialized to
+** zero before the macro is used.
+**
+** exe_* and chk_* macros are helper macros not intended to be used from
+** outside of this header file. Arguments 'Y' and 'Z' of these represent
+** source code file and line number, while Arguments 'A', 'B', etc, are
+** the arguments used to actually call a libcurl function.
+**
+** All easy_* and multi_* macros call a libcurl function and evaluate if
+** the function has succeeded or failed. When the function succeeds 'res'
+** variable is not set nor cleared and program continues normal flow. On
+** the other hand if function fails 'res' variable is set and a jump to
+** label 'test_cleanup' is performed.
+**
+** Every easy_* and multi_* macros have a res_easy_* and res_multi_* macro
+** counterpart that operates in tha same way with the exception that no
+** jump takes place in case of failure. res_easy_* and res_multi_* macros
+** should be immediately followed by checking if 'res' variable has been
+** set.
+**
+** 'res' variable when set will hold a CURLcode, CURLMcode, or any of the
+** TEST_ERR_* values defined above. It is advisable to return this value
+** as test result.
+*/
+
+/* ---------------------------------------------------------------- */
+
+#define exe_easy_init(A,Y,Z) do { \
+ if(((A) = curl_easy_init()) == NULL) { \
+ fprintf(stderr, "%s:%d curl_easy_init() failed\n", (Y), (Z)); \
+ res = TEST_ERR_EASY_INIT; \
+ } \
+} WHILE_FALSE
+
+#define res_easy_init(A) \
+ exe_easy_init((A),(__FILE__),(__LINE__))
+
+#define chk_easy_init(A,Y,Z) do { \
+ exe_easy_init((A),(Y),(Z)); \
+ if(res) \
+ goto test_cleanup; \
+} WHILE_FALSE
+
+#define easy_init(A) \
+ chk_easy_init((A),(__FILE__),(__LINE__))
+
+/* ---------------------------------------------------------------- */
+
+#define exe_multi_init(A,Y,Z) do { \
+ if(((A) = curl_multi_init()) == NULL) { \
+ fprintf(stderr, "%s:%d curl_multi_init() failed\n", (Y), (Z)); \
+ res = TEST_ERR_MULTI_INIT; \
+ } \
+} WHILE_FALSE
+
+#define res_multi_init(A) \
+ exe_multi_init((A),(__FILE__),(__LINE__))
+
+#define chk_multi_init(A,Y,Z) do { \
+ exe_multi_init((A),(Y),(Z)); \
+ if(res) \
+ goto test_cleanup; \
+} WHILE_FALSE
+
+#define multi_init(A) \
+ chk_multi_init((A),(__FILE__),(__LINE__))
+
+/* ---------------------------------------------------------------- */
+
+#define exe_easy_setopt(A,B,C,Y,Z) do { \
+ CURLcode ec; \
+ if((ec = curl_easy_setopt((A),(B),(C))) != CURLE_OK) { \
+ fprintf(stderr, "%s:%d curl_easy_setopt() failed, " \
+ "with code %d (%s)\n", \
+ (Y), (Z), (int)ec, curl_easy_strerror(ec)); \
+ res = (int)ec; \
+ } \
+} WHILE_FALSE
+
+#define res_easy_setopt(A,B,C) \
+ exe_easy_setopt((A),(B),(C),(__FILE__),(__LINE__))
+
+#define chk_easy_setopt(A,B,C,Y,Z) do { \
+ exe_easy_setopt((A),(B),(C),(Y),(Z)); \
+ if(res) \
+ goto test_cleanup; \
+} WHILE_FALSE
+
+#define easy_setopt(A,B,C) \
+ chk_easy_setopt((A),(B),(C),(__FILE__),(__LINE__))
+
+/* ---------------------------------------------------------------- */
+
+#define exe_multi_setopt(A,B,C,Y,Z) do { \
+ CURLMcode ec; \
+ if((ec = curl_multi_setopt((A),(B),(C))) != CURLM_OK) { \
+ fprintf(stderr, "%s:%d curl_multi_setopt() failed, " \
+ "with code %d (%s)\n", \
+ (Y), (Z), (int)ec, curl_multi_strerror(ec)); \
+ res = (int)ec; \
+ } \
+} WHILE_FALSE
+
+#define res_multi_setopt(A,B,C) \
+ exe_multi_setopt((A),(B),(C),(__FILE__),(__LINE__))
+
+#define chk_multi_setopt(A,B,C,Y,Z) do { \
+ exe_multi_setopt((A),(B),(C),(Y),(Z)); \
+ if(res) \
+ goto test_cleanup; \
+} WHILE_FALSE
+
+#define multi_setopt(A,B,C) \
+ chk_multi_setopt((A),(B),(C),(__FILE__),(__LINE__))
+
+/* ---------------------------------------------------------------- */
+
+#define exe_multi_add_handle(A,B,Y,Z) do { \
+ CURLMcode ec; \
+ if((ec = curl_multi_add_handle((A),(B))) != CURLM_OK) { \
+ fprintf(stderr, "%s:%d curl_multi_add_handle() failed, " \
+ "with code %d (%s)\n", \
+ (Y), (Z), (int)ec, curl_multi_strerror(ec)); \
+ res = (int)ec; \
+ } \
+} WHILE_FALSE
+
+#define res_multi_add_handle(A,B) \
+ exe_multi_add_handle((A),(B),(__FILE__),(__LINE__))
+
+#define chk_multi_add_handle(A,B,Y,Z) do { \
+ exe_multi_add_handle((A),(B),(Y),(Z)); \
+ if(res) \
+ goto test_cleanup; \
+} WHILE_FALSE
+
+#define multi_add_handle(A,B) \
+ chk_multi_add_handle((A),(B),(__FILE__),(__LINE__))
+
+/* ---------------------------------------------------------------- */
+
+#define exe_multi_remove_handle(A,B,Y,Z) do { \
+ CURLMcode ec; \
+ if((ec = curl_multi_remove_handle((A),(B))) != CURLM_OK) { \
+ fprintf(stderr, "%s:%d curl_multi_remove_handle() failed, " \
+ "with code %d (%s)\n", \
+ (Y), (Z), (int)ec, curl_multi_strerror(ec)); \
+ res = (int)ec; \
+ } \
+} WHILE_FALSE
+
+#define res_multi_remove_handle(A,B) \
+ exe_multi_remove_handle((A),(B),(__FILE__),(__LINE__))
+
+#define chk_multi_remove_handle(A,B,Y,Z) do { \
+ exe_multi_remove_handle((A),(B),(Y),(Z)); \
+ if(res) \
+ goto test_cleanup; \
+} WHILE_FALSE
+
+
+#define multi_remove_handle(A,B) \
+ chk_multi_remove_handle((A),(B),(__FILE__),(__LINE__))
+
+/* ---------------------------------------------------------------- */
+
+#define exe_multi_perform(A,B,Y,Z) do { \
+ CURLMcode ec; \
+ if((ec = curl_multi_perform((A),(B))) != CURLM_OK) { \
+ fprintf(stderr, "%s:%d curl_multi_perform() failed, " \
+ "with code %d (%s)\n", \
+ (Y), (Z), (int)ec, curl_multi_strerror(ec)); \
+ res = (int)ec; \
+ } \
+ else if(*((B)) < 0) { \
+ fprintf(stderr, "%s:%d curl_multi_perform() succeeded, " \
+ "but returned invalid running_handles value (%d)\n", \
+ (Y), (Z), (int)*((B))); \
+ res = TEST_ERR_NUM_HANDLES; \
+ } \
+} WHILE_FALSE
+
+#define res_multi_perform(A,B) \
+ exe_multi_perform((A),(B),(__FILE__),(__LINE__))
+
+#define chk_multi_perform(A,B,Y,Z) do { \
+ exe_multi_perform((A),(B),(Y),(Z)); \
+ if(res) \
+ goto test_cleanup; \
+} WHILE_FALSE
+
+#define multi_perform(A,B) \
+ chk_multi_perform((A),(B),(__FILE__),(__LINE__))
+
+/* ---------------------------------------------------------------- */
+
+#define exe_multi_fdset(A,B,C,D,E,Y,Z) do { \
+ CURLMcode ec; \
+ if((ec = curl_multi_fdset((A),(B),(C),(D),(E))) != CURLM_OK) { \
+ fprintf(stderr, "%s:%d curl_multi_fdset() failed, " \
+ "with code %d (%s)\n", \
+ (Y), (Z), (int)ec, curl_multi_strerror(ec)); \
+ res = (int)ec; \
+ } \
+ else if(*((E)) < -1) { \
+ fprintf(stderr, "%s:%d curl_multi_fdset() succeeded, " \
+ "but returned invalid max_fd value (%d)\n", \
+ (Y), (Z), (int)*((E))); \
+ res = TEST_ERR_NUM_HANDLES; \
+ } \
+} WHILE_FALSE
+
+#define res_multi_fdset(A,B,C,D,E) \
+ exe_multi_fdset((A),(B),(C),(D),(E),(__FILE__),(__LINE__))
+
+#define chk_multi_fdset(A,B,C,D,E,Y,Z) do { \
+ exe_multi_fdset((A),(B),(C),(D),(E),(Y),(Z)); \
+ if(res) \
+ goto test_cleanup; \
+} WHILE_FALSE
+
+#define multi_fdset(A,B,C,D,E) \
+ chk_multi_fdset((A),(B),(C),(D),(E),(__FILE__),(__LINE__))
+
+/* ---------------------------------------------------------------- */
+
+#define exe_multi_timeout(A,B,Y,Z) do { \
+ CURLMcode ec; \
+ if((ec = curl_multi_timeout((A),(B))) != CURLM_OK) { \
+ fprintf(stderr, "%s:%d curl_multi_timeout() failed, " \
+ "with code %d (%s)\n", \
+ (Y), (Z), (int)ec, curl_multi_strerror(ec)); \
+ res = (int)ec; \
+ } \
+ else if(*((B)) < -1L) { \
+ fprintf(stderr, "%s:%d curl_multi_timeout() succeeded, " \
+ "but returned invalid timeout value (%ld)\n", \
+ (Y), (Z), (long)*((B))); \
+ res = TEST_ERR_BAD_TIMEOUT; \
+ } \
+} WHILE_FALSE
+
+#define res_multi_timeout(A,B) \
+ exe_multi_timeout((A),(B),(__FILE__),(__LINE__))
+
+#define chk_multi_timeout(A,B,Y,Z) do { \
+ exe_multi_timeout((A),(B),(Y),(Z)); \
+ if(res) \
+ goto test_cleanup; \
+} WHILE_FALSE
+
+#define multi_timeout(A,B) \
+ chk_multi_timeout((A),(B),(__FILE__),(__LINE__))
+
+/* ---------------------------------------------------------------- */
+
+#define exe_select_test(A,B,C,D,E,Y,Z) do { \
+ int ec; \
+ if(select_wrapper((A),(B),(C),(D),(E)) == -1 ) { \
+ ec = SOCKERRNO; \
+ fprintf(stderr, "%s:%d select() failed, with " \
+ "errno %d (%s)\n", \
+ (Y), (Z), ec, strerror(ec)); \
+ res = TEST_ERR_SELECT; \
+ } \
+} WHILE_FALSE
+
+#define res_select_test(A,B,C,D,E) \
+ exe_select_test((A),(B),(C),(D),(E),(__FILE__),(__LINE__))
+
+#define chk_select_test(A,B,C,D,E,Y,Z) do { \
+ exe_select_test((A),(B),(C),(D),(E),(Y),(Z)); \
+ if(res) \
+ goto test_cleanup; \
+} WHILE_FALSE
+
+#define select_test(A,B,C,D,E) \
+ chk_select_test((A),(B),(C),(D),(E),(__FILE__),(__LINE__))
+
+/* ---------------------------------------------------------------- */
+
+#define start_test_timing() do { \
+ tv_test_start = tutil_tvnow(); \
+} WHILE_FALSE
+
+#define exe_test_timedout(Y,Z) do { \
+ if(tutil_tvdiff(tutil_tvnow(), tv_test_start) > TEST_HANG_TIMEOUT) { \
+ fprintf(stderr, "%s:%d ABORTING TEST, since it seems " \
+ "that it would have run forever.\n", (Y), (Z)); \
+ res = TEST_ERR_RUNS_FOREVER; \
+ } \
+} WHILE_FALSE
+
+#define res_test_timedout() \
+ exe_test_timedout((__FILE__),(__LINE__))
+
+#define chk_test_timedout(Y,Z) do { \
+ exe_test_timedout(Y,Z); \
+ if(res) \
+ goto test_cleanup; \
+} WHILE_FALSE
+
+#define abort_on_test_timeout() \
+ chk_test_timedout((__FILE__),(__LINE__))
+
+/* ---------------------------------------------------------------- */
+
+#define exe_global_init(A,Y,Z) do { \
+ CURLcode ec; \
+ if((ec = curl_global_init((A))) != CURLE_OK) { \
+ fprintf(stderr, "%s:%d curl_global_init() failed, " \
+ "with code %d (%s)\n", \
+ (Y), (Z), (int)ec, curl_easy_strerror(ec)); \
+ res = (int)ec; \
+ } \
+} WHILE_FALSE
+
+#define res_global_init(A) \
+ exe_global_init((A),(__FILE__),(__LINE__))
+
+#define chk_global_init(A,Y,Z) do { \
+ exe_global_init((A),(Y),(Z)); \
+ if(res) \
+ return res; \
+} WHILE_FALSE
+
+/* global_init() is different than other macros. In case of
+ failure it 'return's instead of going to 'test_cleanup'. */
+
+#define global_init(A) \
+ chk_global_init((A),(__FILE__),(__LINE__))
+
+/* ---------------------------------------------------------------- */
diff --git a/tests/libtest/test1013.pl b/tests/libtest/test1013.pl
new file mode 100755
index 000000000..15e121415
--- /dev/null
+++ b/tests/libtest/test1013.pl
@@ -0,0 +1,50 @@
+#!/usr/bin/env perl
+# Determine if curl-config --protocols/--features matches the
+# curl --version protocols/features
+if ( $#ARGV != 2 )
+{
+ print "Usage: $0 curl-config-script curl-version-output-file features|protocols\n";
+ exit 3;
+}
+
+my $what=$ARGV[2];
+
+# Read the output of curl --version
+my $curl_protocols="";
+open(CURL, "$ARGV[1]") || die "Can't get curl $what list\n";
+while( <CURL> )
+{
+ $curl_protocols = lc($_) if ( /$what:/i );
+}
+close CURL;
+
+$curl_protocols =~ s/\r//;
+$curl_protocols =~ /\w+: (.*)$/;
+@curl = split / /,$1;
+
+# These features are not supported by curl-config
+@curl = grep(!/^(Debug|TrackMemory|Metalink|Largefile|CharConv|GSS-Negotiate|SPNEGO)$/i, @curl);
+@curl = sort @curl;
+
+# Read the output of curl-config
+my @curl_config;
+open(CURLCONFIG, "sh $ARGV[0] --$what|") || die "Can't get curl-config $what list\n";
+while( <CURLCONFIG> )
+{
+ chomp;
+ push @curl_config, lc($_);
+}
+close CURLCONFIG;
+
+@curl_config = sort @curl_config;
+
+my $curlproto = join ' ', @curl;
+my $curlconfigproto = join ' ', @curl_config;
+
+my $different = $curlproto ne $curlconfigproto;
+if ($different) {
+ print "Mismatch in $what lists:\n";
+ print "curl: $curlproto\n";
+ print "curl-config: $curlconfigproto\n";
+}
+exit $different;
diff --git a/tests/libtest/test1022.pl b/tests/libtest/test1022.pl
new file mode 100755
index 000000000..377808c73
--- /dev/null
+++ b/tests/libtest/test1022.pl
@@ -0,0 +1,54 @@
+#!/usr/bin/env perl
+# Determine if curl-config --version matches the curl --version
+if ( $#ARGV != 2 )
+{
+ print "Usage: $0 curl-config-script curl-version-output-file version|vernum\n";
+ exit 3;
+}
+
+my $what=$ARGV[2];
+
+# Read the output of curl --version
+open(CURL, "$ARGV[1]") || die "Can't open curl --version list in $ARGV[1]\n";
+$_ = <CURL>;
+chomp;
+/libcurl\/([\.\d]+((-DEV)|(-\d+))?)/;
+my $version = $1;
+close CURL;
+
+my $curlconfigversion;
+
+# Read the output of curl-config --version/--vernum
+open(CURLCONFIG, "sh $ARGV[0] --$what|") || die "Can't get curl-config --$what list\n";
+$_ = <CURLCONFIG>;
+chomp;
+my $filever=$_;
+if ( $what eq "version" ) {
+ if($filever =~ /^libcurl ([\.\d]+((-DEV)|(-\d+))?)$/) {
+ $curlconfigversion = $1;
+ }
+ else {
+ $curlconfigversion = "illegal value";
+ }
+}
+else { # "vernum" case
+ # Convert hex version to decimal for comparison's sake
+ if($filever =~ /^(..)(..)(..)$/) {
+ $curlconfigversion = hex($1) . "." . hex($2) . "." . hex($3);
+ }
+ else {
+ $curlconfigversion = "illegal value";
+ }
+
+ # Strip off the -DEV from the curl version if it's there
+ $version =~ s/-\w*$//;
+}
+close CURLCONFIG;
+
+my $different = $version ne $curlconfigversion;
+if ($different || !$version) {
+ print "Mismatch in --version:\n";
+ print "curl: $version\n";
+ print "curl-config: $curlconfigversion\n";
+ exit 1;
+}
diff --git a/tests/libtest/test307.pl b/tests/libtest/test307.pl
new file mode 100755
index 000000000..469af3c21
--- /dev/null
+++ b/tests/libtest/test307.pl
@@ -0,0 +1,19 @@
+#!/usr/bin/env perl
+# Determine if the given curl executable supports the 'openssl' SSL engine
+if ( $#ARGV != 0 )
+{
+ print "Usage: $0 curl-executable\n";
+ exit 3;
+}
+if (!open(CURL, "@ARGV[0] -s --engine list|"))
+{
+ print "Can't get SSL engine list\n";
+ exit 2;
+}
+while( <CURL> )
+{
+ exit 0 if ( /openssl/ );
+}
+close CURL;
+print "openssl engine not supported\n";
+exit 1;
diff --git a/tests/libtest/test610.pl b/tests/libtest/test610.pl
new file mode 100755
index 000000000..a900d94b4
--- /dev/null
+++ b/tests/libtest/test610.pl
@@ -0,0 +1,33 @@
+#!/usr/bin/env perl
+# Perform simple file and directory manipulation in a portable way
+if ( $#ARGV <= 0 )
+{
+ print "Usage: $0 mkdir|rmdir|rm|move|gone path1 [path2] [more commands...]\n";
+ exit 1;
+}
+
+use File::Copy;
+while(@ARGV) {
+ my $cmd = shift @ARGV;
+ my $arg = shift @ARGV;
+ if ($cmd eq "mkdir") {
+ mkdir $arg || die "$!";
+ }
+ elsif ($cmd eq "rmdir") {
+ rmdir $arg || die "$!";
+ }
+ elsif ($cmd eq "rm") {
+ unlink $arg || die "$!";
+ }
+ elsif ($cmd eq "move") {
+ my $arg2 = shift @ARGV;
+ move($arg,$arg2) || die "$!";
+ }
+ elsif ($cmd eq "gone") {
+ ! -e $arg || die "Path $arg exists";
+ } else {
+ print "Unsupported command $cmd\n";
+ exit 1;
+ }
+}
+exit 0;
diff --git a/tests/libtest/test613.pl b/tests/libtest/test613.pl
new file mode 100755
index 000000000..b4caaae07
--- /dev/null
+++ b/tests/libtest/test613.pl
@@ -0,0 +1,105 @@
+#!/usr/bin/env perl
+# Prepare a directory with known files and clean up afterwards
+use Time::Local;
+
+if ( $#ARGV < 1 )
+{
+ print "Usage: $0 prepare|postprocess dir [logfile]\n";
+ exit 1;
+}
+
+# <precheck> expects an error message on stdout
+sub errout {
+ print $_[0] . "\n";
+ exit 1;
+}
+
+if ($ARGV[0] eq "prepare")
+{
+ my $dirname = $ARGV[1];
+ mkdir $dirname || errout "$!";
+ chdir $dirname;
+
+ # Create the files in alphabetical order, to increase the chances
+ # of receiving a consistent set of directory contents regardless
+ # of whether the server alphabetizes the results or not.
+ mkdir "asubdir" || errout "$!";
+ chmod 0777, "asubdir";
+
+ open(FILE, ">plainfile.txt") || errout "$!";
+ binmode FILE;
+ print FILE "Test file to support curl test suite\n";
+ close(FILE);
+ utime time, timegm(0,0,12,1,0,100), "plainfile.txt";
+ chmod 0666, "plainfile.txt";
+
+ open(FILE, ">rofile.txt") || errout "$!";
+ binmode FILE;
+ print FILE "Read-only test file to support curl test suite\n";
+ close(FILE);
+ utime time, timegm(0,0,12,31,11,100), "rofile.txt";
+ chmod 0444, "rofile.txt";
+
+ exit 0;
+}
+elsif ($ARGV[0] eq "postprocess")
+{
+ my $dirname = $ARGV[1];
+ my $logfile = $ARGV[2];
+
+ # Clean up the test directory
+ unlink "$dirname/rofile.txt";
+ unlink "$dirname/plainfile.txt";
+ rmdir "$dirname/asubdir";
+
+ rmdir $dirname || die "$!";
+
+ if ($logfile) {
+ # Process the directory file to remove all information that
+ # could be inconsistent from one test run to the next (e.g.
+ # file date) or may be unsupported on some platforms (e.g.
+ # Windows). Also, since 7.17.0, the sftp directory listing
+ # format can be dependent on the server (with a recent
+ # enough version of libssh2) so this script must also
+ # canonicalize the format. Here are examples of the general
+ # format supported:
+ # -r--r--r-- 12 ausername grp 47 Dec 31 2000 rofile.txt
+ # -r--r--r-- 1 1234 4321 47 Dec 31 2000 rofile.txt
+ # The "canonical" format is similar to the first (which is
+ # the one generated on a typical Linux installation):
+ # -r-?r-?r-? 12 U U 47 Dec 31 2000 rofile.txt
+
+ my @canondir;
+ open(IN, "<$logfile") || die "$!";
+ while (<IN>) {
+ /^(.)(..).(..).(..).\s*(\S+)\s+\S+\s+\S+\s+(\S+)\s+(\S+\s+\S+\s+\S+)(.*)$/;
+ if ($1 eq "d") {
+ # Erase all directory metadata except for the name, as it is not
+ # consistent for across all test systems and filesystems
+ push @canondir, "d????????? N U U N ??? N NN:NN$8\n";
+ } elsif ($1 eq "-") {
+ # Erase user and group names, as they are not consistent across
+ # all test systems
+ my $line = sprintf("%s%s?%s?%s?%5d U U %15d %s%s\n", $1,$2,$3,$4,$5,$6,$7,$8);
+ push @canondir, $line;
+ } else {
+ # Unexpected format; just pass it through and let the test fail
+ push @canondir, $_;
+ }
+ }
+ close(IN);
+
+ @canondir = sort {substr($a,57) cmp substr($b,57)} @canondir;
+ my $newfile = $logfile . ".new";
+ open(OUT, ">$newfile") || die "$!";
+ print OUT join('', @canondir);
+ close(OUT);
+
+ unlink $logfile;
+ rename $newfile, $logfile;
+ }
+
+ exit 0;
+}
+print "Unsupported command $ARGV[0]\n";
+exit 1;
diff --git a/tests/libtest/test75.pl b/tests/libtest/test75.pl
new file mode 100755
index 000000000..31cdfb8cc
--- /dev/null
+++ b/tests/libtest/test75.pl
@@ -0,0 +1,13 @@
+#!/usr/bin/env perl
+# Check that the length of a given URL is correct
+if ( $#ARGV != 1 )
+{
+ print "Usage: $0 string length\n";
+ exit 3;
+}
+if (length(@ARGV[0]) != @ARGV[1])
+{
+ print "Given host IP and port not supported\n";
+ exit 1;
+}
+exit 0;
diff --git a/tests/libtest/testtrace.c b/tests/libtest/testtrace.c
new file mode 100644
index 000000000..c977d2105
--- /dev/null
+++ b/tests/libtest/testtrace.c
@@ -0,0 +1,146 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+
+#include "test.h"
+
+#define _MPRINTF_REPLACE /* use our functions only */
+#include <curl/mprintf.h>
+
+#include "testutil.h"
+#include "testtrace.h"
+#include "memdebug.h"
+
+struct libtest_trace_cfg libtest_debug_config;
+
+static time_t epoch_offset; /* for test time tracing */
+static int known_offset; /* for test time tracing */
+
+static
+void libtest_debug_dump(const char *timebuf, const char *text, FILE *stream,
+ const unsigned char *ptr, size_t size, int nohex)
+{
+ size_t i;
+ size_t c;
+
+ unsigned int width = 0x10;
+
+ if(nohex)
+ /* without the hex output, we can fit more on screen */
+ width = 0x40;
+
+ fprintf(stream, "%s%s, %d bytes (0x%x)\n", timebuf, text,
+ (int)size, (int)size);
+
+ for(i = 0; i < size; i += width) {
+
+ fprintf(stream, "%04x: ", (int)i);
+
+ if(!nohex) {
+ /* hex not disabled, show it */
+ for(c = 0; c < width; c++)
+ if(i+c < size)
+ fprintf(stream, "%02x ", ptr[i+c]);
+ else
+ fputs(" ", stream);
+ }
+
+ for(c = 0; (c < width) && (i+c < size); c++) {
+ /* check for 0D0A; if found, skip past and start a new line of output */
+ if(nohex &&
+ (i+c+1 < size) && (ptr[i+c] == 0x0D) && (ptr[i+c+1] == 0x0A)) {
+ i += (c+2-width);
+ break;
+ }
+ fprintf(stream, "%c", ((ptr[i+c] >= 0x20) && (ptr[i+c] < 0x80)) ?
+ ptr[i+c] : '.');
+ /* check again for 0D0A, to avoid an extra \n if it's at width */
+ if(nohex &&
+ (i+c+2 < size) && (ptr[i+c+1] == 0x0D) && (ptr[i+c+2] == 0x0A)) {
+ i += (c+3-width);
+ break;
+ }
+ }
+ fputc('\n', stream); /* newline */
+ }
+ fflush(stream);
+}
+
+int libtest_debug_cb(CURL *handle, curl_infotype type,
+ unsigned char *data, size_t size,
+ void *userp)
+{
+
+ struct libtest_trace_cfg *trace_cfg = userp;
+ const char *text;
+ struct timeval tv;
+ struct tm *now;
+ char timebuf[20];
+ char *timestr;
+ time_t secs;
+
+ (void)handle;
+
+ timebuf[0] = '\0';
+ timestr = &timebuf[0];
+
+ if(trace_cfg->tracetime) {
+ tv = tutil_tvnow();
+ if(!known_offset) {
+ epoch_offset = time(NULL) - tv.tv_sec;
+ known_offset = 1;
+ }
+ secs = epoch_offset + tv.tv_sec;
+ now = localtime(&secs); /* not thread safe but we don't care */
+ snprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld ",
+ now->tm_hour, now->tm_min, now->tm_sec, (long)tv.tv_usec);
+ }
+
+ switch (type) {
+ case CURLINFO_TEXT:
+ fprintf(stderr, "%s== Info: %s", timestr, (char *)data);
+ default: /* in case a new one is introduced to shock us */
+ return 0;
+
+ case CURLINFO_HEADER_OUT:
+ text = "=> Send header";
+ break;
+ case CURLINFO_DATA_OUT:
+ text = "=> Send data";
+ break;
+ case CURLINFO_SSL_DATA_OUT:
+ text = "=> Send SSL data";
+ break;
+ case CURLINFO_HEADER_IN:
+ text = "<= Recv header";
+ break;
+ case CURLINFO_DATA_IN:
+ text = "<= Recv data";
+ break;
+ case CURLINFO_SSL_DATA_IN:
+ text = "<= Recv SSL data";
+ break;
+ }
+
+ libtest_debug_dump(timebuf, text, stderr, data, size, trace_cfg->nohex);
+ return 0;
+}
+
diff --git a/tests/libtest/testtrace.h b/tests/libtest/testtrace.h
new file mode 100644
index 000000000..73d2489a4
--- /dev/null
+++ b/tests/libtest/testtrace.h
@@ -0,0 +1,37 @@
+#ifndef HEADER_LIBTEST_TESTTRACE_H
+#define HEADER_LIBTEST_TESTTRACE_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+
+struct libtest_trace_cfg {
+ int tracetime; /* 0 represents FALSE, anything else TRUE */
+ int nohex; /* 0 represents FALSE, anything else TRUE */
+};
+
+extern struct libtest_trace_cfg libtest_debug_config;
+
+int libtest_debug_cb(CURL *handle, curl_infotype type,
+ unsigned char *data, size_t size,
+ void *userp);
+
+#endif /* HEADER_LIBTEST_TESTTRACE_H */
+
diff --git a/tests/libtest/testutil.c b/tests/libtest/testutil.c
new file mode 100644
index 000000000..3ad18c987
--- /dev/null
+++ b/tests/libtest/testutil.c
@@ -0,0 +1,137 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "setup.h"
+
+#include "testutil.h"
+#include "memdebug.h"
+
+#if defined(WIN32) && !defined(MSDOS)
+
+struct timeval tutil_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.
+ */
+ struct timeval now;
+ DWORD milliseconds = GetTickCount();
+ now.tv_sec = milliseconds / 1000;
+ now.tv_usec = (milliseconds % 1000) * 1000;
+ return now;
+}
+
+#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
+
+struct timeval tutil_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 = 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 = (long)time(NULL);
+ now.tv_usec = 0;
+ }
+#endif
+ return now;
+}
+
+#elif defined(HAVE_GETTIMEOFDAY)
+
+struct timeval tutil_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
+
+struct timeval tutil_tvnow(void)
+{
+ /*
+ ** time() returns the value of time in seconds since the Epoch.
+ */
+ struct timeval now;
+ now.tv_sec = (long)time(NULL);
+ now.tv_usec = 0;
+ return now;
+}
+
+#endif
+
+/*
+ * Make sure that the first argument is the more recent time, as otherwise
+ * we'll get a weird negative time-diff back...
+ *
+ * Returns: the time difference in number of milliseconds.
+ */
+long tutil_tvdiff(struct timeval newer, struct timeval older)
+{
+ return (newer.tv_sec-older.tv_sec)*1000+
+ (newer.tv_usec-older.tv_usec)/1000;
+}
+
+/*
+ * Same as tutil_tvdiff but with full usec resolution.
+ *
+ * Returns: the time difference in seconds with subsecond resolution.
+ */
+double tutil_tvdiff_secs(struct timeval newer, struct timeval older)
+{
+ if(newer.tv_sec != older.tv_sec)
+ return (double)(newer.tv_sec-older.tv_sec)+
+ (double)(newer.tv_usec-older.tv_usec)/1000000.0;
+ else
+ return (double)(newer.tv_usec-older.tv_usec)/1000000.0;
+}
+
+/* return the number of seconds in the given input timeval struct */
+long tutil_tvlong(struct timeval t1)
+{
+ return t1.tv_sec;
+}
+
diff --git a/tests/libtest/testutil.h b/tests/libtest/testutil.h
new file mode 100644
index 000000000..0c6be2fc4
--- /dev/null
+++ b/tests/libtest/testutil.h
@@ -0,0 +1,47 @@
+#ifndef HEADER_CURL_LIBTEST_TESTUTIL_H
+#define HEADER_CURL_LIBTEST_TESTUTIL_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, 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 http://curl.haxx.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.
+ *
+ ***************************************************************************/
+#include "setup.h"
+
+struct timeval tutil_tvnow(void);
+
+/*
+ * Make sure that the first argument (t1) is the more recent time and t2 is
+ * the older time, as otherwise you get a weird negative time-diff back...
+ *
+ * Returns: the time difference in number of milliseconds.
+ */
+long tutil_tvdiff(struct timeval t1, struct timeval t2);
+
+/*
+ * Same as tutil_tvdiff but with full usec resolution.
+ *
+ * Returns: the time difference in seconds with subsecond resolution.
+ */
+double tutil_tvdiff_secs(struct timeval t1, struct timeval t2);
+
+long tutil_tvlong(struct timeval t1);
+
+
+#endif /* HEADER_CURL_LIBTEST_TESTUTIL_H */
+