fix:...
This commit is contained in:
@@ -1,279 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 2005 - 2009, Gisle Vanem <gvanem@yahoo.no>.
|
||||
# Copyright (C) 2005 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
#
|
||||
# Watcom / OpenWatcom / Win32 makefile for libcurl.
|
||||
#
|
||||
|
||||
.ERASE
|
||||
|
||||
!if $(__VERSION__) < 1280
|
||||
!message !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!message ! This Open Watcom version is too old and is no longer supported !
|
||||
!message ! Please download latest version from www.openwatcom.org !
|
||||
!message !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!error Unsupported version of Open Watcom
|
||||
!endif
|
||||
|
||||
!ifndef %watcom
|
||||
!error WATCOM environment variable not set!
|
||||
!endif
|
||||
|
||||
# In order to process Makefile.inc wmake must be called with -u switch!
|
||||
!ifndef %MAKEFLAGS
|
||||
!error You MUST call wmake with the -u switch!
|
||||
!endif
|
||||
|
||||
!ifdef %libname
|
||||
LIBNAME = $(%libname)
|
||||
!else
|
||||
LIBNAME = libcurl
|
||||
!endif
|
||||
TARGETS = $(LIBNAME).dll $(LIBNAME).lib
|
||||
|
||||
CC = wcc386
|
||||
LD = wlink
|
||||
AR = wlib
|
||||
RC = wrc
|
||||
|
||||
!ifdef __LOADDLL__
|
||||
! loaddll wcc386 wccd386
|
||||
! loaddll wpp386 wppd386
|
||||
! loaddll wlib wlibd
|
||||
! loaddll wlink wlinkd
|
||||
!endif
|
||||
|
||||
!ifdef __LINUX__
|
||||
CP = cp
|
||||
MD = mkdir -p
|
||||
!else
|
||||
CP = copy 2>NUL
|
||||
MD = mkdir
|
||||
!endif
|
||||
!if $(__VERSION__) > 1290
|
||||
RD = rm -rf
|
||||
!else ifdef __UNIX__
|
||||
RD = rm -rf
|
||||
!else
|
||||
RD = rmdir /q /s 2>NUL
|
||||
!endif
|
||||
|
||||
SYS_INCL = -I"$(%watcom)/h/nt" -I"$(%watcom)/h"
|
||||
|
||||
CFLAGS = -3r -mf -hc -zff -zgf -zq -zm -zc -s -fr=con -w2 -fpi -oilrtfm &
|
||||
-wcd=201 -bt=nt -d+ -dWIN32 -dCURL_WANTS_CA_BUNDLE_ENV &
|
||||
-dBUILDING_LIBCURL -I. -I"../include" $(SYS_INCL)
|
||||
|
||||
!ifdef %debug
|
||||
DEBUG = -dDEBUG=1 -dDEBUGBUILD
|
||||
CFLAGS += -d3 $(DEBUG)
|
||||
!else
|
||||
CFLAGS += -d0
|
||||
!endif
|
||||
|
||||
!ifdef %use_ipv6
|
||||
CFLAGS += -d_WIN32_WINNT=0x0501 -dENABLE_IPV6
|
||||
!endif
|
||||
|
||||
!ifdef %use_sspi
|
||||
CFLAGS += -dUSE_WINDOWS_SSPI
|
||||
!endif
|
||||
|
||||
!ifdef %use_winssl
|
||||
CFLAGS += -dUSE_WINDOWS_SSPI
|
||||
CFLAGS += -DUSE_SCHANNEL
|
||||
!endif
|
||||
|
||||
!ifdef %use_winidn
|
||||
CFLAGS += -dWINVER=0x0600 -dUSE_WIN32_IDN
|
||||
! if $(__VERSION__) <= 1290
|
||||
CFLAGS += -dWANT_IDN_PROTOTYPES
|
||||
! endif
|
||||
!endif
|
||||
|
||||
#
|
||||
# Change to suite.
|
||||
#
|
||||
!ifdef %zlib_root
|
||||
ZLIB_ROOT = $(%zlib_root)
|
||||
!else
|
||||
ZLIB_ROOT = ../../zlib-1.2.8
|
||||
!endif
|
||||
|
||||
!ifdef %libssh2_root
|
||||
LIBSSH2_ROOT = $(%libssh2_root)
|
||||
!else
|
||||
LIBSSH2_ROOT = ../../libssh2-1.5.0
|
||||
!endif
|
||||
|
||||
!ifdef %librtmp_root
|
||||
LIBRTMP_ROOT = $(%librtmp_root)
|
||||
!else
|
||||
LIBRTMP_ROOT = ../../rtmpdump-2.3
|
||||
!endif
|
||||
|
||||
!ifdef %openssl_root
|
||||
OPENSSL_ROOT = $(%openssl_root)
|
||||
!else
|
||||
OPENSSL_ROOT = ../../openssl-1.0.2a
|
||||
!endif
|
||||
|
||||
!ifdef %ares_root
|
||||
ARES_ROOT = $(%ares_root)
|
||||
!else
|
||||
ARES_ROOT = ../ares
|
||||
!endif
|
||||
|
||||
!ifdef %use_zlib
|
||||
CFLAGS += -dHAVE_ZLIB_H -dHAVE_LIBZ -I"$(ZLIB_ROOT)"
|
||||
!endif
|
||||
|
||||
!ifdef %use_rtmp
|
||||
CFLAGS += -dUSE_LIBRTMP -I"$(LIBRTMP_ROOT)"
|
||||
!endif
|
||||
|
||||
!ifdef %use_ssh2
|
||||
CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H -I"$(LIBSSH2_ROOT)/include" -I"$(LIBSSH2_ROOT)/win32"
|
||||
!endif
|
||||
|
||||
!ifdef %use_ssl
|
||||
CFLAGS += -wcd=138 -dUSE_OPENSSL -dUSE_SSLEAY -I"$(OPENSSL_ROOT)/inc32"
|
||||
!endif
|
||||
|
||||
!ifdef %use_ares
|
||||
CFLAGS += -dUSE_ARES -I"$(ARES_ROOT)"
|
||||
!endif
|
||||
|
||||
!ifdef %use_watt32
|
||||
CFLAGS += -dUSE_WATT32 -I"$(%watt_root)/inc"
|
||||
!endif
|
||||
|
||||
OBJ_BASE = WC_Win32.obj
|
||||
!if $(__VERSION__) > 1290
|
||||
OBJ_STAT = $(OBJ_BASE)/stat
|
||||
OBJ_DYN = $(OBJ_BASE)/dyn
|
||||
!else ifdef __UNIX__
|
||||
OBJ_STAT = $(OBJ_BASE)/stat
|
||||
OBJ_DYN = $(OBJ_BASE)/dyn
|
||||
!else
|
||||
OBJ_STAT = $(OBJ_BASE)\stat
|
||||
OBJ_DYN = $(OBJ_BASE)\dyn
|
||||
!endif
|
||||
|
||||
LINK_ARG = $(OBJ_DYN)/wlink.arg
|
||||
LIB_ARG = $(OBJ_STAT)/wlib.arg
|
||||
|
||||
!include Makefile.inc
|
||||
|
||||
OBJS1 = ./$(CSOURCES:.c=.obj)
|
||||
OBJS2 = $(OBJS1:vtls/=)
|
||||
OBJS3 = $(OBJS2:vauth/=)
|
||||
OBJS4 = $(OBJS3: = ./)
|
||||
OBJS_STAT = $(OBJS4:./=$(OBJ_STAT)/)
|
||||
OBJS_DYN = $(OBJS4:./=$(OBJ_DYN)/)
|
||||
|
||||
CURLBUILDH = ../include/curl/curlbuild.h
|
||||
RESOURCE = $(OBJ_DYN)/libcurl.res
|
||||
|
||||
DIRS = $(OBJ_BASE) $(OBJ_BASE)/stat $(OBJ_BASE)/dyn
|
||||
|
||||
.c : vauth vtls
|
||||
|
||||
all: $(CURLBUILDH) $(DIRS) $(TARGETS) .SYMBOLIC
|
||||
@echo Welcome to libcurl
|
||||
|
||||
clean: .SYMBOLIC
|
||||
-rm -f $(OBJS_STAT)
|
||||
-rm -f $(OBJS_DYN)
|
||||
-rm -f $(RESOURCE) $(LINK_ARG) $(LIB_ARG)
|
||||
|
||||
vclean distclean: clean .SYMBOLIC
|
||||
-rm -f $(TARGETS) $(LIBNAME).map $(LIBNAME).sym
|
||||
-$(RD) $(OBJ_STAT)
|
||||
-$(RD) $(OBJ_DYN)
|
||||
-$(RD) $(OBJ_BASE)
|
||||
|
||||
$(DIRS):
|
||||
-$(MD) $^@
|
||||
|
||||
$(CURLBUILDH): .EXISTSONLY
|
||||
$(CP) $^@.dist $^@
|
||||
|
||||
$(LIBNAME).dll: $(OBJS_DYN) $(RESOURCE) $(__MAKEFILES__)
|
||||
%create $(LINK_ARG)
|
||||
@%append $(LINK_ARG) system nt dll
|
||||
!ifdef %debug
|
||||
@%append $(LINK_ARG) debug all
|
||||
@%append $(LINK_ARG) option symfile
|
||||
!endif
|
||||
@%append $(LINK_ARG) option quiet, caseexact, eliminate
|
||||
@%append $(LINK_ARG) option map=$(OBJ_DYN)/$(LIBNAME).map
|
||||
@%append $(LINK_ARG) option implib=$(LIBNAME)_imp.lib
|
||||
@%append $(LINK_ARG) option res=$(RESOURCE)
|
||||
@for %f in ($(OBJS_DYN)) do @%append $(LINK_ARG) file %f
|
||||
@%append $(LINK_ARG) library wldap32.lib
|
||||
!ifdef %use_watt32
|
||||
@%append $(LINK_ARG) library '$(%watt_root)/lib/wattcpw_imp.lib'
|
||||
!else
|
||||
@%append $(LINK_ARG) library ws2_32.lib
|
||||
!endif
|
||||
!ifdef %use_zlib
|
||||
@%append $(LINK_ARG) library '$(ZLIB_ROOT)/zlib.lib'
|
||||
!endif
|
||||
!ifdef %use_rtmp
|
||||
@%append $(LINK_ARG) library '$(LIBRTMP_ROOT)/librtmp/librtmp.lib'
|
||||
!endif
|
||||
!ifdef %use_ssh2
|
||||
@%append $(LINK_ARG) library '$(LIBSSH2_ROOT)/win32/libssh2.lib'
|
||||
!endif
|
||||
!ifdef %use_ssl
|
||||
@%append $(LINK_ARG) library '$(OPENSSL_ROOT)/out32/libeay32.lib'
|
||||
@%append $(LINK_ARG) library '$(OPENSSL_ROOT)/out32/ssleay32.lib'
|
||||
!endif
|
||||
!ifdef %use_ares
|
||||
@%append $(LINK_ARG) library '$(ARES_ROOT)/cares.lib'
|
||||
!endif
|
||||
!ifdef %use_winidn
|
||||
! if $(__VERSION__) > 1290
|
||||
@%append $(LINK_ARG) library normaliz.lib
|
||||
! else
|
||||
@%append $(LINK_ARG) import '_IdnToAscii@20' 'NORMALIZ.DLL'.'IdnToAscii'
|
||||
@%append $(LINK_ARG) import '_IdnToUnicode@20' 'NORMALIZ.DLL'.'IdnToUnicode'
|
||||
! endif
|
||||
!endif
|
||||
$(LD) name $^@ @$(LINK_ARG)
|
||||
|
||||
$(LIBNAME).lib: $(OBJS_STAT)
|
||||
%create $(LIB_ARG)
|
||||
@for %f in ($<) do @%append $(LIB_ARG) +- %f
|
||||
$(AR) -q -b -c -pa $^@ @$(LIB_ARG)
|
||||
|
||||
$(RESOURCE): libcurl.rc
|
||||
$(RC) $(DEBUG) -q -r -zm -bt=nt -I"../include" $(SYS_INCL) $[@ -fo=$^@
|
||||
|
||||
.c{$(OBJ_DYN)}.obj:
|
||||
$(CC) $(CFLAGS) -bd -br $[@ -fo=$^@
|
||||
|
||||
.c{$(OBJ_STAT)}.obj:
|
||||
$(CC) $(CFLAGS) -DCURL_STATICLIB $[@ -fo=$^@
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,80 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
LIB_VAUTH_CFILES = vauth/vauth.c vauth/cleartext.c vauth/cram.c \
|
||||
vauth/digest.c vauth/digest_sspi.c vauth/krb5_gssapi.c \
|
||||
vauth/krb5_sspi.c vauth/ntlm.c vauth/ntlm_sspi.c vauth/oauth2.c \
|
||||
vauth/spnego_gssapi.c vauth/spnego_sspi.c
|
||||
|
||||
LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h
|
||||
|
||||
LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \
|
||||
vtls/polarssl.c vtls/polarssl_threadlock.c vtls/axtls.c \
|
||||
vtls/cyassl.c vtls/schannel.c vtls/darwinssl.c vtls/gskit.c \
|
||||
vtls/mbedtls.c
|
||||
|
||||
LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \
|
||||
vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h vtls/axtls.h \
|
||||
vtls/cyassl.h vtls/schannel.h vtls/darwinssl.h vtls/gskit.h \
|
||||
vtls/mbedtls.h
|
||||
|
||||
LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
||||
cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \
|
||||
ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c \
|
||||
getinfo.c transfer.c strcase.c easy.c security.c curl_fnmatch.c \
|
||||
fileinfo.c ftplistparser.c wildcard.c krb5.c memdebug.c http_chunks.c \
|
||||
strtok.c connect.c llist.c hash.c multi.c content_encoding.c share.c \
|
||||
http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c \
|
||||
strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c \
|
||||
inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c \
|
||||
ssh.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \
|
||||
curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c \
|
||||
pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c \
|
||||
openldap.c curl_gethostname.c gopher.c idn_win32.c \
|
||||
http_proxy.c non-ascii.c asyn-ares.c asyn-thread.c curl_gssapi.c \
|
||||
http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c \
|
||||
curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c \
|
||||
x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c
|
||||
|
||||
LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
|
||||
formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \
|
||||
speedcheck.h urldata.h curl_ldap.h escape.h telnet.h getinfo.h \
|
||||
strcase.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h \
|
||||
wildcard.h fileinfo.h ftplistparser.h strtok.h connect.h llist.h \
|
||||
hash.h content_encoding.h share.h curl_md4.h curl_md5.h http_digest.h \
|
||||
http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h \
|
||||
inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h \
|
||||
easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h \
|
||||
socks.h ssh.h curl_base64.h curl_addrinfo.h curl_sspi.h \
|
||||
slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h \
|
||||
rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h \
|
||||
curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h \
|
||||
http_ntlm.h curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h \
|
||||
curl_sasl.h curl_multibyte.h hostcheck.h conncache.h \
|
||||
curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h \
|
||||
x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \
|
||||
curl_printf.h system_win32.h rand.h
|
||||
|
||||
LIB_RCFILES = libcurl.rc
|
||||
|
||||
CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES)
|
||||
HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES)
|
||||
@@ -1,363 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1999 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
## Makefile for building libcurl.a with MingW (GCC-3.2 or later)
|
||||
## and optionally OpenSSL (1.0.2a), libssh2 (1.5), zlib (1.2.8), librtmp (2.4)
|
||||
##
|
||||
## Usage: mingw32-make -f Makefile.m32 CFG=-feature1[-feature2][-feature3][...]
|
||||
## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-sspi-winidn
|
||||
##
|
||||
## Hint: you can also set environment vars to control the build, f.e.:
|
||||
## set ZLIB_PATH=c:/zlib-1.2.8
|
||||
## set ZLIB=1
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# Edit the path below to point to the base of your Zlib sources.
|
||||
ifndef ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.8
|
||||
endif
|
||||
# Edit the path below to point to the base of your OpenSSL package.
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-1.0.2a
|
||||
endif
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.5.0
|
||||
endif
|
||||
# Edit the path below to point to the base of your librtmp package.
|
||||
ifndef LIBRTMP_PATH
|
||||
LIBRTMP_PATH = ../../librtmp-2.4
|
||||
endif
|
||||
# Edit the path below to point to the base of your libidn package.
|
||||
ifndef LIBIDN_PATH
|
||||
LIBIDN_PATH = ../../libidn-1.32
|
||||
endif
|
||||
# Edit the path below to point to the base of your MS IDN package.
|
||||
# Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1
|
||||
# https://www.microsoft.com/en-us/download/details.aspx?id=734
|
||||
ifndef WINIDN_PATH
|
||||
WINIDN_PATH = ../../Microsoft IDN Mitigation APIs
|
||||
endif
|
||||
# Edit the path below to point to the base of your Novell LDAP NDK.
|
||||
ifndef LDAP_SDK
|
||||
LDAP_SDK = c:/novell/ndk/cldapsdk/win32
|
||||
endif
|
||||
# Edit the path below to point to the base of your nghttp2 package.
|
||||
ifndef NGHTTP2_PATH
|
||||
NGHTTP2_PATH = ../../nghttp2-1.0.0
|
||||
endif
|
||||
|
||||
PROOT = ..
|
||||
|
||||
# Edit the path below to point to the base of your c-ares package.
|
||||
ifndef LIBCARES_PATH
|
||||
LIBCARES_PATH = $(PROOT)/ares
|
||||
endif
|
||||
|
||||
CC = $(CROSSPREFIX)gcc
|
||||
CFLAGS = $(CURL_CFLAG_EXTRAS) -g -O2 -Wall
|
||||
CFLAGS += -fno-strict-aliasing
|
||||
# comment LDFLAGS below to keep debug info
|
||||
LDFLAGS = $(CURL_LDFLAG_EXTRAS) $(CURL_LDFLAG_EXTRAS_DLL) -s
|
||||
AR = $(CROSSPREFIX)ar
|
||||
RANLIB = $(CROSSPREFIX)ranlib
|
||||
RC = $(CROSSPREFIX)windres
|
||||
RCFLAGS = --include-dir=$(PROOT)/include -DDEBUGBUILD=0 -O COFF
|
||||
STRIP = $(CROSSPREFIX)strip -g
|
||||
|
||||
# Set environment var ARCH to your architecture to override autodetection.
|
||||
ifndef ARCH
|
||||
ifeq ($(findstring x86_64,$(shell $(CC) -dumpmachine)),x86_64)
|
||||
ARCH = w64
|
||||
else
|
||||
ARCH = w32
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),w64)
|
||||
CFLAGS += -m64 -D_AMD64_
|
||||
LDFLAGS += -m64
|
||||
RCFLAGS += -F pe-x86-64
|
||||
else
|
||||
CFLAGS += -m32
|
||||
LDFLAGS += -m32
|
||||
RCFLAGS += -F pe-i386
|
||||
endif
|
||||
|
||||
# Platform-dependent helper tool macros
|
||||
ifeq ($(findstring /sh,$(SHELL)),/sh)
|
||||
DEL = rm -f $1
|
||||
RMDIR = rm -fr $1
|
||||
MKDIR = mkdir -p $1
|
||||
COPY = -cp -afv $1 $2
|
||||
#COPYR = -cp -afr $1/* $2
|
||||
COPYR = -rsync -aC $1/* $2
|
||||
TOUCH = touch $1
|
||||
CAT = cat
|
||||
ECHONL = echo ""
|
||||
DL = '
|
||||
else
|
||||
ifeq "$(OS)" "Windows_NT"
|
||||
DEL = -del 2>NUL /q /f $(subst /,\,$1)
|
||||
RMDIR = -rd 2>NUL /q /s $(subst /,\,$1)
|
||||
else
|
||||
DEL = -del 2>NUL $(subst /,\,$1)
|
||||
RMDIR = -deltree 2>NUL /y $(subst /,\,$1)
|
||||
endif
|
||||
MKDIR = -md 2>NUL $(subst /,\,$1)
|
||||
COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2)
|
||||
COPYR = -xcopy 2>NUL /q /y /e $(subst /,\,$1) $(subst /,\,$2)
|
||||
TOUCH = copy 2>&1>NUL /b $(subst /,\,$1) +,,
|
||||
CAT = type
|
||||
ECHONL = $(ComSpec) /c echo.
|
||||
endif
|
||||
|
||||
########################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
ifeq ($(findstring -dyn,$(CFG)),-dyn)
|
||||
DYN = 1
|
||||
endif
|
||||
ifeq ($(findstring -ares,$(CFG)),-ares)
|
||||
ARES = 1
|
||||
endif
|
||||
ifeq ($(findstring -sync,$(CFG)),-sync)
|
||||
SYNC = 1
|
||||
endif
|
||||
ifeq ($(findstring -rtmp,$(CFG)),-rtmp)
|
||||
RTMP = 1
|
||||
SSL = 1
|
||||
ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -ssh2,$(CFG)),-ssh2)
|
||||
SSH2 = 1
|
||||
ifneq ($(findstring -winssl,$(CFG)),-winssl)
|
||||
SSL = 1
|
||||
endif
|
||||
ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -ssl,$(CFG)),-ssl)
|
||||
SSL = 1
|
||||
endif
|
||||
ifeq ($(findstring -srp,$(CFG)),-srp)
|
||||
SRP = 1
|
||||
endif
|
||||
ifeq ($(findstring -zlib,$(CFG)),-zlib)
|
||||
ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -idn,$(CFG)),-idn)
|
||||
IDN = 1
|
||||
endif
|
||||
ifeq ($(findstring -winidn,$(CFG)),-winidn)
|
||||
WINIDN = 1
|
||||
endif
|
||||
ifeq ($(findstring -sspi,$(CFG)),-sspi)
|
||||
SSPI = 1
|
||||
endif
|
||||
ifeq ($(findstring -ldaps,$(CFG)),-ldaps)
|
||||
LDAPS = 1
|
||||
endif
|
||||
ifeq ($(findstring -ipv6,$(CFG)),-ipv6)
|
||||
IPV6 = 1
|
||||
endif
|
||||
ifeq ($(findstring -winssl,$(CFG)),-winssl)
|
||||
WINSSL = 1
|
||||
SSPI = 1
|
||||
endif
|
||||
ifeq ($(findstring -nghttp2,$(CFG)),-nghttp2)
|
||||
NGHTTP2 = 1
|
||||
endif
|
||||
|
||||
INCLUDES = -I. -I../include
|
||||
CFLAGS += -DBUILDING_LIBCURL
|
||||
|
||||
ifdef SYNC
|
||||
CFLAGS += -DUSE_SYNC_DNS
|
||||
else
|
||||
ifdef ARES
|
||||
INCLUDES += -I"$(LIBCARES_PATH)"
|
||||
CFLAGS += -DUSE_ARES -DCARES_STATICLIB
|
||||
DLL_LIBS += -L"$(LIBCARES_PATH)" -lcares
|
||||
libcurl_dll_DEPENDENCIES = $(LIBCARES_PATH)/libcares.a
|
||||
endif
|
||||
endif
|
||||
ifdef RTMP
|
||||
INCLUDES += -I"$(LIBRTMP_PATH)"
|
||||
CFLAGS += -DUSE_LIBRTMP
|
||||
DLL_LIBS += -L"$(LIBRTMP_PATH)/librtmp" -lrtmp -lwinmm
|
||||
endif
|
||||
ifdef NGHTTP2
|
||||
INCLUDES += -I"$(NGHTTP2_PATH)/include"
|
||||
CFLAGS += -DUSE_NGHTTP2
|
||||
DLL_LIBS += -L"$(NGHTTP2_PATH)/lib" -lnghttp2
|
||||
endif
|
||||
ifdef SSH2
|
||||
INCLUDES += -I"$(LIBSSH2_PATH)/include" -I"$(LIBSSH2_PATH)/win32"
|
||||
CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H
|
||||
DLL_LIBS += -L"$(LIBSSH2_PATH)/win32" -lssh2
|
||||
ifdef WINSSL
|
||||
ifndef DYN
|
||||
DLL_LIBS += -lbcrypt -lcrypt32
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifdef SSL
|
||||
ifndef OPENSSL_INCLUDE
|
||||
ifeq "$(wildcard $(OPENSSL_PATH)/outinc)" "$(OPENSSL_PATH)/outinc"
|
||||
OPENSSL_INCLUDE = $(OPENSSL_PATH)/outinc
|
||||
endif
|
||||
ifeq "$(wildcard $(OPENSSL_PATH)/include)" "$(OPENSSL_PATH)/include"
|
||||
OPENSSL_INCLUDE = $(OPENSSL_PATH)/include
|
||||
endif
|
||||
endif
|
||||
ifneq "$(wildcard $(OPENSSL_INCLUDE)/openssl/opensslv.h)" "$(OPENSSL_INCLUDE)/openssl/opensslv.h"
|
||||
$(error Invalid path to OpenSSL package: $(OPENSSL_PATH))
|
||||
endif
|
||||
ifndef OPENSSL_LIBPATH
|
||||
ifeq "$(wildcard $(OPENSSL_PATH)/out)" "$(OPENSSL_PATH)/out"
|
||||
OPENSSL_LIBPATH = $(OPENSSL_PATH)/out
|
||||
OPENSSL_LIBS = -leay32 -lssl32
|
||||
endif
|
||||
ifeq "$(wildcard $(OPENSSL_PATH)/lib)" "$(OPENSSL_PATH)/lib"
|
||||
OPENSSL_LIBPATH = $(OPENSSL_PATH)/lib
|
||||
OPENSSL_LIBS = -lcrypto -lssl
|
||||
endif
|
||||
endif
|
||||
ifndef DYN
|
||||
OPENSSL_LIBS += -lgdi32 -lcrypt32
|
||||
endif
|
||||
INCLUDES += -I"$(OPENSSL_INCLUDE)"
|
||||
CFLAGS += -DUSE_OPENSSL -DHAVE_OPENSSL_ENGINE_H -DHAVE_OPENSSL_PKCS12_H \
|
||||
-DHAVE_ENGINE_LOAD_BUILTIN_ENGINES -DOPENSSL_NO_KRB5 \
|
||||
-DCURL_WANTS_CA_BUNDLE_ENV
|
||||
DLL_LIBS += -L"$(OPENSSL_LIBPATH)" $(OPENSSL_LIBS)
|
||||
ifdef SRP
|
||||
ifeq "$(wildcard $(OPENSSL_INCLUDE)/openssl/srp.h)" "$(OPENSSL_INCLUDE)/openssl/srp.h"
|
||||
CFLAGS += -DHAVE_OPENSSL_SRP -DUSE_TLS_SRP
|
||||
endif
|
||||
endif
|
||||
else
|
||||
ifdef WINSSL
|
||||
DLL_LIBS += -lcrypt32
|
||||
endif
|
||||
endif
|
||||
ifdef ZLIB
|
||||
INCLUDES += -I"$(ZLIB_PATH)"
|
||||
CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H
|
||||
DLL_LIBS += -L"$(ZLIB_PATH)" -lz
|
||||
endif
|
||||
ifdef IDN
|
||||
INCLUDES += -I"$(LIBIDN_PATH)/include"
|
||||
CFLAGS += -DUSE_LIBIDN
|
||||
DLL_LIBS += -L"$(LIBIDN_PATH)/lib" -lidn
|
||||
else
|
||||
ifdef WINIDN
|
||||
CFLAGS += -DUSE_WIN32_IDN
|
||||
CFLAGS += -DWANT_IDN_PROTOTYPES
|
||||
DLL_LIBS += -L"$(WINIDN_PATH)" -lnormaliz
|
||||
endif
|
||||
endif
|
||||
ifdef SSPI
|
||||
CFLAGS += -DUSE_WINDOWS_SSPI
|
||||
ifdef WINSSL
|
||||
CFLAGS += -DUSE_SCHANNEL
|
||||
endif
|
||||
endif
|
||||
ifdef SPNEGO
|
||||
CFLAGS += -DHAVE_SPNEGO
|
||||
endif
|
||||
ifdef IPV6
|
||||
CFLAGS += -DENABLE_IPV6 -D_WIN32_WINNT=0x0501
|
||||
endif
|
||||
ifdef LDAPS
|
||||
CFLAGS += -DHAVE_LDAP_SSL
|
||||
endif
|
||||
ifdef USE_LDAP_NOVELL
|
||||
INCLUDES += -I"$(LDAP_SDK)/inc"
|
||||
CFLAGS += -DCURL_HAS_NOVELL_LDAPSDK
|
||||
DLL_LIBS += -L"$(LDAP_SDK)/lib/mscvc" -lldapsdk -lldapssl -lldapx
|
||||
endif
|
||||
ifdef USE_LDAP_OPENLDAP
|
||||
INCLUDES += -I"$(LDAP_SDK)/include"
|
||||
CFLAGS += -DCURL_HAS_OPENLDAP_LDAPSDK
|
||||
DLL_LIBS += -L"$(LDAP_SDK)/lib" -lldap -llber
|
||||
endif
|
||||
ifndef USE_LDAP_NOVELL
|
||||
ifndef USE_LDAP_OPENLDAP
|
||||
DLL_LIBS += -lwldap32
|
||||
endif
|
||||
endif
|
||||
DLL_LIBS += -lws2_32
|
||||
|
||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||
include Makefile.inc
|
||||
|
||||
libcurl_dll_LIBRARY = libcurl.dll
|
||||
libcurl_dll_a_LIBRARY = libcurldll.a
|
||||
libcurl_a_LIBRARY = libcurl.a
|
||||
|
||||
libcurl_a_OBJECTS := $(patsubst %.c,%.o,$(strip $(CSOURCES)))
|
||||
libcurl_a_DEPENDENCIES := $(strip $(CSOURCES) $(HHEADERS))
|
||||
|
||||
RESOURCE = libcurl.res
|
||||
|
||||
|
||||
all: $(libcurl_a_LIBRARY) $(libcurl_dll_LIBRARY)
|
||||
|
||||
$(libcurl_a_LIBRARY): $(libcurl_a_OBJECTS) $(libcurl_a_DEPENDENCIES)
|
||||
@$(call DEL, $@)
|
||||
$(AR) cru $@ $(libcurl_a_OBJECTS)
|
||||
$(RANLIB) $@
|
||||
$(STRIP) $@
|
||||
|
||||
# remove the last line above to keep debug info
|
||||
|
||||
$(libcurl_dll_LIBRARY): $(libcurl_a_OBJECTS) $(RESOURCE) $(libcurl_dll_DEPENDENCIES)
|
||||
@$(call DEL, $@)
|
||||
$(CC) $(LDFLAGS) -shared -o $@ \
|
||||
-Wl,--output-def,$(@:.dll=.def),--out-implib,$(libcurl_dll_a_LIBRARY) \
|
||||
$(libcurl_a_OBJECTS) $(RESOURCE) $(DLL_LIBS)
|
||||
|
||||
%.o: %.c $(PROOT)/include/curl/curlbuild.h
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $< -o $@
|
||||
|
||||
%.res: %.rc
|
||||
$(RC) $(RCFLAGS) -i $< -o $@
|
||||
|
||||
clean:
|
||||
ifeq "$(wildcard $(PROOT)/include/curl/curlbuild.h.dist)" "$(PROOT)/include/curl/curlbuild.h.dist"
|
||||
@$(call DEL, $(PROOT)/include/curl/curlbuild.h)
|
||||
endif
|
||||
@$(call DEL, $(libcurl_a_OBJECTS) $(RESOURCE))
|
||||
|
||||
distclean vclean: clean
|
||||
@$(call DEL, $(libcurl_a_LIBRARY) $(libcurl_dll_LIBRARY) $(libcurl_dll_LIBRARY:.dll=.def) $(libcurl_dll_a_LIBRARY))
|
||||
|
||||
$(PROOT)/include/curl/curlbuild.h:
|
||||
@echo Creating $@
|
||||
@$(call COPY, $@.dist, $@)
|
||||
|
||||
$(LIBCARES_PATH)/libcares.a:
|
||||
$(MAKE) -C $(LIBCARES_PATH) -f Makefile.m32
|
||||
@@ -1,799 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 2004 - 2015, Guenter Knauf, <http://www.gknw.net/phpbb>.
|
||||
# Copyright (C) 2001 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
#################################################################
|
||||
#
|
||||
## Makefile for building libcurl.nlm (NetWare version - gnu make)
|
||||
##
|
||||
## Use: make -f Makefile.netware
|
||||
#
|
||||
#################################################################
|
||||
|
||||
# Edit the path below to point to the base of your Novell NDK.
|
||||
ifndef NDKBASE
|
||||
NDKBASE = c:/novell
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your Zlib sources.
|
||||
ifndef ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.8
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your OpenSSL package.
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-1.0.2a
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.5.0
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your axTLS package.
|
||||
ifndef AXTLS_PATH
|
||||
AXTLS_PATH = ../../axTLS-1.2.7
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your libidn package.
|
||||
ifndef LIBIDN_PATH
|
||||
LIBIDN_PATH = ../../libidn-1.18
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your librtmp package.
|
||||
ifndef LIBRTMP_PATH
|
||||
LIBRTMP_PATH = ../../librtmp-2.3
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your nghttp2 package.
|
||||
ifndef NGHTTP2_PATH
|
||||
NGHTTP2_PATH = ../../nghttp2-0.6.7
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your fbopenssl package.
|
||||
ifndef FBOPENSSL_PATH
|
||||
FBOPENSSL_PATH = ../../fbopenssl-0.4
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your c-ares package.
|
||||
ifndef LIBCARES_PATH
|
||||
LIBCARES_PATH = ../ares
|
||||
endif
|
||||
|
||||
ifndef INSTDIR
|
||||
INSTDIR = ..$(DS)curl-$(LIBCURL_VERSION_STR)-bin-nw
|
||||
endif
|
||||
|
||||
# Edit the vars below to change NLM target settings.
|
||||
TARGET = libcurl
|
||||
VERSION = $(LIBCURL_VERSION)
|
||||
COPYR = Copyright (C) $(LIBCURL_COPYRIGHT_STR)
|
||||
DESCR = curl libcurl $(LIBCURL_VERSION_STR) ($(LIBARCH)) - https://curl.haxx.se
|
||||
MTSAFE = YES
|
||||
STACK = 64000
|
||||
SCREEN = none
|
||||
EXPORTF = $(TARGET).imp
|
||||
EXPORTS = @$(EXPORTF)
|
||||
|
||||
# Uncomment the next line to enable linking with POSIX semantics.
|
||||
# POSIXFL = 1
|
||||
|
||||
# Edit the var below to point to your lib architecture.
|
||||
ifndef LIBARCH
|
||||
LIBARCH = LIBC
|
||||
endif
|
||||
|
||||
# must be equal to NDEBUG or DEBUG, CURLDEBUG
|
||||
ifndef DB
|
||||
DB = NDEBUG
|
||||
endif
|
||||
# Optimization: -O<n> or debugging: -g
|
||||
ifeq ($(DB),NDEBUG)
|
||||
OPT = -O2
|
||||
OBJDIR = release
|
||||
else
|
||||
OPT = -g
|
||||
OBJDIR = debug
|
||||
endif
|
||||
|
||||
# The following lines defines your compiler.
|
||||
ifdef CWFolder
|
||||
METROWERKS = $(CWFolder)
|
||||
endif
|
||||
ifdef METROWERKS
|
||||
# MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support
|
||||
MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support/Metrowerks Support
|
||||
CC = mwccnlm
|
||||
else
|
||||
CC = gcc
|
||||
endif
|
||||
PERL = perl
|
||||
# Here you can find a native Win32 binary of the original awk:
|
||||
# http://www.gknw.net/development/prgtools/awk-20100523.zip
|
||||
AWK = awk
|
||||
CP = cp -afv
|
||||
MKDIR = mkdir
|
||||
# RM = rm -f
|
||||
# If you want to mark the target as MTSAFE you will need a tool for
|
||||
# generating the xdc data for the linker; here's a minimal tool:
|
||||
# http://www.gknw.net/development/prgtools/mkxdc.zip
|
||||
MPKXDC = mkxdc
|
||||
|
||||
# LIBARCH_U = $(shell $(AWK) 'BEGIN {print toupper(ARGV[1])}' $(LIBARCH))
|
||||
LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH))
|
||||
|
||||
# Include the version info retrieved from curlver.h
|
||||
-include $(OBJDIR)/version.inc
|
||||
|
||||
# Global flags for all compilers
|
||||
CFLAGS += $(OPT) -D$(DB) -DNETWARE -DHAVE_CONFIG_H -nostdinc
|
||||
|
||||
ifeq ($(CC),mwccnlm)
|
||||
LD = mwldnlm
|
||||
LDFLAGS = -nostdlib $(PRELUDE) $(OBJL) -o $@ -commandfile
|
||||
AR = mwldnlm
|
||||
ARFLAGS = -nostdlib -type library -o
|
||||
LIBEXT = lib
|
||||
#RANLIB =
|
||||
CFLAGS += -msgstyle gcc -gccinc -inline off -opt nointrinsics -proc 586
|
||||
CFLAGS += -relax_pointers
|
||||
#CFLAGS += -w on
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
ifeq ($(POSIXFL),1)
|
||||
PRELUDE = $(NDK_LIBC)/imports/posixpre.o
|
||||
else
|
||||
PRELUDE = $(NDK_LIBC)/imports/libcpre.o
|
||||
endif
|
||||
CFLAGS += -align 4
|
||||
else
|
||||
# PRELUDE = $(NDK_CLIB)/imports/clibpre.o
|
||||
# to avoid the __init_* / __deinit_* whoes dont use prelude from NDK
|
||||
PRELUDE = "$(MWCW_PATH)/libraries/runtime/prelude.obj"
|
||||
# CFLAGS += -include "$(MWCW_PATH)/headers/nlm_clib_prefix.h"
|
||||
CFLAGS += -align 1
|
||||
endif
|
||||
else
|
||||
LD = nlmconv
|
||||
LDFLAGS = -T
|
||||
AR = ar
|
||||
ARFLAGS = -cq
|
||||
LIBEXT = a
|
||||
RANLIB = ranlib
|
||||
CFLAGS += -m32
|
||||
CFLAGS += -fno-builtin -fno-strict-aliasing
|
||||
ifeq ($(findstring gcc,$(CC)),gcc)
|
||||
CFLAGS += -fpcc-struct-return
|
||||
endif
|
||||
CFLAGS += -Wall # -pedantic
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
ifeq ($(POSIXFL),1)
|
||||
PRELUDE = $(NDK_LIBC)/imports/posixpre.gcc.o
|
||||
else
|
||||
PRELUDE = $(NDK_LIBC)/imports/libcpre.gcc.o
|
||||
endif
|
||||
else
|
||||
PRELUDE = $(NDK_CLIB)/imports/clibpre.gcc.o
|
||||
# to avoid the __init_* / __deinit_* whoes dont use prelude from NDK
|
||||
# http://www.gknw.net/development/mk_nlm/gcc_pre.zip
|
||||
# PRELUDE = $(NDK_ROOT)/pre/prelude.o
|
||||
CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h
|
||||
endif
|
||||
endif
|
||||
|
||||
NDK_ROOT = $(NDKBASE)/ndk
|
||||
ifndef NDK_CLIB
|
||||
NDK_CLIB = $(NDK_ROOT)/nwsdk
|
||||
endif
|
||||
ifndef NDK_LIBC
|
||||
NDK_LIBC = $(NDK_ROOT)/libc
|
||||
endif
|
||||
ifndef NDK_LDAP
|
||||
NDK_LDAP = $(NDK_ROOT)/cldapsdk/netware
|
||||
endif
|
||||
CURL_INC = ../include
|
||||
CURL_LIB = ../lib
|
||||
|
||||
INCLUDES = -I$(CURL_INC) -I$(CURL_LIB)
|
||||
|
||||
ifeq ($(findstring -static,$(CFG)),-static)
|
||||
LINK_STATIC = 1
|
||||
endif
|
||||
ifeq ($(findstring -ares,$(CFG)),-ares)
|
||||
WITH_ARES = 1
|
||||
endif
|
||||
ifeq ($(findstring -rtmp,$(CFG)),-rtmp)
|
||||
WITH_RTMP = 1
|
||||
WITH_SSL = 1
|
||||
WITH_ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -ssh2,$(CFG)),-ssh2)
|
||||
WITH_SSH2 = 1
|
||||
WITH_SSL = 1
|
||||
WITH_ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -axtls,$(CFG)),-axtls)
|
||||
WITH_AXTLS = 1
|
||||
WITH_SSL =
|
||||
else
|
||||
ifeq ($(findstring -ssl,$(CFG)),-ssl)
|
||||
WITH_SSL = 1
|
||||
ifeq ($(findstring -srp,$(CFG)),-srp)
|
||||
ifeq "$(wildcard $(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L)/openssl/srp.h)" "$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L)/openssl/srp.h"
|
||||
WITH_SRP = 1
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(findstring -zlib,$(CFG)),-zlib)
|
||||
WITH_ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -idn,$(CFG)),-idn)
|
||||
WITH_IDN = 1
|
||||
endif
|
||||
ifeq ($(findstring -nghttp2,$(CFG)),-nghttp2)
|
||||
WITH_NGHTTP2 = 1
|
||||
endif
|
||||
ifeq ($(findstring -ipv6,$(CFG)),-ipv6)
|
||||
ENABLE_IPV6 = 1
|
||||
endif
|
||||
|
||||
ifdef WITH_ARES
|
||||
INCLUDES += -I$(LIBCARES_PATH)
|
||||
LDLIBS += $(LIBCARES_PATH)/libcares.$(LIBEXT)
|
||||
endif
|
||||
ifdef WITH_SSH2
|
||||
INCLUDES += -I$(LIBSSH2_PATH)/include
|
||||
ifdef LINK_STATIC
|
||||
LDLIBS += $(LIBSSH2_PATH)/nw/libssh2.$(LIBEXT)
|
||||
else
|
||||
MODULES += libssh2.nlm
|
||||
IMPORTS += @$(LIBSSH2_PATH)/nw/libssh2.imp
|
||||
endif
|
||||
endif
|
||||
ifdef WITH_RTMP
|
||||
INCLUDES += -I$(LIBRTMP_PATH)
|
||||
LDLIBS += $(LIBRTMP_PATH)/librtmp/librtmp.$(LIBEXT)
|
||||
endif
|
||||
ifdef WITH_SSL
|
||||
INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L)
|
||||
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/ssl.$(LIBEXT)
|
||||
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT)
|
||||
IMPORTS += GetProcessSwitchCount RunningProcess
|
||||
INSTDEP += ca-bundle.crt
|
||||
else
|
||||
ifdef WITH_AXTLS
|
||||
INCLUDES += -I$(AXTLS_PATH)/inc
|
||||
ifdef LINK_STATIC
|
||||
LDLIBS += $(AXTLS_PATH)/lib/libaxtls.$(LIBEXT)
|
||||
else
|
||||
MODULES += libaxtls.nlm
|
||||
IMPORTS += $(AXTLS_PATH)/lib/libaxtls.imp
|
||||
endif
|
||||
INSTDEP += ca-bundle.crt
|
||||
endif
|
||||
endif
|
||||
ifdef WITH_ZLIB
|
||||
INCLUDES += -I$(ZLIB_PATH)
|
||||
ifdef LINK_STATIC
|
||||
LDLIBS += $(ZLIB_PATH)/nw/$(LIBARCH)/libz.$(LIBEXT)
|
||||
else
|
||||
MODULES += libz.nlm
|
||||
IMPORTS += @$(ZLIB_PATH)/nw/$(LIBARCH)/libz.imp
|
||||
endif
|
||||
endif
|
||||
ifdef WITH_IDN
|
||||
INCLUDES += -I$(LIBIDN_PATH)/include
|
||||
LDLIBS += $(LIBIDN_PATH)/lib/libidn.$(LIBEXT)
|
||||
endif
|
||||
ifdef WITH_NGHTTP2
|
||||
INCLUDES += -I$(NGHTTP2_PATH)/include
|
||||
LDLIBS += $(NGHTTP2_PATH)/lib/libnghttp2.$(LIBEXT)
|
||||
endif
|
||||
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
INCLUDES += -I$(NDK_LIBC)/include
|
||||
# INCLUDES += -I$(NDK_LIBC)/include/nks
|
||||
# INCLUDES += -I$(NDK_LIBC)/include/winsock
|
||||
CFLAGS += -D_POSIX_SOURCE
|
||||
else
|
||||
INCLUDES += -I$(NDK_CLIB)/include/nlm
|
||||
# INCLUDES += -I$(NDK_CLIB)/include/nlm/obsolete
|
||||
# INCLUDES += -I$(NDK_CLIB)/include
|
||||
endif
|
||||
ifndef DISABLE_LDAP
|
||||
INCLUDES += -I$(NDK_LDAP)/$(LIBARCH_L)/inc
|
||||
endif
|
||||
CFLAGS += $(INCLUDES)
|
||||
|
||||
ifeq ($(MTSAFE),YES)
|
||||
XDCOPT = -n
|
||||
endif
|
||||
ifeq ($(MTSAFE),NO)
|
||||
XDCOPT = -u
|
||||
endif
|
||||
ifdef XDCOPT
|
||||
XDCDATA = $(OBJDIR)/$(TARGET).xdc
|
||||
endif
|
||||
|
||||
ifeq ($(findstring /sh,$(SHELL)),/sh)
|
||||
DL = '
|
||||
DS = /
|
||||
PCT = %
|
||||
#-include $(NDKBASE)/nlmconv/ncpfs.inc
|
||||
else
|
||||
DS = \\
|
||||
PCT = %%
|
||||
endif
|
||||
|
||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||
include Makefile.inc
|
||||
|
||||
OBJS := $(patsubst %.c,$(OBJDIR)/%.o,$(strip $(notdir $(CSOURCES)))) $(OBJDIR)/nwos.o
|
||||
|
||||
OBJL = $(OBJS) $(OBJDIR)/nwlib.o $(LDLIBS)
|
||||
|
||||
vpath %.c . vauth vtls
|
||||
|
||||
all: lib nlm
|
||||
|
||||
nlm: prebuild $(TARGET).nlm
|
||||
|
||||
lib: prebuild $(TARGET).$(LIBEXT)
|
||||
|
||||
prebuild: $(OBJDIR) $(CURL_INC)/curl/curlbuild.h $(OBJDIR)/version.inc curl_config.h
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
# @echo Compiling $<
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(OBJDIR)/version.inc: $(CURL_INC)/curl/curlver.h $(OBJDIR)
|
||||
@echo Creating $@
|
||||
@$(AWK) -f ../packages/NetWare/get_ver.awk $< > $@
|
||||
|
||||
install: $(INSTDIR) all $(INSTDEP)
|
||||
@$(CP) $(TARGET).nlm $(INSTDIR)
|
||||
@$(CP) $(TARGET).$(LIBEXT) $(INSTDIR)
|
||||
@$(CP) ../CHANGES $(INSTDIR)
|
||||
@$(CP) ../COPYING $(INSTDIR)
|
||||
@$(CP) ../README $(INSTDIR)
|
||||
@$(CP) ../RELEASE-NOTES $(INSTDIR)
|
||||
ifdef WITH_SSL
|
||||
@-$(CP) ca-bundle.crt $(INSTDIR)/ca-bundle.crt
|
||||
endif
|
||||
|
||||
clean:
|
||||
-$(RM) curl_config.h
|
||||
-$(RM) -r $(OBJDIR)
|
||||
|
||||
distclean vclean: clean
|
||||
-$(RM) $(TARGET).$(LIBEXT) $(TARGET).nlm $(TARGET).imp
|
||||
-$(RM) certdata.txt ca-bundle.crt
|
||||
|
||||
$(OBJDIR) $(INSTDIR):
|
||||
@$(MKDIR) $@
|
||||
|
||||
$(TARGET).$(LIBEXT): $(OBJS)
|
||||
@echo Creating $@
|
||||
@-$(RM) $@
|
||||
@$(AR) $(ARFLAGS) $@ $^
|
||||
ifdef RANLIB
|
||||
@$(RANLIB) $@
|
||||
endif
|
||||
|
||||
$(TARGET).nlm: $(OBJDIR)/$(TARGET).def $(OBJL) $(EXPORTF) $(XDCDATA)
|
||||
@echo Linking $@
|
||||
@-$(RM) $@
|
||||
@$(LD) $(LDFLAGS) $<
|
||||
|
||||
$(OBJDIR)/%.xdc: Makefile.netware
|
||||
@echo Creating $@
|
||||
@$(MPKXDC) $(XDCOPT) $@
|
||||
|
||||
$(OBJDIR)/%.def: Makefile.netware
|
||||
@echo $(DL)# DEF file for linking with $(LD)$(DL) > $@
|
||||
@echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@
|
||||
@echo $(DL)# All your changes will be lost!!$(DL) >> $@
|
||||
@echo $(DL)#$(DL) >> $@
|
||||
@echo $(DL)copyright "$(COPYR)"$(DL) >> $@
|
||||
@echo $(DL)description "$(DESCR)"$(DL) >> $@
|
||||
@echo $(DL)version $(VERSION)$(DL) >> $@
|
||||
ifdef NLMTYPE
|
||||
@echo $(DL)type $(NLMTYPE)$(DL) >> $@
|
||||
endif
|
||||
ifdef STACK
|
||||
@echo $(DL)stack $(STACK)$(DL) >> $@
|
||||
endif
|
||||
ifdef SCREEN
|
||||
@echo $(DL)screenname "$(SCREEN)"$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)screenname "DEFAULT"$(DL) >> $@
|
||||
endif
|
||||
ifneq ($(DB),NDEBUG)
|
||||
@echo $(DL)debug$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)threadname "$(TARGET)"$(DL) >> $@
|
||||
ifdef XDCDATA
|
||||
@echo $(DL)xdcdata $(XDCDATA)$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)flag_on 64$(DL) >> $@
|
||||
ifeq ($(LIBARCH),CLIB)
|
||||
@echo $(DL)start _Prelude$(DL) >> $@
|
||||
@echo $(DL)exit _Stop$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_CLIB)/imports/clib.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_CLIB)/imports/threads.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_CLIB)/imports/nlmlib.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_CLIB)/imports/socklib.imp$(DL) >> $@
|
||||
@echo $(DL)module clib$(DL) >> $@
|
||||
ifndef DISABLE_LDAP
|
||||
@echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapsdk.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapssl.imp$(DL) >> $@
|
||||
# @echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapx.imp$(DL) >> $@
|
||||
@echo $(DL)module ldapsdk ldapssl$(DL) >> $@
|
||||
endif
|
||||
else
|
||||
ifeq ($(POSIXFL),1)
|
||||
@echo $(DL)flag_on 4194304$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)pseudopreemption$(DL) >> $@
|
||||
ifeq ($(findstring posixpre,$(PRELUDE)),posixpre)
|
||||
@echo $(DL)start POSIX_Start$(DL) >> $@
|
||||
@echo $(DL)exit POSIX_Stop$(DL) >> $@
|
||||
@echo $(DL)check POSIX_CheckUnload$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)start _LibCPrelude$(DL) >> $@
|
||||
@echo $(DL)exit _LibCPostlude$(DL) >> $@
|
||||
@echo $(DL)check _LibCCheckUnload$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)import @$(NDK_LIBC)/imports/libc.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_LIBC)/imports/netware.imp$(DL) >> $@
|
||||
@echo $(DL)module libc$(DL) >> $@
|
||||
ifndef DISABLE_LDAP
|
||||
@echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapsdk.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapssl.imp$(DL) >> $@
|
||||
# @echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapx.imp$(DL) >> $@
|
||||
@echo $(DL)module lldapsdk lldapssl$(DL) >> $@
|
||||
endif
|
||||
endif
|
||||
ifdef MODULES
|
||||
@echo $(DL)module $(MODULES)$(DL) >> $@
|
||||
endif
|
||||
ifdef EXPORTS
|
||||
@echo $(DL)export $(EXPORTS)$(DL) >> $@
|
||||
endif
|
||||
ifdef IMPORTS
|
||||
@echo $(DL)import $(IMPORTS)$(DL) >> $@
|
||||
endif
|
||||
ifeq ($(findstring nlmconv,$(LD)),nlmconv)
|
||||
@echo $(DL)input $(PRELUDE)$(DL) >> $@
|
||||
@echo $(DL)input $(OBJL)$(DL) >> $@
|
||||
#ifdef LDLIBS
|
||||
# @echo $(DL)input $(LDLIBS)$(DL) >> $@
|
||||
#endif
|
||||
@echo $(DL)output $(TARGET).nlm$(DL) >> $@
|
||||
endif
|
||||
|
||||
curl_config.h: Makefile.netware
|
||||
@echo Creating $@
|
||||
@echo $(DL)/* $@ for NetWare target.$(DL) > $@
|
||||
@echo $(DL)** Do not edit this file - it is created by make!$(DL) >> $@
|
||||
@echo $(DL)** All your changes will be lost!!$(DL) >> $@
|
||||
@echo $(DL)*/$(DL) >> $@
|
||||
@echo $(DL)#ifndef NETWARE$(DL) >> $@
|
||||
@echo $(DL)#error This $(notdir $@) is created for NetWare platform!$(DL) >> $@
|
||||
@echo $(DL)#endif$(DL) >> $@
|
||||
@echo $(DL)#define VERSION "$(LIBCURL_VERSION_STR)"$(DL) >> $@
|
||||
@echo $(DL)#define PACKAGE_BUGREPORT "a suitable curl mailing list => https://curl.haxx.se/mail/"$(DL) >> $@
|
||||
ifeq ($(LIBARCH),CLIB)
|
||||
@echo $(DL)#define OS "i586-pc-clib-NetWare"$(DL) >> $@
|
||||
@echo $(DL)#define NETDB_USE_INTERNET 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRICMP 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRNICMP 1$(DL) >> $@
|
||||
@echo $(DL)#define RECV_TYPE_ARG1 int$(DL) >> $@
|
||||
@echo $(DL)#define RECV_TYPE_ARG2 char *$(DL) >> $@
|
||||
@echo $(DL)#define RECV_TYPE_ARG3 int$(DL) >> $@
|
||||
@echo $(DL)#define RECV_TYPE_ARG4 int$(DL) >> $@
|
||||
@echo $(DL)#define RECV_TYPE_RETV int$(DL) >> $@
|
||||
@echo $(DL)#define RECVFROM_TYPE_ARG1 int$(DL) >> $@
|
||||
@echo $(DL)#define RECVFROM_TYPE_ARG2 char$(DL) >> $@
|
||||
@echo $(DL)#define RECVFROM_TYPE_ARG3 int$(DL) >> $@
|
||||
@echo $(DL)#define RECVFROM_TYPE_ARG4 int$(DL) >> $@
|
||||
@echo $(DL)#define RECVFROM_TYPE_ARG5 struct sockaddr$(DL) >> $@
|
||||
@echo $(DL)#define RECVFROM_TYPE_ARG6 int$(DL) >> $@
|
||||
@echo $(DL)#define RECVFROM_TYPE_RETV int$(DL) >> $@
|
||||
@echo $(DL)#define SEND_QUAL_ARG2$(DL) >> $@
|
||||
@echo $(DL)#define SEND_TYPE_ARG1 int$(DL) >> $@
|
||||
@echo $(DL)#define SEND_TYPE_ARG2 char *$(DL) >> $@
|
||||
@echo $(DL)#define SEND_TYPE_ARG3 int$(DL) >> $@
|
||||
@echo $(DL)#define SEND_TYPE_ARG4 int$(DL) >> $@
|
||||
@echo $(DL)#define SEND_TYPE_RETV int$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_SIZE_T 4$(DL) >> $@
|
||||
@echo $(DL)#define pressanykey PressAnyKeyToContinue$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)#define OS "i586-pc-libc-NetWare"$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_FTRUNCATE 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETTIMEOFDAY 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_INTTYPES_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LONGLONG 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STDINT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRCASECMP 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRLCAT 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRLCPY 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRTOLL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_PARAM_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_SELECT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_TERMIOS_H 1$(DL) >> $@
|
||||
@echo $(DL)#define RECV_TYPE_ARG1 int$(DL) >> $@
|
||||
@echo $(DL)#define RECV_TYPE_ARG2 void *$(DL) >> $@
|
||||
@echo $(DL)#define RECV_TYPE_ARG3 size_t$(DL) >> $@
|
||||
@echo $(DL)#define RECV_TYPE_ARG4 int$(DL) >> $@
|
||||
@echo $(DL)#define RECV_TYPE_RETV ssize_t$(DL) >> $@
|
||||
@echo $(DL)#define RECVFROM_TYPE_ARG1 int$(DL) >> $@
|
||||
@echo $(DL)#define RECVFROM_TYPE_ARG2 void$(DL) >> $@
|
||||
@echo $(DL)#define RECVFROM_TYPE_ARG3 size_t$(DL) >> $@
|
||||
@echo $(DL)#define RECVFROM_TYPE_ARG4 int$(DL) >> $@
|
||||
@echo $(DL)#define RECVFROM_TYPE_ARG5 struct sockaddr$(DL) >> $@
|
||||
@echo $(DL)#define RECVFROM_TYPE_ARG6 size_t$(DL) >> $@
|
||||
@echo $(DL)#define RECVFROM_TYPE_RETV ssize_t$(DL) >> $@
|
||||
@echo $(DL)#define RECVFROM_TYPE_ARG2_IS_VOID 1$(DL) >> $@
|
||||
@echo $(DL)#define SEND_QUAL_ARG2$(DL) >> $@
|
||||
@echo $(DL)#define SEND_TYPE_ARG1 int$(DL) >> $@
|
||||
@echo $(DL)#define SEND_TYPE_ARG2 void *$(DL) >> $@
|
||||
@echo $(DL)#define SEND_TYPE_ARG3 size_t$(DL) >> $@
|
||||
@echo $(DL)#define SEND_TYPE_ARG4 int$(DL) >> $@
|
||||
@echo $(DL)#define SEND_TYPE_RETV ssize_t$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_OFF_T 8$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_SIZE_T 8$(DL) >> $@
|
||||
@echo $(DL)#define _LARGEFILE 1$(DL) >> $@
|
||||
ifdef ENABLE_IPV6
|
||||
@echo $(DL)#define ENABLE_IPV6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_PF_INET6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_FREEADDRINFO 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETADDRINFO 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_SOCKADDR_IN6 1$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@
|
||||
endif
|
||||
endif
|
||||
@echo $(DL)#define USE_MANUAL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ARPA_INET_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ERRNO_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ERR_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_FCNTL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETHOSTBYADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETHOSTBYNAME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETPROTOBYNAME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GMTIME_R 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_INET_ADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_IOCTL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_IOCTL_FIONBIO 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIMITS_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LOCALE_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LOCALTIME_R 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_MALLOC_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_NETINET_IN_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_RECV 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_RECVFROM 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SELECT 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SEND 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SETJMP_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SETLOCALE 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SIGNAL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SIGNAL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SIG_ATOMIC_T 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SOCKET 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STDLIB_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRDUP 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRFTIME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRING_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRSTR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_TIMEVAL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_IOCTL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_STAT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_TIME_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_TIME_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_UNAME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_UNISTD_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_UTIME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_UTIME_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_WRITEV 1$(DL) >> $@
|
||||
@echo $(DL)#define RETSIGTYPE void$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_INT 4$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_SHORT 2$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@
|
||||
@echo $(DL)#define STDC_HEADERS 1$(DL) >> $@
|
||||
@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@
|
||||
ifdef DISABLE_LDAP
|
||||
@echo $(DL)#define CURL_DISABLE_LDAP 1$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)#define CURL_HAS_NOVELL_LDAPSDK 1$(DL) >> $@
|
||||
ifndef DISABLE_LDAPS
|
||||
@echo $(DL)#define HAVE_LDAP_SSL 1$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)#define HAVE_LDAP_SSL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LDAP_URL_PARSE 1$(DL) >> $@
|
||||
endif
|
||||
ifdef NW_WINSOCK
|
||||
@echo $(DL)#define HAVE_CLOSESOCKET 1$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)#define USE_BSD_SOCKETS 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_TYPES_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_SOCKET_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_SOCKIO_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_NETDB_H 1$(DL) >> $@
|
||||
endif
|
||||
ifdef WITH_ARES
|
||||
@echo $(DL)#define USE_ARES 1$(DL) >> $@
|
||||
endif
|
||||
ifdef WITH_ZLIB
|
||||
@echo $(DL)#define HAVE_ZLIB_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIBZ 1$(DL) >> $@
|
||||
endif
|
||||
ifdef WITH_SSL
|
||||
@echo $(DL)#define USE_SSLEAY 1$(DL) >> $@
|
||||
@echo $(DL)#define USE_OPENSSL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_X509_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_SSL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_RSA_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_PEM_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_ERR_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_CRYPTO_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_ENGINE_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIBSSL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIBCRYPTO 1$(DL) >> $@
|
||||
@echo $(DL)#define OPENSSL_NO_KRB5 1$(DL) >> $@
|
||||
ifdef WITH_SRP
|
||||
@echo $(DL)#define HAVE_SSLEAY_SRP 1$(DL) >> $@
|
||||
@echo $(DL)#define USE_TLS_SRP 1$(DL) >> $@
|
||||
endif
|
||||
ifdef WITH_SPNEGO
|
||||
@echo $(DL)#define HAVE_SPNEGO 1$(DL) >> $@
|
||||
endif
|
||||
else
|
||||
ifdef WITH_AXTLS
|
||||
@echo $(DL)#define USE_AXTLS 1$(DL) >> $@
|
||||
endif
|
||||
endif
|
||||
ifdef WITH_SSH2
|
||||
@echo $(DL)#define USE_LIBSSH2 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIBSSH2_H 1$(DL) >> $@
|
||||
endif
|
||||
ifdef WITH_IDN
|
||||
@echo $(DL)#define HAVE_LIBIDN 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_TLD_H 1$(DL) >> $@
|
||||
endif
|
||||
ifdef WITH_RTMP
|
||||
@echo $(DL)#define USE_LIBRTMP 1$(DL) >> $@
|
||||
endif
|
||||
ifdef WITH_NGHTTP2
|
||||
@echo $(DL)#define USE_NGHTTP2 1$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)#ifdef __GNUC__$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_VARIADIC_MACROS_GCC 1$(DL) >> $@
|
||||
@echo $(DL)#else$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_VARIADIC_MACROS_C99 1$(DL) >> $@
|
||||
@echo $(DL)#endif$(DL) >> $@
|
||||
ifdef CABUNDLE
|
||||
@echo $(DL)#define CURL_CA_BUNDLE "$(CABUNDLE)"$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")$(DL) >> $@
|
||||
endif
|
||||
|
||||
$(EXPORTF): $(CURL_INC)/curl/curl.h $(CURL_INC)/curl/easy.h $(CURL_INC)/curl/multi.h $(CURL_INC)/curl/mprintf.h
|
||||
@echo Creating $@
|
||||
@$(AWK) -f ../packages/NetWare/get_exp.awk $^ > $@
|
||||
|
||||
FORCE: ;
|
||||
|
||||
info: $(OBJDIR)/version.inc
|
||||
@echo Configured to build $(TARGET) with these options:
|
||||
@echo libarchitecture: $(LIBARCH)
|
||||
@echo curl version: $(LIBCURL_VERSION_STR)
|
||||
@echo compiler/linker: $(CC) / $(LD)
|
||||
ifdef CABUNDLE
|
||||
@echo ca-bundle path: $(CABUNDLE)
|
||||
endif
|
||||
ifdef WITH_SSL
|
||||
@echo SSL support: enabled (OpenSSL)
|
||||
else
|
||||
@echo SSL support: no
|
||||
endif
|
||||
ifdef WITH_SRP
|
||||
@echo SRP support: enabled
|
||||
else
|
||||
@echo SRP support: no
|
||||
endif
|
||||
ifdef WITH_SSH2
|
||||
@echo SSH2 support: enabled (libssh2)
|
||||
else
|
||||
@echo SSH2 support: no
|
||||
endif
|
||||
ifdef WITH_ZLIB
|
||||
@echo zlib support: enabled
|
||||
else
|
||||
@echo zlib support: no
|
||||
endif
|
||||
ifdef WITH_NGHTTP2
|
||||
@echo http2 support: enabled
|
||||
else
|
||||
@echo http2 support: no
|
||||
endif
|
||||
ifdef WITH_ARES
|
||||
@echo c-ares support: enabled
|
||||
else
|
||||
@echo c-ares support: no
|
||||
endif
|
||||
ifdef ENABLE_IPV6
|
||||
@echo IPv6 support: enabled
|
||||
else
|
||||
@echo IPv6 support: no
|
||||
endif
|
||||
|
||||
$(CURL_INC)/curl/curlbuild.h: Makefile.netware FORCE
|
||||
@echo Creating $@
|
||||
@echo $(DL)/* $@ intended for NetWare target.$(DL) > $@
|
||||
@echo $(DL)** Do not edit this file - it is created by make!$(DL) >> $@
|
||||
@echo $(DL)** All your changes will be lost!!$(DL) >> $@
|
||||
@echo $(DL)*/$(DL) >> $@
|
||||
@echo $(DL)#ifndef NETWARE$(DL) >> $@
|
||||
@echo $(DL)#error This $(notdir $@) is created for NetWare platform!$(DL) >> $@
|
||||
@echo $(DL)#endif$(DL) >> $@
|
||||
@echo $(DL)#ifndef __CURL_CURLBUILD_H$(DL) >> $@
|
||||
@echo $(DL)#define __CURL_CURLBUILD_H$(DL) >> $@
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
@echo $(DL)#define CURL_SIZEOF_LONG 4$(DL) >> $@
|
||||
@echo $(DL)#define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int$(DL) >> $@
|
||||
@echo $(DL)#define CURL_SIZEOF_CURL_SOCKLEN_T 4$(DL) >> $@
|
||||
@echo $(DL)#define CURL_TYPEOF_CURL_OFF_T long long$(DL) >> $@
|
||||
@echo $(DL)#define CURL_FORMAT_CURL_OFF_T "lld"$(DL) >> $@
|
||||
@echo $(DL)#define CURL_FORMAT_CURL_OFF_TU "llu"$(DL) >> $@
|
||||
@echo $(DL)#define CURL_FORMAT_OFF_T "$(PCT)lld"$(DL) >> $@
|
||||
@echo $(DL)#define CURL_SIZEOF_CURL_OFF_T 8$(DL) >> $@
|
||||
@echo $(DL)#define CURL_SUFFIX_CURL_OFF_T LL$(DL) >> $@
|
||||
@echo $(DL)#define CURL_SUFFIX_CURL_OFF_TU ULL$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)#define CURL_SIZEOF_LONG 4$(DL) >> $@
|
||||
@echo $(DL)#define CURL_TYPEOF_CURL_SOCKLEN_T int$(DL) >> $@
|
||||
@echo $(DL)#define CURL_SIZEOF_CURL_SOCKLEN_T 4$(DL) >> $@
|
||||
@echo $(DL)#define CURL_TYPEOF_CURL_OFF_T long$(DL) >> $@
|
||||
@echo $(DL)#define CURL_FORMAT_CURL_OFF_T "ld"$(DL) >> $@
|
||||
@echo $(DL)#define CURL_FORMAT_CURL_OFF_TU "lu"$(DL) >> $@
|
||||
@echo $(DL)#define CURL_FORMAT_OFF_T "$(PCT)ld"$(DL) >> $@
|
||||
@echo $(DL)#define CURL_SIZEOF_CURL_OFF_T 4$(DL) >> $@
|
||||
@echo $(DL)#define CURL_SUFFIX_CURL_OFF_T L$(DL) >> $@
|
||||
@echo $(DL)#define CURL_SUFFIX_CURL_OFF_TU UL$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;$(DL) >> $@
|
||||
@echo $(DL)typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;$(DL) >> $@
|
||||
@echo $(DL)#endif /* __CURL_CURLBUILD_H */$(DL) >> $@
|
||||
|
||||
$(LIBCARES_PATH)/libcares.$(LIBEXT):
|
||||
$(MAKE) -C $(LIBCARES_PATH) -f Makefile.netware lib
|
||||
|
||||
ca-bundle.crt: mk-ca-bundle.pl
|
||||
@echo Creating $@
|
||||
@-$(PERL) $< -b -n $@
|
||||
|
||||
@@ -1,691 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1999 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
# All files in the Makefile.vc* series are generated automatically from the
|
||||
# one made for MSVC version 6. Alas, if you want to do changes to any of the
|
||||
# files and send back to the project, edit the version six, make your diff and
|
||||
# mail curl-library.
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Makefile for building libcurl with MSVC10
|
||||
#
|
||||
# Usage: see usage message below
|
||||
# Should be invoked from \lib directory
|
||||
# Edit the paths and desired library name
|
||||
# SSL path is only required if you intend compiling
|
||||
# with SSL.
|
||||
#
|
||||
# This make file leaves the result either a .lib or .dll file
|
||||
# in the \lib directory. It should be called from the \lib
|
||||
# directory.
|
||||
#
|
||||
# An option would have been to allow the source directory to
|
||||
# be specified, but I saw no requirement.
|
||||
#
|
||||
# Another option would have been to leave the .lib and .dll
|
||||
# files in the "cfg" directory, but then the make file
|
||||
# in \src would need to be changed.
|
||||
#
|
||||
##############################################################
|
||||
|
||||
# ----------------------------------------------
|
||||
# Verify that current subdir is libcurl's 'lib'
|
||||
# ----------------------------------------------
|
||||
|
||||
!IF ! EXIST(.\curl_addrinfo.c)
|
||||
! MESSAGE Can not process this makefile from outside of libcurl's 'lib' subdirectory.
|
||||
! MESSAGE Change to libcurl's 'lib' subdirectory, and try again.
|
||||
! ERROR See previous message.
|
||||
!ENDIF
|
||||
|
||||
# ------------------------------------------------
|
||||
# Makefile.msvc.names provides libcurl file names
|
||||
# ------------------------------------------------
|
||||
|
||||
!INCLUDE ..\winbuild\Makefile.msvc.names
|
||||
|
||||
!IFNDEF OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-1.0.2a
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.5.0
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.8
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF MACHINE
|
||||
MACHINE = X86
|
||||
!ENDIF
|
||||
|
||||
# USE_WINDOWS_SSPI uses windows libraries to allow NTLM authentication
|
||||
# without an openssl installation and offers the ability to authenticate
|
||||
# using the "current logged in user". Since at least with MSVC10 the sspi.h
|
||||
# header is broken it is either required to install the Windows SDK,
|
||||
# or to fix sspi.h with adding this define at the beginning of sspi.h:
|
||||
# #define FreeCredentialHandle FreeCredentialsHandle
|
||||
#
|
||||
# If, for some reason the Windows SDK is installed but not installed
|
||||
# in the default location, you can specify WINDOWS_SDK_PATH.
|
||||
# It can be downloaded from:
|
||||
# https://msdn.microsoft.com/windows/bb980924.aspx
|
||||
|
||||
# WINDOWS_SSPI = 1
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
!IFNDEF WINDOWS_SDK_PATH
|
||||
WINDOWS_SDK_PATH = "$(PROGRAMFILES)\Microsoft SDK"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
#############################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
CCNODBG = cl.exe /O2 /DNDEBUG
|
||||
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /RTC1
|
||||
CFLAGSSSL = /DUSE_OPENSSL /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
CFLAGSWINSSL = /DUSE_SCHANNEL
|
||||
CFLAGSSSH2 = /DUSE_LIBSSH2 /DCURL_DISABLE_LDAP /DHAVE_LIBSSH2 /DHAVE_LIBSSH2_H /DLIBSSH2_WIN32 /DLIBSSH2_LIBRARY /I "$(LIBSSH2_PATH)/include"
|
||||
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
||||
CFLAGS = /I. /I../include /nologo /W3 /EHsc /DWIN32 /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
|
||||
CFLAGSLIB = /DCURL_STATICLIB
|
||||
LNKDLL = link.exe /DLL
|
||||
LNKLIB = link.exe /lib
|
||||
LFLAGS = /nologo /machine:$(MACHINE)
|
||||
SSLLIBS = libeay32.lib ssleay32.lib
|
||||
WINSSLLIBS = crypt32.lib
|
||||
ZLIBLIBSDLL = zdll.lib
|
||||
ZLIBLIBS = zlib.lib
|
||||
WINLIBS = ws2_32.lib wldap32.lib advapi32.lib
|
||||
CFLAGS = $(CFLAGS)
|
||||
|
||||
CFGSET = FALSE
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
CFLAGS = $(CFLAGS) /DUSE_WINDOWS_SSPI /I$(WINDOWS_SDK_PATH)\include
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IPV6
|
||||
CFLAGS = $(CFLAGS) /DUSE_IPV6
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IDN
|
||||
CFLAGS = $(CFLAGS) /DUSE_WIN32_IDN /DWANT_IDN_PROTOTYPES
|
||||
!ENDIF
|
||||
|
||||
##############################################################
|
||||
# Runtime library configuration
|
||||
|
||||
RTLIB = /MD
|
||||
RTLIBD = /MDd
|
||||
|
||||
!IF "$(RTLIBCFG)" == "static"
|
||||
RTLIB = /MT
|
||||
RTLIBD = /MTd
|
||||
!ENDIF
|
||||
|
||||
|
||||
######################
|
||||
# release
|
||||
|
||||
!IF "$(CFG)" == "release"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl
|
||||
|
||||
!IF "$(CFG)" == "release-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl
|
||||
|
||||
!IF "$(CFG)" == "release-winssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINSSLLIBS) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-winssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSZLIB) $(WINSSLLIBS) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug
|
||||
|
||||
!IF "$(CFG)" == "debug"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)\out32dll
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Usage
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE" && "$(CFG)" != ""
|
||||
!MESSAGE Usage: nmake /f makefile.vc10 CFG=<config> <target>
|
||||
!MESSAGE where <config> is one of:
|
||||
!MESSAGE release - release static library
|
||||
!MESSAGE release-ssl - release static library with ssl
|
||||
!MESSAGE release-zlib - release static library with zlib
|
||||
!MESSAGE release-ssl-zlib - release static library with ssl and zlib
|
||||
!MESSAGE release-ssl-ssh2-zlib - release static library with ssl, ssh2 and zlib
|
||||
!MESSAGE release-ssl-dll - release static library with dynamic ssl
|
||||
!MESSAGE release-zlib-dll - release static library with dynamic zlib
|
||||
!MESSAGE release-ssl-dll-zlib-dll - release static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE release-dll - release dynamic library
|
||||
!MESSAGE release-dll-ssl-dll - release dynamic library with dynamic ssl
|
||||
!MESSAGE release-dll-zlib-dll - release dynamic library with dynamic zlib
|
||||
!MESSAGE release-dll-ssl-dll-zlib-dll - release dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug - debug static library
|
||||
!MESSAGE debug-ssl - debug static library with ssl
|
||||
!MESSAGE debug-zlib - debug static library with zlib
|
||||
!MESSAGE debug-ssl-zlib - debug static library with ssl and zlib
|
||||
!MESSAGE debug-ssl-ssh2-zlib - debug static library with ssl, ssh2 and zlib
|
||||
!MESSAGE debug-ssl-dll - debug static library with dynamic ssl
|
||||
!MESSAGE debug-zlib-dll - debug static library with dynamic zlib
|
||||
!MESSAGE debug-ssl-dll-zlib-dll - debug static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug-dll - debug dynamic library
|
||||
!MESSAGE debug-dll-ssl-dll - debug dynamic library with dynamic ssl
|
||||
!MESSAGE debug-dll-zlib-dll - debug dynamic library with dynamic zlib1
|
||||
!MESSAGE debug-dll-ssl-dll-zlib-dll - debug dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE <target> can be left blank in which case all is assumed
|
||||
!ERROR please choose a valid configuration "$(CFG)"
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Only the clean target can be used if a config was not provided.
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE"
|
||||
clean:
|
||||
@-erase /s *.dll 2> NUL
|
||||
@-erase /s *.exp 2> NUL
|
||||
@-erase /s *.idb 2> NUL
|
||||
@-erase /s *.lib 2> NUL
|
||||
@-erase /s *.obj 2> NUL
|
||||
@-erase /s *.pch 2> NUL
|
||||
@-erase /s *.pdb 2> NUL
|
||||
@-erase /s *.res 2> NUL
|
||||
!ELSE
|
||||
# A config was provided, so the library can be built.
|
||||
#
|
||||
X_OBJS= \
|
||||
$(DIROBJ)\amigaos.obj \
|
||||
$(DIROBJ)\asyn-ares.obj \
|
||||
$(DIROBJ)\asyn-thread.obj \
|
||||
$(DIROBJ)\axtls.obj \
|
||||
$(DIROBJ)\base64.obj \
|
||||
$(DIROBJ)\conncache.obj \
|
||||
$(DIROBJ)\connect.obj \
|
||||
$(DIROBJ)\content_encoding.obj \
|
||||
$(DIROBJ)\cookie.obj \
|
||||
$(DIROBJ)\curl_addrinfo.obj \
|
||||
$(DIROBJ)\curl_des.obj \
|
||||
$(DIROBJ)\curl_endian.obj \
|
||||
$(DIROBJ)\curl_fnmatch.obj \
|
||||
$(DIROBJ)\curl_gethostname.obj \
|
||||
$(DIROBJ)\curl_gssapi.obj \
|
||||
$(DIROBJ)\curl_memrchr.obj \
|
||||
$(DIROBJ)\curl_multibyte.obj \
|
||||
$(DIROBJ)\curl_ntlm_core.obj \
|
||||
$(DIROBJ)\curl_ntlm_wb.obj \
|
||||
$(DIROBJ)\curl_rtmp.obj \
|
||||
$(DIROBJ)\curl_sasl.obj \
|
||||
$(DIROBJ)\curl_sspi.obj \
|
||||
$(DIROBJ)\curl_threads.obj \
|
||||
$(DIROBJ)\cyassl.obj \
|
||||
$(DIROBJ)\darwinssl.obj \
|
||||
$(DIROBJ)\dict.obj \
|
||||
$(DIROBJ)\dotdot.obj \
|
||||
$(DIROBJ)\easy.obj \
|
||||
$(DIROBJ)\escape.obj \
|
||||
$(DIROBJ)\file.obj \
|
||||
$(DIROBJ)\fileinfo.obj \
|
||||
$(DIROBJ)\formdata.obj \
|
||||
$(DIROBJ)\ftp.obj \
|
||||
$(DIROBJ)\ftplistparser.obj \
|
||||
$(DIROBJ)\getenv.obj \
|
||||
$(DIROBJ)\getinfo.obj \
|
||||
$(DIROBJ)\gopher.obj \
|
||||
$(DIROBJ)\gtls.obj \
|
||||
$(DIROBJ)\hash.obj \
|
||||
$(DIROBJ)\hmac.obj \
|
||||
$(DIROBJ)\hostasyn.obj \
|
||||
$(DIROBJ)\hostcheck.obj \
|
||||
$(DIROBJ)\hostip.obj \
|
||||
$(DIROBJ)\hostip4.obj \
|
||||
$(DIROBJ)\hostip6.obj \
|
||||
$(DIROBJ)\hostsyn.obj \
|
||||
$(DIROBJ)\http.obj \
|
||||
$(DIROBJ)\http_chunks.obj \
|
||||
$(DIROBJ)\http_digest.obj \
|
||||
$(DIROBJ)\http_negotiate.obj \
|
||||
$(DIROBJ)\http_ntlm.obj \
|
||||
$(DIROBJ)\http_proxy.obj \
|
||||
$(DIROBJ)\idn_win32.obj \
|
||||
$(DIROBJ)\if2ip.obj \
|
||||
$(DIROBJ)\imap.obj \
|
||||
$(DIROBJ)\inet_ntop.obj \
|
||||
$(DIROBJ)\inet_pton.obj \
|
||||
$(DIROBJ)\krb5.obj \
|
||||
$(DIROBJ)\ldap.obj \
|
||||
$(DIROBJ)\llist.obj \
|
||||
$(DIROBJ)\md4.obj \
|
||||
$(DIROBJ)\md5.obj \
|
||||
$(DIROBJ)\memdebug.obj \
|
||||
$(DIROBJ)\mprintf.obj \
|
||||
$(DIROBJ)\multi.obj \
|
||||
$(DIROBJ)\netrc.obj \
|
||||
$(DIROBJ)\non-ascii.obj \
|
||||
$(DIROBJ)\nonblock.obj \
|
||||
$(DIROBJ)\nss.obj \
|
||||
$(DIROBJ)\openldap.obj \
|
||||
$(DIROBJ)\parsedate.obj \
|
||||
$(DIROBJ)\pingpong.obj \
|
||||
$(DIROBJ)\pipeline.obj \
|
||||
$(DIROBJ)\polarssl.obj \
|
||||
$(DIROBJ)\polarssl_threadlock.obj \
|
||||
$(DIROBJ)\pop3.obj \
|
||||
$(DIROBJ)\progress.obj \
|
||||
$(DIROBJ)\strcase.obj \
|
||||
$(DIROBJ)\rand.obj \
|
||||
$(DIROBJ)\rtsp.obj \
|
||||
$(DIROBJ)\schannel.obj \
|
||||
$(DIROBJ)\security.obj \
|
||||
$(DIROBJ)\select.obj \
|
||||
$(DIROBJ)\sendf.obj \
|
||||
$(DIROBJ)\share.obj \
|
||||
$(DIROBJ)\slist.obj \
|
||||
$(DIROBJ)\smb.obj \
|
||||
$(DIROBJ)\smtp.obj \
|
||||
$(DIROBJ)\socks.obj \
|
||||
$(DIROBJ)\socks_gssapi.obj \
|
||||
$(DIROBJ)\socks_sspi.obj \
|
||||
$(DIROBJ)\speedcheck.obj \
|
||||
$(DIROBJ)\splay.obj \
|
||||
$(DIROBJ)\ssh.obj \
|
||||
$(DIROBJ)\system_win32.obj \
|
||||
$(DIROBJ)\vauth.obj \
|
||||
$(DIROBJ)\cleartext.obj \
|
||||
$(DIROBJ)\cram.obj \
|
||||
$(DIROBJ)\digest.obj \
|
||||
$(DIROBJ)\digest_sspi.obj \
|
||||
$(DIROBJ)\krb5_gssapi.obj \
|
||||
$(DIROBJ)\krb5_sspi.obj \
|
||||
$(DIROBJ)\ntlm.obj \
|
||||
$(DIROBJ)\ntlm_sspi.obj \
|
||||
$(DIROBJ)\oauth2.obj \
|
||||
$(DIROBJ)\spnego_gssapi.obj \
|
||||
$(DIROBJ)\spnego_sspi.obj \
|
||||
$(DIROBJ)\vtls.obj \
|
||||
$(DIROBJ)\openssl.obj \
|
||||
$(DIROBJ)\strdup.obj \
|
||||
$(DIROBJ)\strerror.obj \
|
||||
$(DIROBJ)\strtok.obj \
|
||||
$(DIROBJ)\strtoofft.obj \
|
||||
$(DIROBJ)\telnet.obj \
|
||||
$(DIROBJ)\tftp.obj \
|
||||
$(DIROBJ)\timeval.obj \
|
||||
$(DIROBJ)\transfer.obj \
|
||||
$(DIROBJ)\url.obj \
|
||||
$(DIROBJ)\version.obj \
|
||||
$(DIROBJ)\warnless.obj \
|
||||
$(DIROBJ)\wildcard.obj \
|
||||
$(DIROBJ)\x509asn1.obj \
|
||||
$(RESOURCE)
|
||||
|
||||
all : $(TARGET)
|
||||
|
||||
$(TARGET): $(X_OBJS)
|
||||
$(LNK) $(LFLAGS) $(X_OBJS)
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\*.exp . /y
|
||||
-xcopy $(DIROBJ)\*.pdb . /y
|
||||
|
||||
$(X_OBJS): $(DIROBJ)
|
||||
|
||||
$(DIROBJ):
|
||||
@if not exist "$(DIROBJ)" mkdir $(DIROBJ)
|
||||
|
||||
.SUFFIXES: .c .obj .res
|
||||
|
||||
{.\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vauth\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vtls\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
debug-dll\libcurl.res \
|
||||
debug-dll-ssl-dll\libcurl.res \
|
||||
debug-dll-zlib-dll\libcurl.res \
|
||||
debug-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=1 /Fo $@ libcurl.rc
|
||||
|
||||
release-dll\libcurl.res \
|
||||
release-dll-ssl-dll\libcurl.res \
|
||||
release-dll-zlib-dll\libcurl.res \
|
||||
release-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=0 /Fo $@ libcurl.rc
|
||||
!ENDIF # End of case where a config was provided.
|
||||
@@ -1,691 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1999 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
# All files in the Makefile.vc* series are generated automatically from the
|
||||
# one made for MSVC version 6. Alas, if you want to do changes to any of the
|
||||
# files and send back to the project, edit the version six, make your diff and
|
||||
# mail curl-library.
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Makefile for building libcurl with MSVC11
|
||||
#
|
||||
# Usage: see usage message below
|
||||
# Should be invoked from \lib directory
|
||||
# Edit the paths and desired library name
|
||||
# SSL path is only required if you intend compiling
|
||||
# with SSL.
|
||||
#
|
||||
# This make file leaves the result either a .lib or .dll file
|
||||
# in the \lib directory. It should be called from the \lib
|
||||
# directory.
|
||||
#
|
||||
# An option would have been to allow the source directory to
|
||||
# be specified, but I saw no requirement.
|
||||
#
|
||||
# Another option would have been to leave the .lib and .dll
|
||||
# files in the "cfg" directory, but then the make file
|
||||
# in \src would need to be changed.
|
||||
#
|
||||
##############################################################
|
||||
|
||||
# ----------------------------------------------
|
||||
# Verify that current subdir is libcurl's 'lib'
|
||||
# ----------------------------------------------
|
||||
|
||||
!IF ! EXIST(.\curl_addrinfo.c)
|
||||
! MESSAGE Can not process this makefile from outside of libcurl's 'lib' subdirectory.
|
||||
! MESSAGE Change to libcurl's 'lib' subdirectory, and try again.
|
||||
! ERROR See previous message.
|
||||
!ENDIF
|
||||
|
||||
# ------------------------------------------------
|
||||
# Makefile.msvc.names provides libcurl file names
|
||||
# ------------------------------------------------
|
||||
|
||||
!INCLUDE ..\winbuild\Makefile.msvc.names
|
||||
|
||||
!IFNDEF OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-1.0.2a
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.5.0
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.8
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF MACHINE
|
||||
MACHINE = X86
|
||||
!ENDIF
|
||||
|
||||
# USE_WINDOWS_SSPI uses windows libraries to allow NTLM authentication
|
||||
# without an openssl installation and offers the ability to authenticate
|
||||
# using the "current logged in user". Since at least with MSVC11 the sspi.h
|
||||
# header is broken it is either required to install the Windows SDK,
|
||||
# or to fix sspi.h with adding this define at the beginning of sspi.h:
|
||||
# #define FreeCredentialHandle FreeCredentialsHandle
|
||||
#
|
||||
# If, for some reason the Windows SDK is installed but not installed
|
||||
# in the default location, you can specify WINDOWS_SDK_PATH.
|
||||
# It can be downloaded from:
|
||||
# https://msdn.microsoft.com/windows/bb980924.aspx
|
||||
|
||||
# WINDOWS_SSPI = 1
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
!IFNDEF WINDOWS_SDK_PATH
|
||||
WINDOWS_SDK_PATH = "$(PROGRAMFILES)\Microsoft SDK"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
#############################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
CCNODBG = cl.exe /O2 /DNDEBUG
|
||||
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /RTC1
|
||||
CFLAGSSSL = /DUSE_OPENSSL /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
CFLAGSWINSSL = /DUSE_SCHANNEL
|
||||
CFLAGSSSH2 = /DUSE_LIBSSH2 /DCURL_DISABLE_LDAP /DHAVE_LIBSSH2 /DHAVE_LIBSSH2_H /DLIBSSH2_WIN32 /DLIBSSH2_LIBRARY /I "$(LIBSSH2_PATH)/include"
|
||||
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
||||
CFLAGS = /I. /I../include /nologo /W3 /EHsc /DWIN32 /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
|
||||
CFLAGSLIB = /DCURL_STATICLIB
|
||||
LNKDLL = link.exe /DLL
|
||||
LNKLIB = link.exe /lib
|
||||
LFLAGS = /nologo /machine:$(MACHINE)
|
||||
SSLLIBS = libeay32.lib ssleay32.lib
|
||||
WINSSLLIBS = crypt32.lib
|
||||
ZLIBLIBSDLL = zdll.lib
|
||||
ZLIBLIBS = zlib.lib
|
||||
WINLIBS = ws2_32.lib wldap32.lib advapi32.lib
|
||||
CFLAGS = $(CFLAGS)
|
||||
|
||||
CFGSET = FALSE
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
CFLAGS = $(CFLAGS) /DUSE_WINDOWS_SSPI /I$(WINDOWS_SDK_PATH)\include
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IPV6
|
||||
CFLAGS = $(CFLAGS) /DUSE_IPV6
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IDN
|
||||
CFLAGS = $(CFLAGS) /DUSE_WIN32_IDN /DWANT_IDN_PROTOTYPES
|
||||
!ENDIF
|
||||
|
||||
##############################################################
|
||||
# Runtime library configuration
|
||||
|
||||
RTLIB = /MD
|
||||
RTLIBD = /MDd
|
||||
|
||||
!IF "$(RTLIBCFG)" == "static"
|
||||
RTLIB = /MT
|
||||
RTLIBD = /MTd
|
||||
!ENDIF
|
||||
|
||||
|
||||
######################
|
||||
# release
|
||||
|
||||
!IF "$(CFG)" == "release"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl
|
||||
|
||||
!IF "$(CFG)" == "release-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl
|
||||
|
||||
!IF "$(CFG)" == "release-winssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINSSLLIBS) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-winssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSZLIB) $(WINSSLLIBS) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug
|
||||
|
||||
!IF "$(CFG)" == "debug"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)\out32dll
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Usage
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE" && "$(CFG)" != ""
|
||||
!MESSAGE Usage: nmake /f makefile.vc11 CFG=<config> <target>
|
||||
!MESSAGE where <config> is one of:
|
||||
!MESSAGE release - release static library
|
||||
!MESSAGE release-ssl - release static library with ssl
|
||||
!MESSAGE release-zlib - release static library with zlib
|
||||
!MESSAGE release-ssl-zlib - release static library with ssl and zlib
|
||||
!MESSAGE release-ssl-ssh2-zlib - release static library with ssl, ssh2 and zlib
|
||||
!MESSAGE release-ssl-dll - release static library with dynamic ssl
|
||||
!MESSAGE release-zlib-dll - release static library with dynamic zlib
|
||||
!MESSAGE release-ssl-dll-zlib-dll - release static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE release-dll - release dynamic library
|
||||
!MESSAGE release-dll-ssl-dll - release dynamic library with dynamic ssl
|
||||
!MESSAGE release-dll-zlib-dll - release dynamic library with dynamic zlib
|
||||
!MESSAGE release-dll-ssl-dll-zlib-dll - release dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug - debug static library
|
||||
!MESSAGE debug-ssl - debug static library with ssl
|
||||
!MESSAGE debug-zlib - debug static library with zlib
|
||||
!MESSAGE debug-ssl-zlib - debug static library with ssl and zlib
|
||||
!MESSAGE debug-ssl-ssh2-zlib - debug static library with ssl, ssh2 and zlib
|
||||
!MESSAGE debug-ssl-dll - debug static library with dynamic ssl
|
||||
!MESSAGE debug-zlib-dll - debug static library with dynamic zlib
|
||||
!MESSAGE debug-ssl-dll-zlib-dll - debug static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug-dll - debug dynamic library
|
||||
!MESSAGE debug-dll-ssl-dll - debug dynamic library with dynamic ssl
|
||||
!MESSAGE debug-dll-zlib-dll - debug dynamic library with dynamic zlib1
|
||||
!MESSAGE debug-dll-ssl-dll-zlib-dll - debug dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE <target> can be left blank in which case all is assumed
|
||||
!ERROR please choose a valid configuration "$(CFG)"
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Only the clean target can be used if a config was not provided.
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE"
|
||||
clean:
|
||||
@-erase /s *.dll 2> NUL
|
||||
@-erase /s *.exp 2> NUL
|
||||
@-erase /s *.idb 2> NUL
|
||||
@-erase /s *.lib 2> NUL
|
||||
@-erase /s *.obj 2> NUL
|
||||
@-erase /s *.pch 2> NUL
|
||||
@-erase /s *.pdb 2> NUL
|
||||
@-erase /s *.res 2> NUL
|
||||
!ELSE
|
||||
# A config was provided, so the library can be built.
|
||||
#
|
||||
X_OBJS= \
|
||||
$(DIROBJ)\amigaos.obj \
|
||||
$(DIROBJ)\asyn-ares.obj \
|
||||
$(DIROBJ)\asyn-thread.obj \
|
||||
$(DIROBJ)\axtls.obj \
|
||||
$(DIROBJ)\base64.obj \
|
||||
$(DIROBJ)\conncache.obj \
|
||||
$(DIROBJ)\connect.obj \
|
||||
$(DIROBJ)\content_encoding.obj \
|
||||
$(DIROBJ)\cookie.obj \
|
||||
$(DIROBJ)\curl_addrinfo.obj \
|
||||
$(DIROBJ)\curl_des.obj \
|
||||
$(DIROBJ)\curl_endian.obj \
|
||||
$(DIROBJ)\curl_fnmatch.obj \
|
||||
$(DIROBJ)\curl_gethostname.obj \
|
||||
$(DIROBJ)\curl_gssapi.obj \
|
||||
$(DIROBJ)\curl_memrchr.obj \
|
||||
$(DIROBJ)\curl_multibyte.obj \
|
||||
$(DIROBJ)\curl_ntlm_core.obj \
|
||||
$(DIROBJ)\curl_ntlm_wb.obj \
|
||||
$(DIROBJ)\curl_rtmp.obj \
|
||||
$(DIROBJ)\curl_sasl.obj \
|
||||
$(DIROBJ)\curl_sspi.obj \
|
||||
$(DIROBJ)\curl_threads.obj \
|
||||
$(DIROBJ)\cyassl.obj \
|
||||
$(DIROBJ)\darwinssl.obj \
|
||||
$(DIROBJ)\dict.obj \
|
||||
$(DIROBJ)\dotdot.obj \
|
||||
$(DIROBJ)\easy.obj \
|
||||
$(DIROBJ)\escape.obj \
|
||||
$(DIROBJ)\file.obj \
|
||||
$(DIROBJ)\fileinfo.obj \
|
||||
$(DIROBJ)\formdata.obj \
|
||||
$(DIROBJ)\ftp.obj \
|
||||
$(DIROBJ)\ftplistparser.obj \
|
||||
$(DIROBJ)\getenv.obj \
|
||||
$(DIROBJ)\getinfo.obj \
|
||||
$(DIROBJ)\gopher.obj \
|
||||
$(DIROBJ)\gtls.obj \
|
||||
$(DIROBJ)\hash.obj \
|
||||
$(DIROBJ)\hmac.obj \
|
||||
$(DIROBJ)\hostasyn.obj \
|
||||
$(DIROBJ)\hostcheck.obj \
|
||||
$(DIROBJ)\hostip.obj \
|
||||
$(DIROBJ)\hostip4.obj \
|
||||
$(DIROBJ)\hostip6.obj \
|
||||
$(DIROBJ)\hostsyn.obj \
|
||||
$(DIROBJ)\http.obj \
|
||||
$(DIROBJ)\http_chunks.obj \
|
||||
$(DIROBJ)\http_digest.obj \
|
||||
$(DIROBJ)\http_negotiate.obj \
|
||||
$(DIROBJ)\http_ntlm.obj \
|
||||
$(DIROBJ)\http_proxy.obj \
|
||||
$(DIROBJ)\idn_win32.obj \
|
||||
$(DIROBJ)\if2ip.obj \
|
||||
$(DIROBJ)\imap.obj \
|
||||
$(DIROBJ)\inet_ntop.obj \
|
||||
$(DIROBJ)\inet_pton.obj \
|
||||
$(DIROBJ)\krb5.obj \
|
||||
$(DIROBJ)\ldap.obj \
|
||||
$(DIROBJ)\llist.obj \
|
||||
$(DIROBJ)\md4.obj \
|
||||
$(DIROBJ)\md5.obj \
|
||||
$(DIROBJ)\memdebug.obj \
|
||||
$(DIROBJ)\mprintf.obj \
|
||||
$(DIROBJ)\multi.obj \
|
||||
$(DIROBJ)\netrc.obj \
|
||||
$(DIROBJ)\non-ascii.obj \
|
||||
$(DIROBJ)\nonblock.obj \
|
||||
$(DIROBJ)\nss.obj \
|
||||
$(DIROBJ)\openldap.obj \
|
||||
$(DIROBJ)\parsedate.obj \
|
||||
$(DIROBJ)\pingpong.obj \
|
||||
$(DIROBJ)\pipeline.obj \
|
||||
$(DIROBJ)\polarssl.obj \
|
||||
$(DIROBJ)\polarssl_threadlock.obj \
|
||||
$(DIROBJ)\pop3.obj \
|
||||
$(DIROBJ)\progress.obj \
|
||||
$(DIROBJ)\strcase.obj \
|
||||
$(DIROBJ)\rand.obj \
|
||||
$(DIROBJ)\rtsp.obj \
|
||||
$(DIROBJ)\schannel.obj \
|
||||
$(DIROBJ)\security.obj \
|
||||
$(DIROBJ)\select.obj \
|
||||
$(DIROBJ)\sendf.obj \
|
||||
$(DIROBJ)\share.obj \
|
||||
$(DIROBJ)\slist.obj \
|
||||
$(DIROBJ)\smb.obj \
|
||||
$(DIROBJ)\smtp.obj \
|
||||
$(DIROBJ)\socks.obj \
|
||||
$(DIROBJ)\socks_gssapi.obj \
|
||||
$(DIROBJ)\socks_sspi.obj \
|
||||
$(DIROBJ)\speedcheck.obj \
|
||||
$(DIROBJ)\splay.obj \
|
||||
$(DIROBJ)\ssh.obj \
|
||||
$(DIROBJ)\system_win32.obj \
|
||||
$(DIROBJ)\vauth.obj \
|
||||
$(DIROBJ)\cleartext.obj \
|
||||
$(DIROBJ)\cram.obj \
|
||||
$(DIROBJ)\digest.obj \
|
||||
$(DIROBJ)\digest_sspi.obj \
|
||||
$(DIROBJ)\krb5_gssapi.obj \
|
||||
$(DIROBJ)\krb5_sspi.obj \
|
||||
$(DIROBJ)\ntlm.obj \
|
||||
$(DIROBJ)\ntlm_sspi.obj \
|
||||
$(DIROBJ)\oauth2.obj \
|
||||
$(DIROBJ)\spnego_gssapi.obj \
|
||||
$(DIROBJ)\spnego_sspi.obj \
|
||||
$(DIROBJ)\vtls.obj \
|
||||
$(DIROBJ)\openssl.obj \
|
||||
$(DIROBJ)\strdup.obj \
|
||||
$(DIROBJ)\strerror.obj \
|
||||
$(DIROBJ)\strtok.obj \
|
||||
$(DIROBJ)\strtoofft.obj \
|
||||
$(DIROBJ)\telnet.obj \
|
||||
$(DIROBJ)\tftp.obj \
|
||||
$(DIROBJ)\timeval.obj \
|
||||
$(DIROBJ)\transfer.obj \
|
||||
$(DIROBJ)\url.obj \
|
||||
$(DIROBJ)\version.obj \
|
||||
$(DIROBJ)\warnless.obj \
|
||||
$(DIROBJ)\wildcard.obj \
|
||||
$(DIROBJ)\x509asn1.obj \
|
||||
$(RESOURCE)
|
||||
|
||||
all : $(TARGET)
|
||||
|
||||
$(TARGET): $(X_OBJS)
|
||||
$(LNK) $(LFLAGS) $(X_OBJS)
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\*.exp . /y
|
||||
-xcopy $(DIROBJ)\*.pdb . /y
|
||||
|
||||
$(X_OBJS): $(DIROBJ)
|
||||
|
||||
$(DIROBJ):
|
||||
@if not exist "$(DIROBJ)" mkdir $(DIROBJ)
|
||||
|
||||
.SUFFIXES: .c .obj .res
|
||||
|
||||
{.\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vauth\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vtls\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
debug-dll\libcurl.res \
|
||||
debug-dll-ssl-dll\libcurl.res \
|
||||
debug-dll-zlib-dll\libcurl.res \
|
||||
debug-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=1 /Fo $@ libcurl.rc
|
||||
|
||||
release-dll\libcurl.res \
|
||||
release-dll-ssl-dll\libcurl.res \
|
||||
release-dll-zlib-dll\libcurl.res \
|
||||
release-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=0 /Fo $@ libcurl.rc
|
||||
!ENDIF # End of case where a config was provided.
|
||||
@@ -1,691 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1999 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
# All files in the Makefile.vc* series are generated automatically from the
|
||||
# one made for MSVC version 6. Alas, if you want to do changes to any of the
|
||||
# files and send back to the project, edit the version six, make your diff and
|
||||
# mail curl-library.
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Makefile for building libcurl with MSVC12
|
||||
#
|
||||
# Usage: see usage message below
|
||||
# Should be invoked from \lib directory
|
||||
# Edit the paths and desired library name
|
||||
# SSL path is only required if you intend compiling
|
||||
# with SSL.
|
||||
#
|
||||
# This make file leaves the result either a .lib or .dll file
|
||||
# in the \lib directory. It should be called from the \lib
|
||||
# directory.
|
||||
#
|
||||
# An option would have been to allow the source directory to
|
||||
# be specified, but I saw no requirement.
|
||||
#
|
||||
# Another option would have been to leave the .lib and .dll
|
||||
# files in the "cfg" directory, but then the make file
|
||||
# in \src would need to be changed.
|
||||
#
|
||||
##############################################################
|
||||
|
||||
# ----------------------------------------------
|
||||
# Verify that current subdir is libcurl's 'lib'
|
||||
# ----------------------------------------------
|
||||
|
||||
!IF ! EXIST(.\curl_addrinfo.c)
|
||||
! MESSAGE Can not process this makefile from outside of libcurl's 'lib' subdirectory.
|
||||
! MESSAGE Change to libcurl's 'lib' subdirectory, and try again.
|
||||
! ERROR See previous message.
|
||||
!ENDIF
|
||||
|
||||
# ------------------------------------------------
|
||||
# Makefile.msvc.names provides libcurl file names
|
||||
# ------------------------------------------------
|
||||
|
||||
!INCLUDE ..\winbuild\Makefile.msvc.names
|
||||
|
||||
!IFNDEF OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-1.0.2a
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.5.0
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.8
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF MACHINE
|
||||
MACHINE = X86
|
||||
!ENDIF
|
||||
|
||||
# USE_WINDOWS_SSPI uses windows libraries to allow NTLM authentication
|
||||
# without an openssl installation and offers the ability to authenticate
|
||||
# using the "current logged in user". Since at least with MSVC12 the sspi.h
|
||||
# header is broken it is either required to install the Windows SDK,
|
||||
# or to fix sspi.h with adding this define at the beginning of sspi.h:
|
||||
# #define FreeCredentialHandle FreeCredentialsHandle
|
||||
#
|
||||
# If, for some reason the Windows SDK is installed but not installed
|
||||
# in the default location, you can specify WINDOWS_SDK_PATH.
|
||||
# It can be downloaded from:
|
||||
# https://msdn.microsoft.com/windows/bb980924.aspx
|
||||
|
||||
# WINDOWS_SSPI = 1
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
!IFNDEF WINDOWS_SDK_PATH
|
||||
WINDOWS_SDK_PATH = "$(PROGRAMFILES)\Microsoft SDK"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
#############################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
CCNODBG = cl.exe /O2 /DNDEBUG
|
||||
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /RTC1
|
||||
CFLAGSSSL = /DUSE_OPENSSL /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
CFLAGSWINSSL = /DUSE_SCHANNEL
|
||||
CFLAGSSSH2 = /DUSE_LIBSSH2 /DCURL_DISABLE_LDAP /DHAVE_LIBSSH2 /DHAVE_LIBSSH2_H /DLIBSSH2_WIN32 /DLIBSSH2_LIBRARY /I "$(LIBSSH2_PATH)/include"
|
||||
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
||||
CFLAGS = /I. /I../include /nologo /W3 /EHsc /DWIN32 /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
|
||||
CFLAGSLIB = /DCURL_STATICLIB
|
||||
LNKDLL = link.exe /DLL
|
||||
LNKLIB = link.exe /lib
|
||||
LFLAGS = /nologo /machine:$(MACHINE)
|
||||
SSLLIBS = libeay32.lib ssleay32.lib
|
||||
WINSSLLIBS = crypt32.lib
|
||||
ZLIBLIBSDLL = zdll.lib
|
||||
ZLIBLIBS = zlib.lib
|
||||
WINLIBS = ws2_32.lib wldap32.lib advapi32.lib
|
||||
CFLAGS = $(CFLAGS)
|
||||
|
||||
CFGSET = FALSE
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
CFLAGS = $(CFLAGS) /DUSE_WINDOWS_SSPI /I$(WINDOWS_SDK_PATH)\include
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IPV6
|
||||
CFLAGS = $(CFLAGS) /DUSE_IPV6
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IDN
|
||||
CFLAGS = $(CFLAGS) /DUSE_WIN32_IDN /DWANT_IDN_PROTOTYPES
|
||||
!ENDIF
|
||||
|
||||
##############################################################
|
||||
# Runtime library configuration
|
||||
|
||||
RTLIB = /MD
|
||||
RTLIBD = /MDd
|
||||
|
||||
!IF "$(RTLIBCFG)" == "static"
|
||||
RTLIB = /MT
|
||||
RTLIBD = /MTd
|
||||
!ENDIF
|
||||
|
||||
|
||||
######################
|
||||
# release
|
||||
|
||||
!IF "$(CFG)" == "release"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl
|
||||
|
||||
!IF "$(CFG)" == "release-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl
|
||||
|
||||
!IF "$(CFG)" == "release-winssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINSSLLIBS) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-winssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSZLIB) $(WINSSLLIBS) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug
|
||||
|
||||
!IF "$(CFG)" == "debug"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)\out32dll
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Usage
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE" && "$(CFG)" != ""
|
||||
!MESSAGE Usage: nmake /f makefile.vc12 CFG=<config> <target>
|
||||
!MESSAGE where <config> is one of:
|
||||
!MESSAGE release - release static library
|
||||
!MESSAGE release-ssl - release static library with ssl
|
||||
!MESSAGE release-zlib - release static library with zlib
|
||||
!MESSAGE release-ssl-zlib - release static library with ssl and zlib
|
||||
!MESSAGE release-ssl-ssh2-zlib - release static library with ssl, ssh2 and zlib
|
||||
!MESSAGE release-ssl-dll - release static library with dynamic ssl
|
||||
!MESSAGE release-zlib-dll - release static library with dynamic zlib
|
||||
!MESSAGE release-ssl-dll-zlib-dll - release static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE release-dll - release dynamic library
|
||||
!MESSAGE release-dll-ssl-dll - release dynamic library with dynamic ssl
|
||||
!MESSAGE release-dll-zlib-dll - release dynamic library with dynamic zlib
|
||||
!MESSAGE release-dll-ssl-dll-zlib-dll - release dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug - debug static library
|
||||
!MESSAGE debug-ssl - debug static library with ssl
|
||||
!MESSAGE debug-zlib - debug static library with zlib
|
||||
!MESSAGE debug-ssl-zlib - debug static library with ssl and zlib
|
||||
!MESSAGE debug-ssl-ssh2-zlib - debug static library with ssl, ssh2 and zlib
|
||||
!MESSAGE debug-ssl-dll - debug static library with dynamic ssl
|
||||
!MESSAGE debug-zlib-dll - debug static library with dynamic zlib
|
||||
!MESSAGE debug-ssl-dll-zlib-dll - debug static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug-dll - debug dynamic library
|
||||
!MESSAGE debug-dll-ssl-dll - debug dynamic library with dynamic ssl
|
||||
!MESSAGE debug-dll-zlib-dll - debug dynamic library with dynamic zlib1
|
||||
!MESSAGE debug-dll-ssl-dll-zlib-dll - debug dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE <target> can be left blank in which case all is assumed
|
||||
!ERROR please choose a valid configuration "$(CFG)"
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Only the clean target can be used if a config was not provided.
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE"
|
||||
clean:
|
||||
@-erase /s *.dll 2> NUL
|
||||
@-erase /s *.exp 2> NUL
|
||||
@-erase /s *.idb 2> NUL
|
||||
@-erase /s *.lib 2> NUL
|
||||
@-erase /s *.obj 2> NUL
|
||||
@-erase /s *.pch 2> NUL
|
||||
@-erase /s *.pdb 2> NUL
|
||||
@-erase /s *.res 2> NUL
|
||||
!ELSE
|
||||
# A config was provided, so the library can be built.
|
||||
#
|
||||
X_OBJS= \
|
||||
$(DIROBJ)\amigaos.obj \
|
||||
$(DIROBJ)\asyn-ares.obj \
|
||||
$(DIROBJ)\asyn-thread.obj \
|
||||
$(DIROBJ)\axtls.obj \
|
||||
$(DIROBJ)\base64.obj \
|
||||
$(DIROBJ)\conncache.obj \
|
||||
$(DIROBJ)\connect.obj \
|
||||
$(DIROBJ)\content_encoding.obj \
|
||||
$(DIROBJ)\cookie.obj \
|
||||
$(DIROBJ)\curl_addrinfo.obj \
|
||||
$(DIROBJ)\curl_des.obj \
|
||||
$(DIROBJ)\curl_endian.obj \
|
||||
$(DIROBJ)\curl_fnmatch.obj \
|
||||
$(DIROBJ)\curl_gethostname.obj \
|
||||
$(DIROBJ)\curl_gssapi.obj \
|
||||
$(DIROBJ)\curl_memrchr.obj \
|
||||
$(DIROBJ)\curl_multibyte.obj \
|
||||
$(DIROBJ)\curl_ntlm_core.obj \
|
||||
$(DIROBJ)\curl_ntlm_wb.obj \
|
||||
$(DIROBJ)\curl_rtmp.obj \
|
||||
$(DIROBJ)\curl_sasl.obj \
|
||||
$(DIROBJ)\curl_sspi.obj \
|
||||
$(DIROBJ)\curl_threads.obj \
|
||||
$(DIROBJ)\cyassl.obj \
|
||||
$(DIROBJ)\darwinssl.obj \
|
||||
$(DIROBJ)\dict.obj \
|
||||
$(DIROBJ)\dotdot.obj \
|
||||
$(DIROBJ)\easy.obj \
|
||||
$(DIROBJ)\escape.obj \
|
||||
$(DIROBJ)\file.obj \
|
||||
$(DIROBJ)\fileinfo.obj \
|
||||
$(DIROBJ)\formdata.obj \
|
||||
$(DIROBJ)\ftp.obj \
|
||||
$(DIROBJ)\ftplistparser.obj \
|
||||
$(DIROBJ)\getenv.obj \
|
||||
$(DIROBJ)\getinfo.obj \
|
||||
$(DIROBJ)\gopher.obj \
|
||||
$(DIROBJ)\gtls.obj \
|
||||
$(DIROBJ)\hash.obj \
|
||||
$(DIROBJ)\hmac.obj \
|
||||
$(DIROBJ)\hostasyn.obj \
|
||||
$(DIROBJ)\hostcheck.obj \
|
||||
$(DIROBJ)\hostip.obj \
|
||||
$(DIROBJ)\hostip4.obj \
|
||||
$(DIROBJ)\hostip6.obj \
|
||||
$(DIROBJ)\hostsyn.obj \
|
||||
$(DIROBJ)\http.obj \
|
||||
$(DIROBJ)\http_chunks.obj \
|
||||
$(DIROBJ)\http_digest.obj \
|
||||
$(DIROBJ)\http_negotiate.obj \
|
||||
$(DIROBJ)\http_ntlm.obj \
|
||||
$(DIROBJ)\http_proxy.obj \
|
||||
$(DIROBJ)\idn_win32.obj \
|
||||
$(DIROBJ)\if2ip.obj \
|
||||
$(DIROBJ)\imap.obj \
|
||||
$(DIROBJ)\inet_ntop.obj \
|
||||
$(DIROBJ)\inet_pton.obj \
|
||||
$(DIROBJ)\krb5.obj \
|
||||
$(DIROBJ)\ldap.obj \
|
||||
$(DIROBJ)\llist.obj \
|
||||
$(DIROBJ)\md4.obj \
|
||||
$(DIROBJ)\md5.obj \
|
||||
$(DIROBJ)\memdebug.obj \
|
||||
$(DIROBJ)\mprintf.obj \
|
||||
$(DIROBJ)\multi.obj \
|
||||
$(DIROBJ)\netrc.obj \
|
||||
$(DIROBJ)\non-ascii.obj \
|
||||
$(DIROBJ)\nonblock.obj \
|
||||
$(DIROBJ)\nss.obj \
|
||||
$(DIROBJ)\openldap.obj \
|
||||
$(DIROBJ)\parsedate.obj \
|
||||
$(DIROBJ)\pingpong.obj \
|
||||
$(DIROBJ)\pipeline.obj \
|
||||
$(DIROBJ)\polarssl.obj \
|
||||
$(DIROBJ)\polarssl_threadlock.obj \
|
||||
$(DIROBJ)\pop3.obj \
|
||||
$(DIROBJ)\progress.obj \
|
||||
$(DIROBJ)\strcase.obj \
|
||||
$(DIROBJ)\rand.obj \
|
||||
$(DIROBJ)\rtsp.obj \
|
||||
$(DIROBJ)\schannel.obj \
|
||||
$(DIROBJ)\security.obj \
|
||||
$(DIROBJ)\select.obj \
|
||||
$(DIROBJ)\sendf.obj \
|
||||
$(DIROBJ)\share.obj \
|
||||
$(DIROBJ)\slist.obj \
|
||||
$(DIROBJ)\smb.obj \
|
||||
$(DIROBJ)\smtp.obj \
|
||||
$(DIROBJ)\socks.obj \
|
||||
$(DIROBJ)\socks_gssapi.obj \
|
||||
$(DIROBJ)\socks_sspi.obj \
|
||||
$(DIROBJ)\speedcheck.obj \
|
||||
$(DIROBJ)\splay.obj \
|
||||
$(DIROBJ)\ssh.obj \
|
||||
$(DIROBJ)\system_win32.obj \
|
||||
$(DIROBJ)\vauth.obj \
|
||||
$(DIROBJ)\cleartext.obj \
|
||||
$(DIROBJ)\cram.obj \
|
||||
$(DIROBJ)\digest.obj \
|
||||
$(DIROBJ)\digest_sspi.obj \
|
||||
$(DIROBJ)\krb5_gssapi.obj \
|
||||
$(DIROBJ)\krb5_sspi.obj \
|
||||
$(DIROBJ)\ntlm.obj \
|
||||
$(DIROBJ)\ntlm_sspi.obj \
|
||||
$(DIROBJ)\oauth2.obj \
|
||||
$(DIROBJ)\spnego_gssapi.obj \
|
||||
$(DIROBJ)\spnego_sspi.obj \
|
||||
$(DIROBJ)\vtls.obj \
|
||||
$(DIROBJ)\openssl.obj \
|
||||
$(DIROBJ)\strdup.obj \
|
||||
$(DIROBJ)\strerror.obj \
|
||||
$(DIROBJ)\strtok.obj \
|
||||
$(DIROBJ)\strtoofft.obj \
|
||||
$(DIROBJ)\telnet.obj \
|
||||
$(DIROBJ)\tftp.obj \
|
||||
$(DIROBJ)\timeval.obj \
|
||||
$(DIROBJ)\transfer.obj \
|
||||
$(DIROBJ)\url.obj \
|
||||
$(DIROBJ)\version.obj \
|
||||
$(DIROBJ)\warnless.obj \
|
||||
$(DIROBJ)\wildcard.obj \
|
||||
$(DIROBJ)\x509asn1.obj \
|
||||
$(RESOURCE)
|
||||
|
||||
all : $(TARGET)
|
||||
|
||||
$(TARGET): $(X_OBJS)
|
||||
$(LNK) $(LFLAGS) $(X_OBJS)
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\*.exp . /y
|
||||
-xcopy $(DIROBJ)\*.pdb . /y
|
||||
|
||||
$(X_OBJS): $(DIROBJ)
|
||||
|
||||
$(DIROBJ):
|
||||
@if not exist "$(DIROBJ)" mkdir $(DIROBJ)
|
||||
|
||||
.SUFFIXES: .c .obj .res
|
||||
|
||||
{.\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vauth\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vtls\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
debug-dll\libcurl.res \
|
||||
debug-dll-ssl-dll\libcurl.res \
|
||||
debug-dll-zlib-dll\libcurl.res \
|
||||
debug-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=1 /Fo $@ libcurl.rc
|
||||
|
||||
release-dll\libcurl.res \
|
||||
release-dll-ssl-dll\libcurl.res \
|
||||
release-dll-zlib-dll\libcurl.res \
|
||||
release-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=0 /Fo $@ libcurl.rc
|
||||
!ENDIF # End of case where a config was provided.
|
||||
@@ -1,691 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1999 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
# All files in the Makefile.vc* series are generated automatically from the
|
||||
# one made for MSVC version 6. Alas, if you want to do changes to any of the
|
||||
# files and send back to the project, edit the version six, make your diff and
|
||||
# mail curl-library.
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Makefile for building libcurl with MSVC14
|
||||
#
|
||||
# Usage: see usage message below
|
||||
# Should be invoked from \lib directory
|
||||
# Edit the paths and desired library name
|
||||
# SSL path is only required if you intend compiling
|
||||
# with SSL.
|
||||
#
|
||||
# This make file leaves the result either a .lib or .dll file
|
||||
# in the \lib directory. It should be called from the \lib
|
||||
# directory.
|
||||
#
|
||||
# An option would have been to allow the source directory to
|
||||
# be specified, but I saw no requirement.
|
||||
#
|
||||
# Another option would have been to leave the .lib and .dll
|
||||
# files in the "cfg" directory, but then the make file
|
||||
# in \src would need to be changed.
|
||||
#
|
||||
##############################################################
|
||||
|
||||
# ----------------------------------------------
|
||||
# Verify that current subdir is libcurl's 'lib'
|
||||
# ----------------------------------------------
|
||||
|
||||
!IF ! EXIST(.\curl_addrinfo.c)
|
||||
! MESSAGE Can not process this makefile from outside of libcurl's 'lib' subdirectory.
|
||||
! MESSAGE Change to libcurl's 'lib' subdirectory, and try again.
|
||||
! ERROR See previous message.
|
||||
!ENDIF
|
||||
|
||||
# ------------------------------------------------
|
||||
# Makefile.msvc.names provides libcurl file names
|
||||
# ------------------------------------------------
|
||||
|
||||
!INCLUDE ..\winbuild\Makefile.msvc.names
|
||||
|
||||
!IFNDEF OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-1.0.2a
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.5.0
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.8
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF MACHINE
|
||||
MACHINE = X86
|
||||
!ENDIF
|
||||
|
||||
# USE_WINDOWS_SSPI uses windows libraries to allow NTLM authentication
|
||||
# without an openssl installation and offers the ability to authenticate
|
||||
# using the "current logged in user". Since at least with MSVC14 the sspi.h
|
||||
# header is broken it is either required to install the Windows SDK,
|
||||
# or to fix sspi.h with adding this define at the beginning of sspi.h:
|
||||
# #define FreeCredentialHandle FreeCredentialsHandle
|
||||
#
|
||||
# If, for some reason the Windows SDK is installed but not installed
|
||||
# in the default location, you can specify WINDOWS_SDK_PATH.
|
||||
# It can be downloaded from:
|
||||
# https://msdn.microsoft.com/windows/bb980924.aspx
|
||||
|
||||
# WINDOWS_SSPI = 1
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
!IFNDEF WINDOWS_SDK_PATH
|
||||
WINDOWS_SDK_PATH = "$(PROGRAMFILES)\Microsoft SDK"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
#############################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
CCNODBG = cl.exe /O2 /DNDEBUG
|
||||
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /RTC1
|
||||
CFLAGSSSL = /DUSE_OPENSSL /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
CFLAGSWINSSL = /DUSE_SCHANNEL
|
||||
CFLAGSSSH2 = /DUSE_LIBSSH2 /DCURL_DISABLE_LDAP /DHAVE_LIBSSH2 /DHAVE_LIBSSH2_H /DLIBSSH2_WIN32 /DLIBSSH2_LIBRARY /I "$(LIBSSH2_PATH)/include"
|
||||
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
||||
CFLAGS = /I. /I../include /nologo /W3 /EHsc /DWIN32 /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
|
||||
CFLAGSLIB = /DCURL_STATICLIB
|
||||
LNKDLL = link.exe /DLL
|
||||
LNKLIB = link.exe /lib
|
||||
LFLAGS = /nologo /machine:$(MACHINE)
|
||||
SSLLIBS = libeay32.lib ssleay32.lib
|
||||
WINSSLLIBS = crypt32.lib
|
||||
ZLIBLIBSDLL = zdll.lib
|
||||
ZLIBLIBS = zlib.lib
|
||||
WINLIBS = ws2_32.lib wldap32.lib advapi32.lib
|
||||
CFLAGS = $(CFLAGS)
|
||||
|
||||
CFGSET = FALSE
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
CFLAGS = $(CFLAGS) /DUSE_WINDOWS_SSPI /I$(WINDOWS_SDK_PATH)\include
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IPV6
|
||||
CFLAGS = $(CFLAGS) /DUSE_IPV6
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IDN
|
||||
CFLAGS = $(CFLAGS) /DUSE_WIN32_IDN /DWANT_IDN_PROTOTYPES
|
||||
!ENDIF
|
||||
|
||||
##############################################################
|
||||
# Runtime library configuration
|
||||
|
||||
RTLIB = /MD
|
||||
RTLIBD = /MDd
|
||||
|
||||
!IF "$(RTLIBCFG)" == "static"
|
||||
RTLIB = /MT
|
||||
RTLIBD = /MTd
|
||||
!ENDIF
|
||||
|
||||
|
||||
######################
|
||||
# release
|
||||
|
||||
!IF "$(CFG)" == "release"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl
|
||||
|
||||
!IF "$(CFG)" == "release-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl
|
||||
|
||||
!IF "$(CFG)" == "release-winssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINSSLLIBS) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-winssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSZLIB) $(WINSSLLIBS) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug
|
||||
|
||||
!IF "$(CFG)" == "debug"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)\out32dll
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Usage
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE" && "$(CFG)" != ""
|
||||
!MESSAGE Usage: nmake /f makefile.vc14 CFG=<config> <target>
|
||||
!MESSAGE where <config> is one of:
|
||||
!MESSAGE release - release static library
|
||||
!MESSAGE release-ssl - release static library with ssl
|
||||
!MESSAGE release-zlib - release static library with zlib
|
||||
!MESSAGE release-ssl-zlib - release static library with ssl and zlib
|
||||
!MESSAGE release-ssl-ssh2-zlib - release static library with ssl, ssh2 and zlib
|
||||
!MESSAGE release-ssl-dll - release static library with dynamic ssl
|
||||
!MESSAGE release-zlib-dll - release static library with dynamic zlib
|
||||
!MESSAGE release-ssl-dll-zlib-dll - release static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE release-dll - release dynamic library
|
||||
!MESSAGE release-dll-ssl-dll - release dynamic library with dynamic ssl
|
||||
!MESSAGE release-dll-zlib-dll - release dynamic library with dynamic zlib
|
||||
!MESSAGE release-dll-ssl-dll-zlib-dll - release dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug - debug static library
|
||||
!MESSAGE debug-ssl - debug static library with ssl
|
||||
!MESSAGE debug-zlib - debug static library with zlib
|
||||
!MESSAGE debug-ssl-zlib - debug static library with ssl and zlib
|
||||
!MESSAGE debug-ssl-ssh2-zlib - debug static library with ssl, ssh2 and zlib
|
||||
!MESSAGE debug-ssl-dll - debug static library with dynamic ssl
|
||||
!MESSAGE debug-zlib-dll - debug static library with dynamic zlib
|
||||
!MESSAGE debug-ssl-dll-zlib-dll - debug static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug-dll - debug dynamic library
|
||||
!MESSAGE debug-dll-ssl-dll - debug dynamic library with dynamic ssl
|
||||
!MESSAGE debug-dll-zlib-dll - debug dynamic library with dynamic zlib1
|
||||
!MESSAGE debug-dll-ssl-dll-zlib-dll - debug dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE <target> can be left blank in which case all is assumed
|
||||
!ERROR please choose a valid configuration "$(CFG)"
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Only the clean target can be used if a config was not provided.
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE"
|
||||
clean:
|
||||
@-erase /s *.dll 2> NUL
|
||||
@-erase /s *.exp 2> NUL
|
||||
@-erase /s *.idb 2> NUL
|
||||
@-erase /s *.lib 2> NUL
|
||||
@-erase /s *.obj 2> NUL
|
||||
@-erase /s *.pch 2> NUL
|
||||
@-erase /s *.pdb 2> NUL
|
||||
@-erase /s *.res 2> NUL
|
||||
!ELSE
|
||||
# A config was provided, so the library can be built.
|
||||
#
|
||||
X_OBJS= \
|
||||
$(DIROBJ)\amigaos.obj \
|
||||
$(DIROBJ)\asyn-ares.obj \
|
||||
$(DIROBJ)\asyn-thread.obj \
|
||||
$(DIROBJ)\axtls.obj \
|
||||
$(DIROBJ)\base64.obj \
|
||||
$(DIROBJ)\conncache.obj \
|
||||
$(DIROBJ)\connect.obj \
|
||||
$(DIROBJ)\content_encoding.obj \
|
||||
$(DIROBJ)\cookie.obj \
|
||||
$(DIROBJ)\curl_addrinfo.obj \
|
||||
$(DIROBJ)\curl_des.obj \
|
||||
$(DIROBJ)\curl_endian.obj \
|
||||
$(DIROBJ)\curl_fnmatch.obj \
|
||||
$(DIROBJ)\curl_gethostname.obj \
|
||||
$(DIROBJ)\curl_gssapi.obj \
|
||||
$(DIROBJ)\curl_memrchr.obj \
|
||||
$(DIROBJ)\curl_multibyte.obj \
|
||||
$(DIROBJ)\curl_ntlm_core.obj \
|
||||
$(DIROBJ)\curl_ntlm_wb.obj \
|
||||
$(DIROBJ)\curl_rtmp.obj \
|
||||
$(DIROBJ)\curl_sasl.obj \
|
||||
$(DIROBJ)\curl_sspi.obj \
|
||||
$(DIROBJ)\curl_threads.obj \
|
||||
$(DIROBJ)\cyassl.obj \
|
||||
$(DIROBJ)\darwinssl.obj \
|
||||
$(DIROBJ)\dict.obj \
|
||||
$(DIROBJ)\dotdot.obj \
|
||||
$(DIROBJ)\easy.obj \
|
||||
$(DIROBJ)\escape.obj \
|
||||
$(DIROBJ)\file.obj \
|
||||
$(DIROBJ)\fileinfo.obj \
|
||||
$(DIROBJ)\formdata.obj \
|
||||
$(DIROBJ)\ftp.obj \
|
||||
$(DIROBJ)\ftplistparser.obj \
|
||||
$(DIROBJ)\getenv.obj \
|
||||
$(DIROBJ)\getinfo.obj \
|
||||
$(DIROBJ)\gopher.obj \
|
||||
$(DIROBJ)\gtls.obj \
|
||||
$(DIROBJ)\hash.obj \
|
||||
$(DIROBJ)\hmac.obj \
|
||||
$(DIROBJ)\hostasyn.obj \
|
||||
$(DIROBJ)\hostcheck.obj \
|
||||
$(DIROBJ)\hostip.obj \
|
||||
$(DIROBJ)\hostip4.obj \
|
||||
$(DIROBJ)\hostip6.obj \
|
||||
$(DIROBJ)\hostsyn.obj \
|
||||
$(DIROBJ)\http.obj \
|
||||
$(DIROBJ)\http_chunks.obj \
|
||||
$(DIROBJ)\http_digest.obj \
|
||||
$(DIROBJ)\http_negotiate.obj \
|
||||
$(DIROBJ)\http_ntlm.obj \
|
||||
$(DIROBJ)\http_proxy.obj \
|
||||
$(DIROBJ)\idn_win32.obj \
|
||||
$(DIROBJ)\if2ip.obj \
|
||||
$(DIROBJ)\imap.obj \
|
||||
$(DIROBJ)\inet_ntop.obj \
|
||||
$(DIROBJ)\inet_pton.obj \
|
||||
$(DIROBJ)\krb5.obj \
|
||||
$(DIROBJ)\ldap.obj \
|
||||
$(DIROBJ)\llist.obj \
|
||||
$(DIROBJ)\md4.obj \
|
||||
$(DIROBJ)\md5.obj \
|
||||
$(DIROBJ)\memdebug.obj \
|
||||
$(DIROBJ)\mprintf.obj \
|
||||
$(DIROBJ)\multi.obj \
|
||||
$(DIROBJ)\netrc.obj \
|
||||
$(DIROBJ)\non-ascii.obj \
|
||||
$(DIROBJ)\nonblock.obj \
|
||||
$(DIROBJ)\nss.obj \
|
||||
$(DIROBJ)\openldap.obj \
|
||||
$(DIROBJ)\parsedate.obj \
|
||||
$(DIROBJ)\pingpong.obj \
|
||||
$(DIROBJ)\pipeline.obj \
|
||||
$(DIROBJ)\polarssl.obj \
|
||||
$(DIROBJ)\polarssl_threadlock.obj \
|
||||
$(DIROBJ)\pop3.obj \
|
||||
$(DIROBJ)\progress.obj \
|
||||
$(DIROBJ)\strcase.obj \
|
||||
$(DIROBJ)\rand.obj \
|
||||
$(DIROBJ)\rtsp.obj \
|
||||
$(DIROBJ)\schannel.obj \
|
||||
$(DIROBJ)\security.obj \
|
||||
$(DIROBJ)\select.obj \
|
||||
$(DIROBJ)\sendf.obj \
|
||||
$(DIROBJ)\share.obj \
|
||||
$(DIROBJ)\slist.obj \
|
||||
$(DIROBJ)\smb.obj \
|
||||
$(DIROBJ)\smtp.obj \
|
||||
$(DIROBJ)\socks.obj \
|
||||
$(DIROBJ)\socks_gssapi.obj \
|
||||
$(DIROBJ)\socks_sspi.obj \
|
||||
$(DIROBJ)\speedcheck.obj \
|
||||
$(DIROBJ)\splay.obj \
|
||||
$(DIROBJ)\ssh.obj \
|
||||
$(DIROBJ)\system_win32.obj \
|
||||
$(DIROBJ)\vauth.obj \
|
||||
$(DIROBJ)\cleartext.obj \
|
||||
$(DIROBJ)\cram.obj \
|
||||
$(DIROBJ)\digest.obj \
|
||||
$(DIROBJ)\digest_sspi.obj \
|
||||
$(DIROBJ)\krb5_gssapi.obj \
|
||||
$(DIROBJ)\krb5_sspi.obj \
|
||||
$(DIROBJ)\ntlm.obj \
|
||||
$(DIROBJ)\ntlm_sspi.obj \
|
||||
$(DIROBJ)\oauth2.obj \
|
||||
$(DIROBJ)\spnego_gssapi.obj \
|
||||
$(DIROBJ)\spnego_sspi.obj \
|
||||
$(DIROBJ)\vtls.obj \
|
||||
$(DIROBJ)\openssl.obj \
|
||||
$(DIROBJ)\strdup.obj \
|
||||
$(DIROBJ)\strerror.obj \
|
||||
$(DIROBJ)\strtok.obj \
|
||||
$(DIROBJ)\strtoofft.obj \
|
||||
$(DIROBJ)\telnet.obj \
|
||||
$(DIROBJ)\tftp.obj \
|
||||
$(DIROBJ)\timeval.obj \
|
||||
$(DIROBJ)\transfer.obj \
|
||||
$(DIROBJ)\url.obj \
|
||||
$(DIROBJ)\version.obj \
|
||||
$(DIROBJ)\warnless.obj \
|
||||
$(DIROBJ)\wildcard.obj \
|
||||
$(DIROBJ)\x509asn1.obj \
|
||||
$(RESOURCE)
|
||||
|
||||
all : $(TARGET)
|
||||
|
||||
$(TARGET): $(X_OBJS)
|
||||
$(LNK) $(LFLAGS) $(X_OBJS)
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\*.exp . /y
|
||||
-xcopy $(DIROBJ)\*.pdb . /y
|
||||
|
||||
$(X_OBJS): $(DIROBJ)
|
||||
|
||||
$(DIROBJ):
|
||||
@if not exist "$(DIROBJ)" mkdir $(DIROBJ)
|
||||
|
||||
.SUFFIXES: .c .obj .res
|
||||
|
||||
{.\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vauth\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vtls\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
debug-dll\libcurl.res \
|
||||
debug-dll-ssl-dll\libcurl.res \
|
||||
debug-dll-zlib-dll\libcurl.res \
|
||||
debug-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=1 /Fo $@ libcurl.rc
|
||||
|
||||
release-dll\libcurl.res \
|
||||
release-dll-ssl-dll\libcurl.res \
|
||||
release-dll-zlib-dll\libcurl.res \
|
||||
release-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=0 /Fo $@ libcurl.rc
|
||||
!ENDIF # End of case where a config was provided.
|
||||
@@ -1,691 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1999 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
# All files in the Makefile.vc* series are generated automatically from the
|
||||
# one made for MSVC version 6. Alas, if you want to do changes to any of the
|
||||
# files and send back to the project, edit the version six, make your diff and
|
||||
# mail curl-library.
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Makefile for building libcurl with MSVC6
|
||||
#
|
||||
# Usage: see usage message below
|
||||
# Should be invoked from \lib directory
|
||||
# Edit the paths and desired library name
|
||||
# SSL path is only required if you intend compiling
|
||||
# with SSL.
|
||||
#
|
||||
# This make file leaves the result either a .lib or .dll file
|
||||
# in the \lib directory. It should be called from the \lib
|
||||
# directory.
|
||||
#
|
||||
# An option would have been to allow the source directory to
|
||||
# be specified, but I saw no requirement.
|
||||
#
|
||||
# Another option would have been to leave the .lib and .dll
|
||||
# files in the "cfg" directory, but then the make file
|
||||
# in \src would need to be changed.
|
||||
#
|
||||
##############################################################
|
||||
|
||||
# ----------------------------------------------
|
||||
# Verify that current subdir is libcurl's 'lib'
|
||||
# ----------------------------------------------
|
||||
|
||||
!IF ! EXIST(.\curl_addrinfo.c)
|
||||
! MESSAGE Can not process this makefile from outside of libcurl's 'lib' subdirectory.
|
||||
! MESSAGE Change to libcurl's 'lib' subdirectory, and try again.
|
||||
! ERROR See previous message.
|
||||
!ENDIF
|
||||
|
||||
# ------------------------------------------------
|
||||
# Makefile.msvc.names provides libcurl file names
|
||||
# ------------------------------------------------
|
||||
|
||||
!INCLUDE ..\winbuild\Makefile.msvc.names
|
||||
|
||||
!IFNDEF OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-1.0.2a
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.5.0
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.8
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF MACHINE
|
||||
MACHINE = X86
|
||||
!ENDIF
|
||||
|
||||
# USE_WINDOWS_SSPI uses windows libraries to allow NTLM authentication
|
||||
# without an openssl installation and offers the ability to authenticate
|
||||
# using the "current logged in user". Since at least with MSVC6 the sspi.h
|
||||
# header is broken it is either required to install the Windows SDK,
|
||||
# or to fix sspi.h with adding this define at the beginning of sspi.h:
|
||||
# #define FreeCredentialHandle FreeCredentialsHandle
|
||||
#
|
||||
# If, for some reason the Windows SDK is installed but not installed
|
||||
# in the default location, you can specify WINDOWS_SDK_PATH.
|
||||
# It can be downloaded from:
|
||||
# https://msdn.microsoft.com/windows/bb980924.aspx
|
||||
|
||||
# WINDOWS_SSPI = 1
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
!IFNDEF WINDOWS_SDK_PATH
|
||||
WINDOWS_SDK_PATH = "$(PROGRAMFILES)\Microsoft SDK"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
#############################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
CCNODBG = cl.exe /O2 /DNDEBUG
|
||||
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /GZ
|
||||
CFLAGSSSL = /DUSE_OPENSSL /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
CFLAGSWINSSL = /DUSE_SCHANNEL
|
||||
CFLAGSSSH2 = /DUSE_LIBSSH2 /DCURL_DISABLE_LDAP /DHAVE_LIBSSH2 /DHAVE_LIBSSH2_H /DLIBSSH2_WIN32 /DLIBSSH2_LIBRARY /I "$(LIBSSH2_PATH)/include"
|
||||
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
||||
CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
|
||||
CFLAGSLIB = /DCURL_STATICLIB
|
||||
LNKDLL = link.exe /DLL
|
||||
LNKLIB = link.exe /lib
|
||||
LFLAGS = /nologo /machine:$(MACHINE)
|
||||
SSLLIBS = libeay32.lib ssleay32.lib
|
||||
WINSSLLIBS = crypt32.lib
|
||||
ZLIBLIBSDLL = zdll.lib
|
||||
ZLIBLIBS = zlib.lib
|
||||
WINLIBS = ws2_32.lib wldap32.lib advapi32.lib
|
||||
CFLAGS = $(CFLAGS)
|
||||
|
||||
CFGSET = FALSE
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
CFLAGS = $(CFLAGS) /DUSE_WINDOWS_SSPI /I$(WINDOWS_SDK_PATH)\include
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IPV6
|
||||
CFLAGS = $(CFLAGS) /DUSE_IPV6
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IDN
|
||||
CFLAGS = $(CFLAGS) /DUSE_WIN32_IDN /DWANT_IDN_PROTOTYPES
|
||||
!ENDIF
|
||||
|
||||
##############################################################
|
||||
# Runtime library configuration
|
||||
|
||||
RTLIB = /MD
|
||||
RTLIBD = /MDd
|
||||
|
||||
!IF "$(RTLIBCFG)" == "static"
|
||||
RTLIB = /MT
|
||||
RTLIBD = /MTd
|
||||
!ENDIF
|
||||
|
||||
|
||||
######################
|
||||
# release
|
||||
|
||||
!IF "$(CFG)" == "release"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl
|
||||
|
||||
!IF "$(CFG)" == "release-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl
|
||||
|
||||
!IF "$(CFG)" == "release-winssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINSSLLIBS) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-winssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSZLIB) $(WINSSLLIBS) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug
|
||||
|
||||
!IF "$(CFG)" == "debug"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)\out32dll
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Usage
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE" && "$(CFG)" != ""
|
||||
!MESSAGE Usage: nmake /f makefile.vc6 CFG=<config> <target>
|
||||
!MESSAGE where <config> is one of:
|
||||
!MESSAGE release - release static library
|
||||
!MESSAGE release-ssl - release static library with ssl
|
||||
!MESSAGE release-zlib - release static library with zlib
|
||||
!MESSAGE release-ssl-zlib - release static library with ssl and zlib
|
||||
!MESSAGE release-ssl-ssh2-zlib - release static library with ssl, ssh2 and zlib
|
||||
!MESSAGE release-ssl-dll - release static library with dynamic ssl
|
||||
!MESSAGE release-zlib-dll - release static library with dynamic zlib
|
||||
!MESSAGE release-ssl-dll-zlib-dll - release static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE release-dll - release dynamic library
|
||||
!MESSAGE release-dll-ssl-dll - release dynamic library with dynamic ssl
|
||||
!MESSAGE release-dll-zlib-dll - release dynamic library with dynamic zlib
|
||||
!MESSAGE release-dll-ssl-dll-zlib-dll - release dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug - debug static library
|
||||
!MESSAGE debug-ssl - debug static library with ssl
|
||||
!MESSAGE debug-zlib - debug static library with zlib
|
||||
!MESSAGE debug-ssl-zlib - debug static library with ssl and zlib
|
||||
!MESSAGE debug-ssl-ssh2-zlib - debug static library with ssl, ssh2 and zlib
|
||||
!MESSAGE debug-ssl-dll - debug static library with dynamic ssl
|
||||
!MESSAGE debug-zlib-dll - debug static library with dynamic zlib
|
||||
!MESSAGE debug-ssl-dll-zlib-dll - debug static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug-dll - debug dynamic library
|
||||
!MESSAGE debug-dll-ssl-dll - debug dynamic library with dynamic ssl
|
||||
!MESSAGE debug-dll-zlib-dll - debug dynamic library with dynamic zlib1
|
||||
!MESSAGE debug-dll-ssl-dll-zlib-dll - debug dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE <target> can be left blank in which case all is assumed
|
||||
!ERROR please choose a valid configuration "$(CFG)"
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Only the clean target can be used if a config was not provided.
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE"
|
||||
clean:
|
||||
@-erase /s *.dll 2> NUL
|
||||
@-erase /s *.exp 2> NUL
|
||||
@-erase /s *.idb 2> NUL
|
||||
@-erase /s *.lib 2> NUL
|
||||
@-erase /s *.obj 2> NUL
|
||||
@-erase /s *.pch 2> NUL
|
||||
@-erase /s *.pdb 2> NUL
|
||||
@-erase /s *.res 2> NUL
|
||||
!ELSE
|
||||
# A config was provided, so the library can be built.
|
||||
#
|
||||
X_OBJS= \
|
||||
$(DIROBJ)\amigaos.obj \
|
||||
$(DIROBJ)\asyn-ares.obj \
|
||||
$(DIROBJ)\asyn-thread.obj \
|
||||
$(DIROBJ)\axtls.obj \
|
||||
$(DIROBJ)\base64.obj \
|
||||
$(DIROBJ)\conncache.obj \
|
||||
$(DIROBJ)\connect.obj \
|
||||
$(DIROBJ)\content_encoding.obj \
|
||||
$(DIROBJ)\cookie.obj \
|
||||
$(DIROBJ)\curl_addrinfo.obj \
|
||||
$(DIROBJ)\curl_des.obj \
|
||||
$(DIROBJ)\curl_endian.obj \
|
||||
$(DIROBJ)\curl_fnmatch.obj \
|
||||
$(DIROBJ)\curl_gethostname.obj \
|
||||
$(DIROBJ)\curl_gssapi.obj \
|
||||
$(DIROBJ)\curl_memrchr.obj \
|
||||
$(DIROBJ)\curl_multibyte.obj \
|
||||
$(DIROBJ)\curl_ntlm_core.obj \
|
||||
$(DIROBJ)\curl_ntlm_wb.obj \
|
||||
$(DIROBJ)\curl_rtmp.obj \
|
||||
$(DIROBJ)\curl_sasl.obj \
|
||||
$(DIROBJ)\curl_sspi.obj \
|
||||
$(DIROBJ)\curl_threads.obj \
|
||||
$(DIROBJ)\cyassl.obj \
|
||||
$(DIROBJ)\darwinssl.obj \
|
||||
$(DIROBJ)\dict.obj \
|
||||
$(DIROBJ)\dotdot.obj \
|
||||
$(DIROBJ)\easy.obj \
|
||||
$(DIROBJ)\escape.obj \
|
||||
$(DIROBJ)\file.obj \
|
||||
$(DIROBJ)\fileinfo.obj \
|
||||
$(DIROBJ)\formdata.obj \
|
||||
$(DIROBJ)\ftp.obj \
|
||||
$(DIROBJ)\ftplistparser.obj \
|
||||
$(DIROBJ)\getenv.obj \
|
||||
$(DIROBJ)\getinfo.obj \
|
||||
$(DIROBJ)\gopher.obj \
|
||||
$(DIROBJ)\gtls.obj \
|
||||
$(DIROBJ)\hash.obj \
|
||||
$(DIROBJ)\hmac.obj \
|
||||
$(DIROBJ)\hostasyn.obj \
|
||||
$(DIROBJ)\hostcheck.obj \
|
||||
$(DIROBJ)\hostip.obj \
|
||||
$(DIROBJ)\hostip4.obj \
|
||||
$(DIROBJ)\hostip6.obj \
|
||||
$(DIROBJ)\hostsyn.obj \
|
||||
$(DIROBJ)\http.obj \
|
||||
$(DIROBJ)\http_chunks.obj \
|
||||
$(DIROBJ)\http_digest.obj \
|
||||
$(DIROBJ)\http_negotiate.obj \
|
||||
$(DIROBJ)\http_ntlm.obj \
|
||||
$(DIROBJ)\http_proxy.obj \
|
||||
$(DIROBJ)\idn_win32.obj \
|
||||
$(DIROBJ)\if2ip.obj \
|
||||
$(DIROBJ)\imap.obj \
|
||||
$(DIROBJ)\inet_ntop.obj \
|
||||
$(DIROBJ)\inet_pton.obj \
|
||||
$(DIROBJ)\krb5.obj \
|
||||
$(DIROBJ)\ldap.obj \
|
||||
$(DIROBJ)\llist.obj \
|
||||
$(DIROBJ)\md4.obj \
|
||||
$(DIROBJ)\md5.obj \
|
||||
$(DIROBJ)\memdebug.obj \
|
||||
$(DIROBJ)\mprintf.obj \
|
||||
$(DIROBJ)\multi.obj \
|
||||
$(DIROBJ)\netrc.obj \
|
||||
$(DIROBJ)\non-ascii.obj \
|
||||
$(DIROBJ)\nonblock.obj \
|
||||
$(DIROBJ)\nss.obj \
|
||||
$(DIROBJ)\openldap.obj \
|
||||
$(DIROBJ)\parsedate.obj \
|
||||
$(DIROBJ)\pingpong.obj \
|
||||
$(DIROBJ)\pipeline.obj \
|
||||
$(DIROBJ)\polarssl.obj \
|
||||
$(DIROBJ)\polarssl_threadlock.obj \
|
||||
$(DIROBJ)\pop3.obj \
|
||||
$(DIROBJ)\progress.obj \
|
||||
$(DIROBJ)\strcase.obj \
|
||||
$(DIROBJ)\rand.obj \
|
||||
$(DIROBJ)\rtsp.obj \
|
||||
$(DIROBJ)\schannel.obj \
|
||||
$(DIROBJ)\security.obj \
|
||||
$(DIROBJ)\select.obj \
|
||||
$(DIROBJ)\sendf.obj \
|
||||
$(DIROBJ)\share.obj \
|
||||
$(DIROBJ)\slist.obj \
|
||||
$(DIROBJ)\smb.obj \
|
||||
$(DIROBJ)\smtp.obj \
|
||||
$(DIROBJ)\socks.obj \
|
||||
$(DIROBJ)\socks_gssapi.obj \
|
||||
$(DIROBJ)\socks_sspi.obj \
|
||||
$(DIROBJ)\speedcheck.obj \
|
||||
$(DIROBJ)\splay.obj \
|
||||
$(DIROBJ)\ssh.obj \
|
||||
$(DIROBJ)\system_win32.obj \
|
||||
$(DIROBJ)\vauth.obj \
|
||||
$(DIROBJ)\cleartext.obj \
|
||||
$(DIROBJ)\cram.obj \
|
||||
$(DIROBJ)\digest.obj \
|
||||
$(DIROBJ)\digest_sspi.obj \
|
||||
$(DIROBJ)\krb5_gssapi.obj \
|
||||
$(DIROBJ)\krb5_sspi.obj \
|
||||
$(DIROBJ)\ntlm.obj \
|
||||
$(DIROBJ)\ntlm_sspi.obj \
|
||||
$(DIROBJ)\oauth2.obj \
|
||||
$(DIROBJ)\spnego_gssapi.obj \
|
||||
$(DIROBJ)\spnego_sspi.obj \
|
||||
$(DIROBJ)\vtls.obj \
|
||||
$(DIROBJ)\openssl.obj \
|
||||
$(DIROBJ)\strdup.obj \
|
||||
$(DIROBJ)\strerror.obj \
|
||||
$(DIROBJ)\strtok.obj \
|
||||
$(DIROBJ)\strtoofft.obj \
|
||||
$(DIROBJ)\telnet.obj \
|
||||
$(DIROBJ)\tftp.obj \
|
||||
$(DIROBJ)\timeval.obj \
|
||||
$(DIROBJ)\transfer.obj \
|
||||
$(DIROBJ)\url.obj \
|
||||
$(DIROBJ)\version.obj \
|
||||
$(DIROBJ)\warnless.obj \
|
||||
$(DIROBJ)\wildcard.obj \
|
||||
$(DIROBJ)\x509asn1.obj \
|
||||
$(RESOURCE)
|
||||
|
||||
all : $(TARGET)
|
||||
|
||||
$(TARGET): $(X_OBJS)
|
||||
$(LNK) $(LFLAGS) $(X_OBJS)
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\*.exp . /y
|
||||
-xcopy $(DIROBJ)\*.pdb . /y
|
||||
|
||||
$(X_OBJS): $(DIROBJ)
|
||||
|
||||
$(DIROBJ):
|
||||
@if not exist "$(DIROBJ)" mkdir $(DIROBJ)
|
||||
|
||||
.SUFFIXES: .c .obj .res
|
||||
|
||||
{.\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vauth\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vtls\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
debug-dll\libcurl.res \
|
||||
debug-dll-ssl-dll\libcurl.res \
|
||||
debug-dll-zlib-dll\libcurl.res \
|
||||
debug-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=1 /Fo $@ libcurl.rc
|
||||
|
||||
release-dll\libcurl.res \
|
||||
release-dll-ssl-dll\libcurl.res \
|
||||
release-dll-zlib-dll\libcurl.res \
|
||||
release-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=0 /Fo $@ libcurl.rc
|
||||
!ENDIF # End of case where a config was provided.
|
||||
@@ -1,691 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1999 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
# All files in the Makefile.vc* series are generated automatically from the
|
||||
# one made for MSVC version 6. Alas, if you want to do changes to any of the
|
||||
# files and send back to the project, edit the version six, make your diff and
|
||||
# mail curl-library.
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Makefile for building libcurl with MSVC7
|
||||
#
|
||||
# Usage: see usage message below
|
||||
# Should be invoked from \lib directory
|
||||
# Edit the paths and desired library name
|
||||
# SSL path is only required if you intend compiling
|
||||
# with SSL.
|
||||
#
|
||||
# This make file leaves the result either a .lib or .dll file
|
||||
# in the \lib directory. It should be called from the \lib
|
||||
# directory.
|
||||
#
|
||||
# An option would have been to allow the source directory to
|
||||
# be specified, but I saw no requirement.
|
||||
#
|
||||
# Another option would have been to leave the .lib and .dll
|
||||
# files in the "cfg" directory, but then the make file
|
||||
# in \src would need to be changed.
|
||||
#
|
||||
##############################################################
|
||||
|
||||
# ----------------------------------------------
|
||||
# Verify that current subdir is libcurl's 'lib'
|
||||
# ----------------------------------------------
|
||||
|
||||
!IF ! EXIST(.\curl_addrinfo.c)
|
||||
! MESSAGE Can not process this makefile from outside of libcurl's 'lib' subdirectory.
|
||||
! MESSAGE Change to libcurl's 'lib' subdirectory, and try again.
|
||||
! ERROR See previous message.
|
||||
!ENDIF
|
||||
|
||||
# ------------------------------------------------
|
||||
# Makefile.msvc.names provides libcurl file names
|
||||
# ------------------------------------------------
|
||||
|
||||
!INCLUDE ..\winbuild\Makefile.msvc.names
|
||||
|
||||
!IFNDEF OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-1.0.2a
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.5.0
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.8
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF MACHINE
|
||||
MACHINE = X86
|
||||
!ENDIF
|
||||
|
||||
# USE_WINDOWS_SSPI uses windows libraries to allow NTLM authentication
|
||||
# without an openssl installation and offers the ability to authenticate
|
||||
# using the "current logged in user". Since at least with MSVC7 the sspi.h
|
||||
# header is broken it is either required to install the Windows SDK,
|
||||
# or to fix sspi.h with adding this define at the beginning of sspi.h:
|
||||
# #define FreeCredentialHandle FreeCredentialsHandle
|
||||
#
|
||||
# If, for some reason the Windows SDK is installed but not installed
|
||||
# in the default location, you can specify WINDOWS_SDK_PATH.
|
||||
# It can be downloaded from:
|
||||
# https://msdn.microsoft.com/windows/bb980924.aspx
|
||||
|
||||
# WINDOWS_SSPI = 1
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
!IFNDEF WINDOWS_SDK_PATH
|
||||
WINDOWS_SDK_PATH = "$(PROGRAMFILES)\Microsoft SDK"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
#############################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
CCNODBG = cl.exe /O2 /DNDEBUG
|
||||
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /GZ
|
||||
CFLAGSSSL = /DUSE_OPENSSL /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
CFLAGSWINSSL = /DUSE_SCHANNEL
|
||||
CFLAGSSSH2 = /DUSE_LIBSSH2 /DCURL_DISABLE_LDAP /DHAVE_LIBSSH2 /DHAVE_LIBSSH2_H /DLIBSSH2_WIN32 /DLIBSSH2_LIBRARY /I "$(LIBSSH2_PATH)/include"
|
||||
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
||||
CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
|
||||
CFLAGSLIB = /DCURL_STATICLIB
|
||||
LNKDLL = link.exe /DLL
|
||||
LNKLIB = link.exe /lib
|
||||
LFLAGS = /nologo /machine:$(MACHINE)
|
||||
SSLLIBS = libeay32.lib ssleay32.lib
|
||||
WINSSLLIBS = crypt32.lib
|
||||
ZLIBLIBSDLL = zdll.lib
|
||||
ZLIBLIBS = zlib.lib
|
||||
WINLIBS = ws2_32.lib wldap32.lib advapi32.lib
|
||||
CFLAGS = $(CFLAGS)
|
||||
|
||||
CFGSET = FALSE
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
CFLAGS = $(CFLAGS) /DUSE_WINDOWS_SSPI /I$(WINDOWS_SDK_PATH)\include
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IPV6
|
||||
CFLAGS = $(CFLAGS) /DUSE_IPV6
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IDN
|
||||
CFLAGS = $(CFLAGS) /DUSE_WIN32_IDN /DWANT_IDN_PROTOTYPES
|
||||
!ENDIF
|
||||
|
||||
##############################################################
|
||||
# Runtime library configuration
|
||||
|
||||
RTLIB = /MD
|
||||
RTLIBD = /MDd
|
||||
|
||||
!IF "$(RTLIBCFG)" == "static"
|
||||
RTLIB = /MT
|
||||
RTLIBD = /MTd
|
||||
!ENDIF
|
||||
|
||||
|
||||
######################
|
||||
# release
|
||||
|
||||
!IF "$(CFG)" == "release"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl
|
||||
|
||||
!IF "$(CFG)" == "release-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl
|
||||
|
||||
!IF "$(CFG)" == "release-winssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINSSLLIBS) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-winssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSZLIB) $(WINSSLLIBS) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug
|
||||
|
||||
!IF "$(CFG)" == "debug"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)\out32dll
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Usage
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE" && "$(CFG)" != ""
|
||||
!MESSAGE Usage: nmake /f makefile.vc6 CFG=<config> <target>
|
||||
!MESSAGE where <config> is one of:
|
||||
!MESSAGE release - release static library
|
||||
!MESSAGE release-ssl - release static library with ssl
|
||||
!MESSAGE release-zlib - release static library with zlib
|
||||
!MESSAGE release-ssl-zlib - release static library with ssl and zlib
|
||||
!MESSAGE release-ssl-ssh2-zlib - release static library with ssl, ssh2 and zlib
|
||||
!MESSAGE release-ssl-dll - release static library with dynamic ssl
|
||||
!MESSAGE release-zlib-dll - release static library with dynamic zlib
|
||||
!MESSAGE release-ssl-dll-zlib-dll - release static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE release-dll - release dynamic library
|
||||
!MESSAGE release-dll-ssl-dll - release dynamic library with dynamic ssl
|
||||
!MESSAGE release-dll-zlib-dll - release dynamic library with dynamic zlib
|
||||
!MESSAGE release-dll-ssl-dll-zlib-dll - release dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug - debug static library
|
||||
!MESSAGE debug-ssl - debug static library with ssl
|
||||
!MESSAGE debug-zlib - debug static library with zlib
|
||||
!MESSAGE debug-ssl-zlib - debug static library with ssl and zlib
|
||||
!MESSAGE debug-ssl-ssh2-zlib - debug static library with ssl, ssh2 and zlib
|
||||
!MESSAGE debug-ssl-dll - debug static library with dynamic ssl
|
||||
!MESSAGE debug-zlib-dll - debug static library with dynamic zlib
|
||||
!MESSAGE debug-ssl-dll-zlib-dll - debug static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug-dll - debug dynamic library
|
||||
!MESSAGE debug-dll-ssl-dll - debug dynamic library with dynamic ssl
|
||||
!MESSAGE debug-dll-zlib-dll - debug dynamic library with dynamic zlib1
|
||||
!MESSAGE debug-dll-ssl-dll-zlib-dll - debug dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE <target> can be left blank in which case all is assumed
|
||||
!ERROR please choose a valid configuration "$(CFG)"
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Only the clean target can be used if a config was not provided.
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE"
|
||||
clean:
|
||||
@-erase /s *.dll 2> NUL
|
||||
@-erase /s *.exp 2> NUL
|
||||
@-erase /s *.idb 2> NUL
|
||||
@-erase /s *.lib 2> NUL
|
||||
@-erase /s *.obj 2> NUL
|
||||
@-erase /s *.pch 2> NUL
|
||||
@-erase /s *.pdb 2> NUL
|
||||
@-erase /s *.res 2> NUL
|
||||
!ELSE
|
||||
# A config was provided, so the library can be built.
|
||||
#
|
||||
X_OBJS= \
|
||||
$(DIROBJ)\amigaos.obj \
|
||||
$(DIROBJ)\asyn-ares.obj \
|
||||
$(DIROBJ)\asyn-thread.obj \
|
||||
$(DIROBJ)\axtls.obj \
|
||||
$(DIROBJ)\base64.obj \
|
||||
$(DIROBJ)\conncache.obj \
|
||||
$(DIROBJ)\connect.obj \
|
||||
$(DIROBJ)\content_encoding.obj \
|
||||
$(DIROBJ)\cookie.obj \
|
||||
$(DIROBJ)\curl_addrinfo.obj \
|
||||
$(DIROBJ)\curl_des.obj \
|
||||
$(DIROBJ)\curl_endian.obj \
|
||||
$(DIROBJ)\curl_fnmatch.obj \
|
||||
$(DIROBJ)\curl_gethostname.obj \
|
||||
$(DIROBJ)\curl_gssapi.obj \
|
||||
$(DIROBJ)\curl_memrchr.obj \
|
||||
$(DIROBJ)\curl_multibyte.obj \
|
||||
$(DIROBJ)\curl_ntlm_core.obj \
|
||||
$(DIROBJ)\curl_ntlm_wb.obj \
|
||||
$(DIROBJ)\curl_rtmp.obj \
|
||||
$(DIROBJ)\curl_sasl.obj \
|
||||
$(DIROBJ)\curl_sspi.obj \
|
||||
$(DIROBJ)\curl_threads.obj \
|
||||
$(DIROBJ)\cyassl.obj \
|
||||
$(DIROBJ)\darwinssl.obj \
|
||||
$(DIROBJ)\dict.obj \
|
||||
$(DIROBJ)\dotdot.obj \
|
||||
$(DIROBJ)\easy.obj \
|
||||
$(DIROBJ)\escape.obj \
|
||||
$(DIROBJ)\file.obj \
|
||||
$(DIROBJ)\fileinfo.obj \
|
||||
$(DIROBJ)\formdata.obj \
|
||||
$(DIROBJ)\ftp.obj \
|
||||
$(DIROBJ)\ftplistparser.obj \
|
||||
$(DIROBJ)\getenv.obj \
|
||||
$(DIROBJ)\getinfo.obj \
|
||||
$(DIROBJ)\gopher.obj \
|
||||
$(DIROBJ)\gtls.obj \
|
||||
$(DIROBJ)\hash.obj \
|
||||
$(DIROBJ)\hmac.obj \
|
||||
$(DIROBJ)\hostasyn.obj \
|
||||
$(DIROBJ)\hostcheck.obj \
|
||||
$(DIROBJ)\hostip.obj \
|
||||
$(DIROBJ)\hostip4.obj \
|
||||
$(DIROBJ)\hostip6.obj \
|
||||
$(DIROBJ)\hostsyn.obj \
|
||||
$(DIROBJ)\http.obj \
|
||||
$(DIROBJ)\http_chunks.obj \
|
||||
$(DIROBJ)\http_digest.obj \
|
||||
$(DIROBJ)\http_negotiate.obj \
|
||||
$(DIROBJ)\http_ntlm.obj \
|
||||
$(DIROBJ)\http_proxy.obj \
|
||||
$(DIROBJ)\idn_win32.obj \
|
||||
$(DIROBJ)\if2ip.obj \
|
||||
$(DIROBJ)\imap.obj \
|
||||
$(DIROBJ)\inet_ntop.obj \
|
||||
$(DIROBJ)\inet_pton.obj \
|
||||
$(DIROBJ)\krb5.obj \
|
||||
$(DIROBJ)\ldap.obj \
|
||||
$(DIROBJ)\llist.obj \
|
||||
$(DIROBJ)\md4.obj \
|
||||
$(DIROBJ)\md5.obj \
|
||||
$(DIROBJ)\memdebug.obj \
|
||||
$(DIROBJ)\mprintf.obj \
|
||||
$(DIROBJ)\multi.obj \
|
||||
$(DIROBJ)\netrc.obj \
|
||||
$(DIROBJ)\non-ascii.obj \
|
||||
$(DIROBJ)\nonblock.obj \
|
||||
$(DIROBJ)\nss.obj \
|
||||
$(DIROBJ)\openldap.obj \
|
||||
$(DIROBJ)\parsedate.obj \
|
||||
$(DIROBJ)\pingpong.obj \
|
||||
$(DIROBJ)\pipeline.obj \
|
||||
$(DIROBJ)\polarssl.obj \
|
||||
$(DIROBJ)\polarssl_threadlock.obj \
|
||||
$(DIROBJ)\pop3.obj \
|
||||
$(DIROBJ)\progress.obj \
|
||||
$(DIROBJ)\strcase.obj \
|
||||
$(DIROBJ)\rand.obj \
|
||||
$(DIROBJ)\rtsp.obj \
|
||||
$(DIROBJ)\schannel.obj \
|
||||
$(DIROBJ)\security.obj \
|
||||
$(DIROBJ)\select.obj \
|
||||
$(DIROBJ)\sendf.obj \
|
||||
$(DIROBJ)\share.obj \
|
||||
$(DIROBJ)\slist.obj \
|
||||
$(DIROBJ)\smb.obj \
|
||||
$(DIROBJ)\smtp.obj \
|
||||
$(DIROBJ)\socks.obj \
|
||||
$(DIROBJ)\socks_gssapi.obj \
|
||||
$(DIROBJ)\socks_sspi.obj \
|
||||
$(DIROBJ)\speedcheck.obj \
|
||||
$(DIROBJ)\splay.obj \
|
||||
$(DIROBJ)\ssh.obj \
|
||||
$(DIROBJ)\system_win32.obj \
|
||||
$(DIROBJ)\vauth.obj \
|
||||
$(DIROBJ)\cleartext.obj \
|
||||
$(DIROBJ)\cram.obj \
|
||||
$(DIROBJ)\digest.obj \
|
||||
$(DIROBJ)\digest_sspi.obj \
|
||||
$(DIROBJ)\krb5_gssapi.obj \
|
||||
$(DIROBJ)\krb5_sspi.obj \
|
||||
$(DIROBJ)\ntlm.obj \
|
||||
$(DIROBJ)\ntlm_sspi.obj \
|
||||
$(DIROBJ)\oauth2.obj \
|
||||
$(DIROBJ)\spnego_gssapi.obj \
|
||||
$(DIROBJ)\spnego_sspi.obj \
|
||||
$(DIROBJ)\vtls.obj \
|
||||
$(DIROBJ)\openssl.obj \
|
||||
$(DIROBJ)\strdup.obj \
|
||||
$(DIROBJ)\strerror.obj \
|
||||
$(DIROBJ)\strtok.obj \
|
||||
$(DIROBJ)\strtoofft.obj \
|
||||
$(DIROBJ)\telnet.obj \
|
||||
$(DIROBJ)\tftp.obj \
|
||||
$(DIROBJ)\timeval.obj \
|
||||
$(DIROBJ)\transfer.obj \
|
||||
$(DIROBJ)\url.obj \
|
||||
$(DIROBJ)\version.obj \
|
||||
$(DIROBJ)\warnless.obj \
|
||||
$(DIROBJ)\wildcard.obj \
|
||||
$(DIROBJ)\x509asn1.obj \
|
||||
$(RESOURCE)
|
||||
|
||||
all : $(TARGET)
|
||||
|
||||
$(TARGET): $(X_OBJS)
|
||||
$(LNK) $(LFLAGS) $(X_OBJS)
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\*.exp . /y
|
||||
-xcopy $(DIROBJ)\*.pdb . /y
|
||||
|
||||
$(X_OBJS): $(DIROBJ)
|
||||
|
||||
$(DIROBJ):
|
||||
@if not exist "$(DIROBJ)" mkdir $(DIROBJ)
|
||||
|
||||
.SUFFIXES: .c .obj .res
|
||||
|
||||
{.\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vauth\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vtls\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
debug-dll\libcurl.res \
|
||||
debug-dll-ssl-dll\libcurl.res \
|
||||
debug-dll-zlib-dll\libcurl.res \
|
||||
debug-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=1 /Fo $@ libcurl.rc
|
||||
|
||||
release-dll\libcurl.res \
|
||||
release-dll-ssl-dll\libcurl.res \
|
||||
release-dll-zlib-dll\libcurl.res \
|
||||
release-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=0 /Fo $@ libcurl.rc
|
||||
!ENDIF # End of case where a config was provided.
|
||||
@@ -1,691 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1999 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
# All files in the Makefile.vc* series are generated automatically from the
|
||||
# one made for MSVC version 6. Alas, if you want to do changes to any of the
|
||||
# files and send back to the project, edit the version six, make your diff and
|
||||
# mail curl-library.
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Makefile for building libcurl with MSVC8
|
||||
#
|
||||
# Usage: see usage message below
|
||||
# Should be invoked from \lib directory
|
||||
# Edit the paths and desired library name
|
||||
# SSL path is only required if you intend compiling
|
||||
# with SSL.
|
||||
#
|
||||
# This make file leaves the result either a .lib or .dll file
|
||||
# in the \lib directory. It should be called from the \lib
|
||||
# directory.
|
||||
#
|
||||
# An option would have been to allow the source directory to
|
||||
# be specified, but I saw no requirement.
|
||||
#
|
||||
# Another option would have been to leave the .lib and .dll
|
||||
# files in the "cfg" directory, but then the make file
|
||||
# in \src would need to be changed.
|
||||
#
|
||||
##############################################################
|
||||
|
||||
# ----------------------------------------------
|
||||
# Verify that current subdir is libcurl's 'lib'
|
||||
# ----------------------------------------------
|
||||
|
||||
!IF ! EXIST(.\curl_addrinfo.c)
|
||||
! MESSAGE Can not process this makefile from outside of libcurl's 'lib' subdirectory.
|
||||
! MESSAGE Change to libcurl's 'lib' subdirectory, and try again.
|
||||
! ERROR See previous message.
|
||||
!ENDIF
|
||||
|
||||
# ------------------------------------------------
|
||||
# Makefile.msvc.names provides libcurl file names
|
||||
# ------------------------------------------------
|
||||
|
||||
!INCLUDE ..\winbuild\Makefile.msvc.names
|
||||
|
||||
!IFNDEF OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-1.0.2a
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.5.0
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.8
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF MACHINE
|
||||
MACHINE = X86
|
||||
!ENDIF
|
||||
|
||||
# USE_WINDOWS_SSPI uses windows libraries to allow NTLM authentication
|
||||
# without an openssl installation and offers the ability to authenticate
|
||||
# using the "current logged in user". Since at least with MSVC8 the sspi.h
|
||||
# header is broken it is either required to install the Windows SDK,
|
||||
# or to fix sspi.h with adding this define at the beginning of sspi.h:
|
||||
# #define FreeCredentialHandle FreeCredentialsHandle
|
||||
#
|
||||
# If, for some reason the Windows SDK is installed but not installed
|
||||
# in the default location, you can specify WINDOWS_SDK_PATH.
|
||||
# It can be downloaded from:
|
||||
# https://msdn.microsoft.com/windows/bb980924.aspx
|
||||
|
||||
# WINDOWS_SSPI = 1
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
!IFNDEF WINDOWS_SDK_PATH
|
||||
WINDOWS_SDK_PATH = "$(PROGRAMFILES)\Microsoft SDK"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
#############################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
CCNODBG = cl.exe /O2 /DNDEBUG
|
||||
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /RTC1
|
||||
CFLAGSSSL = /DUSE_OPENSSL /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
CFLAGSWINSSL = /DUSE_SCHANNEL
|
||||
CFLAGSSSH2 = /DUSE_LIBSSH2 /DCURL_DISABLE_LDAP /DHAVE_LIBSSH2 /DHAVE_LIBSSH2_H /DLIBSSH2_WIN32 /DLIBSSH2_LIBRARY /I "$(LIBSSH2_PATH)/include"
|
||||
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
||||
CFLAGS = /I. /I../include /nologo /W3 /EHsc /DWIN32 /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
|
||||
CFLAGSLIB = /DCURL_STATICLIB
|
||||
LNKDLL = link.exe /DLL
|
||||
LNKLIB = link.exe /lib
|
||||
LFLAGS = /nologo /machine:$(MACHINE)
|
||||
SSLLIBS = libeay32.lib ssleay32.lib
|
||||
WINSSLLIBS = crypt32.lib
|
||||
ZLIBLIBSDLL = zdll.lib
|
||||
ZLIBLIBS = zlib.lib
|
||||
WINLIBS = ws2_32.lib bufferoverflowu.lib wldap32.lib advapi32.lib
|
||||
CFLAGS = $(CFLAGS)
|
||||
|
||||
CFGSET = FALSE
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
CFLAGS = $(CFLAGS) /DUSE_WINDOWS_SSPI /I$(WINDOWS_SDK_PATH)\include
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IPV6
|
||||
CFLAGS = $(CFLAGS) /DUSE_IPV6
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IDN
|
||||
CFLAGS = $(CFLAGS) /DUSE_WIN32_IDN /DWANT_IDN_PROTOTYPES
|
||||
!ENDIF
|
||||
|
||||
##############################################################
|
||||
# Runtime library configuration
|
||||
|
||||
RTLIB = /MD
|
||||
RTLIBD = /MDd
|
||||
|
||||
!IF "$(RTLIBCFG)" == "static"
|
||||
RTLIB = /MT
|
||||
RTLIBD = /MTd
|
||||
!ENDIF
|
||||
|
||||
|
||||
######################
|
||||
# release
|
||||
|
||||
!IF "$(CFG)" == "release"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl
|
||||
|
||||
!IF "$(CFG)" == "release-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl
|
||||
|
||||
!IF "$(CFG)" == "release-winssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINSSLLIBS) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-winssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSZLIB) $(WINSSLLIBS) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug
|
||||
|
||||
!IF "$(CFG)" == "debug"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)\out32dll
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Usage
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE" && "$(CFG)" != ""
|
||||
!MESSAGE Usage: nmake /f makefile.vc6 CFG=<config> <target>
|
||||
!MESSAGE where <config> is one of:
|
||||
!MESSAGE release - release static library
|
||||
!MESSAGE release-ssl - release static library with ssl
|
||||
!MESSAGE release-zlib - release static library with zlib
|
||||
!MESSAGE release-ssl-zlib - release static library with ssl and zlib
|
||||
!MESSAGE release-ssl-ssh2-zlib - release static library with ssl, ssh2 and zlib
|
||||
!MESSAGE release-ssl-dll - release static library with dynamic ssl
|
||||
!MESSAGE release-zlib-dll - release static library with dynamic zlib
|
||||
!MESSAGE release-ssl-dll-zlib-dll - release static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE release-dll - release dynamic library
|
||||
!MESSAGE release-dll-ssl-dll - release dynamic library with dynamic ssl
|
||||
!MESSAGE release-dll-zlib-dll - release dynamic library with dynamic zlib
|
||||
!MESSAGE release-dll-ssl-dll-zlib-dll - release dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug - debug static library
|
||||
!MESSAGE debug-ssl - debug static library with ssl
|
||||
!MESSAGE debug-zlib - debug static library with zlib
|
||||
!MESSAGE debug-ssl-zlib - debug static library with ssl and zlib
|
||||
!MESSAGE debug-ssl-ssh2-zlib - debug static library with ssl, ssh2 and zlib
|
||||
!MESSAGE debug-ssl-dll - debug static library with dynamic ssl
|
||||
!MESSAGE debug-zlib-dll - debug static library with dynamic zlib
|
||||
!MESSAGE debug-ssl-dll-zlib-dll - debug static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug-dll - debug dynamic library
|
||||
!MESSAGE debug-dll-ssl-dll - debug dynamic library with dynamic ssl
|
||||
!MESSAGE debug-dll-zlib-dll - debug dynamic library with dynamic zlib1
|
||||
!MESSAGE debug-dll-ssl-dll-zlib-dll - debug dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE <target> can be left blank in which case all is assumed
|
||||
!ERROR please choose a valid configuration "$(CFG)"
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Only the clean target can be used if a config was not provided.
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE"
|
||||
clean:
|
||||
@-erase /s *.dll 2> NUL
|
||||
@-erase /s *.exp 2> NUL
|
||||
@-erase /s *.idb 2> NUL
|
||||
@-erase /s *.lib 2> NUL
|
||||
@-erase /s *.obj 2> NUL
|
||||
@-erase /s *.pch 2> NUL
|
||||
@-erase /s *.pdb 2> NUL
|
||||
@-erase /s *.res 2> NUL
|
||||
!ELSE
|
||||
# A config was provided, so the library can be built.
|
||||
#
|
||||
X_OBJS= \
|
||||
$(DIROBJ)\amigaos.obj \
|
||||
$(DIROBJ)\asyn-ares.obj \
|
||||
$(DIROBJ)\asyn-thread.obj \
|
||||
$(DIROBJ)\axtls.obj \
|
||||
$(DIROBJ)\base64.obj \
|
||||
$(DIROBJ)\conncache.obj \
|
||||
$(DIROBJ)\connect.obj \
|
||||
$(DIROBJ)\content_encoding.obj \
|
||||
$(DIROBJ)\cookie.obj \
|
||||
$(DIROBJ)\curl_addrinfo.obj \
|
||||
$(DIROBJ)\curl_des.obj \
|
||||
$(DIROBJ)\curl_endian.obj \
|
||||
$(DIROBJ)\curl_fnmatch.obj \
|
||||
$(DIROBJ)\curl_gethostname.obj \
|
||||
$(DIROBJ)\curl_gssapi.obj \
|
||||
$(DIROBJ)\curl_memrchr.obj \
|
||||
$(DIROBJ)\curl_multibyte.obj \
|
||||
$(DIROBJ)\curl_ntlm_core.obj \
|
||||
$(DIROBJ)\curl_ntlm_wb.obj \
|
||||
$(DIROBJ)\curl_rtmp.obj \
|
||||
$(DIROBJ)\curl_sasl.obj \
|
||||
$(DIROBJ)\curl_sspi.obj \
|
||||
$(DIROBJ)\curl_threads.obj \
|
||||
$(DIROBJ)\cyassl.obj \
|
||||
$(DIROBJ)\darwinssl.obj \
|
||||
$(DIROBJ)\dict.obj \
|
||||
$(DIROBJ)\dotdot.obj \
|
||||
$(DIROBJ)\easy.obj \
|
||||
$(DIROBJ)\escape.obj \
|
||||
$(DIROBJ)\file.obj \
|
||||
$(DIROBJ)\fileinfo.obj \
|
||||
$(DIROBJ)\formdata.obj \
|
||||
$(DIROBJ)\ftp.obj \
|
||||
$(DIROBJ)\ftplistparser.obj \
|
||||
$(DIROBJ)\getenv.obj \
|
||||
$(DIROBJ)\getinfo.obj \
|
||||
$(DIROBJ)\gopher.obj \
|
||||
$(DIROBJ)\gtls.obj \
|
||||
$(DIROBJ)\hash.obj \
|
||||
$(DIROBJ)\hmac.obj \
|
||||
$(DIROBJ)\hostasyn.obj \
|
||||
$(DIROBJ)\hostcheck.obj \
|
||||
$(DIROBJ)\hostip.obj \
|
||||
$(DIROBJ)\hostip4.obj \
|
||||
$(DIROBJ)\hostip6.obj \
|
||||
$(DIROBJ)\hostsyn.obj \
|
||||
$(DIROBJ)\http.obj \
|
||||
$(DIROBJ)\http_chunks.obj \
|
||||
$(DIROBJ)\http_digest.obj \
|
||||
$(DIROBJ)\http_negotiate.obj \
|
||||
$(DIROBJ)\http_ntlm.obj \
|
||||
$(DIROBJ)\http_proxy.obj \
|
||||
$(DIROBJ)\idn_win32.obj \
|
||||
$(DIROBJ)\if2ip.obj \
|
||||
$(DIROBJ)\imap.obj \
|
||||
$(DIROBJ)\inet_ntop.obj \
|
||||
$(DIROBJ)\inet_pton.obj \
|
||||
$(DIROBJ)\krb5.obj \
|
||||
$(DIROBJ)\ldap.obj \
|
||||
$(DIROBJ)\llist.obj \
|
||||
$(DIROBJ)\md4.obj \
|
||||
$(DIROBJ)\md5.obj \
|
||||
$(DIROBJ)\memdebug.obj \
|
||||
$(DIROBJ)\mprintf.obj \
|
||||
$(DIROBJ)\multi.obj \
|
||||
$(DIROBJ)\netrc.obj \
|
||||
$(DIROBJ)\non-ascii.obj \
|
||||
$(DIROBJ)\nonblock.obj \
|
||||
$(DIROBJ)\nss.obj \
|
||||
$(DIROBJ)\openldap.obj \
|
||||
$(DIROBJ)\parsedate.obj \
|
||||
$(DIROBJ)\pingpong.obj \
|
||||
$(DIROBJ)\pipeline.obj \
|
||||
$(DIROBJ)\polarssl.obj \
|
||||
$(DIROBJ)\polarssl_threadlock.obj \
|
||||
$(DIROBJ)\pop3.obj \
|
||||
$(DIROBJ)\progress.obj \
|
||||
$(DIROBJ)\strcase.obj \
|
||||
$(DIROBJ)\rand.obj \
|
||||
$(DIROBJ)\rtsp.obj \
|
||||
$(DIROBJ)\schannel.obj \
|
||||
$(DIROBJ)\security.obj \
|
||||
$(DIROBJ)\select.obj \
|
||||
$(DIROBJ)\sendf.obj \
|
||||
$(DIROBJ)\share.obj \
|
||||
$(DIROBJ)\slist.obj \
|
||||
$(DIROBJ)\smb.obj \
|
||||
$(DIROBJ)\smtp.obj \
|
||||
$(DIROBJ)\socks.obj \
|
||||
$(DIROBJ)\socks_gssapi.obj \
|
||||
$(DIROBJ)\socks_sspi.obj \
|
||||
$(DIROBJ)\speedcheck.obj \
|
||||
$(DIROBJ)\splay.obj \
|
||||
$(DIROBJ)\ssh.obj \
|
||||
$(DIROBJ)\system_win32.obj \
|
||||
$(DIROBJ)\vauth.obj \
|
||||
$(DIROBJ)\cleartext.obj \
|
||||
$(DIROBJ)\cram.obj \
|
||||
$(DIROBJ)\digest.obj \
|
||||
$(DIROBJ)\digest_sspi.obj \
|
||||
$(DIROBJ)\krb5_gssapi.obj \
|
||||
$(DIROBJ)\krb5_sspi.obj \
|
||||
$(DIROBJ)\ntlm.obj \
|
||||
$(DIROBJ)\ntlm_sspi.obj \
|
||||
$(DIROBJ)\oauth2.obj \
|
||||
$(DIROBJ)\spnego_gssapi.obj \
|
||||
$(DIROBJ)\spnego_sspi.obj \
|
||||
$(DIROBJ)\vtls.obj \
|
||||
$(DIROBJ)\openssl.obj \
|
||||
$(DIROBJ)\strdup.obj \
|
||||
$(DIROBJ)\strerror.obj \
|
||||
$(DIROBJ)\strtok.obj \
|
||||
$(DIROBJ)\strtoofft.obj \
|
||||
$(DIROBJ)\telnet.obj \
|
||||
$(DIROBJ)\tftp.obj \
|
||||
$(DIROBJ)\timeval.obj \
|
||||
$(DIROBJ)\transfer.obj \
|
||||
$(DIROBJ)\url.obj \
|
||||
$(DIROBJ)\version.obj \
|
||||
$(DIROBJ)\warnless.obj \
|
||||
$(DIROBJ)\wildcard.obj \
|
||||
$(DIROBJ)\x509asn1.obj \
|
||||
$(RESOURCE)
|
||||
|
||||
all : $(TARGET)
|
||||
|
||||
$(TARGET): $(X_OBJS)
|
||||
$(LNK) $(LFLAGS) $(X_OBJS)
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\*.exp . /y
|
||||
-xcopy $(DIROBJ)\*.pdb . /y
|
||||
|
||||
$(X_OBJS): $(DIROBJ)
|
||||
|
||||
$(DIROBJ):
|
||||
@if not exist "$(DIROBJ)" mkdir $(DIROBJ)
|
||||
|
||||
.SUFFIXES: .c .obj .res
|
||||
|
||||
{.\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vauth\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vtls\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
debug-dll\libcurl.res \
|
||||
debug-dll-ssl-dll\libcurl.res \
|
||||
debug-dll-zlib-dll\libcurl.res \
|
||||
debug-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=1 /Fo $@ libcurl.rc
|
||||
|
||||
release-dll\libcurl.res \
|
||||
release-dll-ssl-dll\libcurl.res \
|
||||
release-dll-zlib-dll\libcurl.res \
|
||||
release-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=0 /Fo $@ libcurl.rc
|
||||
!ENDIF # End of case where a config was provided.
|
||||
@@ -1,691 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1999 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
# All files in the Makefile.vc* series are generated automatically from the
|
||||
# one made for MSVC version 6. Alas, if you want to do changes to any of the
|
||||
# files and send back to the project, edit the version six, make your diff and
|
||||
# mail curl-library.
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Makefile for building libcurl with MSVC9
|
||||
#
|
||||
# Usage: see usage message below
|
||||
# Should be invoked from \lib directory
|
||||
# Edit the paths and desired library name
|
||||
# SSL path is only required if you intend compiling
|
||||
# with SSL.
|
||||
#
|
||||
# This make file leaves the result either a .lib or .dll file
|
||||
# in the \lib directory. It should be called from the \lib
|
||||
# directory.
|
||||
#
|
||||
# An option would have been to allow the source directory to
|
||||
# be specified, but I saw no requirement.
|
||||
#
|
||||
# Another option would have been to leave the .lib and .dll
|
||||
# files in the "cfg" directory, but then the make file
|
||||
# in \src would need to be changed.
|
||||
#
|
||||
##############################################################
|
||||
|
||||
# ----------------------------------------------
|
||||
# Verify that current subdir is libcurl's 'lib'
|
||||
# ----------------------------------------------
|
||||
|
||||
!IF ! EXIST(.\curl_addrinfo.c)
|
||||
! MESSAGE Can not process this makefile from outside of libcurl's 'lib' subdirectory.
|
||||
! MESSAGE Change to libcurl's 'lib' subdirectory, and try again.
|
||||
! ERROR See previous message.
|
||||
!ENDIF
|
||||
|
||||
# ------------------------------------------------
|
||||
# Makefile.msvc.names provides libcurl file names
|
||||
# ------------------------------------------------
|
||||
|
||||
!INCLUDE ..\winbuild\Makefile.msvc.names
|
||||
|
||||
!IFNDEF OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-1.0.2a
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.5.0
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.8
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF MACHINE
|
||||
MACHINE = X86
|
||||
!ENDIF
|
||||
|
||||
# USE_WINDOWS_SSPI uses windows libraries to allow NTLM authentication
|
||||
# without an openssl installation and offers the ability to authenticate
|
||||
# using the "current logged in user". Since at least with MSVC9 the sspi.h
|
||||
# header is broken it is either required to install the Windows SDK,
|
||||
# or to fix sspi.h with adding this define at the beginning of sspi.h:
|
||||
# #define FreeCredentialHandle FreeCredentialsHandle
|
||||
#
|
||||
# If, for some reason the Windows SDK is installed but not installed
|
||||
# in the default location, you can specify WINDOWS_SDK_PATH.
|
||||
# It can be downloaded from:
|
||||
# https://msdn.microsoft.com/windows/bb980924.aspx
|
||||
|
||||
# WINDOWS_SSPI = 1
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
!IFNDEF WINDOWS_SDK_PATH
|
||||
WINDOWS_SDK_PATH = "$(PROGRAMFILES)\Microsoft SDK"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
#############################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
CCNODBG = cl.exe /O2 /DNDEBUG
|
||||
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /RTC1
|
||||
CFLAGSSSL = /DUSE_OPENSSL /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
CFLAGSWINSSL = /DUSE_SCHANNEL
|
||||
CFLAGSSSH2 = /DUSE_LIBSSH2 /DCURL_DISABLE_LDAP /DHAVE_LIBSSH2 /DHAVE_LIBSSH2_H /DLIBSSH2_WIN32 /DLIBSSH2_LIBRARY /I "$(LIBSSH2_PATH)/include"
|
||||
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
||||
CFLAGS = /I. /I../include /nologo /W3 /EHsc /DWIN32 /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
|
||||
CFLAGSLIB = /DCURL_STATICLIB
|
||||
LNKDLL = link.exe /DLL
|
||||
LNKLIB = link.exe /lib
|
||||
LFLAGS = /nologo /machine:$(MACHINE)
|
||||
SSLLIBS = libeay32.lib ssleay32.lib
|
||||
WINSSLLIBS = crypt32.lib
|
||||
ZLIBLIBSDLL = zdll.lib
|
||||
ZLIBLIBS = zlib.lib
|
||||
WINLIBS = ws2_32.lib wldap32.lib advapi32.lib
|
||||
CFLAGS = $(CFLAGS)
|
||||
|
||||
CFGSET = FALSE
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
CFLAGS = $(CFLAGS) /DUSE_WINDOWS_SSPI /I$(WINDOWS_SDK_PATH)\include
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IPV6
|
||||
CFLAGS = $(CFLAGS) /DUSE_IPV6
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IDN
|
||||
CFLAGS = $(CFLAGS) /DUSE_WIN32_IDN /DWANT_IDN_PROTOTYPES
|
||||
!ENDIF
|
||||
|
||||
##############################################################
|
||||
# Runtime library configuration
|
||||
|
||||
RTLIB = /MD
|
||||
RTLIBD = /MDd
|
||||
|
||||
!IF "$(RTLIBCFG)" == "static"
|
||||
RTLIB = /MT
|
||||
RTLIBD = /MTd
|
||||
!ENDIF
|
||||
|
||||
|
||||
######################
|
||||
# release
|
||||
|
||||
!IF "$(CFG)" == "release"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl
|
||||
|
||||
!IF "$(CFG)" == "release-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl
|
||||
|
||||
!IF "$(CFG)" == "release-winssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINSSLLIBS) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-winssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSZLIB) $(WINSSLLIBS) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug
|
||||
|
||||
!IF "$(CFG)" == "debug"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)\out32dll
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Usage
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE" && "$(CFG)" != ""
|
||||
!MESSAGE Usage: nmake /f makefile.vc9 CFG=<config> <target>
|
||||
!MESSAGE where <config> is one of:
|
||||
!MESSAGE release - release static library
|
||||
!MESSAGE release-ssl - release static library with ssl
|
||||
!MESSAGE release-zlib - release static library with zlib
|
||||
!MESSAGE release-ssl-zlib - release static library with ssl and zlib
|
||||
!MESSAGE release-ssl-ssh2-zlib - release static library with ssl, ssh2 and zlib
|
||||
!MESSAGE release-ssl-dll - release static library with dynamic ssl
|
||||
!MESSAGE release-zlib-dll - release static library with dynamic zlib
|
||||
!MESSAGE release-ssl-dll-zlib-dll - release static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE release-dll - release dynamic library
|
||||
!MESSAGE release-dll-ssl-dll - release dynamic library with dynamic ssl
|
||||
!MESSAGE release-dll-zlib-dll - release dynamic library with dynamic zlib
|
||||
!MESSAGE release-dll-ssl-dll-zlib-dll - release dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug - debug static library
|
||||
!MESSAGE debug-ssl - debug static library with ssl
|
||||
!MESSAGE debug-zlib - debug static library with zlib
|
||||
!MESSAGE debug-ssl-zlib - debug static library with ssl and zlib
|
||||
!MESSAGE debug-ssl-ssh2-zlib - debug static library with ssl, ssh2 and zlib
|
||||
!MESSAGE debug-ssl-dll - debug static library with dynamic ssl
|
||||
!MESSAGE debug-zlib-dll - debug static library with dynamic zlib
|
||||
!MESSAGE debug-ssl-dll-zlib-dll - debug static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug-dll - debug dynamic library
|
||||
!MESSAGE debug-dll-ssl-dll - debug dynamic library with dynamic ssl
|
||||
!MESSAGE debug-dll-zlib-dll - debug dynamic library with dynamic zlib1
|
||||
!MESSAGE debug-dll-ssl-dll-zlib-dll - debug dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE <target> can be left blank in which case all is assumed
|
||||
!ERROR please choose a valid configuration "$(CFG)"
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Only the clean target can be used if a config was not provided.
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE"
|
||||
clean:
|
||||
@-erase /s *.dll 2> NUL
|
||||
@-erase /s *.exp 2> NUL
|
||||
@-erase /s *.idb 2> NUL
|
||||
@-erase /s *.lib 2> NUL
|
||||
@-erase /s *.obj 2> NUL
|
||||
@-erase /s *.pch 2> NUL
|
||||
@-erase /s *.pdb 2> NUL
|
||||
@-erase /s *.res 2> NUL
|
||||
!ELSE
|
||||
# A config was provided, so the library can be built.
|
||||
#
|
||||
X_OBJS= \
|
||||
$(DIROBJ)\amigaos.obj \
|
||||
$(DIROBJ)\asyn-ares.obj \
|
||||
$(DIROBJ)\asyn-thread.obj \
|
||||
$(DIROBJ)\axtls.obj \
|
||||
$(DIROBJ)\base64.obj \
|
||||
$(DIROBJ)\conncache.obj \
|
||||
$(DIROBJ)\connect.obj \
|
||||
$(DIROBJ)\content_encoding.obj \
|
||||
$(DIROBJ)\cookie.obj \
|
||||
$(DIROBJ)\curl_addrinfo.obj \
|
||||
$(DIROBJ)\curl_des.obj \
|
||||
$(DIROBJ)\curl_endian.obj \
|
||||
$(DIROBJ)\curl_fnmatch.obj \
|
||||
$(DIROBJ)\curl_gethostname.obj \
|
||||
$(DIROBJ)\curl_gssapi.obj \
|
||||
$(DIROBJ)\curl_memrchr.obj \
|
||||
$(DIROBJ)\curl_multibyte.obj \
|
||||
$(DIROBJ)\curl_ntlm_core.obj \
|
||||
$(DIROBJ)\curl_ntlm_wb.obj \
|
||||
$(DIROBJ)\curl_rtmp.obj \
|
||||
$(DIROBJ)\curl_sasl.obj \
|
||||
$(DIROBJ)\curl_sspi.obj \
|
||||
$(DIROBJ)\curl_threads.obj \
|
||||
$(DIROBJ)\cyassl.obj \
|
||||
$(DIROBJ)\darwinssl.obj \
|
||||
$(DIROBJ)\dict.obj \
|
||||
$(DIROBJ)\dotdot.obj \
|
||||
$(DIROBJ)\easy.obj \
|
||||
$(DIROBJ)\escape.obj \
|
||||
$(DIROBJ)\file.obj \
|
||||
$(DIROBJ)\fileinfo.obj \
|
||||
$(DIROBJ)\formdata.obj \
|
||||
$(DIROBJ)\ftp.obj \
|
||||
$(DIROBJ)\ftplistparser.obj \
|
||||
$(DIROBJ)\getenv.obj \
|
||||
$(DIROBJ)\getinfo.obj \
|
||||
$(DIROBJ)\gopher.obj \
|
||||
$(DIROBJ)\gtls.obj \
|
||||
$(DIROBJ)\hash.obj \
|
||||
$(DIROBJ)\hmac.obj \
|
||||
$(DIROBJ)\hostasyn.obj \
|
||||
$(DIROBJ)\hostcheck.obj \
|
||||
$(DIROBJ)\hostip.obj \
|
||||
$(DIROBJ)\hostip4.obj \
|
||||
$(DIROBJ)\hostip6.obj \
|
||||
$(DIROBJ)\hostsyn.obj \
|
||||
$(DIROBJ)\http.obj \
|
||||
$(DIROBJ)\http_chunks.obj \
|
||||
$(DIROBJ)\http_digest.obj \
|
||||
$(DIROBJ)\http_negotiate.obj \
|
||||
$(DIROBJ)\http_ntlm.obj \
|
||||
$(DIROBJ)\http_proxy.obj \
|
||||
$(DIROBJ)\idn_win32.obj \
|
||||
$(DIROBJ)\if2ip.obj \
|
||||
$(DIROBJ)\imap.obj \
|
||||
$(DIROBJ)\inet_ntop.obj \
|
||||
$(DIROBJ)\inet_pton.obj \
|
||||
$(DIROBJ)\krb5.obj \
|
||||
$(DIROBJ)\ldap.obj \
|
||||
$(DIROBJ)\llist.obj \
|
||||
$(DIROBJ)\md4.obj \
|
||||
$(DIROBJ)\md5.obj \
|
||||
$(DIROBJ)\memdebug.obj \
|
||||
$(DIROBJ)\mprintf.obj \
|
||||
$(DIROBJ)\multi.obj \
|
||||
$(DIROBJ)\netrc.obj \
|
||||
$(DIROBJ)\non-ascii.obj \
|
||||
$(DIROBJ)\nonblock.obj \
|
||||
$(DIROBJ)\nss.obj \
|
||||
$(DIROBJ)\openldap.obj \
|
||||
$(DIROBJ)\parsedate.obj \
|
||||
$(DIROBJ)\pingpong.obj \
|
||||
$(DIROBJ)\pipeline.obj \
|
||||
$(DIROBJ)\polarssl.obj \
|
||||
$(DIROBJ)\polarssl_threadlock.obj \
|
||||
$(DIROBJ)\pop3.obj \
|
||||
$(DIROBJ)\progress.obj \
|
||||
$(DIROBJ)\strcase.obj \
|
||||
$(DIROBJ)\rand.obj \
|
||||
$(DIROBJ)\rtsp.obj \
|
||||
$(DIROBJ)\schannel.obj \
|
||||
$(DIROBJ)\security.obj \
|
||||
$(DIROBJ)\select.obj \
|
||||
$(DIROBJ)\sendf.obj \
|
||||
$(DIROBJ)\share.obj \
|
||||
$(DIROBJ)\slist.obj \
|
||||
$(DIROBJ)\smb.obj \
|
||||
$(DIROBJ)\smtp.obj \
|
||||
$(DIROBJ)\socks.obj \
|
||||
$(DIROBJ)\socks_gssapi.obj \
|
||||
$(DIROBJ)\socks_sspi.obj \
|
||||
$(DIROBJ)\speedcheck.obj \
|
||||
$(DIROBJ)\splay.obj \
|
||||
$(DIROBJ)\ssh.obj \
|
||||
$(DIROBJ)\system_win32.obj \
|
||||
$(DIROBJ)\vauth.obj \
|
||||
$(DIROBJ)\cleartext.obj \
|
||||
$(DIROBJ)\cram.obj \
|
||||
$(DIROBJ)\digest.obj \
|
||||
$(DIROBJ)\digest_sspi.obj \
|
||||
$(DIROBJ)\krb5_gssapi.obj \
|
||||
$(DIROBJ)\krb5_sspi.obj \
|
||||
$(DIROBJ)\ntlm.obj \
|
||||
$(DIROBJ)\ntlm_sspi.obj \
|
||||
$(DIROBJ)\oauth2.obj \
|
||||
$(DIROBJ)\spnego_gssapi.obj \
|
||||
$(DIROBJ)\spnego_sspi.obj \
|
||||
$(DIROBJ)\vtls.obj \
|
||||
$(DIROBJ)\openssl.obj \
|
||||
$(DIROBJ)\strdup.obj \
|
||||
$(DIROBJ)\strerror.obj \
|
||||
$(DIROBJ)\strtok.obj \
|
||||
$(DIROBJ)\strtoofft.obj \
|
||||
$(DIROBJ)\telnet.obj \
|
||||
$(DIROBJ)\tftp.obj \
|
||||
$(DIROBJ)\timeval.obj \
|
||||
$(DIROBJ)\transfer.obj \
|
||||
$(DIROBJ)\url.obj \
|
||||
$(DIROBJ)\version.obj \
|
||||
$(DIROBJ)\warnless.obj \
|
||||
$(DIROBJ)\wildcard.obj \
|
||||
$(DIROBJ)\x509asn1.obj \
|
||||
$(RESOURCE)
|
||||
|
||||
all : $(TARGET)
|
||||
|
||||
$(TARGET): $(X_OBJS)
|
||||
$(LNK) $(LFLAGS) $(X_OBJS)
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\*.exp . /y
|
||||
-xcopy $(DIROBJ)\*.pdb . /y
|
||||
|
||||
$(X_OBJS): $(DIROBJ)
|
||||
|
||||
$(DIROBJ):
|
||||
@if not exist "$(DIROBJ)" mkdir $(DIROBJ)
|
||||
|
||||
.SUFFIXES: .c .obj .res
|
||||
|
||||
{.\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vauth\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vtls\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
debug-dll\libcurl.res \
|
||||
debug-dll-ssl-dll\libcurl.res \
|
||||
debug-dll-zlib-dll\libcurl.res \
|
||||
debug-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=1 /Fo $@ libcurl.rc
|
||||
|
||||
release-dll\libcurl.res \
|
||||
release-dll-ssl-dll\libcurl.res \
|
||||
release-dll-zlib-dll\libcurl.res \
|
||||
release-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=0 /Fo $@ libcurl.rc
|
||||
!ENDIF # End of case where a config was provided.
|
||||
@@ -1,177 +0,0 @@
|
||||
#*****************************************************************************
|
||||
#
|
||||
#
|
||||
#Filename : Makefile.vxworks
|
||||
#Description: makefile to be used in order to compile libcurl for VxWoorks 6.3.
|
||||
#
|
||||
#How to use:
|
||||
# 1. Adjust environment variables at the file beginning
|
||||
# 2. Open the Command Prompt window and change directory ('cd')
|
||||
# into the 'lib' folder
|
||||
# 3. Add <CYGWIN>/bin folder to the PATH environment variable
|
||||
# For example type 'set PATH=C:/embedded/cygwin/bin;%PATH%'
|
||||
# 4. Build the library by typing 'make -f ./Makefile.vxworks'
|
||||
# As a result the libcurl.a should be created in the 'lib' folder.
|
||||
# To clean package use 'make -f ./Makefile.vxworks clean'
|
||||
#Requirements:
|
||||
# 1. WinXP machine
|
||||
# 2. Full CYGWIN installation (open source) with GNU make version
|
||||
# v3.78 or higher
|
||||
# 3. WindRiver Workbench with vxWorks 6.3 (commercial)
|
||||
#*****************************************************************************
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Environment
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
export WIND_HOME := C:/embedded/Workbench2.5.0.1
|
||||
export WIND_BASE := $(WIND_HOME)/vxworks-6.3
|
||||
export WIND_HOST_TYPE := x86-win32
|
||||
|
||||
# BUILD_TYE:= <debug>|<release> (build with debugging info or optimized)
|
||||
BUILD_TYPE := debug
|
||||
USER_CFLAGS:=
|
||||
|
||||
# directories where to seek for includes and libraries
|
||||
OPENSSL_INC := D:/libraries/openssl/openssl-0.9.8zc-vxWorks6.3/include
|
||||
OPENSSL_LIB := D:/libraries/openssl/openssl-0.9.8zc-vxWorks6.3
|
||||
ZLIB_INC := D:/libraries/zlib/zlib-1.2.8-VxWorks6.3/zlib-1.2.8
|
||||
ZLIB_LIB := D:/libraries/zlib/zlib-1.2.8-VxWorks6.3/binaries/vxworks_3.1_gnu/Debug/lib
|
||||
ARES_INC :=
|
||||
ARES_LIB :=
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Compiler
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
CC := ccppc
|
||||
AR := arppc
|
||||
LINK := ccppc
|
||||
CFLAGS := -D__GNUC__ -D__ppc__ -msoft-float -fno-builtin -mcpu=604 -mlongcall -DCPU=PPC604 -D_GNU_TOOL -Wall -W -Winline $(USER_CFLAGS)
|
||||
LDFLAGS := -nostdlib -Wl,-i -Wl,-X
|
||||
INCLUDE_FLAG := -I
|
||||
C_DEBUGFLAG := -g
|
||||
C_OPTFLAG := -O2
|
||||
COMPILE_ONLY_FLAG := -c
|
||||
OBJ_EXTENSION := .o
|
||||
CC_OBJ_OUTPUT = -o $@
|
||||
ARFLAGS := -rc
|
||||
LIBS_FLAG := -l
|
||||
LIBS_DIRFLAG:= -L
|
||||
LD_DEBUGFLAG := $(C_DEBUGFLAG)
|
||||
EXECUTE_EXTENSION := .out
|
||||
TOOL_CHAIN_BIN := $(WIND_HOME)/gnu/3.4.4-vxworks-6.3/$(WIND_HOST_TYPE)/bin/
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# Add -DINET6 if the OS kernel image was built with IPv6 support
|
||||
# CFLAGS += -DINET6
|
||||
|
||||
# Set up compiler and linker flags for debug or optimization
|
||||
ifeq ($(BUILD_TYPE), debug)
|
||||
CFLAGS += $(C_DEBUGFLAG)
|
||||
LDFLAGS += $(LD_DEBUGFLAG)
|
||||
else
|
||||
CFLAGS += $(C_OPTFLAG)
|
||||
endif
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# Main Makefile and possible sub-make files
|
||||
MAKEFILES := Makefile.vxworks
|
||||
|
||||
# List of external include directories
|
||||
#-----
|
||||
# IMPORTANT: include OPENSSL directories before system
|
||||
# in order to prevent WindRiver OpenSSL to be used.
|
||||
#-----
|
||||
INCLUDE_DIRS := ../include $(OPENSSL_INC) $(ZLIB_INC) $(ARES_INC) $(WIND_BASE)/target/h $(WIND_BASE)/target/h/wrn/coreip
|
||||
|
||||
# List of external libraries and their directories
|
||||
LIBS_LIST := .
|
||||
LIB_DIRS := .
|
||||
ifneq ($(OPENSSL_LIB), )
|
||||
LIBS_LIST += crypto ssl
|
||||
LIB_DIRS += $(OPENSSL_LIB)
|
||||
endif
|
||||
ifneq ($(ZLIB_LIB), )
|
||||
LIBS_LIST += z
|
||||
LIB_DIRS += $(ZLIB_LIB)
|
||||
endif
|
||||
ifneq ($(ARES_LIB), )
|
||||
LIBS_LIST += ares
|
||||
LIB_DIRS += $(ARES_LIB)
|
||||
endif
|
||||
|
||||
# Add include and library directories and libraries
|
||||
CFLAGS += $(INCLUDE_DIRS:%=$(INCLUDE_FLAG)%)
|
||||
LDFLAGS += $(LIB_DIRS:%=$(LIBS_DIRFLAG)%)
|
||||
|
||||
# List of targets to make for libs target
|
||||
LIBS_TARGET_LIST := libcurl.a
|
||||
|
||||
# List of execuatble applications to make in addition to libs for all target
|
||||
EXE_TARGET_LIST :=
|
||||
|
||||
# Support for echoing rules
|
||||
# If ECHORULES variable was set (for example, using 'make' command line)
|
||||
# some shell commands in the rules will be echoed
|
||||
ifneq ($(strip $(findstring $(ECHORULES), yes YES 1 true TRUE)),)
|
||||
_@_ :=
|
||||
else
|
||||
_@_ := @
|
||||
endif
|
||||
|
||||
# Directory to hold compilation intermediate files
|
||||
TMP_DIR := tmp
|
||||
|
||||
# Get sources and headers to be compiled
|
||||
include Makefile.inc
|
||||
|
||||
# List of headers
|
||||
INCLUDE_FILES := $(HHEADERS)
|
||||
INCLUDE_FILES += $(shell find ../include -name \*.h)
|
||||
|
||||
# List of sources
|
||||
OBJLIST := $(CSOURCES:%.c=$(TMP_DIR)/%$(OBJ_EXTENSION))
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
#### default rule
|
||||
# It should be first rule in this file
|
||||
.PHONY: default
|
||||
default: libcurl.a
|
||||
|
||||
#### Compiling C files
|
||||
$(TMP_DIR)/%$(OBJ_EXTENSION): %.c $(MAKEFILES)
|
||||
@echo Compiling C file $< $(ECHO_STDOUT)
|
||||
@[ -d $(@D) ] || mkdir -p $(@D)
|
||||
$(_@_) $(TOOL_CHAIN_BIN)$(CC) $(COMPILE_ONLY_FLAG) $(CFLAGS) $< $(CC_OBJ_OUTPUT)
|
||||
|
||||
#### Creating library
|
||||
$(LIBS_TARGET_LIST): $(INCLUDE_FILES) $(MAKEFILES) $(OBJLIST)
|
||||
@echo Creating library $@ $(ECHO_STDOUT)
|
||||
$(_@_) [ -d $(@D) ] || mkdir -p $(@D)
|
||||
$(_@_) rm -f $@
|
||||
$(_@_) $(TOOL_CHAIN_BIN)$(AR) $(ARFLAGS) $@ $(filter %$(OBJ_EXTENSION), $^)
|
||||
|
||||
#### Creating application
|
||||
$(EXE_TARGET_LIST): $(INCLUDE_FILES) $(MAKEFILES) $(LIBS_TARGET_LIST)
|
||||
@echo Creating application $@
|
||||
@[ -d $(@D) ] || mkdir -p $(@D)
|
||||
$(_@_) $(TOOL_CHAIN_BIN)$(LINK) $(CC_OBJ_OUTPUT) $($(@)_EXE_OBJ_LIST) $(LDFLAGS) $($(@)_EXE_LIBS_NEEDED:%=$(LIBS_FLAG)%) $(LIBS_LIST:%=$(LIBS_FLAG)%) $(USER_LIBS_LIST) $(USER_LIBS_LIST)
|
||||
|
||||
#### Master Targets
|
||||
libs: $(LIBS_TARGET_LIST)
|
||||
@echo All libs made.
|
||||
|
||||
all: $(LIBS_TARGET_LIST) $(EXE_TARGET_LIST) $(INCLUDE_TARGET_LIST)
|
||||
@echo All targets made.
|
||||
|
||||
# Clean up
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(_@_) rm -rf $(TMP_DIR)
|
||||
@echo libcurl was cleaned.
|
||||
@@ -1,73 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 2003 - 2008, Gisle Vanem <gvanem@yahoo.no>.
|
||||
# Copyright (C) 2003 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
#
|
||||
# Adapted for djgpp2 / Watt-32 / DOS
|
||||
#
|
||||
|
||||
DEPEND_PREREQ = curl_config.h
|
||||
VPATH = vtls
|
||||
TOPDIR = ..
|
||||
|
||||
include ../packages/DOS/common.dj
|
||||
include Makefile.inc
|
||||
|
||||
SOURCES = $(sort $(CSOURCES))
|
||||
OBJECTS = $(addprefix $(OBJ_DIR)/, $(notdir $(SOURCES:.c=.o)))
|
||||
|
||||
CURL_LIB = libcurl.a
|
||||
|
||||
# NOTE: if ../include/curl/curlbuild.h is missing, you're probably building
|
||||
# this from a git checkout and then you need to run buildconf.bat first.
|
||||
|
||||
all: $(OBJ_DIR) curl_config.h $(CURL_LIB)
|
||||
|
||||
$(CURL_LIB): $(OBJECTS)
|
||||
ar rs $@ $?
|
||||
|
||||
curl_config.h: config-dos.h
|
||||
$(COPY) $^ $@
|
||||
|
||||
# clean generated files
|
||||
#
|
||||
genclean:
|
||||
- $(DELETE) curl_config.h
|
||||
|
||||
# clean object files and subdir
|
||||
#
|
||||
objclean: genclean
|
||||
- $(DELETE) $(OBJ_DIR)$(DS)*.o
|
||||
- $(RMDIR) $(OBJ_DIR)
|
||||
|
||||
# clean without removing built library
|
||||
#
|
||||
clean: objclean
|
||||
- $(DELETE) depend.dj
|
||||
|
||||
# clean everything
|
||||
#
|
||||
realclean vclean: clean
|
||||
- $(DELETE) $(CURL_LIB)
|
||||
|
||||
-include depend.dj
|
||||
|
||||
@@ -1,305 +0,0 @@
|
||||
/*
|
||||
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
|
||||
* MD4 Message-Digest Algorithm (RFC 1320).
|
||||
*
|
||||
* Homepage:
|
||||
http://openwall.info/wiki/people/solar/software/public-domain-source-code/md4
|
||||
*
|
||||
* Author:
|
||||
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
|
||||
*
|
||||
* This software was written by Alexander Peslyak in 2001. No copyright is
|
||||
* claimed, and the software is hereby placed in the public domain. In case
|
||||
* this attempt to disclaim copyright and place the software in the public
|
||||
* domain is deemed null and void, then the software is Copyright (c) 2001
|
||||
* Alexander Peslyak and it is hereby released to the general public under the
|
||||
* following terms:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted.
|
||||
*
|
||||
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
*
|
||||
* (This is a heavily cut-down "BSD license".)
|
||||
*
|
||||
* This differs from Colin Plumb's older public domain implementation in that
|
||||
* no exactly 32-bit integer data type is required (any 32-bit or wider
|
||||
* unsigned integer data type will do), there's no compile-time endianness
|
||||
* configuration, and the function prototypes match OpenSSL's. No code from
|
||||
* Colin Plumb's implementation has been reused; this comment merely compares
|
||||
* the properties of the two independent implementations.
|
||||
*
|
||||
* The primary goals of this implementation are portability and ease of use.
|
||||
* It is meant to be fast, but not as fast as possible. Some known
|
||||
* optimizations are not included to reduce source code size and avoid
|
||||
* compile-time configuration.
|
||||
*/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
/* NSS and OS/400 crypto library do not provide the MD4 hash algorithm, so
|
||||
* that we have a local implementation of it */
|
||||
#if defined(USE_NSS) || defined(USE_OS400CRYPTO)
|
||||
|
||||
#include "curl_md4.h"
|
||||
#include "warnless.h"
|
||||
|
||||
#ifndef HAVE_OPENSSL
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Any 32-bit or wider unsigned integer data type will do */
|
||||
typedef unsigned int MD4_u32plus;
|
||||
|
||||
typedef struct {
|
||||
MD4_u32plus lo, hi;
|
||||
MD4_u32plus a, b, c, d;
|
||||
unsigned char buffer[64];
|
||||
MD4_u32plus block[16];
|
||||
} MD4_CTX;
|
||||
|
||||
static void MD4_Init(MD4_CTX *ctx);
|
||||
static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size);
|
||||
static void MD4_Final(unsigned char *result, MD4_CTX *ctx);
|
||||
|
||||
/*
|
||||
* The basic MD4 functions.
|
||||
*
|
||||
* F and G are optimized compared to their RFC 1320 definitions, with the
|
||||
* optimization for F borrowed from Colin Plumb's MD5 implementation.
|
||||
*/
|
||||
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||
#define G(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
|
||||
/*
|
||||
* The MD4 transformation for all three rounds.
|
||||
*/
|
||||
#define STEP(f, a, b, c, d, x, s) \
|
||||
(a) += f((b), (c), (d)) + (x); \
|
||||
(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s))));
|
||||
|
||||
/*
|
||||
* SET reads 4 input bytes in little-endian byte order and stores them
|
||||
* in a properly aligned word in host byte order.
|
||||
*
|
||||
* The check for little-endian architectures that tolerate unaligned
|
||||
* memory accesses is just an optimization. Nothing will break if it
|
||||
* doesn't work.
|
||||
*/
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
|
||||
#define SET(n) \
|
||||
(*(MD4_u32plus *)&ptr[(n) * 4])
|
||||
#define GET(n) \
|
||||
SET(n)
|
||||
#else
|
||||
#define SET(n) \
|
||||
(ctx->block[(n)] = \
|
||||
(MD4_u32plus)ptr[(n) * 4] | \
|
||||
((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \
|
||||
((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \
|
||||
((MD4_u32plus)ptr[(n) * 4 + 3] << 24))
|
||||
#define GET(n) \
|
||||
(ctx->block[(n)])
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This processes one or more 64-byte data blocks, but does NOT update
|
||||
* the bit counters. There are no alignment requirements.
|
||||
*/
|
||||
static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
|
||||
{
|
||||
const unsigned char *ptr;
|
||||
MD4_u32plus a, b, c, d;
|
||||
MD4_u32plus saved_a, saved_b, saved_c, saved_d;
|
||||
|
||||
ptr = (const unsigned char *)data;
|
||||
|
||||
a = ctx->a;
|
||||
b = ctx->b;
|
||||
c = ctx->c;
|
||||
d = ctx->d;
|
||||
|
||||
do {
|
||||
saved_a = a;
|
||||
saved_b = b;
|
||||
saved_c = c;
|
||||
saved_d = d;
|
||||
|
||||
/* Round 1 */
|
||||
STEP(F, a, b, c, d, SET(0), 3)
|
||||
STEP(F, d, a, b, c, SET(1), 7)
|
||||
STEP(F, c, d, a, b, SET(2), 11)
|
||||
STEP(F, b, c, d, a, SET(3), 19)
|
||||
STEP(F, a, b, c, d, SET(4), 3)
|
||||
STEP(F, d, a, b, c, SET(5), 7)
|
||||
STEP(F, c, d, a, b, SET(6), 11)
|
||||
STEP(F, b, c, d, a, SET(7), 19)
|
||||
STEP(F, a, b, c, d, SET(8), 3)
|
||||
STEP(F, d, a, b, c, SET(9), 7)
|
||||
STEP(F, c, d, a, b, SET(10), 11)
|
||||
STEP(F, b, c, d, a, SET(11), 19)
|
||||
STEP(F, a, b, c, d, SET(12), 3)
|
||||
STEP(F, d, a, b, c, SET(13), 7)
|
||||
STEP(F, c, d, a, b, SET(14), 11)
|
||||
STEP(F, b, c, d, a, SET(15), 19)
|
||||
|
||||
/* Round 2 */
|
||||
STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3)
|
||||
STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5)
|
||||
STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9)
|
||||
STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13)
|
||||
STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3)
|
||||
STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5)
|
||||
STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9)
|
||||
STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13)
|
||||
STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3)
|
||||
STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5)
|
||||
STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9)
|
||||
STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13)
|
||||
STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3)
|
||||
STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5)
|
||||
STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9)
|
||||
STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13)
|
||||
|
||||
/* Round 3 */
|
||||
STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3)
|
||||
STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9)
|
||||
STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11)
|
||||
STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15)
|
||||
STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3)
|
||||
STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9)
|
||||
STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11)
|
||||
STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15)
|
||||
STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3)
|
||||
STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9)
|
||||
STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11)
|
||||
STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15)
|
||||
STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3)
|
||||
STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9)
|
||||
STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11)
|
||||
STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15)
|
||||
|
||||
a += saved_a;
|
||||
b += saved_b;
|
||||
c += saved_c;
|
||||
d += saved_d;
|
||||
|
||||
ptr += 64;
|
||||
} while(size -= 64);
|
||||
|
||||
ctx->a = a;
|
||||
ctx->b = b;
|
||||
ctx->c = c;
|
||||
ctx->d = d;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void MD4_Init(MD4_CTX *ctx)
|
||||
{
|
||||
ctx->a = 0x67452301;
|
||||
ctx->b = 0xefcdab89;
|
||||
ctx->c = 0x98badcfe;
|
||||
ctx->d = 0x10325476;
|
||||
|
||||
ctx->lo = 0;
|
||||
ctx->hi = 0;
|
||||
}
|
||||
|
||||
static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
|
||||
{
|
||||
MD4_u32plus saved_lo;
|
||||
unsigned long used, available;
|
||||
|
||||
saved_lo = ctx->lo;
|
||||
ctx->lo = (saved_lo + size) & 0x1fffffff;
|
||||
if(ctx->lo < saved_lo)
|
||||
ctx->hi++;
|
||||
ctx->hi += (MD4_u32plus)size >> 29;
|
||||
|
||||
used = saved_lo & 0x3f;
|
||||
|
||||
if(used) {
|
||||
available = 64 - used;
|
||||
|
||||
if(size < available) {
|
||||
memcpy(&ctx->buffer[used], data, size);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&ctx->buffer[used], data, available);
|
||||
data = (const unsigned char *)data + available;
|
||||
size -= available;
|
||||
body(ctx, ctx->buffer, 64);
|
||||
}
|
||||
|
||||
if(size >= 64) {
|
||||
data = body(ctx, data, size & ~(unsigned long)0x3f);
|
||||
size &= 0x3f;
|
||||
}
|
||||
|
||||
memcpy(ctx->buffer, data, size);
|
||||
}
|
||||
|
||||
static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
|
||||
{
|
||||
unsigned long used, available;
|
||||
|
||||
used = ctx->lo & 0x3f;
|
||||
|
||||
ctx->buffer[used++] = 0x80;
|
||||
|
||||
available = 64 - used;
|
||||
|
||||
if(available < 8) {
|
||||
memset(&ctx->buffer[used], 0, available);
|
||||
body(ctx, ctx->buffer, 64);
|
||||
used = 0;
|
||||
available = 64;
|
||||
}
|
||||
|
||||
memset(&ctx->buffer[used], 0, available - 8);
|
||||
|
||||
ctx->lo <<= 3;
|
||||
ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
|
||||
ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
|
||||
ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
|
||||
ctx->buffer[59] = curlx_ultouc((ctx->lo >> 24)&0xff);
|
||||
ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
|
||||
ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
|
||||
ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
|
||||
ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
|
||||
|
||||
body(ctx, ctx->buffer, 64);
|
||||
|
||||
result[0] = curlx_ultouc((ctx->a)&0xff);
|
||||
result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
|
||||
result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
|
||||
result[3] = curlx_ultouc(ctx->a >> 24);
|
||||
result[4] = curlx_ultouc((ctx->b)&0xff);
|
||||
result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
|
||||
result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
|
||||
result[7] = curlx_ultouc(ctx->b >> 24);
|
||||
result[8] = curlx_ultouc((ctx->c)&0xff);
|
||||
result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
|
||||
result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
|
||||
result[11] = curlx_ultouc(ctx->c >> 24);
|
||||
result[12] = curlx_ultouc((ctx->d)&0xff);
|
||||
result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
|
||||
result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
|
||||
result[15] = curlx_ultouc(ctx->d >> 24);
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len)
|
||||
{
|
||||
MD4_CTX ctx;
|
||||
MD4_Init(&ctx);
|
||||
MD4_Update(&ctx, input, curlx_uztoui(len));
|
||||
MD4_Final(output, &ctx);
|
||||
}
|
||||
#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) */
|
||||
@@ -1,563 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "curl_md5.h"
|
||||
#include "curl_hmac.h"
|
||||
#include "warnless.h"
|
||||
|
||||
#if defined(USE_GNUTLS_NETTLE)
|
||||
|
||||
#include <nettle/md5.h>
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
typedef struct md5_ctx MD5_CTX;
|
||||
|
||||
static void MD5_Init(MD5_CTX * ctx)
|
||||
{
|
||||
md5_init(ctx);
|
||||
}
|
||||
|
||||
static void MD5_Update(MD5_CTX * ctx,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
md5_update(ctx, inputLen, input);
|
||||
}
|
||||
|
||||
static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
|
||||
{
|
||||
md5_digest(ctx, 16, digest);
|
||||
}
|
||||
|
||||
#elif defined(USE_GNUTLS)
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
typedef gcry_md_hd_t MD5_CTX;
|
||||
|
||||
static void MD5_Init(MD5_CTX * ctx)
|
||||
{
|
||||
gcry_md_open(ctx, GCRY_MD_MD5, 0);
|
||||
}
|
||||
|
||||
static void MD5_Update(MD5_CTX * ctx,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
gcry_md_write(*ctx, input, inputLen);
|
||||
}
|
||||
|
||||
static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
|
||||
{
|
||||
memcpy(digest, gcry_md_read(*ctx, 0), 16);
|
||||
gcry_md_close(*ctx);
|
||||
}
|
||||
|
||||
#elif defined(USE_OPENSSL)
|
||||
/* When OpenSSL is available we use the MD5-function from OpenSSL */
|
||||
#include <openssl/md5.h>
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
|
||||
(__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
|
||||
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
|
||||
(__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
|
||||
|
||||
/* For Apple operating systems: CommonCrypto has the functions we need.
|
||||
These functions are available on Tiger and later, as well as iOS 2.0
|
||||
and later. If you're building for an older cat, well, sorry.
|
||||
|
||||
Declaring the functions as static like this seems to be a bit more
|
||||
reliable than defining COMMON_DIGEST_FOR_OPENSSL on older cats. */
|
||||
# include <CommonCrypto/CommonDigest.h>
|
||||
# define MD5_CTX CC_MD5_CTX
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
static void MD5_Init(MD5_CTX *ctx)
|
||||
{
|
||||
CC_MD5_Init(ctx);
|
||||
}
|
||||
|
||||
static void MD5_Update(MD5_CTX *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
CC_MD5_Update(ctx, input, inputLen);
|
||||
}
|
||||
|
||||
static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
|
||||
{
|
||||
CC_MD5_Final(digest, ctx);
|
||||
}
|
||||
|
||||
#elif defined(_WIN32) && !defined(CURL_WINDOWS_APP)
|
||||
|
||||
#include <wincrypt.h>
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
typedef struct {
|
||||
HCRYPTPROV hCryptProv;
|
||||
HCRYPTHASH hHash;
|
||||
} MD5_CTX;
|
||||
|
||||
static void MD5_Init(MD5_CTX *ctx)
|
||||
{
|
||||
if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
|
||||
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
|
||||
CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
|
||||
}
|
||||
}
|
||||
|
||||
static void MD5_Update(MD5_CTX *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
|
||||
}
|
||||
|
||||
static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
|
||||
{
|
||||
unsigned long length = 0;
|
||||
CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
|
||||
if(length == 16)
|
||||
CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
|
||||
if(ctx->hHash)
|
||||
CryptDestroyHash(ctx->hHash);
|
||||
if(ctx->hCryptProv)
|
||||
CryptReleaseContext(ctx->hCryptProv, 0);
|
||||
}
|
||||
|
||||
#elif defined(USE_AXTLS)
|
||||
#include <axTLS/config.h>
|
||||
#include <axTLS/os_int.h>
|
||||
#include <axTLS/crypto.h>
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
#else
|
||||
/* When no other crypto library is available we use this code segment */
|
||||
/*
|
||||
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
|
||||
* MD5 Message-Digest Algorithm (RFC 1321).
|
||||
*
|
||||
* Homepage:
|
||||
http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
|
||||
*
|
||||
* Author:
|
||||
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
|
||||
*
|
||||
* This software was written by Alexander Peslyak in 2001. No copyright is
|
||||
* claimed, and the software is hereby placed in the public domain.
|
||||
* In case this attempt to disclaim copyright and place the software in the
|
||||
* public domain is deemed null and void, then the software is
|
||||
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
|
||||
* general public under the following terms:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted.
|
||||
*
|
||||
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
*
|
||||
* (This is a heavily cut-down "BSD license".)
|
||||
*
|
||||
* This differs from Colin Plumb's older public domain implementation in that
|
||||
* no exactly 32-bit integer data type is required (any 32-bit or wider
|
||||
* unsigned integer data type will do), there's no compile-time endianness
|
||||
* configuration, and the function prototypes match OpenSSL's. No code from
|
||||
* Colin Plumb's implementation has been reused; this comment merely compares
|
||||
* the properties of the two independent implementations.
|
||||
*
|
||||
* The primary goals of this implementation are portability and ease of use.
|
||||
* It is meant to be fast, but not as fast as possible. Some known
|
||||
* optimizations are not included to reduce source code size and avoid
|
||||
* compile-time configuration.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* Any 32-bit or wider unsigned integer data type will do */
|
||||
typedef unsigned int MD5_u32plus;
|
||||
|
||||
typedef struct {
|
||||
MD5_u32plus lo, hi;
|
||||
MD5_u32plus a, b, c, d;
|
||||
unsigned char buffer[64];
|
||||
MD5_u32plus block[16];
|
||||
} MD5_CTX;
|
||||
|
||||
static void MD5_Init(MD5_CTX *ctx);
|
||||
static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
|
||||
static void MD5_Final(unsigned char *result, MD5_CTX *ctx);
|
||||
|
||||
/*
|
||||
* The basic MD5 functions.
|
||||
*
|
||||
* F and G are optimized compared to their RFC 1321 definitions for
|
||||
* architectures that lack an AND-NOT instruction, just like in Colin Plumb's
|
||||
* implementation.
|
||||
*/
|
||||
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||
#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
|
||||
#define H(x, y, z) (((x) ^ (y)) ^ (z))
|
||||
#define H2(x, y, z) ((x) ^ ((y) ^ (z)))
|
||||
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
|
||||
|
||||
/*
|
||||
* The MD5 transformation for all four rounds.
|
||||
*/
|
||||
#define STEP(f, a, b, c, d, x, t, s) \
|
||||
(a) += f((b), (c), (d)) + (x) + (t); \
|
||||
(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
|
||||
(a) += (b);
|
||||
|
||||
/*
|
||||
* SET reads 4 input bytes in little-endian byte order and stores them
|
||||
* in a properly aligned word in host byte order.
|
||||
*
|
||||
* The check for little-endian architectures that tolerate unaligned
|
||||
* memory accesses is just an optimization. Nothing will break if it
|
||||
* doesn't work.
|
||||
*/
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
|
||||
#define SET(n) \
|
||||
(*(MD5_u32plus *)&ptr[(n) * 4])
|
||||
#define GET(n) \
|
||||
SET(n)
|
||||
#else
|
||||
#define SET(n) \
|
||||
(ctx->block[(n)] = \
|
||||
(MD5_u32plus)ptr[(n) * 4] | \
|
||||
((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
|
||||
((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
|
||||
((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
|
||||
#define GET(n) \
|
||||
(ctx->block[(n)])
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This processes one or more 64-byte data blocks, but does NOT update
|
||||
* the bit counters. There are no alignment requirements.
|
||||
*/
|
||||
static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||
{
|
||||
const unsigned char *ptr;
|
||||
MD5_u32plus a, b, c, d;
|
||||
MD5_u32plus saved_a, saved_b, saved_c, saved_d;
|
||||
|
||||
ptr = (const unsigned char *)data;
|
||||
|
||||
a = ctx->a;
|
||||
b = ctx->b;
|
||||
c = ctx->c;
|
||||
d = ctx->d;
|
||||
|
||||
do {
|
||||
saved_a = a;
|
||||
saved_b = b;
|
||||
saved_c = c;
|
||||
saved_d = d;
|
||||
|
||||
/* Round 1 */
|
||||
STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
|
||||
STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
|
||||
STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
|
||||
STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
|
||||
STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
|
||||
STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
|
||||
STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
|
||||
STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
|
||||
STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
|
||||
STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
|
||||
STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
|
||||
STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
|
||||
STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
|
||||
STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
|
||||
STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
|
||||
STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
|
||||
|
||||
/* Round 2 */
|
||||
STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
|
||||
STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
|
||||
STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
|
||||
STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
|
||||
STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
|
||||
STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
|
||||
STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
|
||||
STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
|
||||
STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
|
||||
STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
|
||||
STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
|
||||
STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
|
||||
STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
|
||||
STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
|
||||
STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
|
||||
STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
|
||||
|
||||
/* Round 3 */
|
||||
STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
|
||||
STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
|
||||
STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
|
||||
STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
|
||||
STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
|
||||
STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
|
||||
STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
|
||||
STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
|
||||
STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
|
||||
STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
|
||||
STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
|
||||
STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
|
||||
STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
|
||||
STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
|
||||
STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
|
||||
STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
|
||||
|
||||
/* Round 4 */
|
||||
STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
|
||||
STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
|
||||
STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
|
||||
STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
|
||||
STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
|
||||
STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
|
||||
STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
|
||||
STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
|
||||
STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
|
||||
STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
|
||||
STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
|
||||
STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
|
||||
STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
|
||||
STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
|
||||
STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
|
||||
STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
|
||||
|
||||
a += saved_a;
|
||||
b += saved_b;
|
||||
c += saved_c;
|
||||
d += saved_d;
|
||||
|
||||
ptr += 64;
|
||||
} while(size -= 64);
|
||||
|
||||
ctx->a = a;
|
||||
ctx->b = b;
|
||||
ctx->c = c;
|
||||
ctx->d = d;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void MD5_Init(MD5_CTX *ctx)
|
||||
{
|
||||
ctx->a = 0x67452301;
|
||||
ctx->b = 0xefcdab89;
|
||||
ctx->c = 0x98badcfe;
|
||||
ctx->d = 0x10325476;
|
||||
|
||||
ctx->lo = 0;
|
||||
ctx->hi = 0;
|
||||
}
|
||||
|
||||
static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||
{
|
||||
MD5_u32plus saved_lo;
|
||||
unsigned long used, available;
|
||||
|
||||
saved_lo = ctx->lo;
|
||||
ctx->lo = (saved_lo + size) & 0x1fffffff;
|
||||
if(ctx->lo < saved_lo)
|
||||
ctx->hi++;
|
||||
ctx->hi += (MD5_u32plus)size >> 29;
|
||||
|
||||
used = saved_lo & 0x3f;
|
||||
|
||||
if(used) {
|
||||
available = 64 - used;
|
||||
|
||||
if(size < available) {
|
||||
memcpy(&ctx->buffer[used], data, size);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&ctx->buffer[used], data, available);
|
||||
data = (const unsigned char *)data + available;
|
||||
size -= available;
|
||||
body(ctx, ctx->buffer, 64);
|
||||
}
|
||||
|
||||
if(size >= 64) {
|
||||
data = body(ctx, data, size & ~(unsigned long)0x3f);
|
||||
size &= 0x3f;
|
||||
}
|
||||
|
||||
memcpy(ctx->buffer, data, size);
|
||||
}
|
||||
|
||||
static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
|
||||
{
|
||||
unsigned long used, available;
|
||||
|
||||
used = ctx->lo & 0x3f;
|
||||
|
||||
ctx->buffer[used++] = 0x80;
|
||||
|
||||
available = 64 - used;
|
||||
|
||||
if(available < 8) {
|
||||
memset(&ctx->buffer[used], 0, available);
|
||||
body(ctx, ctx->buffer, 64);
|
||||
used = 0;
|
||||
available = 64;
|
||||
}
|
||||
|
||||
memset(&ctx->buffer[used], 0, available - 8);
|
||||
|
||||
ctx->lo <<= 3;
|
||||
ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
|
||||
ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
|
||||
ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
|
||||
ctx->buffer[59] = curlx_ultouc(ctx->lo >> 24);
|
||||
ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
|
||||
ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
|
||||
ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
|
||||
ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
|
||||
|
||||
body(ctx, ctx->buffer, 64);
|
||||
|
||||
result[0] = curlx_ultouc((ctx->a)&0xff);
|
||||
result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
|
||||
result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
|
||||
result[3] = curlx_ultouc(ctx->a >> 24);
|
||||
result[4] = curlx_ultouc((ctx->b)&0xff);
|
||||
result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
|
||||
result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
|
||||
result[7] = curlx_ultouc(ctx->b >> 24);
|
||||
result[8] = curlx_ultouc((ctx->c)&0xff);
|
||||
result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
|
||||
result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
|
||||
result[11] = curlx_ultouc(ctx->c >> 24);
|
||||
result[12] = curlx_ultouc((ctx->d)&0xff);
|
||||
result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
|
||||
result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
|
||||
result[15] = curlx_ultouc(ctx->d >> 24);
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
#endif /* CRYPTO LIBS */
|
||||
|
||||
const HMAC_params Curl_HMAC_MD5[] = {
|
||||
{
|
||||
(HMAC_hinit_func) MD5_Init, /* Hash initialization function. */
|
||||
(HMAC_hupdate_func) MD5_Update, /* Hash update function. */
|
||||
(HMAC_hfinal_func) MD5_Final, /* Hash computation end function. */
|
||||
sizeof(MD5_CTX), /* Size of hash context structure. */
|
||||
64, /* Maximum key length. */
|
||||
16 /* Result size. */
|
||||
}
|
||||
};
|
||||
|
||||
const MD5_params Curl_DIGEST_MD5[] = {
|
||||
{
|
||||
(Curl_MD5_init_func) MD5_Init, /* Digest initialization function */
|
||||
(Curl_MD5_update_func) MD5_Update, /* Digest update function */
|
||||
(Curl_MD5_final_func) MD5_Final, /* Digest computation end function */
|
||||
sizeof(MD5_CTX), /* Size of digest context struct */
|
||||
16 /* Result size */
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* @unittest: 1601
|
||||
*/
|
||||
void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
|
||||
const unsigned char *input)
|
||||
{
|
||||
MD5_CTX ctx;
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, input, curlx_uztoui(strlen((char *)input)));
|
||||
MD5_Final(outbuffer, &ctx);
|
||||
}
|
||||
|
||||
MD5_context *Curl_MD5_init(const MD5_params *md5params)
|
||||
{
|
||||
MD5_context *ctxt;
|
||||
|
||||
/* Create MD5 context */
|
||||
ctxt = malloc(sizeof *ctxt);
|
||||
|
||||
if(!ctxt)
|
||||
return ctxt;
|
||||
|
||||
ctxt->md5_hashctx = malloc(md5params->md5_ctxtsize);
|
||||
|
||||
if(!ctxt->md5_hashctx) {
|
||||
free(ctxt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctxt->md5_hash = md5params;
|
||||
|
||||
(*md5params->md5_init_func)(ctxt->md5_hashctx);
|
||||
|
||||
return ctxt;
|
||||
}
|
||||
|
||||
int Curl_MD5_update(MD5_context *context,
|
||||
const unsigned char *data,
|
||||
unsigned int len)
|
||||
{
|
||||
(*context->md5_hash->md5_update_func)(context->md5_hashctx, data, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Curl_MD5_final(MD5_context *context, unsigned char *result)
|
||||
{
|
||||
(*context->md5_hash->md5_final_func)(result, context->md5_hashctx);
|
||||
|
||||
free(context->md5_hashctx);
|
||||
free(context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CURL_DISABLE_CRYPTO_AUTH */
|
||||
@@ -1,488 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "urldata.h"
|
||||
|
||||
#define MEMDEBUG_NODEFINES /* don't redefine the standard functions */
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifndef HAVE_ASSERT_H
|
||||
# define assert(x) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Until 2011-08-17 libcurl's Memory Tracking feature also performed
|
||||
* automatic malloc and free filling operations using 0xA5 and 0x13
|
||||
* values. Our own preinitialization of dynamically allocated memory
|
||||
* might be useful when not using third party memory debuggers, but
|
||||
* on the other hand this would fool memory debuggers into thinking
|
||||
* that all dynamically allocated memory is properly initialized.
|
||||
*
|
||||
* As a default setting, libcurl's Memory Tracking feature no longer
|
||||
* performs preinitialization of dynamically allocated memory on its
|
||||
* own. If you know what you are doing, and really want to retain old
|
||||
* behavior, you can achieve this compiling with preprocessor symbols
|
||||
* CURL_MT_MALLOC_FILL and CURL_MT_FREE_FILL defined with appropriate
|
||||
* values.
|
||||
*/
|
||||
|
||||
#ifdef CURL_MT_MALLOC_FILL
|
||||
# if (CURL_MT_MALLOC_FILL < 0) || (CURL_MT_MALLOC_FILL > 0xff)
|
||||
# error "invalid CURL_MT_MALLOC_FILL or out of range"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CURL_MT_FREE_FILL
|
||||
# if (CURL_MT_FREE_FILL < 0) || (CURL_MT_FREE_FILL > 0xff)
|
||||
# error "invalid CURL_MT_FREE_FILL or out of range"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(CURL_MT_MALLOC_FILL) && defined(CURL_MT_FREE_FILL)
|
||||
# if (CURL_MT_MALLOC_FILL == CURL_MT_FREE_FILL)
|
||||
# error "CURL_MT_MALLOC_FILL same as CURL_MT_FREE_FILL"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CURL_MT_MALLOC_FILL
|
||||
# define mt_malloc_fill(buf,len) memset((buf), CURL_MT_MALLOC_FILL, (len))
|
||||
#else
|
||||
# define mt_malloc_fill(buf,len) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
#ifdef CURL_MT_FREE_FILL
|
||||
# define mt_free_fill(buf,len) memset((buf), CURL_MT_FREE_FILL, (len))
|
||||
#else
|
||||
# define mt_free_fill(buf,len) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
struct memdebug {
|
||||
size_t size;
|
||||
union {
|
||||
curl_off_t o;
|
||||
double d;
|
||||
void *p;
|
||||
} mem[1];
|
||||
/* I'm hoping this is the thing with the strictest alignment
|
||||
* requirements. That also means we waste some space :-( */
|
||||
};
|
||||
|
||||
/*
|
||||
* Note that these debug functions are very simple and they are meant to
|
||||
* remain so. For advanced analysis, record a log file and write perl scripts
|
||||
* to analyze them!
|
||||
*
|
||||
* Don't use these with multithreaded test programs!
|
||||
*/
|
||||
|
||||
#define logfile curl_debuglogfile
|
||||
FILE *curl_debuglogfile = NULL;
|
||||
static bool memlimit = FALSE; /* enable memory limit */
|
||||
static long memsize = 0; /* set number of mallocs allowed */
|
||||
|
||||
/* this sets the log file name */
|
||||
void curl_memdebug(const char *logname)
|
||||
{
|
||||
if(!logfile) {
|
||||
if(logname && *logname)
|
||||
logfile = fopen(logname, FOPEN_WRITETEXT);
|
||||
else
|
||||
logfile = stderr;
|
||||
#ifdef MEMDEBUG_LOG_SYNC
|
||||
/* Flush the log file after every line so the log isn't lost in a crash */
|
||||
setbuf(logfile, (char *)NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* This function sets the number of malloc() calls that should return
|
||||
successfully! */
|
||||
void curl_memlimit(long limit)
|
||||
{
|
||||
if(!memlimit) {
|
||||
memlimit = TRUE;
|
||||
memsize = limit;
|
||||
}
|
||||
}
|
||||
|
||||
/* returns TRUE if this isn't allowed! */
|
||||
static bool countcheck(const char *func, int line, const char *source)
|
||||
{
|
||||
/* if source is NULL, then the call is made internally and this check
|
||||
should not be made */
|
||||
if(memlimit && source) {
|
||||
if(!memsize) {
|
||||
if(source) {
|
||||
/* log to file */
|
||||
curl_memlog("LIMIT %s:%d %s reached memlimit\n",
|
||||
source, line, func);
|
||||
/* log to stderr also */
|
||||
fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n",
|
||||
source, line, func);
|
||||
fflush(logfile); /* because it might crash now */
|
||||
}
|
||||
SET_ERRNO(ENOMEM);
|
||||
return TRUE; /* RETURN ERROR! */
|
||||
}
|
||||
else
|
||||
memsize--; /* countdown */
|
||||
|
||||
|
||||
}
|
||||
|
||||
return FALSE; /* allow this */
|
||||
}
|
||||
|
||||
void *curl_domalloc(size_t wantedsize, int line, const char *source)
|
||||
{
|
||||
struct memdebug *mem;
|
||||
size_t size;
|
||||
|
||||
assert(wantedsize != 0);
|
||||
|
||||
if(countcheck("malloc", line, source))
|
||||
return NULL;
|
||||
|
||||
/* alloc at least 64 bytes */
|
||||
size = sizeof(struct memdebug)+wantedsize;
|
||||
|
||||
mem = (Curl_cmalloc)(size);
|
||||
if(mem) {
|
||||
/* fill memory with junk */
|
||||
mt_malloc_fill(mem->mem, wantedsize);
|
||||
mem->size = wantedsize;
|
||||
}
|
||||
|
||||
if(source)
|
||||
curl_memlog("MEM %s:%d malloc(%zu) = %p\n",
|
||||
source, line, wantedsize,
|
||||
mem ? (void *)mem->mem : (void *)0);
|
||||
|
||||
return (mem ? mem->mem : NULL);
|
||||
}
|
||||
|
||||
void *curl_docalloc(size_t wanted_elements, size_t wanted_size,
|
||||
int line, const char *source)
|
||||
{
|
||||
struct memdebug *mem;
|
||||
size_t size, user_size;
|
||||
|
||||
assert(wanted_elements != 0);
|
||||
assert(wanted_size != 0);
|
||||
|
||||
if(countcheck("calloc", line, source))
|
||||
return NULL;
|
||||
|
||||
/* alloc at least 64 bytes */
|
||||
user_size = wanted_size * wanted_elements;
|
||||
size = sizeof(struct memdebug) + user_size;
|
||||
|
||||
mem = (Curl_ccalloc)(1, size);
|
||||
if(mem)
|
||||
mem->size = user_size;
|
||||
|
||||
if(source)
|
||||
curl_memlog("MEM %s:%d calloc(%zu,%zu) = %p\n",
|
||||
source, line, wanted_elements, wanted_size,
|
||||
mem ? (void *)mem->mem : (void *)0);
|
||||
|
||||
return (mem ? mem->mem : NULL);
|
||||
}
|
||||
|
||||
char *curl_dostrdup(const char *str, int line, const char *source)
|
||||
{
|
||||
char *mem;
|
||||
size_t len;
|
||||
|
||||
assert(str != NULL);
|
||||
|
||||
if(countcheck("strdup", line, source))
|
||||
return NULL;
|
||||
|
||||
len=strlen(str)+1;
|
||||
|
||||
mem=curl_domalloc(len, 0, NULL); /* NULL prevents logging */
|
||||
if(mem)
|
||||
memcpy(mem, str, len);
|
||||
|
||||
if(source)
|
||||
curl_memlog("MEM %s:%d strdup(%p) (%zu) = %p\n",
|
||||
source, line, (void *)str, len, (void *)mem);
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
#if defined(WIN32) && defined(UNICODE)
|
||||
wchar_t *curl_dowcsdup(const wchar_t *str, int line, const char *source)
|
||||
{
|
||||
wchar_t *mem;
|
||||
size_t wsiz, bsiz;
|
||||
|
||||
assert(str != NULL);
|
||||
|
||||
if(countcheck("wcsdup", line, source))
|
||||
return NULL;
|
||||
|
||||
wsiz = wcslen(str) + 1;
|
||||
bsiz = wsiz * sizeof(wchar_t);
|
||||
|
||||
mem = curl_domalloc(bsiz, 0, NULL); /* NULL prevents logging */
|
||||
if(mem)
|
||||
memcpy(mem, str, bsiz);
|
||||
|
||||
if(source)
|
||||
curl_memlog("MEM %s:%d wcsdup(%p) (%zu) = %p\n",
|
||||
source, line, (void *)str, bsiz, (void *)mem);
|
||||
|
||||
return mem;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We provide a realloc() that accepts a NULL as pointer, which then
|
||||
performs a malloc(). In order to work with ares. */
|
||||
void *curl_dorealloc(void *ptr, size_t wantedsize,
|
||||
int line, const char *source)
|
||||
{
|
||||
struct memdebug *mem=NULL;
|
||||
|
||||
size_t size = sizeof(struct memdebug)+wantedsize;
|
||||
|
||||
assert(wantedsize != 0);
|
||||
|
||||
if(countcheck("realloc", line, source))
|
||||
return NULL;
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:1684)
|
||||
/* 1684: conversion from pointer to same-sized integral type */
|
||||
#endif
|
||||
|
||||
if(ptr)
|
||||
mem = (void *)((char *)ptr - offsetof(struct memdebug, mem));
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
mem = (Curl_crealloc)(mem, size);
|
||||
if(source)
|
||||
curl_memlog("MEM %s:%d realloc(%p, %zu) = %p\n",
|
||||
source, line, (void *)ptr, wantedsize,
|
||||
mem ? (void *)mem->mem : (void *)0);
|
||||
|
||||
if(mem) {
|
||||
mem->size = wantedsize;
|
||||
return mem->mem;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void curl_dofree(void *ptr, int line, const char *source)
|
||||
{
|
||||
struct memdebug *mem;
|
||||
|
||||
if(ptr) {
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:1684)
|
||||
/* 1684: conversion from pointer to same-sized integral type */
|
||||
#endif
|
||||
|
||||
mem = (void *)((char *)ptr - offsetof(struct memdebug, mem));
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
/* destroy */
|
||||
mt_free_fill(mem->mem, mem->size);
|
||||
|
||||
/* free for real */
|
||||
(Curl_cfree)(mem);
|
||||
}
|
||||
|
||||
if(source)
|
||||
curl_memlog("MEM %s:%d free(%p)\n", source, line, (void *)ptr);
|
||||
}
|
||||
|
||||
curl_socket_t curl_socket(int domain, int type, int protocol,
|
||||
int line, const char *source)
|
||||
{
|
||||
const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
|
||||
"FD %s:%d socket() = %d\n" :
|
||||
(sizeof(curl_socket_t) == sizeof(long)) ?
|
||||
"FD %s:%d socket() = %ld\n" :
|
||||
"FD %s:%d socket() = %zd\n";
|
||||
|
||||
curl_socket_t sockfd = socket(domain, type, protocol);
|
||||
|
||||
if(source && (sockfd != CURL_SOCKET_BAD))
|
||||
curl_memlog(fmt, source, line, sockfd);
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
int curl_socketpair(int domain, int type, int protocol,
|
||||
curl_socket_t socket_vector[2],
|
||||
int line, const char *source)
|
||||
{
|
||||
const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
|
||||
"FD %s:%d socketpair() = %d %d\n" :
|
||||
(sizeof(curl_socket_t) == sizeof(long)) ?
|
||||
"FD %s:%d socketpair() = %ld %ld\n" :
|
||||
"FD %s:%d socketpair() = %zd %zd\n";
|
||||
|
||||
int res = socketpair(domain, type, protocol, socket_vector);
|
||||
|
||||
if(source && (0 == res))
|
||||
curl_memlog(fmt, source, line, socket_vector[0], socket_vector[1]);
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
curl_socket_t curl_accept(curl_socket_t s, void *saddr, void *saddrlen,
|
||||
int line, const char *source)
|
||||
{
|
||||
const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
|
||||
"FD %s:%d accept() = %d\n" :
|
||||
(sizeof(curl_socket_t) == sizeof(long)) ?
|
||||
"FD %s:%d accept() = %ld\n" :
|
||||
"FD %s:%d accept() = %zd\n";
|
||||
|
||||
struct sockaddr *addr = (struct sockaddr *)saddr;
|
||||
curl_socklen_t *addrlen = (curl_socklen_t *)saddrlen;
|
||||
|
||||
curl_socket_t sockfd = accept(s, addr, addrlen);
|
||||
|
||||
if(source && (sockfd != CURL_SOCKET_BAD))
|
||||
curl_memlog(fmt, source, line, sockfd);
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
/* separate function to allow libcurl to mark a "faked" close */
|
||||
void curl_mark_sclose(curl_socket_t sockfd, int line, const char *source)
|
||||
{
|
||||
const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
|
||||
"FD %s:%d sclose(%d)\n":
|
||||
(sizeof(curl_socket_t) == sizeof(long)) ?
|
||||
"FD %s:%d sclose(%ld)\n":
|
||||
"FD %s:%d sclose(%zd)\n";
|
||||
|
||||
if(source)
|
||||
curl_memlog(fmt, source, line, sockfd);
|
||||
}
|
||||
|
||||
/* this is our own defined way to close sockets on *ALL* platforms */
|
||||
int curl_sclose(curl_socket_t sockfd, int line, const char *source)
|
||||
{
|
||||
int res=sclose(sockfd);
|
||||
curl_mark_sclose(sockfd, line, source);
|
||||
return res;
|
||||
}
|
||||
|
||||
FILE *curl_fopen(const char *file, const char *mode,
|
||||
int line, const char *source)
|
||||
{
|
||||
FILE *res=fopen(file, mode);
|
||||
|
||||
if(source)
|
||||
curl_memlog("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n",
|
||||
source, line, file, mode, (void *)res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FDOPEN
|
||||
FILE *curl_fdopen(int filedes, const char *mode,
|
||||
int line, const char *source)
|
||||
{
|
||||
FILE *res=fdopen(filedes, mode);
|
||||
|
||||
if(source)
|
||||
curl_memlog("FILE %s:%d fdopen(\"%d\",\"%s\") = %p\n",
|
||||
source, line, filedes, mode, (void *)res);
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
int curl_fclose(FILE *file, int line, const char *source)
|
||||
{
|
||||
int res;
|
||||
|
||||
assert(file != NULL);
|
||||
|
||||
res=fclose(file);
|
||||
|
||||
if(source)
|
||||
curl_memlog("FILE %s:%d fclose(%p)\n",
|
||||
source, line, (void *)file);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#define LOGLINE_BUFSIZE 1024
|
||||
|
||||
/* this does the writting to the memory tracking log file */
|
||||
void curl_memlog(const char *format, ...)
|
||||
{
|
||||
char *buf;
|
||||
int nchars;
|
||||
va_list ap;
|
||||
|
||||
if(!logfile)
|
||||
return;
|
||||
|
||||
buf = (Curl_cmalloc)(LOGLINE_BUFSIZE);
|
||||
if(!buf)
|
||||
return;
|
||||
|
||||
va_start(ap, format);
|
||||
nchars = vsnprintf(buf, LOGLINE_BUFSIZE, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if(nchars > LOGLINE_BUFSIZE - 1)
|
||||
nchars = LOGLINE_BUFSIZE - 1;
|
||||
|
||||
if(nchars > 0)
|
||||
fwrite(buf, 1, nchars, logfile);
|
||||
|
||||
(Curl_cfree)(buf);
|
||||
}
|
||||
|
||||
#endif /* CURLDEBUG */
|
||||
@@ -1,173 +0,0 @@
|
||||
#ifndef HEADER_CURL_MEMDEBUG_H
|
||||
#define HEADER_CURL_MEMDEBUG_H
|
||||
#ifdef CURLDEBUG
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* CAUTION: this header is designed to work when included by the app-side
|
||||
* as well as the library. Do not mix with library internals!
|
||||
*/
|
||||
|
||||
#define CURL_MT_LOGFNAME_BUFSIZE 512
|
||||
|
||||
#define logfile curl_debuglogfile
|
||||
|
||||
extern FILE *logfile;
|
||||
|
||||
/* memory functions */
|
||||
CURL_EXTERN void *curl_domalloc(size_t size, int line, const char *source);
|
||||
CURL_EXTERN void *curl_docalloc(size_t elements, size_t size, int line,
|
||||
const char *source);
|
||||
CURL_EXTERN void *curl_dorealloc(void *ptr, size_t size, int line,
|
||||
const char *source);
|
||||
CURL_EXTERN void curl_dofree(void *ptr, int line, const char *source);
|
||||
CURL_EXTERN char *curl_dostrdup(const char *str, int line, const char *source);
|
||||
#if defined(WIN32) && defined(UNICODE)
|
||||
CURL_EXTERN wchar_t *curl_dowcsdup(const wchar_t *str, int line,
|
||||
const char *source);
|
||||
#endif
|
||||
|
||||
CURL_EXTERN void curl_memdebug(const char *logname);
|
||||
CURL_EXTERN void curl_memlimit(long limit);
|
||||
CURL_EXTERN void curl_memlog(const char *format, ...);
|
||||
|
||||
/* file descriptor manipulators */
|
||||
CURL_EXTERN curl_socket_t curl_socket(int domain, int type, int protocol,
|
||||
int line, const char *source);
|
||||
CURL_EXTERN void curl_mark_sclose(curl_socket_t sockfd,
|
||||
int line, const char *source);
|
||||
CURL_EXTERN int curl_sclose(curl_socket_t sockfd,
|
||||
int line, const char *source);
|
||||
CURL_EXTERN curl_socket_t curl_accept(curl_socket_t s, void *a, void *alen,
|
||||
int line, const char *source);
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
CURL_EXTERN int curl_socketpair(int domain, int type, int protocol,
|
||||
curl_socket_t socket_vector[2],
|
||||
int line, const char *source);
|
||||
#endif
|
||||
|
||||
/* FILE functions */
|
||||
CURL_EXTERN FILE *curl_fopen(const char *file, const char *mode, int line,
|
||||
const char *source);
|
||||
#ifdef HAVE_FDOPEN
|
||||
CURL_EXTERN FILE *curl_fdopen(int filedes, const char *mode, int line,
|
||||
const char *source);
|
||||
#endif
|
||||
CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
|
||||
|
||||
#ifndef MEMDEBUG_NODEFINES
|
||||
|
||||
/* Set this symbol on the command-line, recompile all lib-sources */
|
||||
#undef strdup
|
||||
#define strdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__)
|
||||
#define malloc(size) curl_domalloc(size, __LINE__, __FILE__)
|
||||
#define calloc(nbelem,size) curl_docalloc(nbelem, size, __LINE__, __FILE__)
|
||||
#define realloc(ptr,size) curl_dorealloc(ptr, size, __LINE__, __FILE__)
|
||||
#define free(ptr) curl_dofree(ptr, __LINE__, __FILE__)
|
||||
|
||||
#ifdef WIN32
|
||||
# ifdef UNICODE
|
||||
# undef wcsdup
|
||||
# define wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
|
||||
# undef _wcsdup
|
||||
# define _wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
|
||||
# undef _tcsdup
|
||||
# define _tcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
|
||||
# else
|
||||
# undef _tcsdup
|
||||
# define _tcsdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#undef socket
|
||||
#define socket(domain,type,protocol)\
|
||||
curl_socket(domain, type, protocol, __LINE__, __FILE__)
|
||||
#undef accept /* for those with accept as a macro */
|
||||
#define accept(sock,addr,len)\
|
||||
curl_accept(sock, addr, len, __LINE__, __FILE__)
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
#define socketpair(domain,type,protocol,socket_vector)\
|
||||
curl_socketpair(domain, type, protocol, socket_vector, __LINE__, __FILE__)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
#if defined(getaddrinfo) && defined(__osf__)
|
||||
/* OSF/1 and Tru64 have getaddrinfo as a define already, so we cannot define
|
||||
our macro as for other platforms. Instead, we redefine the new name they
|
||||
define getaddrinfo to become! */
|
||||
#define ogetaddrinfo(host,serv,hint,res) \
|
||||
curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
|
||||
#else
|
||||
#undef getaddrinfo
|
||||
#define getaddrinfo(host,serv,hint,res) \
|
||||
curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
|
||||
#endif
|
||||
#endif /* HAVE_GETADDRINFO */
|
||||
|
||||
#ifdef HAVE_GETNAMEINFO
|
||||
#undef getnameinfo
|
||||
#define getnameinfo(sa,salen,host,hostlen,serv,servlen,flags) \
|
||||
curl_dogetnameinfo(sa, salen, host, hostlen, serv, servlen, flags, \
|
||||
__LINE__, __FILE__)
|
||||
#endif /* HAVE_GETNAMEINFO */
|
||||
|
||||
#ifdef HAVE_FREEADDRINFO
|
||||
#undef freeaddrinfo
|
||||
#define freeaddrinfo(data) \
|
||||
curl_dofreeaddrinfo(data, __LINE__, __FILE__)
|
||||
#endif /* HAVE_FREEADDRINFO */
|
||||
|
||||
/* sclose is probably already defined, redefine it! */
|
||||
#undef sclose
|
||||
#define sclose(sockfd) curl_sclose(sockfd,__LINE__,__FILE__)
|
||||
|
||||
#define fake_sclose(sockfd) curl_mark_sclose(sockfd,__LINE__,__FILE__)
|
||||
|
||||
#undef fopen
|
||||
#define fopen(file,mode) curl_fopen(file,mode,__LINE__,__FILE__)
|
||||
#undef fdopen
|
||||
#define fdopen(file,mode) curl_fdopen(file,mode,__LINE__,__FILE__)
|
||||
#define fclose(file) curl_fclose(file,__LINE__,__FILE__)
|
||||
|
||||
#endif /* MEMDEBUG_NODEFINES */
|
||||
|
||||
#endif /* CURLDEBUG */
|
||||
|
||||
/*
|
||||
** Following section applies even when CURLDEBUG is not defined.
|
||||
*/
|
||||
|
||||
#ifndef fake_sclose
|
||||
#define fake_sclose(x) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_safefree defined as a macro to allow MemoryTracking feature
|
||||
* to log free() calls at same location where Curl_safefree is used.
|
||||
* This macro also assigns NULL to given pointer when free'd.
|
||||
*/
|
||||
|
||||
#define Curl_safefree(ptr) \
|
||||
do { free((ptr)); (ptr) = NULL;} WHILE_FALSE
|
||||
|
||||
#endif /* HEADER_CURL_MEMDEBUG_H */
|
||||
@@ -1,554 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
# ***************************************************************************
|
||||
# * _ _ ____ _
|
||||
# * Project ___| | | | _ \| |
|
||||
# * / __| | | | |_) | |
|
||||
# * | (__| |_| | _ <| |___
|
||||
# * \___|\___/|_| \_\_____|
|
||||
# *
|
||||
# * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# *
|
||||
# * This software is licensed as described in the file COPYING, which
|
||||
# * you should have received as part of this distribution. The terms
|
||||
# * are also available at https://curl.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 Perl script creates a fresh ca-bundle.crt file for use with libcurl.
|
||||
# It downloads certdata.txt from Mozilla's source tree (see URL below),
|
||||
# then parses certdata.txt and extracts CA Root Certificates into PEM format.
|
||||
# These are then processed with the OpenSSL commandline tool to produce the
|
||||
# final ca-bundle.crt file.
|
||||
# The script is based on the parse-certs script written by Roland Krikava.
|
||||
# This Perl script works on almost any platform since its only external
|
||||
# dependency is the OpenSSL commandline tool for optional text listing.
|
||||
# Hacked by Guenter Knauf.
|
||||
#
|
||||
use Encode;
|
||||
use Getopt::Std;
|
||||
use MIME::Base64;
|
||||
use strict;
|
||||
use vars qw($opt_b $opt_d $opt_f $opt_h $opt_i $opt_k $opt_l $opt_m $opt_n $opt_p $opt_q $opt_s $opt_t $opt_u $opt_v $opt_w);
|
||||
use List::Util;
|
||||
use Text::Wrap;
|
||||
my $MOD_SHA = "Digest::SHA";
|
||||
eval "require $MOD_SHA";
|
||||
if ($@) {
|
||||
$MOD_SHA = "Digest::SHA::PurePerl";
|
||||
eval "require $MOD_SHA";
|
||||
}
|
||||
eval "require LWP::UserAgent";
|
||||
|
||||
my %urls = (
|
||||
'nss' =>
|
||||
'https://hg.mozilla.org/projects/nss/raw-file/tip/lib/ckfw/builtins/certdata.txt',
|
||||
'central' =>
|
||||
'https://hg.mozilla.org/mozilla-central/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||
'aurora' =>
|
||||
'https://hg.mozilla.org/releases/mozilla-aurora/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||
'beta' =>
|
||||
'https://hg.mozilla.org/releases/mozilla-beta/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||
'release' =>
|
||||
'https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||
);
|
||||
|
||||
$opt_d = 'release';
|
||||
|
||||
# If the OpenSSL commandline is not in search path you can configure it here!
|
||||
my $openssl = 'openssl';
|
||||
|
||||
my $version = '1.27';
|
||||
|
||||
$opt_w = 76; # default base64 encoded lines length
|
||||
|
||||
# default cert types to include in the output (default is to include CAs which may issue SSL server certs)
|
||||
my $default_mozilla_trust_purposes = "SERVER_AUTH";
|
||||
my $default_mozilla_trust_levels = "TRUSTED_DELEGATOR";
|
||||
$opt_p = $default_mozilla_trust_purposes . ":" . $default_mozilla_trust_levels;
|
||||
|
||||
my @valid_mozilla_trust_purposes = (
|
||||
"DIGITAL_SIGNATURE",
|
||||
"NON_REPUDIATION",
|
||||
"KEY_ENCIPHERMENT",
|
||||
"DATA_ENCIPHERMENT",
|
||||
"KEY_AGREEMENT",
|
||||
"KEY_CERT_SIGN",
|
||||
"CRL_SIGN",
|
||||
"SERVER_AUTH",
|
||||
"CLIENT_AUTH",
|
||||
"CODE_SIGNING",
|
||||
"EMAIL_PROTECTION",
|
||||
"IPSEC_END_SYSTEM",
|
||||
"IPSEC_TUNNEL",
|
||||
"IPSEC_USER",
|
||||
"TIME_STAMPING",
|
||||
"STEP_UP_APPROVED"
|
||||
);
|
||||
|
||||
my @valid_mozilla_trust_levels = (
|
||||
"TRUSTED_DELEGATOR", # CAs
|
||||
"NOT_TRUSTED", # Don't trust these certs.
|
||||
"MUST_VERIFY_TRUST", # This explicitly tells us that it ISN'T a CA but is otherwise ok. In other words, this should tell the app to ignore any other sources that claim this is a CA.
|
||||
"TRUSTED" # This cert is trusted, but only for itself and not for delegates (i.e. it is not a CA).
|
||||
);
|
||||
|
||||
my $default_signature_algorithms = $opt_s = "MD5";
|
||||
|
||||
my @valid_signature_algorithms = (
|
||||
"MD5",
|
||||
"SHA1",
|
||||
"SHA256",
|
||||
"SHA384",
|
||||
"SHA512"
|
||||
);
|
||||
|
||||
$0 =~ s@.*(/|\\)@@;
|
||||
$Getopt::Std::STANDARD_HELP_VERSION = 1;
|
||||
getopts('bd:fhiklmnp:qs:tuvw:');
|
||||
|
||||
if(!defined($opt_d)) {
|
||||
# to make plain "-d" use not cause warnings, and actually still work
|
||||
$opt_d = 'release';
|
||||
}
|
||||
|
||||
# Use predefined URL or else custom URL specified on command line.
|
||||
my $url;
|
||||
if(defined($urls{$opt_d})) {
|
||||
$url = $urls{$opt_d};
|
||||
if(!$opt_k && $url !~ /^https:\/\//i) {
|
||||
die "The URL for '$opt_d' is not HTTPS. Use -k to override (insecure).\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$url = $opt_d;
|
||||
}
|
||||
|
||||
my $curl = `curl -V`;
|
||||
|
||||
if ($opt_i) {
|
||||
print ("=" x 78 . "\n");
|
||||
print "Script Version : $version\n";
|
||||
print "Perl Version : $]\n";
|
||||
print "Operating System Name : $^O\n";
|
||||
print "Getopt::Std.pm Version : ${Getopt::Std::VERSION}\n";
|
||||
print "MIME::Base64.pm Version : ${MIME::Base64::VERSION}\n";
|
||||
print "LWP::UserAgent.pm Version : ${LWP::UserAgent::VERSION}\n" if($LWP::UserAgent::VERSION);
|
||||
print "LWP.pm Version : ${LWP::VERSION}\n" if($LWP::VERSION);
|
||||
print "Digest::SHA.pm Version : ${Digest::SHA::VERSION}\n" if ($Digest::SHA::VERSION);
|
||||
print "Digest::SHA::PurePerl.pm Version : ${Digest::SHA::PurePerl::VERSION}\n" if ($Digest::SHA::PurePerl::VERSION);
|
||||
print ("=" x 78 . "\n");
|
||||
}
|
||||
|
||||
sub warning_message() {
|
||||
if ( $opt_d =~ m/^risk$/i ) { # Long Form Warning and Exit
|
||||
print "Warning: Use of this script may pose some risk:\n";
|
||||
print "\n";
|
||||
print " 1) If you use HTTP URLs they are subject to a man in the middle attack\n";
|
||||
print " 2) Default to 'release', but more recent updates may be found in other trees\n";
|
||||
print " 3) certdata.txt file format may change, lag time to update this script\n";
|
||||
print " 4) Generally unwise to blindly trust CAs without manual review & verification\n";
|
||||
print " 5) Mozilla apps use additional security checks aren't represented in certdata\n";
|
||||
print " 6) Use of this script will make a security engineer grind his teeth and\n";
|
||||
print " swear at you. ;)\n";
|
||||
exit;
|
||||
} else { # Short Form Warning
|
||||
print "Warning: Use of this script may pose some risk, -d risk for more details.\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub HELP_MESSAGE() {
|
||||
print "Usage:\t${0} [-b] [-d<certdata>] [-f] [-i] [-k] [-l] [-n] [-p<purposes:levels>] [-q] [-s<algorithms>] [-t] [-u] [-v] [-w<l>] [<outputfile>]\n";
|
||||
print "\t-b\tbackup an existing version of ca-bundle.crt\n";
|
||||
print "\t-d\tspecify Mozilla tree to pull certdata.txt or custom URL\n";
|
||||
print "\t\t Valid names are:\n";
|
||||
print "\t\t ", join( ", ", map { ( $_ =~ m/$opt_d/ ) ? "$_ (default)" : "$_" } sort keys %urls ), "\n";
|
||||
print "\t-f\tforce rebuild even if certdata.txt is current\n";
|
||||
print "\t-i\tprint version info about used modules\n";
|
||||
print "\t-k\tallow URLs other than HTTPS, enable HTTP fallback (insecure)\n";
|
||||
print "\t-l\tprint license info about certdata.txt\n";
|
||||
print "\t-m\tinclude meta data in output\n";
|
||||
print "\t-n\tno download of certdata.txt (to use existing)\n";
|
||||
print wrap("\t","\t\t", "-p\tlist of Mozilla trust purposes and levels for certificates to include in output. Takes the form of a comma separated list of purposes, a colon, and a comma separated list of levels. (default: $default_mozilla_trust_purposes:$default_mozilla_trust_levels)"), "\n";
|
||||
print "\t\t Valid purposes are:\n";
|
||||
print wrap("\t\t ","\t\t ", join( ", ", "ALL", @valid_mozilla_trust_purposes ) ), "\n";
|
||||
print "\t\t Valid levels are:\n";
|
||||
print wrap("\t\t ","\t\t ", join( ", ", "ALL", @valid_mozilla_trust_levels ) ), "\n";
|
||||
print "\t-q\tbe really quiet (no progress output at all)\n";
|
||||
print wrap("\t","\t\t", "-s\tcomma separated list of certificate signatures/hashes to output in plain text mode. (default: $default_signature_algorithms)\n");
|
||||
print "\t\t Valid signature algorithms are:\n";
|
||||
print wrap("\t\t ","\t\t ", join( ", ", "ALL", @valid_signature_algorithms ) ), "\n";
|
||||
print "\t-t\tinclude plain text listing of certificates\n";
|
||||
print "\t-u\tunlink (remove) certdata.txt after processing\n";
|
||||
print "\t-v\tbe verbose and print out processed CAs\n";
|
||||
print "\t-w <l>\twrap base64 output lines after <l> chars (default: ${opt_w})\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
sub VERSION_MESSAGE() {
|
||||
print "${0} version ${version} running Perl ${]} on ${^O}\n";
|
||||
}
|
||||
|
||||
warning_message() unless ($opt_q || $url =~ m/^(ht|f)tps:/i );
|
||||
HELP_MESSAGE() if ($opt_h);
|
||||
|
||||
sub report($@) {
|
||||
my $output = shift;
|
||||
|
||||
print STDERR $output . "\n" unless $opt_q;
|
||||
}
|
||||
|
||||
sub is_in_list($@) {
|
||||
my $target = shift;
|
||||
|
||||
return defined(List::Util::first { $target eq $_ } @_);
|
||||
}
|
||||
|
||||
# Parses $param_string as a case insensitive comma separated list with optional whitespace
|
||||
# validates that only allowed parameters are supplied
|
||||
sub parse_csv_param($$@) {
|
||||
my $description = shift;
|
||||
my $param_string = shift;
|
||||
my @valid_values = @_;
|
||||
|
||||
my @values = map {
|
||||
s/^\s+//; # strip leading spaces
|
||||
s/\s+$//; # strip trailing spaces
|
||||
uc $_ # return the modified string as upper case
|
||||
} split( ',', $param_string );
|
||||
|
||||
# Find all values which are not in the list of valid values or "ALL"
|
||||
my @invalid = grep { !is_in_list($_,"ALL",@valid_values) } @values;
|
||||
|
||||
if ( scalar(@invalid) > 0 ) {
|
||||
# Tell the user which parameters were invalid and print the standard help message which will exit
|
||||
print "Error: Invalid ", $description, scalar(@invalid) == 1 ? ": " : "s: ", join( ", ", map { "\"$_\"" } @invalid ), "\n";
|
||||
HELP_MESSAGE();
|
||||
}
|
||||
|
||||
@values = @valid_values if ( is_in_list("ALL",@values) );
|
||||
|
||||
return @values;
|
||||
}
|
||||
|
||||
sub sha256 {
|
||||
my $result;
|
||||
if ($Digest::SHA::VERSION || $Digest::SHA::PurePerl::VERSION) {
|
||||
open(FILE, $_[0]) or die "Can't open '$_[0]': $!";
|
||||
binmode(FILE);
|
||||
$result = $MOD_SHA->new(256)->addfile(*FILE)->hexdigest;
|
||||
close(FILE);
|
||||
} else {
|
||||
# Use OpenSSL command if Perl Digest::SHA modules not available
|
||||
$result = `"$openssl" dgst -r -sha256 "$_[0]"`;
|
||||
$result =~ s/^([0-9a-f]{64}) .+/$1/is;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
sub oldhash {
|
||||
my $hash = "";
|
||||
open(C, "<$_[0]") || return 0;
|
||||
while(<C>) {
|
||||
chomp;
|
||||
if($_ =~ /^\#\# SHA256: (.*)/) {
|
||||
$hash = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close(C);
|
||||
return $hash;
|
||||
}
|
||||
|
||||
if ( $opt_p !~ m/:/ ) {
|
||||
print "Error: Mozilla trust identifier list must include both purposes and levels\n";
|
||||
HELP_MESSAGE();
|
||||
}
|
||||
|
||||
(my $included_mozilla_trust_purposes_string, my $included_mozilla_trust_levels_string) = split( ':', $opt_p );
|
||||
my @included_mozilla_trust_purposes = parse_csv_param( "trust purpose", $included_mozilla_trust_purposes_string, @valid_mozilla_trust_purposes );
|
||||
my @included_mozilla_trust_levels = parse_csv_param( "trust level", $included_mozilla_trust_levels_string, @valid_mozilla_trust_levels );
|
||||
|
||||
my @included_signature_algorithms = parse_csv_param( "signature algorithm", $opt_s, @valid_signature_algorithms );
|
||||
|
||||
sub should_output_cert(%) {
|
||||
my %trust_purposes_by_level = @_;
|
||||
|
||||
foreach my $level (@included_mozilla_trust_levels) {
|
||||
# for each level we want to output, see if any of our desired purposes are included
|
||||
return 1 if ( defined( List::Util::first { is_in_list( $_, @included_mozilla_trust_purposes ) } @{$trust_purposes_by_level{$level}} ) );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
my $crt = $ARGV[0] || 'ca-bundle.crt';
|
||||
(my $txt = $url) =~ s@(.*/|\?.*)@@g;
|
||||
|
||||
my $stdout = $crt eq '-';
|
||||
my $resp;
|
||||
my $fetched;
|
||||
|
||||
my $oldhash = oldhash($crt);
|
||||
|
||||
report "SHA256 of old file: $oldhash";
|
||||
|
||||
if(!$opt_n) {
|
||||
report "Downloading $txt ...";
|
||||
|
||||
# If we have an HTTPS URL then use curl
|
||||
if($url =~ /^https:\/\//i) {
|
||||
if($curl) {
|
||||
if($curl =~ /^Protocols:.* https( |$)/m) {
|
||||
report "Get certdata with curl!";
|
||||
my $proto = !$opt_k ? "--proto =https" : "";
|
||||
my $quiet = $opt_q ? "-s" : "";
|
||||
my @out = `curl -w %{response_code} $proto $quiet -o "$txt" "$url"`;
|
||||
if(@out && $out[0] == 200) {
|
||||
$fetched = 1;
|
||||
report "Downloaded $txt";
|
||||
}
|
||||
else {
|
||||
report "Failed downloading via HTTPS with curl";
|
||||
if(-e $txt && !unlink($txt)) {
|
||||
report "Failed to remove '$txt': $!";
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
report "curl lacks https support";
|
||||
}
|
||||
}
|
||||
else {
|
||||
report "curl not found";
|
||||
}
|
||||
}
|
||||
|
||||
# If nothing was fetched then use LWP
|
||||
if(!$fetched) {
|
||||
if($url =~ /^https:\/\//i) {
|
||||
report "Falling back to HTTP";
|
||||
$url =~ s/^https:\/\//http:\/\//i;
|
||||
}
|
||||
if(!$opt_k) {
|
||||
report "URLs other than HTTPS are disabled by default, to enable use -k";
|
||||
exit 1;
|
||||
}
|
||||
report "Get certdata with LWP!";
|
||||
if(!defined(${LWP::UserAgent::VERSION})) {
|
||||
report "LWP is not available (LWP::UserAgent not found)";
|
||||
exit 1;
|
||||
}
|
||||
my $ua = new LWP::UserAgent(agent => "$0/$version");
|
||||
$ua->env_proxy();
|
||||
$resp = $ua->mirror($url, $txt);
|
||||
if($resp && $resp->code eq '304') {
|
||||
report "Not modified";
|
||||
exit 0 if -e $crt && !$opt_f;
|
||||
}
|
||||
else {
|
||||
$fetched = 1;
|
||||
report "Downloaded $txt";
|
||||
}
|
||||
if(!$resp || $resp->code !~ /^(?:200|304)$/) {
|
||||
report "Unable to download latest data: "
|
||||
. ($resp? $resp->code . ' - ' . $resp->message : "LWP failed");
|
||||
exit 1 if -e $crt || ! -r $txt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $filedate = $resp ? $resp->last_modified : (stat($txt))[9];
|
||||
my $datesrc = "as of";
|
||||
if(!$filedate) {
|
||||
# mxr.mozilla.org gave us a time, hg.mozilla.org does not!
|
||||
$filedate = time();
|
||||
$datesrc="downloaded on";
|
||||
}
|
||||
|
||||
# get the hash from the download file
|
||||
my $newhash= sha256($txt);
|
||||
|
||||
if(!$opt_f && $oldhash eq $newhash) {
|
||||
report "Downloaded file identical to previous run\'s source file. Exiting";
|
||||
exit;
|
||||
}
|
||||
|
||||
report "SHA256 of new file: $newhash";
|
||||
|
||||
my $currentdate = scalar gmtime($filedate);
|
||||
|
||||
my $format = $opt_t ? "plain text and " : "";
|
||||
if( $stdout ) {
|
||||
open(CRT, '> -') or die "Couldn't open STDOUT: $!\n";
|
||||
} else {
|
||||
open(CRT,">$crt.~") or die "Couldn't open $crt.~: $!\n";
|
||||
}
|
||||
print CRT <<EOT;
|
||||
##
|
||||
## Bundle of CA Root Certificates
|
||||
##
|
||||
## Certificate data from Mozilla ${datesrc}: ${currentdate} GMT
|
||||
##
|
||||
## This is a bundle of X.509 certificates of public Certificate Authorities
|
||||
## (CA). These were automatically extracted from Mozilla's root certificates
|
||||
## file (certdata.txt). This file can be found in the mozilla source tree:
|
||||
## ${url}
|
||||
##
|
||||
## It contains the certificates in ${format}PEM format and therefore
|
||||
## can be directly used with curl / libcurl / php_curl, or with
|
||||
## an Apache+mod_ssl webserver for SSL client authentication.
|
||||
## Just configure this file as the SSLCACertificateFile.
|
||||
##
|
||||
## Conversion done with mk-ca-bundle.pl version $version.
|
||||
## SHA256: $newhash
|
||||
##
|
||||
|
||||
EOT
|
||||
|
||||
report "Processing '$txt' ...";
|
||||
my $caname;
|
||||
my $certnum = 0;
|
||||
my $skipnum = 0;
|
||||
my $start_of_cert = 0;
|
||||
my @precert;
|
||||
|
||||
open(TXT,"$txt") or die "Couldn't open $txt: $!\n";
|
||||
while (<TXT>) {
|
||||
if (/\*\*\*\*\* BEGIN LICENSE BLOCK \*\*\*\*\*/) {
|
||||
print CRT;
|
||||
print if ($opt_l);
|
||||
while (<TXT>) {
|
||||
print CRT;
|
||||
print if ($opt_l);
|
||||
last if (/\*\*\*\*\* END LICENSE BLOCK \*\*\*\*\*/);
|
||||
}
|
||||
}
|
||||
elsif(/^# (Issuer|Serial Number|Subject|Not Valid Before|Not Valid After |Fingerprint \(MD5\)|Fingerprint \(SHA1\)):/) {
|
||||
push @precert, $_;
|
||||
next;
|
||||
}
|
||||
elsif(/^#|^\s*$/) {
|
||||
undef @precert;
|
||||
next;
|
||||
}
|
||||
chomp;
|
||||
|
||||
# this is a match for the start of a certificate
|
||||
if (/^CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE/) {
|
||||
$start_of_cert = 1
|
||||
}
|
||||
if ($start_of_cert && /^CKA_LABEL UTF8 \"(.*)\"/) {
|
||||
$caname = $1;
|
||||
}
|
||||
my %trust_purposes_by_level;
|
||||
if ($start_of_cert && /^CKA_VALUE MULTILINE_OCTAL/) {
|
||||
my $data;
|
||||
while (<TXT>) {
|
||||
last if (/^END/);
|
||||
chomp;
|
||||
my @octets = split(/\\/);
|
||||
shift @octets;
|
||||
for (@octets) {
|
||||
$data .= chr(oct);
|
||||
}
|
||||
}
|
||||
# scan forwards until the trust part
|
||||
while (<TXT>) {
|
||||
last if (/^CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST/);
|
||||
chomp;
|
||||
}
|
||||
# now scan the trust part to determine how we should trust this cert
|
||||
while (<TXT>) {
|
||||
last if (/^#/);
|
||||
if (/^CKA_TRUST_([A-Z_]+)\s+CK_TRUST\s+CKT_NSS_([A-Z_]+)\s*$/) {
|
||||
if ( !is_in_list($1,@valid_mozilla_trust_purposes) ) {
|
||||
report "Warning: Unrecognized trust purpose for cert: $caname. Trust purpose: $1. Trust Level: $2";
|
||||
} elsif ( !is_in_list($2,@valid_mozilla_trust_levels) ) {
|
||||
report "Warning: Unrecognized trust level for cert: $caname. Trust purpose: $1. Trust Level: $2";
|
||||
} else {
|
||||
push @{$trust_purposes_by_level{$2}}, $1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !should_output_cert(%trust_purposes_by_level) ) {
|
||||
$skipnum ++;
|
||||
} else {
|
||||
my $encoded = MIME::Base64::encode_base64($data, '');
|
||||
$encoded =~ s/(.{1,${opt_w}})/$1\n/g;
|
||||
my $pem = "-----BEGIN CERTIFICATE-----\n"
|
||||
. $encoded
|
||||
. "-----END CERTIFICATE-----\n";
|
||||
print CRT "\n$caname\n";
|
||||
print CRT @precert if($opt_m);
|
||||
my $maxStringLength = length(decode('UTF-8', $caname, Encode::FB_CROAK));
|
||||
if ($opt_t) {
|
||||
foreach my $key (keys %trust_purposes_by_level) {
|
||||
my $string = $key . ": " . join(", ", @{$trust_purposes_by_level{$key}});
|
||||
$maxStringLength = List::Util::max( length($string), $maxStringLength );
|
||||
print CRT $string . "\n";
|
||||
}
|
||||
}
|
||||
print CRT ("=" x $maxStringLength . "\n");
|
||||
if (!$opt_t) {
|
||||
print CRT $pem;
|
||||
} else {
|
||||
my $pipe = "";
|
||||
foreach my $hash (@included_signature_algorithms) {
|
||||
$pipe = "|$openssl x509 -" . $hash . " -fingerprint -noout -inform PEM";
|
||||
if (!$stdout) {
|
||||
$pipe .= " >> $crt.~";
|
||||
close(CRT) or die "Couldn't close $crt.~: $!";
|
||||
}
|
||||
open(TMP, $pipe) or die "Couldn't open openssl pipe: $!";
|
||||
print TMP $pem;
|
||||
close(TMP) or die "Couldn't close openssl pipe: $!";
|
||||
if (!$stdout) {
|
||||
open(CRT, ">>$crt.~") or die "Couldn't open $crt.~: $!";
|
||||
}
|
||||
}
|
||||
$pipe = "|$openssl x509 -text -inform PEM";
|
||||
if (!$stdout) {
|
||||
$pipe .= " >> $crt.~";
|
||||
close(CRT) or die "Couldn't close $crt.~: $!";
|
||||
}
|
||||
open(TMP, $pipe) or die "Couldn't open openssl pipe: $!";
|
||||
print TMP $pem;
|
||||
close(TMP) or die "Couldn't close openssl pipe: $!";
|
||||
if (!$stdout) {
|
||||
open(CRT, ">>$crt.~") or die "Couldn't open $crt.~: $!";
|
||||
}
|
||||
}
|
||||
report "Parsing: $caname" if ($opt_v);
|
||||
$certnum ++;
|
||||
$start_of_cert = 0;
|
||||
}
|
||||
undef @precert;
|
||||
}
|
||||
|
||||
}
|
||||
close(TXT) or die "Couldn't close $txt: $!\n";
|
||||
close(CRT) or die "Couldn't close $crt.~: $!\n";
|
||||
unless( $stdout ) {
|
||||
if ($opt_b && -e $crt) {
|
||||
my $bk = 1;
|
||||
while (-e "$crt.~${bk}~") {
|
||||
$bk++;
|
||||
}
|
||||
rename $crt, "$crt.~${bk}~" or die "Failed to create backup $crt.~$bk}~: $!\n";
|
||||
} elsif( -e $crt ) {
|
||||
unlink( $crt ) or die "Failed to remove $crt: $!\n";
|
||||
}
|
||||
rename "$crt.~", $crt or die "Failed to rename $crt.~ to $crt: $!\n";
|
||||
}
|
||||
if($opt_u && -e $txt && !unlink($txt)) {
|
||||
report "Failed to remove $txt: $!\n";
|
||||
}
|
||||
report "Done ($certnum CA certs processed, $skipnum skipped).";
|
||||
@@ -1,431 +0,0 @@
|
||||
'***************************************************************************
|
||||
'* _ _ ____ _
|
||||
'* Project ___| | | | _ \| |
|
||||
'* / __| | | | |_) | |
|
||||
'* | (__| |_| | _ <| |___
|
||||
'* \___|\___/|_| \_\_____|
|
||||
'*
|
||||
'* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
'*
|
||||
'* This software is licensed as described in the file COPYING, which
|
||||
'* you should have received as part of this distribution. The terms
|
||||
'* are also available at https://curl.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.
|
||||
'*
|
||||
'***************************************************************************
|
||||
'* Script to fetch certdata.txt from Mozilla.org site and create a
|
||||
'* ca-bundle.crt for use with OpenSSL / libcurl / libcurl bindings
|
||||
'* Requires WinHttp.WinHttpRequest.5.1 and ADODB.Stream which are part of
|
||||
'* W2000 SP3 or later, WXP SP1 or later, W2003 Server SP1 or later.
|
||||
'* Hacked by Guenter Knauf
|
||||
'***************************************************************************
|
||||
Option Explicit
|
||||
Const myVersion = "0.4.0"
|
||||
|
||||
Const myUrl = "https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt"
|
||||
|
||||
Const myOpenSSL = "openssl.exe"
|
||||
Dim myUseOpenSSL
|
||||
myUseOpenSSL = TRUE ' Flag: TRUE to use OpenSSL. If TRUE and is not
|
||||
' found then a warning is shown before continuing.
|
||||
|
||||
Const myCdSavF = TRUE ' Flag: save downloaded data to file certdata.txt
|
||||
Const myCaBakF = TRUE ' Flag: backup existing ca-bundle certificate
|
||||
Const myAskLiF = TRUE ' Flag: display certdata.txt license agreement
|
||||
Const myWrapLe = 76 ' Default length of base64 output lines
|
||||
|
||||
' cert info code doesn't work properly with any recent openssl, leave disabled.
|
||||
' Also: we want our certificate output by default to be as similar as possible
|
||||
' to mk-ca-bundle.pl and setting this TRUE changes the base64 width to
|
||||
' OpenSSL's built-in default width, which is not the same as mk-ca-bundle.pl.
|
||||
Const myAskTiF = FALSE ' Flag: ask to include certificate text info
|
||||
|
||||
'
|
||||
'******************* Nothing to configure below! *******************
|
||||
'
|
||||
Const adTypeBinary = 1
|
||||
Const adTypeText = 2
|
||||
Const adSaveCreateNotExist = 1
|
||||
Const adSaveCreateOverWrite = 2
|
||||
Dim objShell, objNetwork, objFSO, objHttp
|
||||
Dim myBase, mySelf, myStream, myTmpFh, myCdData, myCdFile
|
||||
Dim myCaFile, myTmpName, myBakNum, myOptTxt, i
|
||||
Set objNetwork = WScript.CreateObject("WScript.Network")
|
||||
Set objShell = WScript.CreateObject("WScript.Shell")
|
||||
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
|
||||
Set objHttp = WScript.CreateObject("WinHttp.WinHttpRequest.5.1")
|
||||
If objHttp Is Nothing Then Set objHttp = WScript.CreateObject("WinHttp.WinHttpRequest")
|
||||
myBase = Left(WScript.ScriptFullName, InstrRev(WScript.ScriptFullName, "\"))
|
||||
mySelf = Left(WScript.ScriptName, InstrRev(WScript.ScriptName, ".") - 1) & " " & myVersion
|
||||
|
||||
myCdFile = Mid(myUrl, InstrRev(myUrl, "/") + 1)
|
||||
myCaFile = "ca-bundle.crt"
|
||||
myTmpName = InputBox("It will take a minute to download and parse the " & _
|
||||
"certificate data." & _
|
||||
vbLf & vbLf & _
|
||||
"Please enter the output filename:", mySelf, myCaFile)
|
||||
If (myTmpName = "") Then
|
||||
WScript.Quit 1
|
||||
End If
|
||||
myCaFile = myTmpName
|
||||
If (myCdFile = "") Then
|
||||
MsgBox("URL does not contain filename!"), vbCritical, mySelf
|
||||
WScript.Quit 1
|
||||
End If
|
||||
|
||||
' Don't use OpenSSL if it's not present.
|
||||
If (myUseOpenSSL = TRUE) Then
|
||||
Dim errnum
|
||||
|
||||
On Error Resume Next
|
||||
Call objShell.Run("""" & myOpenSSL & """ version", 0, TRUE)
|
||||
errnum = Err.Number
|
||||
On Error GoTo 0
|
||||
|
||||
If Not (errnum = 0) Then
|
||||
myUseOpenSSL = FALSE
|
||||
MsgBox("OpenSSL was not found so the certificate bundle will not " & _
|
||||
"include the SHA256 hash of the raw certificate data file " & _
|
||||
"that was used to generate the certificates in the bundle. " & _
|
||||
vbLf & vbLf & _
|
||||
"This does not have any effect on the certificate output, " & _
|
||||
"so this script will continue." & _
|
||||
vbLf & vbLf & _
|
||||
"If you want to set a custom location for OpenSSL or disable " & _
|
||||
"this message then edit the variables at the start of the " & _
|
||||
"script."), vbInformation, mySelf
|
||||
End If
|
||||
End If
|
||||
|
||||
If (myAskTiF = TRUE) And (myUseOpenSSL = TRUE) Then
|
||||
If (6 = objShell.PopUp("Do you want to include text information about " & _
|
||||
"each certificate?" & vbLf & _
|
||||
"(Requires OpenSSL.exe in the current directory " & _
|
||||
"or search path)",, _
|
||||
mySelf, vbQuestion + vbYesNo + vbDefaultButton2)) Then
|
||||
myOptTxt = TRUE
|
||||
Else
|
||||
myOptTxt = FALSE
|
||||
End If
|
||||
End If
|
||||
|
||||
' Uncomment the line below to ignore SSL invalid cert errors
|
||||
' objHttp.Option(4) = 256 + 512 + 4096 + 8192
|
||||
objHttp.SetTimeouts 0, 5000, 10000, 10000
|
||||
objHttp.Open "GET", myUrl, FALSE
|
||||
objHttp.setRequestHeader "User-Agent", WScript.ScriptName & "/" & myVersion
|
||||
objHttp.Send ""
|
||||
If Not (objHttp.Status = 200) Then
|
||||
MsgBox("Failed to download '" & myCdFile & "': " & objHttp.Status & " - " & objHttp.StatusText), vbCritical, mySelf
|
||||
WScript.Quit 1
|
||||
End If
|
||||
' Write received data to file if enabled
|
||||
If (myCdSavF = TRUE) Then
|
||||
Call SaveBinaryData(myCdFile, objHttp.ResponseBody)
|
||||
End If
|
||||
' Convert data from ResponseBody instead of using ResponseText because of UTF-8
|
||||
myCdData = ConvertBinaryToUTF8(objHttp.ResponseBody)
|
||||
Set objHttp = Nothing
|
||||
' Backup exitsing ca-bundle certificate file
|
||||
If (myCaBakF = TRUE) Then
|
||||
If objFSO.FileExists(myCaFile) Then
|
||||
Dim myBakFile, b
|
||||
b = 1
|
||||
myBakFile = myCaFile & ".~" & b & "~"
|
||||
While objFSO.FileExists(myBakFile)
|
||||
b = b + 1
|
||||
myBakFile = myCaFile & ".~" & b & "~"
|
||||
Wend
|
||||
Set myTmpFh = objFSO.GetFile(myCaFile)
|
||||
myTmpFh.Move myBakFile
|
||||
End If
|
||||
End If
|
||||
|
||||
' Process the received data
|
||||
Dim myLines, myPattern, myInsideCert, myInsideLicense, myLicenseText, myNumCerts, myNumSkipped
|
||||
Dim myLabel, myOctets, myData, myPem, myRev, myUntrusted, j
|
||||
myNumSkipped = 0
|
||||
myNumCerts = 0
|
||||
myData = ""
|
||||
myLines = Split(myCdData, vbLf, -1)
|
||||
Set myStream = CreateObject("ADODB.Stream")
|
||||
myStream.Open
|
||||
myStream.Type = adTypeText
|
||||
myStream.Charset = "utf-8"
|
||||
myStream.WriteText "##" & vbLf & _
|
||||
"## Bundle of CA Root Certificates" & vbLf & _
|
||||
"##" & vbLf & _
|
||||
"## Certificate data from Mozilla as of: " & _
|
||||
ConvertDateToString(LocalDateToUTC(Now)) & " GMT" & vbLf & _
|
||||
"##" & vbLf & _
|
||||
"## This is a bundle of X.509 certificates of public Certificate Authorities" & vbLf & _
|
||||
"## (CA). These were automatically extracted from Mozilla's root certificates" & vbLf & _
|
||||
"## file (certdata.txt). This file can be found in the mozilla source tree:" & vbLf & _
|
||||
"## " & myUrl & vbLf & _
|
||||
"##" & vbLf & _
|
||||
"## It contains the certificates in PEM format and therefore" & vbLf & _
|
||||
"## can be directly used with curl / libcurl / php_curl, or with" & vbLf & _
|
||||
"## an Apache+mod_ssl webserver for SSL client authentication." & vbLf & _
|
||||
"## Just configure this file as the SSLCACertificateFile." & vbLf & _
|
||||
"##" & vbLf & _
|
||||
"## Conversion done with mk-ca-bundle.vbs version " & myVersion & "." & vbLf
|
||||
If (myCdSavF = TRUE) And (myUseOpenSSL = TRUE) Then
|
||||
myStream.WriteText "## SHA256: " & FileSHA256(myCdFile) & vbLf
|
||||
End If
|
||||
myStream.WriteText "##" & vbLf & vbLf
|
||||
|
||||
myStream.WriteText vbLf
|
||||
For i = 0 To UBound(myLines)
|
||||
If InstrRev(myLines(i), "CKA_LABEL ") Then
|
||||
myPattern = "^CKA_LABEL\s+[A-Z0-9]+\s+""(.+?)"""
|
||||
myLabel = RegExprFirst(myPattern, myLines(i))
|
||||
End If
|
||||
If (myInsideCert = TRUE) Then
|
||||
If InstrRev(myLines(i), "END") Then
|
||||
myInsideCert = FALSE
|
||||
While (i < UBound(myLines)) And Not (myLines(i) = "#")
|
||||
i = i + 1
|
||||
If InstrRev(myLines(i), "CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR") Then
|
||||
myUntrusted = FALSE
|
||||
End If
|
||||
Wend
|
||||
If (myUntrusted = TRUE) Then
|
||||
myNumSkipped = myNumSkipped + 1
|
||||
Else
|
||||
myStream.WriteText myLabel & vbLf
|
||||
myStream.WriteText String(Len(myLabel), "=") & vbLf
|
||||
myPem = "-----BEGIN CERTIFICATE-----" & vbLf & _
|
||||
Base64Encode(myData) & vbLf & _
|
||||
"-----END CERTIFICATE-----" & vbLf
|
||||
If (myOptTxt = FALSE) Then
|
||||
myStream.WriteText myPem & vbLf
|
||||
Else
|
||||
Dim myCmd, myRval, myTmpIn, myTmpOut
|
||||
myTmpIn = objFSO.GetSpecialFolder(2).Path & "\" & objFSO.GetTempName
|
||||
myTmpOut = objFSO.GetSpecialFolder(2).Path & "\" & objFSO.GetTempName
|
||||
Set myTmpFh = objFSO.OpenTextFile(myTmpIn, 2, TRUE)
|
||||
myTmpFh.Write myPem
|
||||
myTmpFh.Close
|
||||
myCmd = """" & myOpenSSL & """ x509 -md5 -fingerprint -text " & _
|
||||
"-inform PEM -in " & myTmpIn & " -out " & myTmpOut
|
||||
myRval = objShell.Run (myCmd, 0, TRUE)
|
||||
objFSO.DeleteFile myTmpIn, TRUE
|
||||
If Not (myRval = 0) Then
|
||||
MsgBox("Failed to process PEM cert with OpenSSL commandline!"), vbCritical, mySelf
|
||||
objFSO.DeleteFile myTmpOut, TRUE
|
||||
WScript.Quit 3
|
||||
End If
|
||||
Set myTmpFh = objFSO.OpenTextFile(myTmpOut, 1)
|
||||
myStream.WriteText myTmpFh.ReadAll & vbLf
|
||||
myTmpFh.Close
|
||||
objFSO.DeleteFile myTmpOut, TRUE
|
||||
End If
|
||||
myNumCerts = myNumCerts + 1
|
||||
End If
|
||||
Else
|
||||
myOctets = Split(myLines(i), "\")
|
||||
For j = 1 To UBound(myOctets)
|
||||
myData = myData & Chr(CByte("&o" & myOctets(j)))
|
||||
Next
|
||||
End If
|
||||
End If
|
||||
If InstrRev(myLines(i), "CVS_ID ") Then
|
||||
myPattern = "^CVS_ID\s+""(.+?)"""
|
||||
myRev = RegExprFirst(myPattern, myLines(i))
|
||||
myStream.WriteText "# " & myRev & vbLf & vbLf
|
||||
End If
|
||||
If InstrRev(myLines(i), "CKA_VALUE MULTILINE_OCTAL") Then
|
||||
myInsideCert = TRUE
|
||||
myUntrusted = TRUE
|
||||
myData = ""
|
||||
End If
|
||||
If InstrRev(myLines(i), "***** BEGIN LICENSE BLOCK *****") Then
|
||||
myInsideLicense = TRUE
|
||||
End If
|
||||
If (myInsideLicense = TRUE) Then
|
||||
myStream.WriteText myLines(i) & vbLf
|
||||
myLicenseText = myLicenseText & Mid(myLines(i), 2) & vbLf
|
||||
End If
|
||||
If InstrRev(myLines(i), "***** END LICENSE BLOCK *****") Then
|
||||
myInsideLicense = FALSE
|
||||
If (myAskLiF = TRUE) Then
|
||||
If Not (6 = objShell.PopUp(myLicenseText & vbLf & _
|
||||
"Do you agree to the license shown above (required to proceed) ?",, _
|
||||
mySelf, vbQuestion + vbYesNo + vbDefaultButton1)) Then
|
||||
myStream.Close
|
||||
objFSO.DeleteFile myCaFile, TRUE
|
||||
WScript.Quit 2
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
|
||||
' To stop the UTF-8 BOM from being written the stream has to be copied and
|
||||
' then saved as binary.
|
||||
Dim myCopy
|
||||
Set myCopy = CreateObject("ADODB.Stream")
|
||||
myCopy.Type = adTypeBinary
|
||||
myCopy.Open
|
||||
myStream.Position = 3 ' Skip UTF-8 BOM
|
||||
myStream.CopyTo myCopy
|
||||
myCopy.SaveToFile myCaFile, adSaveCreateOverWrite
|
||||
myCopy.Close
|
||||
myStream.Close
|
||||
Set myCopy = Nothing
|
||||
Set myStream = Nothing
|
||||
|
||||
' Done
|
||||
objShell.PopUp "Done (" & myNumCerts & " CA certs processed, " & myNumSkipped & _
|
||||
" untrusted skipped).", 20, mySelf, vbInformation
|
||||
WScript.Quit 0
|
||||
|
||||
Function ConvertBinaryToUTF8(arrBytes)
|
||||
Dim objStream
|
||||
Set objStream = CreateObject("ADODB.Stream")
|
||||
objStream.Open
|
||||
objStream.Type = adTypeBinary
|
||||
objStream.Write arrBytes
|
||||
objStream.Position = 0
|
||||
objStream.Type = adTypeText
|
||||
objStream.Charset = "utf-8"
|
||||
ConvertBinaryToUTF8 = objStream.ReadText
|
||||
Set objStream = Nothing
|
||||
End Function
|
||||
|
||||
Function SaveBinaryData(filename, data)
|
||||
Dim objStream
|
||||
Set objStream = CreateObject("ADODB.Stream")
|
||||
objStream.Type = adTypeBinary
|
||||
objStream.Open
|
||||
objStream.Write data
|
||||
objStream.SaveToFile filename, adSaveCreateOverWrite
|
||||
objStream.Close
|
||||
Set objStream = Nothing
|
||||
End Function
|
||||
|
||||
Function RegExprFirst(SearchPattern, TheString)
|
||||
Dim objRegExp, Matches ' create variables.
|
||||
Set objRegExp = New RegExp ' create a regular expression.
|
||||
objRegExp.Pattern = SearchPattern ' sets the search pattern.
|
||||
objRegExp.IgnoreCase = TRUE ' set to ignores case.
|
||||
objRegExp.Global = TRUE ' set to gloabal search.
|
||||
Set Matches = objRegExp.Execute(TheString) ' do the search.
|
||||
If (Matches.Count) Then
|
||||
RegExprFirst = Matches(0).SubMatches(0) ' return first match.
|
||||
Else
|
||||
RegExprFirst = ""
|
||||
End If
|
||||
Set objRegExp = Nothing
|
||||
End Function
|
||||
|
||||
Function Base64Encode(inData)
|
||||
Const Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||
Dim cOut, sOut, lWrap, I
|
||||
lWrap = Int(myWrapLe * 3 / 4)
|
||||
|
||||
'For each group of 3 bytes
|
||||
For I = 1 To Len(inData) Step 3
|
||||
Dim nGroup, pOut, sGroup
|
||||
|
||||
'Create one long from this 3 bytes.
|
||||
nGroup = &H10000 * Asc(Mid(inData, I, 1)) + _
|
||||
&H100 * MyASC(Mid(inData, I + 1, 1)) + _
|
||||
MyASC(Mid(inData, I + 2, 1))
|
||||
|
||||
'Oct splits the long To 8 groups with 3 bits
|
||||
nGroup = Oct(nGroup)
|
||||
|
||||
'Add leading zeros
|
||||
nGroup = String(8 - Len(nGroup), "0") & nGroup
|
||||
|
||||
'Convert To base64
|
||||
pOut = Mid(Base64, CLng("&o" & Mid(nGroup, 1, 2)) + 1, 1) & _
|
||||
Mid(Base64, CLng("&o" & Mid(nGroup, 3, 2)) + 1, 1) & _
|
||||
Mid(Base64, CLng("&o" & Mid(nGroup, 5, 2)) + 1, 1) & _
|
||||
Mid(Base64, CLng("&o" & Mid(nGroup, 7, 2)) + 1, 1)
|
||||
|
||||
'Add the part To OutPut string
|
||||
sOut = sOut + pOut
|
||||
|
||||
'Add a new line For Each myWrapLe chars In dest
|
||||
If (I < Len(inData) - 2) Then
|
||||
If (I + 2) Mod lWrap = 0 Then sOut = sOut & vbLf
|
||||
End If
|
||||
Next
|
||||
Select Case Len(inData) Mod 3
|
||||
Case 1: '8 bit final
|
||||
sOut = Left(sOut, Len(sOut) - 2) & "=="
|
||||
Case 2: '16 bit final
|
||||
sOut = Left(sOut, Len(sOut) - 1) & "="
|
||||
End Select
|
||||
Base64Encode = sOut
|
||||
End Function
|
||||
|
||||
Function MyASC(OneChar)
|
||||
If OneChar = "" Then MyASC = 0 Else MyASC = Asc(OneChar)
|
||||
End Function
|
||||
|
||||
' Return the date in the same format as perl to match mk-ca-bundle.pl output:
|
||||
' Wed Sep 7 03:12:05 2016
|
||||
Function ConvertDateToString(input)
|
||||
Dim output
|
||||
output = WeekDayName(WeekDay(input), TRUE) & " " & _
|
||||
MonthName(Month(input), TRUE) & " "
|
||||
If (Len(Day(input)) = 1) Then
|
||||
output = output & " "
|
||||
End If
|
||||
output = output & _
|
||||
Day(input) & " " & _
|
||||
FormatDateTime(input, vbShortTime) & ":"
|
||||
If (Len(Second(input)) = 1) Then
|
||||
output = output & "0"
|
||||
End If
|
||||
output = output & _
|
||||
Second(input) & " " & _
|
||||
Year(input)
|
||||
ConvertDateToString = output
|
||||
End Function
|
||||
|
||||
' Convert local Date to UTC. Microsoft says:
|
||||
' Use Win32_ComputerSystem CurrentTimeZone property, because it automatically
|
||||
' adjusts the Time Zone bias for daylight saving time; Win32_Time Zone Bias
|
||||
' property does not.
|
||||
' https://msdn.microsoft.com/en-us/library/windows/desktop/ms696015.aspx
|
||||
Function LocalDateToUTC(localdate)
|
||||
Dim item, offset
|
||||
For Each item In GetObject("winmgmts:").InstancesOf("Win32_ComputerSystem")
|
||||
offset = item.CurrentTimeZone ' the offset in minutes
|
||||
Next
|
||||
If (offset < 0) Then
|
||||
LocalDateToUTC = DateAdd("n", ABS(offset), localdate)
|
||||
Else
|
||||
LocalDateToUTC = DateAdd("n", -ABS(offset), localdate)
|
||||
End If
|
||||
'objShell.PopUp LocalDateToUTC
|
||||
End Function
|
||||
|
||||
Function FileSHA256(filename)
|
||||
Dim cmd, rval, tmpOut, tmpFh
|
||||
if (myUseOpenSSL = TRUE) Then
|
||||
tmpOut = objFSO.GetSpecialFolder(2).Path & "\" & objFSO.GetTempName
|
||||
cmd = """" & myOpenSSL & """ dgst -r -sha256 -out """ & tmpOut & """ """ & filename & """"
|
||||
rval = objShell.Run(cmd, 0, TRUE)
|
||||
If Not (rval = 0) Then
|
||||
MsgBox("Failed to get sha256 of """ & filename & """ with OpenSSL commandline!"), vbCritical, mySelf
|
||||
objFSO.DeleteFile tmpOut, TRUE
|
||||
WScript.Quit 3
|
||||
End If
|
||||
Set tmpFh = objFSO.OpenTextFile(tmpOut, 1)
|
||||
FileSHA256 = RegExprFirst("^([0-9a-f]{64}) .+", tmpFh.ReadAll)
|
||||
tmpFh.Close
|
||||
objFSO.DeleteFile tmpOut, TRUE
|
||||
Else
|
||||
FileSHA256 = ""
|
||||
End If
|
||||
End Function
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,154 +0,0 @@
|
||||
#ifndef HEADER_CURL_MULTIHANDLE_H
|
||||
#define HEADER_CURL_MULTIHANDLE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "conncache.h"
|
||||
|
||||
struct Curl_message {
|
||||
/* the 'CURLMsg' is the part that is visible to the external user */
|
||||
struct CURLMsg extmsg;
|
||||
};
|
||||
|
||||
/* NOTE: if you add a state here, add the name to the statename[] array as
|
||||
well!
|
||||
*/
|
||||
typedef enum {
|
||||
CURLM_STATE_INIT, /* 0 - start in this state */
|
||||
CURLM_STATE_CONNECT_PEND, /* 1 - no connections, waiting for one */
|
||||
CURLM_STATE_CONNECT, /* 2 - resolve/connect has been sent off */
|
||||
CURLM_STATE_WAITRESOLVE, /* 3 - awaiting the resolve to finalize */
|
||||
CURLM_STATE_WAITCONNECT, /* 4 - awaiting the TCP connect to finalize */
|
||||
CURLM_STATE_WAITPROXYCONNECT, /* 5 - awaiting HTTPS proxy SSL initialization
|
||||
to complete and/or proxy CONNECT to
|
||||
finalize */
|
||||
CURLM_STATE_SENDPROTOCONNECT, /* 6 - initiate protocol connect procedure */
|
||||
CURLM_STATE_PROTOCONNECT, /* 7 - completing the protocol-specific connect
|
||||
phase */
|
||||
CURLM_STATE_WAITDO, /* 8 - wait for our turn to send the request */
|
||||
CURLM_STATE_DO, /* 9 - start send off the request (part 1) */
|
||||
CURLM_STATE_DOING, /* 10 - sending off the request (part 1) */
|
||||
CURLM_STATE_DO_MORE, /* 11 - send off the request (part 2) */
|
||||
CURLM_STATE_DO_DONE, /* 12 - done sending off request */
|
||||
CURLM_STATE_WAITPERFORM, /* 13 - wait for our turn to read the response */
|
||||
CURLM_STATE_PERFORM, /* 14 - transfer data */
|
||||
CURLM_STATE_TOOFAST, /* 15 - wait because limit-rate exceeded */
|
||||
CURLM_STATE_DONE, /* 16 - post data transfer operation */
|
||||
CURLM_STATE_COMPLETED, /* 17 - operation complete */
|
||||
CURLM_STATE_MSGSENT, /* 18 - the operation complete message is sent */
|
||||
CURLM_STATE_LAST /* 19 - not a true state, never use this */
|
||||
} CURLMstate;
|
||||
|
||||
/* we support N sockets per easy handle. Set the corresponding bit to what
|
||||
action we should wait for */
|
||||
#define MAX_SOCKSPEREASYHANDLE 5
|
||||
#define GETSOCK_READABLE (0x00ff)
|
||||
#define GETSOCK_WRITABLE (0xff00)
|
||||
|
||||
#define CURLPIPE_ANY (CURLPIPE_HTTP1 | CURLPIPE_MULTIPLEX)
|
||||
|
||||
/* This is the struct known as CURLM on the outside */
|
||||
struct Curl_multi {
|
||||
/* First a simple identifier to easier detect if a user mix up
|
||||
this multi handle with an easy handle. Set this to CURL_MULTI_HANDLE. */
|
||||
long type;
|
||||
|
||||
/* We have a doubly-linked circular list with easy handles */
|
||||
struct Curl_easy *easyp;
|
||||
struct Curl_easy *easylp; /* last node */
|
||||
|
||||
int num_easy; /* amount of entries in the linked list above. */
|
||||
int num_alive; /* amount of easy handles that are added but have not yet
|
||||
reached COMPLETE state */
|
||||
|
||||
struct curl_llist *msglist; /* a list of messages from completed transfers */
|
||||
|
||||
struct curl_llist *pending; /* Curl_easys that are in the
|
||||
CURLM_STATE_CONNECT_PEND state */
|
||||
|
||||
/* callback function and user data pointer for the *socket() API */
|
||||
curl_socket_callback socket_cb;
|
||||
void *socket_userp;
|
||||
|
||||
/* callback function and user data pointer for server push */
|
||||
curl_push_callback push_cb;
|
||||
void *push_userp;
|
||||
|
||||
/* Hostname cache */
|
||||
struct curl_hash hostcache;
|
||||
|
||||
/* timetree points to the splay-tree of time nodes to figure out expire
|
||||
times of all currently set timers */
|
||||
struct Curl_tree *timetree;
|
||||
|
||||
/* 'sockhash' is the lookup hash for socket descriptor => easy handles (note
|
||||
the pluralis form, there can be more than one easy handle waiting on the
|
||||
same actual socket) */
|
||||
struct curl_hash sockhash;
|
||||
|
||||
/* pipelining wanted bits (CURLPIPE*) */
|
||||
long pipelining;
|
||||
|
||||
bool recheckstate; /* see Curl_multi_connchanged */
|
||||
|
||||
/* Shared connection cache (bundles)*/
|
||||
struct conncache conn_cache;
|
||||
|
||||
/* This handle will be used for closing the cached connections in
|
||||
curl_multi_cleanup() */
|
||||
struct Curl_easy *closure_handle;
|
||||
|
||||
long maxconnects; /* if >0, a fixed limit of the maximum number of entries
|
||||
we're allowed to grow the connection cache to */
|
||||
|
||||
long max_host_connections; /* if >0, a fixed limit of the maximum number
|
||||
of connections per host */
|
||||
|
||||
long max_total_connections; /* if >0, a fixed limit of the maximum number
|
||||
of connections in total */
|
||||
|
||||
long max_pipeline_length; /* if >0, maximum number of requests in a
|
||||
pipeline */
|
||||
|
||||
long content_length_penalty_size; /* a connection with a
|
||||
content-length bigger than
|
||||
this is not considered
|
||||
for pipelining */
|
||||
|
||||
long chunk_length_penalty_size; /* a connection with a chunk length
|
||||
bigger than this is not
|
||||
considered for pipelining */
|
||||
|
||||
struct curl_llist *pipelining_site_bl; /* List of sites that are blacklisted
|
||||
from pipelining */
|
||||
|
||||
struct curl_llist *pipelining_server_bl; /* List of server types that are
|
||||
blacklisted from pipelining */
|
||||
|
||||
/* timer callback and user data pointer for the *socket() API */
|
||||
curl_multi_timer_callback timer_cb;
|
||||
void *timer_userp;
|
||||
struct timeval timer_lastcall; /* the fixed time for the timeout for the
|
||||
previous callback */
|
||||
};
|
||||
|
||||
#endif /* HEADER_CURL_MULTIHANDLE_H */
|
||||
@@ -1,98 +0,0 @@
|
||||
#ifndef HEADER_CURL_MULTIIF_H
|
||||
#define HEADER_CURL_MULTIIF_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* Prototypes for library-wide functions provided by multi.c
|
||||
*/
|
||||
void Curl_expire(struct Curl_easy *data, time_t milli);
|
||||
void Curl_expire_clear(struct Curl_easy *data);
|
||||
void Curl_expire_latest(struct Curl_easy *data, time_t milli);
|
||||
bool Curl_pipeline_wanted(const struct Curl_multi* multi, int bits);
|
||||
void Curl_multi_handlePipeBreak(struct Curl_easy *data);
|
||||
|
||||
/* Internal version of curl_multi_init() accepts size parameters for the
|
||||
socket and connection hashes */
|
||||
struct Curl_multi *Curl_multi_handle(int hashsize, int chashsize);
|
||||
|
||||
/* the write bits start at bit 16 for the *getsock() bitmap */
|
||||
#define GETSOCK_WRITEBITSTART 16
|
||||
|
||||
#define GETSOCK_BLANK 0 /* no bits set */
|
||||
|
||||
/* set the bit for the given sock number to make the bitmap for writable */
|
||||
#define GETSOCK_WRITESOCK(x) (1 << (GETSOCK_WRITEBITSTART + (x)))
|
||||
|
||||
/* set the bit for the given sock number to make the bitmap for readable */
|
||||
#define GETSOCK_READSOCK(x) (1 << (x))
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
/*
|
||||
* Curl_multi_dump is not a stable public function, this is only meant to
|
||||
* allow easier tracking of the internal handle's state and what sockets
|
||||
* they use. Only for research and development DEBUGBUILD enabled builds.
|
||||
*/
|
||||
void Curl_multi_dump(struct Curl_multi *multi);
|
||||
#endif
|
||||
|
||||
void Curl_multi_process_pending_handles(struct Curl_multi *multi);
|
||||
|
||||
/* Return the value of the CURLMOPT_MAX_HOST_CONNECTIONS option */
|
||||
size_t Curl_multi_max_host_connections(struct Curl_multi *multi);
|
||||
|
||||
/* Return the value of the CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE option */
|
||||
curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi);
|
||||
|
||||
/* Return the value of the CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE option */
|
||||
curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi);
|
||||
|
||||
/* Return the value of the CURLMOPT_PIPELINING_SITE_BL option */
|
||||
struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi);
|
||||
|
||||
/* Return the value of the CURLMOPT_PIPELINING_SERVER_BL option */
|
||||
struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi);
|
||||
|
||||
/* Return the value of the CURLMOPT_MAX_TOTAL_CONNECTIONS option */
|
||||
size_t Curl_multi_max_total_connections(struct Curl_multi *multi);
|
||||
|
||||
void Curl_multi_connchanged(struct Curl_multi *multi);
|
||||
|
||||
/*
|
||||
* Curl_multi_closed()
|
||||
*
|
||||
* Used by the connect code to tell the multi_socket code that one of the
|
||||
* sockets we were using is about to be closed. This function will then
|
||||
* remove it from the sockethash for this handle to make the multi_socket API
|
||||
* behave properly, especially for the case when libcurl will create another
|
||||
* socket again and it gets the same file descriptor number.
|
||||
*/
|
||||
|
||||
void Curl_multi_closed(struct connectdata *conn, curl_socket_t s);
|
||||
|
||||
/*
|
||||
* Add a handle and move it into PERFORM state at once. For pushed streams.
|
||||
*/
|
||||
CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
#endif /* HEADER_CURL_MULTIIF_H */
|
||||
@@ -1,201 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "netrc.h"
|
||||
#include "strtok.h"
|
||||
#include "strcase.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* Get user and password from .netrc when given a machine name */
|
||||
|
||||
enum host_lookup_state {
|
||||
NOTHING,
|
||||
HOSTFOUND, /* the 'machine' keyword was found */
|
||||
HOSTVALID /* this is "our" machine! */
|
||||
};
|
||||
|
||||
/*
|
||||
* @unittest: 1304
|
||||
*
|
||||
* *loginp and *passwordp MUST be allocated if they aren't NULL when passed
|
||||
* in.
|
||||
*/
|
||||
int Curl_parsenetrc(const char *host,
|
||||
char **loginp,
|
||||
char **passwordp,
|
||||
char *netrcfile)
|
||||
{
|
||||
FILE *file;
|
||||
int retcode=1;
|
||||
int specific_login = (*loginp && **loginp != 0);
|
||||
bool netrc_alloc = FALSE;
|
||||
enum host_lookup_state state=NOTHING;
|
||||
|
||||
char state_login=0; /* Found a login keyword */
|
||||
char state_password=0; /* Found a password keyword */
|
||||
int state_our_login=FALSE; /* With specific_login, found *our* login name */
|
||||
|
||||
#define NETRC DOT_CHAR "netrc"
|
||||
|
||||
if(!netrcfile) {
|
||||
bool home_alloc = FALSE;
|
||||
char *home = curl_getenv("HOME"); /* portable environment reader */
|
||||
if(home) {
|
||||
home_alloc = TRUE;
|
||||
#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
|
||||
}
|
||||
else {
|
||||
struct passwd pw, *pw_res;
|
||||
char pwbuf[1024];
|
||||
if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res)
|
||||
&& pw_res) {
|
||||
home = strdup(pw.pw_dir);
|
||||
if(!home)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
home_alloc = TRUE;
|
||||
}
|
||||
#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
|
||||
}
|
||||
else {
|
||||
struct passwd *pw;
|
||||
pw= getpwuid(geteuid());
|
||||
if(pw) {
|
||||
home = pw->pw_dir;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if(!home)
|
||||
return retcode; /* no home directory found (or possibly out of memory) */
|
||||
|
||||
netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC);
|
||||
if(home_alloc)
|
||||
free(home);
|
||||
if(!netrcfile) {
|
||||
return -1;
|
||||
}
|
||||
netrc_alloc = TRUE;
|
||||
}
|
||||
|
||||
file = fopen(netrcfile, FOPEN_READTEXT);
|
||||
if(netrc_alloc)
|
||||
free(netrcfile);
|
||||
if(file) {
|
||||
char *tok;
|
||||
char *tok_buf;
|
||||
bool done=FALSE;
|
||||
char netrcbuffer[256];
|
||||
int netrcbuffsize = (int)sizeof(netrcbuffer);
|
||||
|
||||
while(!done && fgets(netrcbuffer, netrcbuffsize, file)) {
|
||||
tok=strtok_r(netrcbuffer, " \t\n", &tok_buf);
|
||||
while(!done && tok) {
|
||||
|
||||
if((*loginp && **loginp) && (*passwordp && **passwordp)) {
|
||||
done=TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(state) {
|
||||
case NOTHING:
|
||||
if(strcasecompare("machine", tok)) {
|
||||
/* the next tok is the machine name, this is in itself the
|
||||
delimiter that starts the stuff entered for this machine,
|
||||
after this we need to search for 'login' and
|
||||
'password'. */
|
||||
state=HOSTFOUND;
|
||||
}
|
||||
else if(strcasecompare("default", tok)) {
|
||||
state=HOSTVALID;
|
||||
retcode=0; /* we did find our host */
|
||||
}
|
||||
break;
|
||||
case HOSTFOUND:
|
||||
if(strcasecompare(host, tok)) {
|
||||
/* and yes, this is our host! */
|
||||
state=HOSTVALID;
|
||||
retcode=0; /* we did find our host */
|
||||
}
|
||||
else
|
||||
/* not our host */
|
||||
state=NOTHING;
|
||||
break;
|
||||
case HOSTVALID:
|
||||
/* we are now parsing sub-keywords concerning "our" host */
|
||||
if(state_login) {
|
||||
if(specific_login) {
|
||||
state_our_login = strcasecompare(*loginp, tok);
|
||||
}
|
||||
else {
|
||||
free(*loginp);
|
||||
*loginp = strdup(tok);
|
||||
if(!*loginp) {
|
||||
retcode = -1; /* allocation failed */
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
state_login=0;
|
||||
}
|
||||
else if(state_password) {
|
||||
if(state_our_login || !specific_login) {
|
||||
free(*passwordp);
|
||||
*passwordp = strdup(tok);
|
||||
if(!*passwordp) {
|
||||
retcode = -1; /* allocation failed */
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
state_password=0;
|
||||
}
|
||||
else if(strcasecompare("login", tok))
|
||||
state_login=1;
|
||||
else if(strcasecompare("password", tok))
|
||||
state_password=1;
|
||||
else if(strcasecompare("machine", tok)) {
|
||||
/* ok, there's machine here go => */
|
||||
state = HOSTFOUND;
|
||||
state_our_login = FALSE;
|
||||
}
|
||||
break;
|
||||
} /* switch (state) */
|
||||
|
||||
tok = strtok_r(NULL, " \t\n", &tok_buf);
|
||||
} /* while(tok) */
|
||||
} /* while fgets() */
|
||||
|
||||
out:
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
return retcode;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
#ifndef HEADER_CURL_NETRC_H
|
||||
#define HEADER_CURL_NETRC_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 https://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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */
|
||||
int Curl_parsenetrc(const char *host,
|
||||
char **loginp,
|
||||
char **passwordp,
|
||||
char *filename);
|
||||
/* Assume: (*passwordp)[0]=0, host[0] != 0.
|
||||
* If (*loginp)[0] = 0, search for login and password within a machine
|
||||
* section in the netrc.
|
||||
* If (*loginp)[0] != 0, search for password within machine and login.
|
||||
*/
|
||||
|
||||
#endif /* HEADER_CURL_NETRC_H */
|
||||
@@ -1,338 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "non-ascii.h"
|
||||
#include "formdata.h"
|
||||
#include "sendf.h"
|
||||
#include "urldata.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef HAVE_ICONV
|
||||
#include <iconv.h>
|
||||
/* set default codesets for iconv */
|
||||
#ifndef CURL_ICONV_CODESET_OF_NETWORK
|
||||
#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
|
||||
#endif
|
||||
#ifndef CURL_ICONV_CODESET_FOR_UTF8
|
||||
#define CURL_ICONV_CODESET_FOR_UTF8 "UTF-8"
|
||||
#endif
|
||||
#define ICONV_ERROR (size_t)-1
|
||||
#endif /* HAVE_ICONV */
|
||||
|
||||
/*
|
||||
* Curl_convert_clone() returns a malloced copy of the source string (if
|
||||
* returning CURLE_OK), with the data converted to network format.
|
||||
*/
|
||||
CURLcode Curl_convert_clone(struct Curl_easy *data,
|
||||
const char *indata,
|
||||
size_t insize,
|
||||
char **outbuf)
|
||||
{
|
||||
char *convbuf;
|
||||
CURLcode result;
|
||||
|
||||
convbuf = malloc(insize);
|
||||
if(!convbuf)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
memcpy(convbuf, indata, insize);
|
||||
result = Curl_convert_to_network(data, convbuf, insize);
|
||||
if(result) {
|
||||
free(convbuf);
|
||||
return result;
|
||||
}
|
||||
|
||||
*outbuf = convbuf; /* return the converted buffer */
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_convert_to_network() is an internal function for performing ASCII
|
||||
* conversions on non-ASCII platforms. It convers the buffer _in place_.
|
||||
*/
|
||||
CURLcode Curl_convert_to_network(struct Curl_easy *data,
|
||||
char *buffer, size_t length)
|
||||
{
|
||||
if(data->set.convtonetwork) {
|
||||
/* use translation callback */
|
||||
CURLcode result = data->set.convtonetwork(buffer, length);
|
||||
if(result) {
|
||||
failf(data,
|
||||
"CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %d: %s",
|
||||
(int)result, curl_easy_strerror(result));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
#ifdef HAVE_ICONV
|
||||
/* do the translation ourselves */
|
||||
char *input_ptr, *output_ptr;
|
||||
size_t in_bytes, out_bytes, rc;
|
||||
int error;
|
||||
|
||||
/* open an iconv conversion descriptor if necessary */
|
||||
if(data->outbound_cd == (iconv_t)-1) {
|
||||
data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
|
||||
CURL_ICONV_CODESET_OF_HOST);
|
||||
if(data->outbound_cd == (iconv_t)-1) {
|
||||
error = ERRNO;
|
||||
failf(data,
|
||||
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
|
||||
CURL_ICONV_CODESET_OF_NETWORK,
|
||||
CURL_ICONV_CODESET_OF_HOST,
|
||||
error, strerror(error));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
}
|
||||
/* call iconv */
|
||||
input_ptr = output_ptr = buffer;
|
||||
in_bytes = out_bytes = length;
|
||||
rc = iconv(data->outbound_cd, (const char **)&input_ptr, &in_bytes,
|
||||
&output_ptr, &out_bytes);
|
||||
if((rc == ICONV_ERROR) || (in_bytes != 0)) {
|
||||
error = ERRNO;
|
||||
failf(data,
|
||||
"The Curl_convert_to_network iconv call failed with errno %i: %s",
|
||||
error, strerror(error));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
#else
|
||||
failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required");
|
||||
return CURLE_CONV_REQD;
|
||||
#endif /* HAVE_ICONV */
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_convert_from_network() is an internal function for performing ASCII
|
||||
* conversions on non-ASCII platforms. It convers the buffer _in place_.
|
||||
*/
|
||||
CURLcode Curl_convert_from_network(struct Curl_easy *data,
|
||||
char *buffer, size_t length)
|
||||
{
|
||||
if(data->set.convfromnetwork) {
|
||||
/* use translation callback */
|
||||
CURLcode result = data->set.convfromnetwork(buffer, length);
|
||||
if(result) {
|
||||
failf(data,
|
||||
"CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %d: %s",
|
||||
(int)result, curl_easy_strerror(result));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
#ifdef HAVE_ICONV
|
||||
/* do the translation ourselves */
|
||||
char *input_ptr, *output_ptr;
|
||||
size_t in_bytes, out_bytes, rc;
|
||||
int error;
|
||||
|
||||
/* open an iconv conversion descriptor if necessary */
|
||||
if(data->inbound_cd == (iconv_t)-1) {
|
||||
data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_OF_NETWORK);
|
||||
if(data->inbound_cd == (iconv_t)-1) {
|
||||
error = ERRNO;
|
||||
failf(data,
|
||||
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
|
||||
CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_OF_NETWORK,
|
||||
error, strerror(error));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
}
|
||||
/* call iconv */
|
||||
input_ptr = output_ptr = buffer;
|
||||
in_bytes = out_bytes = length;
|
||||
rc = iconv(data->inbound_cd, (const char **)&input_ptr, &in_bytes,
|
||||
&output_ptr, &out_bytes);
|
||||
if((rc == ICONV_ERROR) || (in_bytes != 0)) {
|
||||
error = ERRNO;
|
||||
failf(data,
|
||||
"Curl_convert_from_network iconv call failed with errno %i: %s",
|
||||
error, strerror(error));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
#else
|
||||
failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required");
|
||||
return CURLE_CONV_REQD;
|
||||
#endif /* HAVE_ICONV */
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_convert_from_utf8() is an internal function for performing UTF-8
|
||||
* conversions on non-ASCII platforms.
|
||||
*/
|
||||
CURLcode Curl_convert_from_utf8(struct Curl_easy *data,
|
||||
char *buffer, size_t length)
|
||||
{
|
||||
if(data->set.convfromutf8) {
|
||||
/* use translation callback */
|
||||
CURLcode result = data->set.convfromutf8(buffer, length);
|
||||
if(result) {
|
||||
failf(data,
|
||||
"CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %d: %s",
|
||||
(int)result, curl_easy_strerror(result));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
#ifdef HAVE_ICONV
|
||||
/* do the translation ourselves */
|
||||
const char *input_ptr;
|
||||
char *output_ptr;
|
||||
size_t in_bytes, out_bytes, rc;
|
||||
int error;
|
||||
|
||||
/* open an iconv conversion descriptor if necessary */
|
||||
if(data->utf8_cd == (iconv_t)-1) {
|
||||
data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_FOR_UTF8);
|
||||
if(data->utf8_cd == (iconv_t)-1) {
|
||||
error = ERRNO;
|
||||
failf(data,
|
||||
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
|
||||
CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_FOR_UTF8,
|
||||
error, strerror(error));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
}
|
||||
/* call iconv */
|
||||
input_ptr = output_ptr = buffer;
|
||||
in_bytes = out_bytes = length;
|
||||
rc = iconv(data->utf8_cd, &input_ptr, &in_bytes,
|
||||
&output_ptr, &out_bytes);
|
||||
if((rc == ICONV_ERROR) || (in_bytes != 0)) {
|
||||
error = ERRNO;
|
||||
failf(data,
|
||||
"The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
|
||||
error, strerror(error));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
if(output_ptr < input_ptr) {
|
||||
/* null terminate the now shorter output string */
|
||||
*output_ptr = 0x00;
|
||||
}
|
||||
#else
|
||||
failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required");
|
||||
return CURLE_CONV_REQD;
|
||||
#endif /* HAVE_ICONV */
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Init conversion stuff for a Curl_easy
|
||||
*/
|
||||
void Curl_convert_init(struct Curl_easy *data)
|
||||
{
|
||||
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
|
||||
/* conversion descriptors for iconv calls */
|
||||
data->outbound_cd = (iconv_t)-1;
|
||||
data->inbound_cd = (iconv_t)-1;
|
||||
data->utf8_cd = (iconv_t)-1;
|
||||
#else
|
||||
(void)data;
|
||||
#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup conversion stuff for a Curl_easy
|
||||
*/
|
||||
void Curl_convert_setup(struct Curl_easy *data)
|
||||
{
|
||||
data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_OF_NETWORK);
|
||||
data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
|
||||
CURL_ICONV_CODESET_OF_HOST);
|
||||
data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_FOR_UTF8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Close conversion stuff for a Curl_easy
|
||||
*/
|
||||
|
||||
void Curl_convert_close(struct Curl_easy *data)
|
||||
{
|
||||
#ifdef HAVE_ICONV
|
||||
/* close iconv conversion descriptors */
|
||||
if(data->inbound_cd != (iconv_t)-1) {
|
||||
iconv_close(data->inbound_cd);
|
||||
}
|
||||
if(data->outbound_cd != (iconv_t)-1) {
|
||||
iconv_close(data->outbound_cd);
|
||||
}
|
||||
if(data->utf8_cd != (iconv_t)-1) {
|
||||
iconv_close(data->utf8_cd);
|
||||
}
|
||||
#else
|
||||
(void)data;
|
||||
#endif /* HAVE_ICONV */
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_convert_form() is used from http.c, this converts any form items that
|
||||
need to be sent in the network encoding. Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_convert_form(struct Curl_easy *data, struct FormData *form)
|
||||
{
|
||||
CURLcode result;
|
||||
|
||||
if(!data)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
while(form) {
|
||||
if(form->type == FORM_DATA) {
|
||||
result = Curl_convert_to_network(data, form->line, form->length);
|
||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
form = form->next;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
@@ -1,63 +0,0 @@
|
||||
#ifndef HEADER_CURL_NON_ASCII_H
|
||||
#define HEADER_CURL_NON_ASCII_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 https://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 "curl_setup.h"
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
|
||||
#include "urldata.h"
|
||||
|
||||
/*
|
||||
* Curl_convert_clone() returns a malloced copy of the source string (if
|
||||
* returning CURLE_OK), with the data converted to network format.
|
||||
*
|
||||
* If no conversion was needed *outbuf may be NULL.
|
||||
*/
|
||||
CURLcode Curl_convert_clone(struct Curl_easy *data,
|
||||
const char *indata,
|
||||
size_t insize,
|
||||
char **outbuf);
|
||||
|
||||
void Curl_convert_init(struct Curl_easy *data);
|
||||
void Curl_convert_setup(struct Curl_easy *data);
|
||||
void Curl_convert_close(struct Curl_easy *data);
|
||||
|
||||
CURLcode Curl_convert_to_network(struct Curl_easy *data,
|
||||
char *buffer, size_t length);
|
||||
CURLcode Curl_convert_from_network(struct Curl_easy *data,
|
||||
char *buffer, size_t length);
|
||||
CURLcode Curl_convert_from_utf8(struct Curl_easy *data,
|
||||
char *buffer, size_t length);
|
||||
CURLcode Curl_convert_form(struct Curl_easy *data, struct FormData *form);
|
||||
#else
|
||||
#define Curl_convert_clone(a,b,c,d) ((void)a, CURLE_OK)
|
||||
#define Curl_convert_init(x) Curl_nop_stmt
|
||||
#define Curl_convert_setup(x) Curl_nop_stmt
|
||||
#define Curl_convert_close(x) Curl_nop_stmt
|
||||
#define Curl_convert_to_network(a,b,c) ((void)a, CURLE_OK)
|
||||
#define Curl_convert_from_network(a,b,c) ((void)a, CURLE_OK)
|
||||
#define Curl_convert_from_utf8(a,b,c) ((void)a, CURLE_OK)
|
||||
#define Curl_convert_form(a,b) CURLE_OK
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_NON_ASCII_H */
|
||||
@@ -1,91 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#if (defined(HAVE_IOCTL_FIONBIO) && defined(NETWARE))
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
#ifdef __VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
#endif
|
||||
|
||||
#include "nonblock.h"
|
||||
|
||||
/*
|
||||
* curlx_nonblock() set the given socket to either blocking or non-blocking
|
||||
* mode based on the 'nonblock' boolean argument. This function is highly
|
||||
* portable.
|
||||
*/
|
||||
int curlx_nonblock(curl_socket_t sockfd, /* operate on this */
|
||||
int nonblock /* TRUE or FALSE */)
|
||||
{
|
||||
#if defined(USE_BLOCKING_SOCKETS)
|
||||
|
||||
return 0; /* returns success */
|
||||
|
||||
#elif defined(HAVE_FCNTL_O_NONBLOCK)
|
||||
|
||||
/* most recent unix versions */
|
||||
int flags;
|
||||
flags = sfcntl(sockfd, F_GETFL, 0);
|
||||
if(nonblock)
|
||||
return sfcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||
else
|
||||
return sfcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
|
||||
|
||||
#elif defined(HAVE_IOCTL_FIONBIO)
|
||||
|
||||
/* older unix versions */
|
||||
int flags = nonblock ? 1 : 0;
|
||||
return ioctl(sockfd, FIONBIO, &flags);
|
||||
|
||||
#elif defined(HAVE_IOCTLSOCKET_FIONBIO)
|
||||
|
||||
/* Windows */
|
||||
unsigned long flags = nonblock ? 1UL : 0UL;
|
||||
return ioctlsocket(sockfd, FIONBIO, &flags);
|
||||
|
||||
#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
|
||||
|
||||
/* Amiga */
|
||||
long flags = nonblock ? 1L : 0L;
|
||||
return IoctlSocket(sockfd, FIONBIO, (char *)&flags);
|
||||
|
||||
#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
|
||||
|
||||
/* BeOS */
|
||||
long b = nonblock ? 1L : 0L;
|
||||
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
|
||||
|
||||
#else
|
||||
# error "no non-blocking method was found/used/set"
|
||||
#endif
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#ifndef HEADER_CURL_NONBLOCK_H
|
||||
#define HEADER_CURL_NONBLOCK_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 <curl/curl.h> /* for curl_socket_t */
|
||||
|
||||
int curlx_nonblock(curl_socket_t sockfd, /* operate on this */
|
||||
int nonblock /* TRUE or FALSE */);
|
||||
|
||||
#endif /* HEADER_CURL_NONBLOCK_H */
|
||||
|
||||
@@ -1,327 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#ifdef NETWARE /* Novell NetWare */
|
||||
|
||||
#ifdef __NOVELL_LIBC__
|
||||
/* For native LibC-based NLM we need to register as a real lib. */
|
||||
#include <library.h>
|
||||
#include <netware.h>
|
||||
#include <screen.h>
|
||||
#include <nks/thread.h>
|
||||
#include <nks/synch.h>
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int _errno;
|
||||
void *twentybytes;
|
||||
} libthreaddata_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
void *tenbytes;
|
||||
NXKey_t perthreadkey; /* if -1, no key obtained... */
|
||||
NXMutex_t *lock;
|
||||
} libdata_t;
|
||||
|
||||
int gLibId = -1;
|
||||
void *gLibHandle = (void *) NULL;
|
||||
rtag_t gAllocTag = (rtag_t) NULL;
|
||||
NXMutex_t *gLibLock = (NXMutex_t *) NULL;
|
||||
|
||||
/* internal library function prototypes... */
|
||||
int DisposeLibraryData(void *);
|
||||
void DisposeThreadData(void *);
|
||||
int GetOrSetUpData(int id, libdata_t **data, libthreaddata_t **threaddata);
|
||||
|
||||
|
||||
int _NonAppStart(void *NLMHandle,
|
||||
void *errorScreen,
|
||||
const char *cmdLine,
|
||||
const char *loadDirPath,
|
||||
size_t uninitializedDataLength,
|
||||
void *NLMFileHandle,
|
||||
int (*readRoutineP)(int conn,
|
||||
void *fileHandle, size_t offset,
|
||||
size_t nbytes,
|
||||
size_t *bytesRead,
|
||||
void *buffer),
|
||||
size_t customDataOffset,
|
||||
size_t customDataSize,
|
||||
int messageCount,
|
||||
const char **messages)
|
||||
{
|
||||
NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0);
|
||||
|
||||
#ifndef __GNUC__
|
||||
#pragma unused(cmdLine)
|
||||
#pragma unused(loadDirPath)
|
||||
#pragma unused(uninitializedDataLength)
|
||||
#pragma unused(NLMFileHandle)
|
||||
#pragma unused(readRoutineP)
|
||||
#pragma unused(customDataOffset)
|
||||
#pragma unused(customDataSize)
|
||||
#pragma unused(messageCount)
|
||||
#pragma unused(messages)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Here we process our command line, post errors (to the error screen),
|
||||
* perform initializations and anything else we need to do before being able
|
||||
* to accept calls into us. If we succeed, we return non-zero and the NetWare
|
||||
* Loader will leave us up, otherwise we fail to load and get dumped.
|
||||
*/
|
||||
gAllocTag = AllocateResourceTag(NLMHandle,
|
||||
"<library-name> memory allocations",
|
||||
AllocSignature);
|
||||
|
||||
if(!gAllocTag) {
|
||||
OutputToScreen(errorScreen, "Unable to allocate resource tag for "
|
||||
"library memory allocations.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gLibId = register_library(DisposeLibraryData);
|
||||
|
||||
if(gLibId < -1) {
|
||||
OutputToScreen(errorScreen, "Unable to register library with kernel.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gLibHandle = NLMHandle;
|
||||
|
||||
gLibLock = NXMutexAlloc(0, 0, &liblock);
|
||||
|
||||
if(!gLibLock) {
|
||||
OutputToScreen(errorScreen, "Unable to allocate library data lock.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we clean up any resources we allocated. Resource tags is a big part
|
||||
* of what we created, but NetWare doesn't ask us to free those.
|
||||
*/
|
||||
void _NonAppStop(void)
|
||||
{
|
||||
(void) unregister_library(gLibId);
|
||||
NXMutexFree(gLibLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function cannot be the first in the file for if the file is linked
|
||||
* first, then the check-unload function's offset will be nlmname.nlm+0
|
||||
* which is how to tell that there isn't one. When the check function is
|
||||
* first in the linked objects, it is ambiguous. For this reason, we will
|
||||
* put it inside this file after the stop function.
|
||||
*
|
||||
* Here we check to see if it's alright to ourselves to be unloaded. If not,
|
||||
* we return a non-zero value. Right now, there isn't any reason not to allow
|
||||
* it.
|
||||
*/
|
||||
int _NonAppCheckUnload(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetOrSetUpData(int id, libdata_t **appData,
|
||||
libthreaddata_t **threadData)
|
||||
{
|
||||
int err;
|
||||
libdata_t *app_data;
|
||||
libthreaddata_t *thread_data;
|
||||
NXKey_t key;
|
||||
NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0);
|
||||
|
||||
err = 0;
|
||||
thread_data = (libthreaddata_t *) NULL;
|
||||
|
||||
/*
|
||||
* Attempt to get our data for the application calling us. This is where we
|
||||
* store whatever application-specific information we need to carry in
|
||||
* support of calling applications.
|
||||
*/
|
||||
app_data = (libdata_t *) get_app_data(id);
|
||||
|
||||
if(!app_data) {
|
||||
/*
|
||||
* This application hasn't called us before; set up application AND
|
||||
* per-thread data. Of course, just in case a thread from this same
|
||||
* application is calling us simultaneously, we better lock our application
|
||||
* data-creation mutex. We also need to recheck for data after we acquire
|
||||
* the lock because WE might be that other thread that was too late to
|
||||
* create the data and the first thread in will have created it.
|
||||
*/
|
||||
NXLock(gLibLock);
|
||||
|
||||
app_data = (libdata_t *) get_app_data(id);
|
||||
if(!app_data) {
|
||||
app_data = malloc(sizeof(libdata_t));
|
||||
|
||||
if(app_data) {
|
||||
memset(app_data, 0, sizeof(libdata_t));
|
||||
|
||||
app_data->tenbytes = malloc(10);
|
||||
app_data->lock = NXMutexAlloc(0, 0, &liblock);
|
||||
|
||||
if(!app_data->tenbytes || !app_data->lock) {
|
||||
if(app_data->lock)
|
||||
NXMutexFree(app_data->lock);
|
||||
|
||||
free(app_data);
|
||||
app_data = (libdata_t *) NULL;
|
||||
err = ENOMEM;
|
||||
}
|
||||
|
||||
if(app_data) {
|
||||
/*
|
||||
* Here we burn in the application data that we were trying to get
|
||||
* by calling get_app_data(). Next time we call the first function,
|
||||
* we'll get this data we're just now setting. We also go on here to
|
||||
* establish the per-thread data for the calling thread, something
|
||||
* we'll have to do on each application thread the first time
|
||||
* it calls us.
|
||||
*/
|
||||
err = set_app_data(gLibId, app_data);
|
||||
|
||||
if(err) {
|
||||
free(app_data);
|
||||
app_data = (libdata_t *) NULL;
|
||||
err = ENOMEM;
|
||||
}
|
||||
else {
|
||||
/* create key for thread-specific data... */
|
||||
err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key);
|
||||
|
||||
if(err) /* (no more keys left?) */
|
||||
key = -1;
|
||||
|
||||
app_data->perthreadkey = key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NXUnlock(gLibLock);
|
||||
}
|
||||
|
||||
if(app_data) {
|
||||
key = app_data->perthreadkey;
|
||||
|
||||
if(key != -1 /* couldn't create a key? no thread data */
|
||||
&& !(err = NXKeyGetValue(key, (void **) &thread_data))
|
||||
&& !thread_data) {
|
||||
/*
|
||||
* Allocate the per-thread data for the calling thread. Regardless of
|
||||
* whether there was already application data or not, this may be the
|
||||
* first call by a new thread. The fact that we allocation 20 bytes on
|
||||
* a pointer is not very important, this just helps to demonstrate that
|
||||
* we can have arbitrarily complex per-thread data.
|
||||
*/
|
||||
thread_data = malloc(sizeof(libthreaddata_t));
|
||||
|
||||
if(thread_data) {
|
||||
thread_data->_errno = 0;
|
||||
thread_data->twentybytes = malloc(20);
|
||||
|
||||
if(!thread_data->twentybytes) {
|
||||
free(thread_data);
|
||||
thread_data = (libthreaddata_t *) NULL;
|
||||
err = ENOMEM;
|
||||
}
|
||||
|
||||
err = NXKeySetValue(key, thread_data);
|
||||
if(err) {
|
||||
free(thread_data->twentybytes);
|
||||
free(thread_data);
|
||||
thread_data = (libthreaddata_t *) NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(appData)
|
||||
*appData = app_data;
|
||||
|
||||
if(threadData)
|
||||
*threadData = thread_data;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int DisposeLibraryData(void *data)
|
||||
{
|
||||
if(data) {
|
||||
void *tenbytes = ((libdata_t *) data)->tenbytes;
|
||||
|
||||
free(tenbytes);
|
||||
free(data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DisposeThreadData(void *data)
|
||||
{
|
||||
if(data) {
|
||||
void *twentybytes = ((libthreaddata_t *) data)->twentybytes;
|
||||
|
||||
free(twentybytes);
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
#else /* __NOVELL_LIBC__ */
|
||||
/* For native CLib-based NLM seems we can do a bit more simple. */
|
||||
#include <nwthread.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* initialize any globals here... */
|
||||
|
||||
/* do this if any global initializing was done
|
||||
SynchronizeStart();
|
||||
*/
|
||||
ExitThread(TSR_THREAD, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __NOVELL_LIBC__ */
|
||||
|
||||
#else /* NETWARE */
|
||||
|
||||
#ifdef __POCC__
|
||||
# pragma warn(disable:2024) /* Disable warning #2024: Empty input file */
|
||||
#endif
|
||||
|
||||
#endif /* NETWARE */
|
||||
@@ -1,88 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#ifdef NETWARE /* Novell NetWare */
|
||||
|
||||
#ifdef __NOVELL_LIBC__
|
||||
/* For native LibC-based NLM we need to do nothing. */
|
||||
int netware_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* __NOVELL_LIBC__ */
|
||||
|
||||
/* For native CLib-based NLM we need to initialize the LONG namespace. */
|
||||
#include <nwnspace.h>
|
||||
#include <nwthread.h>
|
||||
#include <nwadv.h>
|
||||
/* Make the CLIB Ctx stuff link */
|
||||
#include <netdb.h>
|
||||
NETDB_DEFINE_CONTEXT
|
||||
/* Make the CLIB Inet stuff link */
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
NETINET_DEFINE_CONTEXT
|
||||
|
||||
int netware_init(void)
|
||||
{
|
||||
int rc = 0;
|
||||
unsigned int myHandle = GetNLMHandle();
|
||||
/* import UnAugmentAsterisk dynamically for NW4.x compatibility */
|
||||
void (*pUnAugmentAsterisk)(int) = (void(*)(int))
|
||||
ImportSymbol(myHandle, "UnAugmentAsterisk");
|
||||
/* import UseAccurateCaseForPaths dynamically for NW3.x compatibility */
|
||||
void (*pUseAccurateCaseForPaths)(int) = (void(*)(int))
|
||||
ImportSymbol(myHandle, "UseAccurateCaseForPaths");
|
||||
if(pUnAugmentAsterisk)
|
||||
pUnAugmentAsterisk(1);
|
||||
if(pUseAccurateCaseForPaths)
|
||||
pUseAccurateCaseForPaths(1);
|
||||
UnimportSymbol(myHandle, "UnAugmentAsterisk");
|
||||
UnimportSymbol(myHandle, "UseAccurateCaseForPaths");
|
||||
/* set long name space */
|
||||
if((SetCurrentNameSpace(4) == 255)) {
|
||||
rc = 1;
|
||||
}
|
||||
if((SetTargetNameSpace(4) == 255)) {
|
||||
rc = rc + 2;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* dummy function to satisfy newer prelude */
|
||||
int __init_environment(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* dummy function to satisfy newer prelude */
|
||||
int __deinit_environment(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __NOVELL_LIBC__ */
|
||||
|
||||
#endif /* NETWARE */
|
||||
@@ -1,217 +0,0 @@
|
||||
#!/bin/sh
|
||||
# ***************************************************************************
|
||||
# * _ _ ____ _
|
||||
# * Project ___| | | | _ \| |
|
||||
# * / __| | | | |_) | |
|
||||
# * | (__| |_| | _ <| |___
|
||||
# * \___|\___/|_| \_\_____|
|
||||
# *
|
||||
# * Copyright (C) 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# *
|
||||
# * This software is licensed as described in the file COPYING, which
|
||||
# * you should have received as part of this distribution. The terms
|
||||
# * are also available at https://curl.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 Bourne shell script file is used by test case 1222 to do
|
||||
# unit testing of curl_8char_object_name() shell function which
|
||||
# is defined in file objnames.inc and sourced by this file and
|
||||
# any other shell script that may use it.
|
||||
#
|
||||
|
||||
#
|
||||
# argument validation
|
||||
#
|
||||
|
||||
if test $# -eq 1; then
|
||||
:
|
||||
else
|
||||
echo "Usage: ${0} srcdir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -f "${1}/runtests.pl"; then
|
||||
:
|
||||
else
|
||||
echo "${0}: Wrong srcdir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
srcdir=${1}
|
||||
|
||||
if test -f "$srcdir/../lib/objnames.inc"; then
|
||||
:
|
||||
else
|
||||
echo "$0: Missing objnames.inc"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#
|
||||
# Some variables
|
||||
#
|
||||
|
||||
logdir=log
|
||||
tstnum=1222
|
||||
|
||||
list_c=$logdir/${tstnum}_list_c
|
||||
list_obj=$logdir/${tstnum}_list_obj
|
||||
list_obj_c=$logdir/${tstnum}_list_obj_c
|
||||
list_obj_uniq=$logdir/${tstnum}_list_obj_uniq
|
||||
|
||||
|
||||
#
|
||||
# Source curl_8char_object_name() function definition
|
||||
#
|
||||
|
||||
. $srcdir/../lib/objnames.inc
|
||||
|
||||
#
|
||||
# Some curl_8char_object_name() unit tests
|
||||
#
|
||||
|
||||
echo 'Testing curl_8char_object_name...'
|
||||
echo ""
|
||||
|
||||
argstr=123__678__ABC__FGH__KLM__PQRSTUV
|
||||
expect=16AFKPQR
|
||||
outstr=`curl_8char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=123__678__ABC__FGH__KLM__PQ.S.UV
|
||||
expect=16AFKPQ
|
||||
outstr=`curl_8char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=123__678__ABC..FGH..KLM..PQRSTUV
|
||||
expect=16ABC
|
||||
outstr=`curl_8char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=123__678_.ABC._FGH__KLM__PQRSTUV
|
||||
expect=16
|
||||
outstr=`curl_8char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=123.567.90ABCDEFGHIJKLMNOPQRSTUV
|
||||
expect=123
|
||||
outstr=`curl_8char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=1234567.90A.CDEFGHIJKLMNOPQRSTUV
|
||||
expect=1234567
|
||||
outstr=`curl_8char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=1234567890.BCD.FGHIJKLMNOPQRSTUV
|
||||
expect=12345678
|
||||
outstr=`curl_8char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=12=45-78+0AB.DE.GHIJKLMNOPQRSTUV
|
||||
expect=1470AB
|
||||
outstr=`curl_8char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=1234567890ABCDEFGHIJKLMNOPQRSTUV
|
||||
expect=12345678
|
||||
outstr=`curl_8char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=123_567_90A_CDE_GHIJKLMNOPQRSTUV
|
||||
expect=159CGHIJ
|
||||
outstr=`curl_8char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=123_567_90A_CDEFGHIJKLMNOPQRSTUV
|
||||
expect=159CDEFG
|
||||
outstr=`curl_8char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=123_567_90ABCDEFGHIJKLMNOPQRSTUV
|
||||
expect=1590ABCD
|
||||
outstr=`curl_8char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=123_567890ABCDEFGHIJKLMNOPQRSTUV
|
||||
expect=1567890A
|
||||
outstr=`curl_8char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=1234567890ABCDEFGHIJKLMNOPQRSTUV
|
||||
expect=12345678
|
||||
outstr=`curl_8char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
#
|
||||
# Verify that generated object name is distinct for
|
||||
# all *.c source files in lib and src subdirectories.
|
||||
#
|
||||
|
||||
ls $srcdir/../lib/*.c > $list_c
|
||||
ls $srcdir/../src/*.c >> $list_c
|
||||
|
||||
rm -f $list_obj
|
||||
|
||||
for c_fname in `cat $list_c`; do
|
||||
obj_name=`curl_8char_object_name $c_fname`
|
||||
echo "$obj_name" >> $list_obj
|
||||
done
|
||||
|
||||
sort -u $list_obj > $list_obj_uniq
|
||||
|
||||
cnt_c=`cat $list_c | wc -l`
|
||||
cnt_u=`cat $list_obj_uniq | wc -l`
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
if test $cnt_c -eq $cnt_u; then
|
||||
echo "8-characters-or-less generated object names are unique."
|
||||
obj_name_clash="no"
|
||||
else
|
||||
echo "8-characters-or-less generated object names are clashing..."
|
||||
obj_name_clash="yes"
|
||||
fi
|
||||
|
||||
if test $obj_name_clash = "yes"; then
|
||||
#
|
||||
# Show clashing object names and respective source file names
|
||||
#
|
||||
echo ""
|
||||
paste $list_obj $list_c | sort > $list_obj_c
|
||||
prev_match="no"
|
||||
prev_line="unknown"
|
||||
prev_obj_name="unknown"
|
||||
while read this_line; do
|
||||
obj_name=`echo "$this_line" | cut -f1`
|
||||
if test "x$obj_name" = "x$prev_obj_name"; then
|
||||
if test "x$prev_match" != "xyes"; then
|
||||
echo "$prev_line"
|
||||
echo "$this_line"
|
||||
prev_match="yes"
|
||||
else
|
||||
echo "$this_line"
|
||||
fi
|
||||
else
|
||||
prev_match="no"
|
||||
fi
|
||||
prev_line=$this_line
|
||||
prev_obj_name=$obj_name
|
||||
done < $list_obj_c
|
||||
fi
|
||||
|
||||
rm -f $list_c
|
||||
rm -f $list_obj
|
||||
rm -f $list_obj_c
|
||||
rm -f $list_obj_uniq
|
||||
|
||||
# end of objnames-test.sh
|
||||
@@ -1,217 +0,0 @@
|
||||
#!/bin/sh
|
||||
# ***************************************************************************
|
||||
# * _ _ ____ _
|
||||
# * Project ___| | | | _ \| |
|
||||
# * / __| | | | |_) | |
|
||||
# * | (__| |_| | _ <| |___
|
||||
# * \___|\___/|_| \_\_____|
|
||||
# *
|
||||
# * Copyright (C) 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# *
|
||||
# * This software is licensed as described in the file COPYING, which
|
||||
# * you should have received as part of this distribution. The terms
|
||||
# * are also available at https://curl.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 Bourne shell script file is used by test case 1221 to do
|
||||
# unit testing of curl_10char_object_name() shell function which
|
||||
# is defined in file objnames.inc and sourced by this file and
|
||||
# any other shell script that may use it.
|
||||
#
|
||||
|
||||
#
|
||||
# argument validation
|
||||
#
|
||||
|
||||
if test $# -eq 1; then
|
||||
:
|
||||
else
|
||||
echo "Usage: ${0} srcdir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -f "${1}/runtests.pl"; then
|
||||
:
|
||||
else
|
||||
echo "${0}: Wrong srcdir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
srcdir=${1}
|
||||
|
||||
if test -f "$srcdir/../lib/objnames.inc"; then
|
||||
:
|
||||
else
|
||||
echo "$0: Missing objnames.inc"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#
|
||||
# Some variables
|
||||
#
|
||||
|
||||
logdir=log
|
||||
tstnum=1221
|
||||
|
||||
list_c=$logdir/${tstnum}_list_c
|
||||
list_obj=$logdir/${tstnum}_list_obj
|
||||
list_obj_c=$logdir/${tstnum}_list_obj_c
|
||||
list_obj_uniq=$logdir/${tstnum}_list_obj_uniq
|
||||
|
||||
|
||||
#
|
||||
# Source curl_10char_object_name() function definition
|
||||
#
|
||||
|
||||
. $srcdir/../lib/objnames.inc
|
||||
|
||||
#
|
||||
# Some curl_10char_object_name() unit tests
|
||||
#
|
||||
|
||||
echo 'Testing curl_10char_object_name...'
|
||||
echo ""
|
||||
|
||||
argstr=123__678__ABC__FGH__KLM__PQRSTUV
|
||||
expect=16AFKPQRST
|
||||
outstr=`curl_10char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=123__678__ABC__FGH__KLM__PQ.S.UV
|
||||
expect=16AFKPQ
|
||||
outstr=`curl_10char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=123__678__ABC..FGH..KLM..PQRSTUV
|
||||
expect=16ABC
|
||||
outstr=`curl_10char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=123__678_.ABC._FGH__KLM__PQRSTUV
|
||||
expect=16
|
||||
outstr=`curl_10char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=123.567.90ABCDEFGHIJKLMNOPQRSTUV
|
||||
expect=123
|
||||
outstr=`curl_10char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=1234567.90A.CDEFGHIJKLMNOPQRSTUV
|
||||
expect=1234567
|
||||
outstr=`curl_10char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=1234567890.BCD.FGHIJKLMNOPQRSTUV
|
||||
expect=1234567890
|
||||
outstr=`curl_10char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=12=45-78+0AB.DE.GHIJKLMNOPQRSTUV
|
||||
expect=1470AB
|
||||
outstr=`curl_10char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=1234567890ABCDEFGHIJKLMNOPQRSTUV
|
||||
expect=1234567890
|
||||
outstr=`curl_10char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=123_567_90A_CDE_GHIJKLMNOPQRSTUV
|
||||
expect=159CGHIJKL
|
||||
outstr=`curl_10char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=123_567_90A_CDEFGHIJKLMNOPQRSTUV
|
||||
expect=159CDEFGHI
|
||||
outstr=`curl_10char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=123_567_90ABCDEFGHIJKLMNOPQRSTUV
|
||||
expect=1590ABCDEF
|
||||
outstr=`curl_10char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=123_567890ABCDEFGHIJKLMNOPQRSTUV
|
||||
expect=1567890ABC
|
||||
outstr=`curl_10char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
argstr=1234567890ABCDEFGHIJKLMNOPQRSTUV
|
||||
expect=1234567890
|
||||
outstr=`curl_10char_object_name $argstr`
|
||||
echo "result: $outstr expected: $expect input: $argstr"
|
||||
|
||||
#
|
||||
# Verify that generated object name is distinct for
|
||||
# all *.c source files in lib and src subdirectories.
|
||||
#
|
||||
|
||||
ls $srcdir/../lib/*.c > $list_c
|
||||
ls $srcdir/../src/*.c >> $list_c
|
||||
|
||||
rm -f $list_obj
|
||||
|
||||
for c_fname in `cat $list_c`; do
|
||||
obj_name=`curl_10char_object_name $c_fname`
|
||||
echo "$obj_name" >> $list_obj
|
||||
done
|
||||
|
||||
sort -u $list_obj > $list_obj_uniq
|
||||
|
||||
cnt_c=`cat $list_c | wc -l`
|
||||
cnt_u=`cat $list_obj_uniq | wc -l`
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
if test $cnt_c -eq $cnt_u; then
|
||||
echo "10-characters-or-less generated object names are unique."
|
||||
obj_name_clash="no"
|
||||
else
|
||||
echo "10-characters-or-less generated object names are clashing..."
|
||||
obj_name_clash="yes"
|
||||
fi
|
||||
|
||||
if test $obj_name_clash = "yes"; then
|
||||
#
|
||||
# Show clashing object names and respective source file names
|
||||
#
|
||||
echo ""
|
||||
paste $list_obj $list_c | sort > $list_obj_c
|
||||
prev_match="no"
|
||||
prev_line="unknown"
|
||||
prev_obj_name="unknown"
|
||||
while read this_line; do
|
||||
obj_name=`echo "$this_line" | cut -f1`
|
||||
if test "x$obj_name" = "x$prev_obj_name"; then
|
||||
if test "x$prev_match" != "xyes"; then
|
||||
echo "$prev_line"
|
||||
echo "$this_line"
|
||||
prev_match="yes"
|
||||
else
|
||||
echo "$this_line"
|
||||
fi
|
||||
else
|
||||
prev_match="no"
|
||||
fi
|
||||
prev_line=$this_line
|
||||
prev_obj_name=$obj_name
|
||||
done < $list_obj_c
|
||||
fi
|
||||
|
||||
rm -f $list_c
|
||||
rm -f $list_obj
|
||||
rm -f $list_obj_c
|
||||
rm -f $list_obj_uniq
|
||||
|
||||
# end of objnames-test10.sh
|
||||
@@ -1,107 +0,0 @@
|
||||
# ***************************************************************************
|
||||
# * _ _ ____ _
|
||||
# * 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 https://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 file is sourced from curl/packages/OS400/initscript.sh and
|
||||
# other Bourne shell scripts. Keep it as portable as possible.
|
||||
#
|
||||
|
||||
#
|
||||
# curl_10char_object_name
|
||||
#
|
||||
# This shell function accepts a single string argument with unspecified
|
||||
# length representing a (*.c) source file name and returns a string which
|
||||
# is a transformation of given argument.
|
||||
#
|
||||
# The intended purpose of this function is to transliterate a (*.c) source
|
||||
# file name that may be longer than 10 characters, or not, into a string
|
||||
# with at most 10 characters which may be used as an OS/400 object name.
|
||||
#
|
||||
# This function might not be universally usefull, nor we care about it.
|
||||
#
|
||||
# It is intended to be used with libcurl's (*.c) source file names, so
|
||||
# dependency on libcurl's source file naming scheme is acceptable and
|
||||
# good enough for its intended use. Specifically it makes use of the fact
|
||||
# that libcurl's (*.c) source file names which may be longer than 10 chars
|
||||
# are conformed with underscore '_' separated substrings, or separated by
|
||||
# other character which does not belong to the [0-9], [a-z] or [A-Z] sets.
|
||||
#
|
||||
# This allows repeatable and automatic short object name generation with
|
||||
# no need for a hardcoded mapping table.
|
||||
#
|
||||
# Transformation is done in the following way:
|
||||
#
|
||||
# 1) Leading directory components are removed.
|
||||
# 2) Leftmost dot character and any other char following it are removed.
|
||||
# 3) Lowercase characters are transliterated to uppercase.
|
||||
# 4) Characters not in [A-Z] or [0-9] are transliterated to underscore '_'.
|
||||
# 5) Every sequence of one or more underscores is replaced with a single one.
|
||||
# 6) Five leftmost substrings which end in an underscore character are
|
||||
# replaced by the first character of each substring, while retaining
|
||||
# the rest of the string.
|
||||
# 7) Finally the result is truncated to 10 characters.
|
||||
#
|
||||
# Resulting object name may be shorter than 10 characters.
|
||||
#
|
||||
# Test case 1221 does unit testng of this function and also verifies
|
||||
# that it is possible to generate distinct short object names for all
|
||||
# curl and libcurl *.c source file names.
|
||||
#
|
||||
|
||||
curl_10char_object_name() {
|
||||
echo "${1}" | \
|
||||
sed -e 's:.*/::' \
|
||||
-e 's:[.].*::' \
|
||||
-e 'y:abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:' \
|
||||
-e 's:[^ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_]:_:g' \
|
||||
-e 's:__*:_:g' \
|
||||
-e 's:\([^_]\)[^_]*_\(.*\):\1\2:' \
|
||||
-e 's:\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3:' \
|
||||
-e 's:\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4:' \
|
||||
-e 's:\([^_]\)\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4\5:' \
|
||||
-e 's:\([^_]\)\([^_]\)\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4\5\6:' \
|
||||
-e 's:^\(..........\).*:\1:'
|
||||
}
|
||||
|
||||
#
|
||||
# curl_8char_object_name
|
||||
#
|
||||
# Same as curl_10char_object_name() description and details above, except
|
||||
# that object name is limited to 8 charcters maximum.
|
||||
#
|
||||
|
||||
curl_8char_object_name() {
|
||||
echo "${1}" | \
|
||||
sed -e 's:.*/::' \
|
||||
-e 's:[.].*::' \
|
||||
-e 'y:abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:' \
|
||||
-e 's:[^ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_]:_:g' \
|
||||
-e 's:__*:_:g' \
|
||||
-e 's:\([^_]\)[^_]*_\(.*\):\1\2:' \
|
||||
-e 's:\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3:' \
|
||||
-e 's:\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4:' \
|
||||
-e 's:\([^_]\)\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4\5:' \
|
||||
-e 's:\([^_]\)\([^_]\)\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4\5\6:' \
|
||||
-e 's:^\(........\).*:\1:'
|
||||
}
|
||||
|
||||
# end of objectname.inc
|
||||
@@ -1,711 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2010, Howard Chu, <hyc@openldap.org>
|
||||
* Copyright (C) 2011 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_LDAP) && defined(USE_OPENLDAP)
|
||||
|
||||
/*
|
||||
* Notice that USE_OPENLDAP is only a source code selection switch. When
|
||||
* libcurl is built with USE_OPENLDAP defined the libcurl source code that
|
||||
* gets compiled is the code from openldap.c, otherwise the code that gets
|
||||
* compiled is the code from ldap.c.
|
||||
*
|
||||
* When USE_OPENLDAP is defined a recent version of the OpenLDAP library
|
||||
* might be required for compilation and runtime. In order to use ancient
|
||||
* OpenLDAP library versions, USE_OPENLDAP shall not be defined.
|
||||
*/
|
||||
|
||||
#include <ldap.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include "sendf.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "transfer.h"
|
||||
#include "curl_ldap.h"
|
||||
#include "curl_base64.h"
|
||||
#include "connect.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifndef _LDAP_PVT_H
|
||||
extern int ldap_pvt_url_scheme2proto(const char *);
|
||||
extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url,
|
||||
LDAP **ld);
|
||||
#endif
|
||||
|
||||
static CURLcode ldap_setup_connection(struct connectdata *conn);
|
||||
static CURLcode ldap_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode ldap_done(struct connectdata *conn, CURLcode, bool);
|
||||
static CURLcode ldap_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode ldap_connecting(struct connectdata *conn, bool *done);
|
||||
static CURLcode ldap_disconnect(struct connectdata *conn, bool dead);
|
||||
|
||||
static Curl_recv ldap_recv;
|
||||
|
||||
/*
|
||||
* LDAP protocol handler.
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_ldap = {
|
||||
"LDAP", /* scheme */
|
||||
ldap_setup_connection, /* setup_connection */
|
||||
ldap_do, /* do_it */
|
||||
ldap_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
ldap_connect, /* connect_it */
|
||||
ldap_connecting, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ldap_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_LDAP, /* defport */
|
||||
CURLPROTO_LDAP, /* protocol */
|
||||
PROTOPT_NONE /* flags */
|
||||
};
|
||||
|
||||
#ifdef USE_SSL
|
||||
/*
|
||||
* LDAPS protocol handler.
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_ldaps = {
|
||||
"LDAPS", /* scheme */
|
||||
ldap_setup_connection, /* setup_connection */
|
||||
ldap_do, /* do_it */
|
||||
ldap_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
ldap_connect, /* connect_it */
|
||||
ldap_connecting, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ldap_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_LDAPS, /* defport */
|
||||
CURLPROTO_LDAP, /* protocol */
|
||||
PROTOPT_SSL /* flags */
|
||||
};
|
||||
#endif
|
||||
|
||||
static const char *url_errs[] = {
|
||||
"success",
|
||||
"out of memory",
|
||||
"bad parameter",
|
||||
"unrecognized scheme",
|
||||
"unbalanced delimiter",
|
||||
"bad URL",
|
||||
"bad host or port",
|
||||
"bad or missing attributes",
|
||||
"bad or missing scope",
|
||||
"bad or missing filter",
|
||||
"bad or missing extensions"
|
||||
};
|
||||
|
||||
typedef struct ldapconninfo {
|
||||
LDAP *ld;
|
||||
Curl_recv *recv; /* for stacking SSL handler */
|
||||
Curl_send *send;
|
||||
int proto;
|
||||
int msgid;
|
||||
bool ssldone;
|
||||
bool sslinst;
|
||||
bool didbind;
|
||||
} ldapconninfo;
|
||||
|
||||
typedef struct ldapreqinfo {
|
||||
int msgid;
|
||||
int nument;
|
||||
} ldapreqinfo;
|
||||
|
||||
static CURLcode ldap_setup_connection(struct connectdata *conn)
|
||||
{
|
||||
ldapconninfo *li;
|
||||
LDAPURLDesc *lud;
|
||||
struct Curl_easy *data=conn->data;
|
||||
int rc, proto;
|
||||
CURLcode status;
|
||||
|
||||
rc = ldap_url_parse(data->change.url, &lud);
|
||||
if(rc != LDAP_URL_SUCCESS) {
|
||||
const char *msg = "url parsing problem";
|
||||
status = CURLE_URL_MALFORMAT;
|
||||
if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
|
||||
if(rc == LDAP_URL_ERR_MEM)
|
||||
status = CURLE_OUT_OF_MEMORY;
|
||||
msg = url_errs[rc];
|
||||
}
|
||||
failf(conn->data, "LDAP local: %s", msg);
|
||||
return status;
|
||||
}
|
||||
proto = ldap_pvt_url_scheme2proto(lud->lud_scheme);
|
||||
ldap_free_urldesc(lud);
|
||||
|
||||
li = calloc(1, sizeof(ldapconninfo));
|
||||
if(!li)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
li->proto = proto;
|
||||
conn->proto.generic = li;
|
||||
connkeep(conn, "OpenLDAP default");
|
||||
/* TODO:
|
||||
* - provide option to choose SASL Binds instead of Simple
|
||||
*/
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#ifdef USE_SSL
|
||||
static Sockbuf_IO ldapsb_tls;
|
||||
#endif
|
||||
|
||||
static CURLcode ldap_connect(struct connectdata *conn, bool *done)
|
||||
{
|
||||
ldapconninfo *li = conn->proto.generic;
|
||||
struct Curl_easy *data = conn->data;
|
||||
int rc, proto = LDAP_VERSION3;
|
||||
char hosturl[1024];
|
||||
char *ptr;
|
||||
|
||||
(void)done;
|
||||
|
||||
strcpy(hosturl, "ldap");
|
||||
ptr = hosturl+4;
|
||||
if(conn->handler->flags & PROTOPT_SSL)
|
||||
*ptr++ = 's';
|
||||
snprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d",
|
||||
conn->host.name, conn->remote_port);
|
||||
|
||||
rc = ldap_init_fd(conn->sock[FIRSTSOCKET], li->proto, hosturl, &li->ld);
|
||||
if(rc) {
|
||||
failf(data, "LDAP local: Cannot connect to %s, %s",
|
||||
hosturl, ldap_err2string(rc));
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
|
||||
|
||||
#ifdef USE_SSL
|
||||
if(conn->handler->flags & PROTOPT_SSL) {
|
||||
CURLcode result;
|
||||
result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
|
||||
{
|
||||
ldapconninfo *li = conn->proto.generic;
|
||||
struct Curl_easy *data = conn->data;
|
||||
LDAPMessage *msg = NULL;
|
||||
struct timeval tv = {0, 1}, *tvp;
|
||||
int rc, err;
|
||||
char *info = NULL;
|
||||
|
||||
#ifdef USE_SSL
|
||||
if(conn->handler->flags & PROTOPT_SSL) {
|
||||
/* Is the SSL handshake complete yet? */
|
||||
if(!li->ssldone) {
|
||||
CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET,
|
||||
&li->ssldone);
|
||||
if(result || !li->ssldone)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Have we installed the libcurl SSL handlers into the sockbuf yet? */
|
||||
if(!li->sslinst) {
|
||||
Sockbuf *sb;
|
||||
ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb);
|
||||
ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, conn);
|
||||
li->sslinst = TRUE;
|
||||
li->recv = conn->recv[FIRSTSOCKET];
|
||||
li->send = conn->send[FIRSTSOCKET];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
tvp = &tv;
|
||||
|
||||
retry:
|
||||
if(!li->didbind) {
|
||||
char *binddn;
|
||||
struct berval passwd;
|
||||
|
||||
if(conn->bits.user_passwd) {
|
||||
binddn = conn->user;
|
||||
passwd.bv_val = conn->passwd;
|
||||
passwd.bv_len = strlen(passwd.bv_val);
|
||||
}
|
||||
else {
|
||||
binddn = NULL;
|
||||
passwd.bv_val = NULL;
|
||||
passwd.bv_len = 0;
|
||||
}
|
||||
rc = ldap_sasl_bind(li->ld, binddn, LDAP_SASL_SIMPLE, &passwd,
|
||||
NULL, NULL, &li->msgid);
|
||||
if(rc)
|
||||
return CURLE_LDAP_CANNOT_BIND;
|
||||
li->didbind = TRUE;
|
||||
if(tvp)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, tvp, &msg);
|
||||
if(rc < 0) {
|
||||
failf(data, "LDAP local: bind ldap_result %s", ldap_err2string(rc));
|
||||
return CURLE_LDAP_CANNOT_BIND;
|
||||
}
|
||||
if(rc == 0) {
|
||||
/* timed out */
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
rc = ldap_parse_result(li->ld, msg, &err, NULL, &info, NULL, NULL, 1);
|
||||
if(rc) {
|
||||
failf(data, "LDAP local: bind ldap_parse_result %s", ldap_err2string(rc));
|
||||
return CURLE_LDAP_CANNOT_BIND;
|
||||
}
|
||||
|
||||
/* Try to fallback to LDAPv2? */
|
||||
if(err == LDAP_PROTOCOL_ERROR) {
|
||||
int proto;
|
||||
ldap_get_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
|
||||
if(proto == LDAP_VERSION3) {
|
||||
if(info) {
|
||||
ldap_memfree(info);
|
||||
info = NULL;
|
||||
}
|
||||
proto = LDAP_VERSION2;
|
||||
ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
|
||||
li->didbind = FALSE;
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
if(err) {
|
||||
failf(data, "LDAP remote: bind failed %s %s", ldap_err2string(rc),
|
||||
info ? info : "");
|
||||
if(info)
|
||||
ldap_memfree(info);
|
||||
return CURLE_LOGIN_DENIED;
|
||||
}
|
||||
|
||||
if(info)
|
||||
ldap_memfree(info);
|
||||
conn->recv[FIRSTSOCKET] = ldap_recv;
|
||||
*done = TRUE;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
{
|
||||
ldapconninfo *li = conn->proto.generic;
|
||||
(void) dead_connection;
|
||||
|
||||
if(li) {
|
||||
if(li->ld) {
|
||||
ldap_unbind_ext(li->ld, NULL, NULL);
|
||||
li->ld = NULL;
|
||||
}
|
||||
conn->proto.generic = NULL;
|
||||
free(li);
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode ldap_do(struct connectdata *conn, bool *done)
|
||||
{
|
||||
ldapconninfo *li = conn->proto.generic;
|
||||
ldapreqinfo *lr;
|
||||
CURLcode status = CURLE_OK;
|
||||
int rc = 0;
|
||||
LDAPURLDesc *ludp = NULL;
|
||||
int msgid;
|
||||
struct Curl_easy *data=conn->data;
|
||||
|
||||
connkeep(conn, "OpenLDAP do");
|
||||
|
||||
infof(data, "LDAP local: %s\n", data->change.url);
|
||||
|
||||
rc = ldap_url_parse(data->change.url, &ludp);
|
||||
if(rc != LDAP_URL_SUCCESS) {
|
||||
const char *msg = "url parsing problem";
|
||||
status = CURLE_URL_MALFORMAT;
|
||||
if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
|
||||
if(rc == LDAP_URL_ERR_MEM)
|
||||
status = CURLE_OUT_OF_MEMORY;
|
||||
msg = url_errs[rc];
|
||||
}
|
||||
failf(conn->data, "LDAP local: %s", msg);
|
||||
return status;
|
||||
}
|
||||
|
||||
rc = ldap_search_ext(li->ld, ludp->lud_dn, ludp->lud_scope,
|
||||
ludp->lud_filter, ludp->lud_attrs, 0,
|
||||
NULL, NULL, NULL, 0, &msgid);
|
||||
ldap_free_urldesc(ludp);
|
||||
if(rc != LDAP_SUCCESS) {
|
||||
failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc));
|
||||
return CURLE_LDAP_SEARCH_FAILED;
|
||||
}
|
||||
lr = calloc(1, sizeof(ldapreqinfo));
|
||||
if(!lr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
lr->msgid = msgid;
|
||||
data->req.protop = lr;
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
|
||||
*done = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
|
||||
bool premature)
|
||||
{
|
||||
ldapreqinfo *lr = conn->data->req.protop;
|
||||
|
||||
(void)res;
|
||||
(void)premature;
|
||||
|
||||
if(lr) {
|
||||
/* if there was a search in progress, abandon it */
|
||||
if(lr->msgid) {
|
||||
ldapconninfo *li = conn->proto.generic;
|
||||
ldap_abandon_ext(li->ld, lr->msgid, NULL, NULL);
|
||||
lr->msgid = 0;
|
||||
}
|
||||
conn->data->req.protop = NULL;
|
||||
free(lr);
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
size_t len, CURLcode *err)
|
||||
{
|
||||
ldapconninfo *li = conn->proto.generic;
|
||||
struct Curl_easy *data = conn->data;
|
||||
ldapreqinfo *lr = data->req.protop;
|
||||
int rc, ret;
|
||||
LDAPMessage *msg = NULL;
|
||||
LDAPMessage *ent;
|
||||
BerElement *ber = NULL;
|
||||
struct timeval tv = {0, 1};
|
||||
|
||||
(void)len;
|
||||
(void)buf;
|
||||
(void)sockindex;
|
||||
|
||||
rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &msg);
|
||||
if(rc < 0) {
|
||||
failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc));
|
||||
*err = CURLE_RECV_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*err = CURLE_AGAIN;
|
||||
ret = -1;
|
||||
|
||||
/* timed out */
|
||||
if(!msg)
|
||||
return ret;
|
||||
|
||||
for(ent = ldap_first_message(li->ld, msg); ent;
|
||||
ent = ldap_next_message(li->ld, ent)) {
|
||||
struct berval bv, *bvals, **bvp = &bvals;
|
||||
int binary = 0, msgtype;
|
||||
CURLcode writeerr;
|
||||
|
||||
msgtype = ldap_msgtype(ent);
|
||||
if(msgtype == LDAP_RES_SEARCH_RESULT) {
|
||||
int code;
|
||||
char *info = NULL;
|
||||
rc = ldap_parse_result(li->ld, ent, &code, NULL, &info, NULL, NULL, 0);
|
||||
if(rc) {
|
||||
failf(data, "LDAP local: search ldap_parse_result %s",
|
||||
ldap_err2string(rc));
|
||||
*err = CURLE_LDAP_SEARCH_FAILED;
|
||||
}
|
||||
else if(code && code != LDAP_SIZELIMIT_EXCEEDED) {
|
||||
failf(data, "LDAP remote: search failed %s %s", ldap_err2string(rc),
|
||||
info ? info : "");
|
||||
*err = CURLE_LDAP_SEARCH_FAILED;
|
||||
}
|
||||
else {
|
||||
/* successful */
|
||||
if(code == LDAP_SIZELIMIT_EXCEEDED)
|
||||
infof(data, "There are more than %d entries\n", lr->nument);
|
||||
data->req.size = data->req.bytecount;
|
||||
*err = CURLE_OK;
|
||||
ret = 0;
|
||||
}
|
||||
lr->msgid = 0;
|
||||
ldap_memfree(info);
|
||||
break;
|
||||
}
|
||||
else if(msgtype != LDAP_RES_SEARCH_ENTRY)
|
||||
continue;
|
||||
|
||||
lr->nument++;
|
||||
rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv);
|
||||
if(rc < 0) {
|
||||
/* TODO: verify that this is really how this return code should be
|
||||
handled */
|
||||
*err = CURLE_RECV_ERROR;
|
||||
return -1;
|
||||
}
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
|
||||
bv.bv_len);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
data->req.bytecount += bv.bv_len + 5;
|
||||
|
||||
for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp);
|
||||
rc == LDAP_SUCCESS;
|
||||
rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) {
|
||||
int i;
|
||||
|
||||
if(bv.bv_val == NULL) break;
|
||||
|
||||
if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7))
|
||||
binary = 1;
|
||||
else
|
||||
binary = 0;
|
||||
|
||||
for(i=0; bvals[i].bv_val != NULL; i++) {
|
||||
int binval = 0;
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
|
||||
bv.bv_len);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
data->req.bytecount += bv.bv_len + 2;
|
||||
|
||||
if(!binary) {
|
||||
/* check for leading or trailing whitespace */
|
||||
if(ISSPACE(bvals[i].bv_val[0]) ||
|
||||
ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1]))
|
||||
binval = 1;
|
||||
else {
|
||||
/* check for unprintable characters */
|
||||
unsigned int j;
|
||||
for(j=0; j<bvals[i].bv_len; j++)
|
||||
if(!ISPRINT(bvals[i].bv_val[j])) {
|
||||
binval = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(binary || binval) {
|
||||
char *val_b64 = NULL;
|
||||
size_t val_b64_sz = 0;
|
||||
/* Binary value, encode to base64. */
|
||||
CURLcode error = Curl_base64_encode(data,
|
||||
bvals[i].bv_val,
|
||||
bvals[i].bv_len,
|
||||
&val_b64,
|
||||
&val_b64_sz);
|
||||
if(error) {
|
||||
ber_memfree(bvals);
|
||||
ber_free(ber, 0);
|
||||
ldap_msgfree(msg);
|
||||
*err = error;
|
||||
return -1;
|
||||
}
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY,
|
||||
(char *)": ", 2);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
data->req.bytecount += 2;
|
||||
if(val_b64_sz > 0) {
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
|
||||
val_b64_sz);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
free(val_b64);
|
||||
data->req.bytecount += val_b64_sz;
|
||||
}
|
||||
}
|
||||
else {
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val,
|
||||
bvals[i].bv_len);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
data->req.bytecount += bvals[i].bv_len + 1;
|
||||
}
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
data->req.bytecount++;
|
||||
}
|
||||
ber_memfree(bvals);
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
data->req.bytecount++;
|
||||
}
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
data->req.bytecount++;
|
||||
ber_free(ber, 0);
|
||||
}
|
||||
ldap_msgfree(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef USE_SSL
|
||||
static int
|
||||
ldapsb_tls_setup(Sockbuf_IO_Desc *sbiod, void *arg)
|
||||
{
|
||||
sbiod->sbiod_pvt = arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ldapsb_tls_remove(Sockbuf_IO_Desc *sbiod)
|
||||
{
|
||||
sbiod->sbiod_pvt = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We don't need to do anything because libcurl does it already */
|
||||
static int
|
||||
ldapsb_tls_close(Sockbuf_IO_Desc *sbiod)
|
||||
{
|
||||
(void)sbiod;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ldapsb_tls_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
if(opt == LBER_SB_OPT_DATA_READY) {
|
||||
struct connectdata *conn = sbiod->sbiod_pvt;
|
||||
return Curl_ssl_data_pending(conn, FIRSTSOCKET);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ber_slen_t
|
||||
ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
|
||||
{
|
||||
struct connectdata *conn = sbiod->sbiod_pvt;
|
||||
ldapconninfo *li = conn->proto.generic;
|
||||
ber_slen_t ret;
|
||||
CURLcode err = CURLE_RECV_ERROR;
|
||||
|
||||
ret = li->recv(conn, FIRSTSOCKET, buf, len, &err);
|
||||
if(ret < 0 && err == CURLE_AGAIN) {
|
||||
SET_SOCKERRNO(EWOULDBLOCK);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ber_slen_t
|
||||
ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
|
||||
{
|
||||
struct connectdata *conn = sbiod->sbiod_pvt;
|
||||
ldapconninfo *li = conn->proto.generic;
|
||||
ber_slen_t ret;
|
||||
CURLcode err = CURLE_SEND_ERROR;
|
||||
|
||||
ret = li->send(conn, FIRSTSOCKET, buf, len, &err);
|
||||
if(ret < 0 && err == CURLE_AGAIN) {
|
||||
SET_SOCKERRNO(EWOULDBLOCK);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Sockbuf_IO ldapsb_tls =
|
||||
{
|
||||
ldapsb_tls_setup,
|
||||
ldapsb_tls_remove,
|
||||
ldapsb_tls_ctrl,
|
||||
ldapsb_tls_read,
|
||||
ldapsb_tls_write,
|
||||
ldapsb_tls_close
|
||||
};
|
||||
#endif /* USE_SSL */
|
||||
|
||||
#endif /* !CURL_DISABLE_LDAP && USE_OPENLDAP */
|
||||
@@ -1,585 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
***************************************************************************/
|
||||
/*
|
||||
A brief summary of the date string formats this parser groks:
|
||||
|
||||
RFC 2616 3.3.1
|
||||
|
||||
Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
|
||||
Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
|
||||
Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
|
||||
|
||||
we support dates without week day name:
|
||||
|
||||
06 Nov 1994 08:49:37 GMT
|
||||
06-Nov-94 08:49:37 GMT
|
||||
Nov 6 08:49:37 1994
|
||||
|
||||
without the time zone:
|
||||
|
||||
06 Nov 1994 08:49:37
|
||||
06-Nov-94 08:49:37
|
||||
|
||||
weird order:
|
||||
|
||||
1994 Nov 6 08:49:37 (GNU date fails)
|
||||
GMT 08:49:37 06-Nov-94 Sunday
|
||||
94 6 Nov 08:49:37 (GNU date fails)
|
||||
|
||||
time left out:
|
||||
|
||||
1994 Nov 6
|
||||
06-Nov-94
|
||||
Sun Nov 6 94
|
||||
|
||||
unusual separators:
|
||||
|
||||
1994.Nov.6
|
||||
Sun/Nov/6/94/GMT
|
||||
|
||||
commonly used time zone names:
|
||||
|
||||
Sun, 06 Nov 1994 08:49:37 CET
|
||||
06 Nov 1994 08:49:37 EST
|
||||
|
||||
time zones specified using RFC822 style:
|
||||
|
||||
Sun, 12 Sep 2004 15:05:58 -0700
|
||||
Sat, 11 Sep 2004 21:32:11 +0200
|
||||
|
||||
compact numerical date strings:
|
||||
|
||||
20040912 15:05:58 -0700
|
||||
20040911 +0200
|
||||
|
||||
*/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "strcase.h"
|
||||
#include "warnless.h"
|
||||
#include "parsedate.h"
|
||||
|
||||
const char * const Curl_wkday[] =
|
||||
{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
|
||||
static const char * const weekday[] =
|
||||
{ "Monday", "Tuesday", "Wednesday", "Thursday",
|
||||
"Friday", "Saturday", "Sunday" };
|
||||
const char * const Curl_month[]=
|
||||
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||
|
||||
struct tzinfo {
|
||||
char name[5];
|
||||
int offset; /* +/- in minutes */
|
||||
};
|
||||
|
||||
/*
|
||||
* parsedate()
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* PARSEDATE_OK - a fine conversion
|
||||
* PARSEDATE_FAIL - failed to convert
|
||||
* PARSEDATE_LATER - time overflow at the far end of time_t
|
||||
* PARSEDATE_SOONER - time underflow at the low end of time_t
|
||||
*/
|
||||
|
||||
static int parsedate(const char *date, time_t *output);
|
||||
|
||||
#define PARSEDATE_OK 0
|
||||
#define PARSEDATE_FAIL -1
|
||||
#define PARSEDATE_LATER 1
|
||||
#define PARSEDATE_SOONER 2
|
||||
|
||||
/* Here's a bunch of frequently used time zone names. These were supported
|
||||
by the old getdate parser. */
|
||||
#define tDAYZONE -60 /* offset for daylight savings time */
|
||||
static const struct tzinfo tz[]= {
|
||||
{"GMT", 0}, /* Greenwich Mean */
|
||||
{"UTC", 0}, /* Universal (Coordinated) */
|
||||
{"WET", 0}, /* Western European */
|
||||
{"BST", 0 tDAYZONE}, /* British Summer */
|
||||
{"WAT", 60}, /* West Africa */
|
||||
{"AST", 240}, /* Atlantic Standard */
|
||||
{"ADT", 240 tDAYZONE}, /* Atlantic Daylight */
|
||||
{"EST", 300}, /* Eastern Standard */
|
||||
{"EDT", 300 tDAYZONE}, /* Eastern Daylight */
|
||||
{"CST", 360}, /* Central Standard */
|
||||
{"CDT", 360 tDAYZONE}, /* Central Daylight */
|
||||
{"MST", 420}, /* Mountain Standard */
|
||||
{"MDT", 420 tDAYZONE}, /* Mountain Daylight */
|
||||
{"PST", 480}, /* Pacific Standard */
|
||||
{"PDT", 480 tDAYZONE}, /* Pacific Daylight */
|
||||
{"YST", 540}, /* Yukon Standard */
|
||||
{"YDT", 540 tDAYZONE}, /* Yukon Daylight */
|
||||
{"HST", 600}, /* Hawaii Standard */
|
||||
{"HDT", 600 tDAYZONE}, /* Hawaii Daylight */
|
||||
{"CAT", 600}, /* Central Alaska */
|
||||
{"AHST", 600}, /* Alaska-Hawaii Standard */
|
||||
{"NT", 660}, /* Nome */
|
||||
{"IDLW", 720}, /* International Date Line West */
|
||||
{"CET", -60}, /* Central European */
|
||||
{"MET", -60}, /* Middle European */
|
||||
{"MEWT", -60}, /* Middle European Winter */
|
||||
{"MEST", -60 tDAYZONE}, /* Middle European Summer */
|
||||
{"CEST", -60 tDAYZONE}, /* Central European Summer */
|
||||
{"MESZ", -60 tDAYZONE}, /* Middle European Summer */
|
||||
{"FWT", -60}, /* French Winter */
|
||||
{"FST", -60 tDAYZONE}, /* French Summer */
|
||||
{"EET", -120}, /* Eastern Europe, USSR Zone 1 */
|
||||
{"WAST", -420}, /* West Australian Standard */
|
||||
{"WADT", -420 tDAYZONE}, /* West Australian Daylight */
|
||||
{"CCT", -480}, /* China Coast, USSR Zone 7 */
|
||||
{"JST", -540}, /* Japan Standard, USSR Zone 8 */
|
||||
{"EAST", -600}, /* Eastern Australian Standard */
|
||||
{"EADT", -600 tDAYZONE}, /* Eastern Australian Daylight */
|
||||
{"GST", -600}, /* Guam Standard, USSR Zone 9 */
|
||||
{"NZT", -720}, /* New Zealand */
|
||||
{"NZST", -720}, /* New Zealand Standard */
|
||||
{"NZDT", -720 tDAYZONE}, /* New Zealand Daylight */
|
||||
{"IDLE", -720}, /* International Date Line East */
|
||||
/* Next up: Military timezone names. RFC822 allowed these, but (as noted in
|
||||
RFC 1123) had their signs wrong. Here we use the correct signs to match
|
||||
actual military usage.
|
||||
*/
|
||||
{"A", +1 * 60}, /* Alpha */
|
||||
{"B", +2 * 60}, /* Bravo */
|
||||
{"C", +3 * 60}, /* Charlie */
|
||||
{"D", +4 * 60}, /* Delta */
|
||||
{"E", +5 * 60}, /* Echo */
|
||||
{"F", +6 * 60}, /* Foxtrot */
|
||||
{"G", +7 * 60}, /* Golf */
|
||||
{"H", +8 * 60}, /* Hotel */
|
||||
{"I", +9 * 60}, /* India */
|
||||
/* "J", Juliet is not used as a timezone, to indicate the observer's local
|
||||
time */
|
||||
{"K", +10 * 60}, /* Kilo */
|
||||
{"L", +11 * 60}, /* Lima */
|
||||
{"M", +12 * 60}, /* Mike */
|
||||
{"N", -1 * 60}, /* November */
|
||||
{"O", -2 * 60}, /* Oscar */
|
||||
{"P", -3 * 60}, /* Papa */
|
||||
{"Q", -4 * 60}, /* Quebec */
|
||||
{"R", -5 * 60}, /* Romeo */
|
||||
{"S", -6 * 60}, /* Sierra */
|
||||
{"T", -7 * 60}, /* Tango */
|
||||
{"U", -8 * 60}, /* Uniform */
|
||||
{"V", -9 * 60}, /* Victor */
|
||||
{"W", -10 * 60}, /* Whiskey */
|
||||
{"X", -11 * 60}, /* X-ray */
|
||||
{"Y", -12 * 60}, /* Yankee */
|
||||
{"Z", 0}, /* Zulu, zero meridian, a.k.a. UTC */
|
||||
};
|
||||
|
||||
/* returns:
|
||||
-1 no day
|
||||
0 monday - 6 sunday
|
||||
*/
|
||||
|
||||
static int checkday(const char *check, size_t len)
|
||||
{
|
||||
int i;
|
||||
const char * const *what;
|
||||
bool found= FALSE;
|
||||
if(len > 3)
|
||||
what = &weekday[0];
|
||||
else
|
||||
what = &Curl_wkday[0];
|
||||
for(i=0; i<7; i++) {
|
||||
if(strcasecompare(check, what[0])) {
|
||||
found=TRUE;
|
||||
break;
|
||||
}
|
||||
what++;
|
||||
}
|
||||
return found?i:-1;
|
||||
}
|
||||
|
||||
static int checkmonth(const char *check)
|
||||
{
|
||||
int i;
|
||||
const char * const *what;
|
||||
bool found= FALSE;
|
||||
|
||||
what = &Curl_month[0];
|
||||
for(i=0; i<12; i++) {
|
||||
if(strcasecompare(check, what[0])) {
|
||||
found=TRUE;
|
||||
break;
|
||||
}
|
||||
what++;
|
||||
}
|
||||
return found?i:-1; /* return the offset or -1, no real offset is -1 */
|
||||
}
|
||||
|
||||
/* return the time zone offset between GMT and the input one, in number
|
||||
of seconds or -1 if the timezone wasn't found/legal */
|
||||
|
||||
static int checktz(const char *check)
|
||||
{
|
||||
unsigned int i;
|
||||
const struct tzinfo *what;
|
||||
bool found= FALSE;
|
||||
|
||||
what = tz;
|
||||
for(i=0; i< sizeof(tz)/sizeof(tz[0]); i++) {
|
||||
if(strcasecompare(check, what->name)) {
|
||||
found=TRUE;
|
||||
break;
|
||||
}
|
||||
what++;
|
||||
}
|
||||
return found?what->offset*60:-1;
|
||||
}
|
||||
|
||||
static void skip(const char **date)
|
||||
{
|
||||
/* skip everything that aren't letters or digits */
|
||||
while(**date && !ISALNUM(**date))
|
||||
(*date)++;
|
||||
}
|
||||
|
||||
enum assume {
|
||||
DATE_MDAY,
|
||||
DATE_YEAR,
|
||||
DATE_TIME
|
||||
};
|
||||
|
||||
/* this is a clone of 'struct tm' but with all fields we don't need or use
|
||||
cut out */
|
||||
struct my_tm {
|
||||
int tm_sec;
|
||||
int tm_min;
|
||||
int tm_hour;
|
||||
int tm_mday;
|
||||
int tm_mon;
|
||||
int tm_year;
|
||||
};
|
||||
|
||||
/* struct tm to time since epoch in GMT time zone.
|
||||
* This is similar to the standard mktime function but for GMT only, and
|
||||
* doesn't suffer from the various bugs and portability problems that
|
||||
* some systems' implementations have.
|
||||
*/
|
||||
static time_t my_timegm(struct my_tm *tm)
|
||||
{
|
||||
static const int month_days_cumulative [12] =
|
||||
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
|
||||
int month, year, leap_days;
|
||||
|
||||
if(tm->tm_year < 70)
|
||||
/* we don't support years before 1970 as they will cause this function
|
||||
to return a negative value */
|
||||
return -1;
|
||||
|
||||
year = tm->tm_year + 1900;
|
||||
month = tm->tm_mon;
|
||||
if(month < 0) {
|
||||
year += (11 - month) / 12;
|
||||
month = 11 - (11 - month) % 12;
|
||||
}
|
||||
else if(month >= 12) {
|
||||
year -= month / 12;
|
||||
month = month % 12;
|
||||
}
|
||||
|
||||
leap_days = year - (tm->tm_mon <= 1);
|
||||
leap_days = ((leap_days / 4) - (leap_days / 100) + (leap_days / 400)
|
||||
- (1969 / 4) + (1969 / 100) - (1969 / 400));
|
||||
|
||||
return ((((time_t) (year - 1970) * 365
|
||||
+ leap_days + month_days_cumulative [month] + tm->tm_mday - 1) * 24
|
||||
+ tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec;
|
||||
}
|
||||
|
||||
/*
|
||||
* parsedate()
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* PARSEDATE_OK - a fine conversion
|
||||
* PARSEDATE_FAIL - failed to convert
|
||||
* PARSEDATE_LATER - time overflow at the far end of time_t
|
||||
* PARSEDATE_SOONER - time underflow at the low end of time_t
|
||||
*/
|
||||
|
||||
static int parsedate(const char *date, time_t *output)
|
||||
{
|
||||
time_t t = 0;
|
||||
int wdaynum=-1; /* day of the week number, 0-6 (mon-sun) */
|
||||
int monnum=-1; /* month of the year number, 0-11 */
|
||||
int mdaynum=-1; /* day of month, 1 - 31 */
|
||||
int hournum=-1;
|
||||
int minnum=-1;
|
||||
int secnum=-1;
|
||||
int yearnum=-1;
|
||||
int tzoff=-1;
|
||||
struct my_tm tm;
|
||||
enum assume dignext = DATE_MDAY;
|
||||
const char *indate = date; /* save the original pointer */
|
||||
int part = 0; /* max 6 parts */
|
||||
|
||||
while(*date && (part < 6)) {
|
||||
bool found=FALSE;
|
||||
|
||||
skip(&date);
|
||||
|
||||
if(ISALPHA(*date)) {
|
||||
/* a name coming up */
|
||||
char buf[32]="";
|
||||
size_t len;
|
||||
if(sscanf(date, "%31[ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz]", buf))
|
||||
len = strlen(buf);
|
||||
else
|
||||
len = 0;
|
||||
|
||||
if(wdaynum == -1) {
|
||||
wdaynum = checkday(buf, len);
|
||||
if(wdaynum != -1)
|
||||
found = TRUE;
|
||||
}
|
||||
if(!found && (monnum == -1)) {
|
||||
monnum = checkmonth(buf);
|
||||
if(monnum != -1)
|
||||
found = TRUE;
|
||||
}
|
||||
|
||||
if(!found && (tzoff == -1)) {
|
||||
/* this just must be a time zone string */
|
||||
tzoff = checktz(buf);
|
||||
if(tzoff != -1)
|
||||
found = TRUE;
|
||||
}
|
||||
|
||||
if(!found)
|
||||
return PARSEDATE_FAIL; /* bad string */
|
||||
|
||||
date += len;
|
||||
}
|
||||
else if(ISDIGIT(*date)) {
|
||||
/* a digit */
|
||||
int val;
|
||||
char *end;
|
||||
int len=0;
|
||||
if((secnum == -1) &&
|
||||
(3 == sscanf(date, "%02d:%02d:%02d%n",
|
||||
&hournum, &minnum, &secnum, &len))) {
|
||||
/* time stamp! */
|
||||
date += len;
|
||||
}
|
||||
else if((secnum == -1) &&
|
||||
(2 == sscanf(date, "%02d:%02d%n", &hournum, &minnum, &len))) {
|
||||
/* time stamp without seconds */
|
||||
date += len;
|
||||
secnum = 0;
|
||||
}
|
||||
else {
|
||||
long lval;
|
||||
int error;
|
||||
int old_errno;
|
||||
|
||||
old_errno = ERRNO;
|
||||
SET_ERRNO(0);
|
||||
lval = strtol(date, &end, 10);
|
||||
error = ERRNO;
|
||||
if(error != old_errno)
|
||||
SET_ERRNO(old_errno);
|
||||
|
||||
if(error)
|
||||
return PARSEDATE_FAIL;
|
||||
|
||||
#if LONG_MAX != INT_MAX
|
||||
if((lval > (long)INT_MAX) || (lval < (long)INT_MIN))
|
||||
return PARSEDATE_FAIL;
|
||||
#endif
|
||||
|
||||
val = curlx_sltosi(lval);
|
||||
|
||||
if((tzoff == -1) &&
|
||||
((end - date) == 4) &&
|
||||
(val <= 1400) &&
|
||||
(indate< date) &&
|
||||
((date[-1] == '+' || date[-1] == '-'))) {
|
||||
/* four digits and a value less than or equal to 1400 (to take into
|
||||
account all sorts of funny time zone diffs) and it is preceded
|
||||
with a plus or minus. This is a time zone indication. 1400 is
|
||||
picked since +1300 is frequently used and +1400 is mentioned as
|
||||
an edge number in the document "ISO C 200X Proposal: Timezone
|
||||
Functions" at http://david.tribble.com/text/c0xtimezone.html If
|
||||
anyone has a more authoritative source for the exact maximum time
|
||||
zone offsets, please speak up! */
|
||||
found = TRUE;
|
||||
tzoff = (val/100 * 60 + val%100)*60;
|
||||
|
||||
/* the + and - prefix indicates the local time compared to GMT,
|
||||
this we need ther reversed math to get what we want */
|
||||
tzoff = date[-1]=='+'?-tzoff:tzoff;
|
||||
}
|
||||
|
||||
if(((end - date) == 8) &&
|
||||
(yearnum == -1) &&
|
||||
(monnum == -1) &&
|
||||
(mdaynum == -1)) {
|
||||
/* 8 digits, no year, month or day yet. This is YYYYMMDD */
|
||||
found = TRUE;
|
||||
yearnum = val/10000;
|
||||
monnum = (val%10000)/100-1; /* month is 0 - 11 */
|
||||
mdaynum = val%100;
|
||||
}
|
||||
|
||||
if(!found && (dignext == DATE_MDAY) && (mdaynum == -1)) {
|
||||
if((val > 0) && (val<32)) {
|
||||
mdaynum = val;
|
||||
found = TRUE;
|
||||
}
|
||||
dignext = DATE_YEAR;
|
||||
}
|
||||
|
||||
if(!found && (dignext == DATE_YEAR) && (yearnum == -1)) {
|
||||
yearnum = val;
|
||||
found = TRUE;
|
||||
if(yearnum < 1900) {
|
||||
if(yearnum > 70)
|
||||
yearnum += 1900;
|
||||
else
|
||||
yearnum += 2000;
|
||||
}
|
||||
if(mdaynum == -1)
|
||||
dignext = DATE_MDAY;
|
||||
}
|
||||
|
||||
if(!found)
|
||||
return PARSEDATE_FAIL;
|
||||
|
||||
date = end;
|
||||
}
|
||||
}
|
||||
|
||||
part++;
|
||||
}
|
||||
|
||||
if(-1 == secnum)
|
||||
secnum = minnum = hournum = 0; /* no time, make it zero */
|
||||
|
||||
if((-1 == mdaynum) ||
|
||||
(-1 == monnum) ||
|
||||
(-1 == yearnum))
|
||||
/* lacks vital info, fail */
|
||||
return PARSEDATE_FAIL;
|
||||
|
||||
#if SIZEOF_TIME_T < 5
|
||||
/* 32 bit time_t can only hold dates to the beginning of 2038 */
|
||||
if(yearnum > 2037) {
|
||||
*output = 0x7fffffff;
|
||||
return PARSEDATE_LATER;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(yearnum < 1970) {
|
||||
*output = 0;
|
||||
return PARSEDATE_SOONER;
|
||||
}
|
||||
|
||||
if((mdaynum > 31) || (monnum > 11) ||
|
||||
(hournum > 23) || (minnum > 59) || (secnum > 60))
|
||||
return PARSEDATE_FAIL; /* clearly an illegal date */
|
||||
|
||||
tm.tm_sec = secnum;
|
||||
tm.tm_min = minnum;
|
||||
tm.tm_hour = hournum;
|
||||
tm.tm_mday = mdaynum;
|
||||
tm.tm_mon = monnum;
|
||||
tm.tm_year = yearnum - 1900;
|
||||
|
||||
/* my_timegm() returns a time_t. time_t is often 32 bits, even on many
|
||||
architectures that feature 64 bit 'long'.
|
||||
|
||||
Some systems have 64 bit time_t and deal with years beyond 2038. However,
|
||||
even on some of the systems with 64 bit time_t mktime() returns -1 for
|
||||
dates beyond 03:14:07 UTC, January 19, 2038. (Such as AIX 5100-06)
|
||||
*/
|
||||
t = my_timegm(&tm);
|
||||
|
||||
/* time zone adjust (cast t to int to compare to negative one) */
|
||||
if(-1 != (int)t) {
|
||||
|
||||
/* Add the time zone diff between local time zone and GMT. */
|
||||
long delta = (long)(tzoff!=-1?tzoff:0);
|
||||
|
||||
if((delta>0) && (t > LONG_MAX - delta)) {
|
||||
*output = 0x7fffffff;
|
||||
return PARSEDATE_LATER; /* time_t overflow */
|
||||
}
|
||||
|
||||
t += delta;
|
||||
}
|
||||
|
||||
*output = t;
|
||||
|
||||
return PARSEDATE_OK;
|
||||
}
|
||||
|
||||
time_t curl_getdate(const char *p, const time_t *now)
|
||||
{
|
||||
time_t parsed = -1;
|
||||
int rc = parsedate(p, &parsed);
|
||||
(void)now; /* legacy argument from the past that we ignore */
|
||||
|
||||
switch(rc) {
|
||||
case PARSEDATE_OK:
|
||||
case PARSEDATE_LATER:
|
||||
case PARSEDATE_SOONER:
|
||||
return parsed;
|
||||
}
|
||||
/* everything else is fail */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_gmtime() is a gmtime() replacement for portability. Do not use the
|
||||
* gmtime_r() or gmtime() functions anywhere else but here.
|
||||
*
|
||||
*/
|
||||
|
||||
CURLcode Curl_gmtime(time_t intime, struct tm *store)
|
||||
{
|
||||
const struct tm *tm;
|
||||
#ifdef HAVE_GMTIME_R
|
||||
/* thread-safe version */
|
||||
tm = (struct tm *)gmtime_r(&intime, store);
|
||||
#else
|
||||
tm = gmtime(&intime);
|
||||
if(tm)
|
||||
*store = *tm; /* copy the pointed struct to the local copy */
|
||||
#endif
|
||||
|
||||
if(!tm)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#ifndef HEADER_CURL_PARSEDATE_H
|
||||
#define HEADER_CURL_PARSEDATE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 https://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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
extern const char * const Curl_wkday[7];
|
||||
extern const char * const Curl_month[12];
|
||||
|
||||
CURLcode Curl_gmtime(time_t intime, struct tm *store);
|
||||
|
||||
#endif /* HEADER_CURL_PARSEDATE_H */
|
||||
|
||||
@@ -1,510 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* 'pingpong' is for generic back-and-forth support functions used by FTP,
|
||||
* IMAP, POP3, SMTP and whatever more that likes them.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "select.h"
|
||||
#include "progress.h"
|
||||
#include "speedcheck.h"
|
||||
#include "pingpong.h"
|
||||
#include "multiif.h"
|
||||
#include "non-ascii.h"
|
||||
#include "vtls/vtls.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef USE_PINGPONG
|
||||
|
||||
/* Returns timeout in ms. 0 or negative number means the timeout has already
|
||||
triggered */
|
||||
time_t Curl_pp_state_timeout(struct pingpong *pp)
|
||||
{
|
||||
struct connectdata *conn = pp->conn;
|
||||
struct Curl_easy *data=conn->data;
|
||||
time_t timeout_ms; /* in milliseconds */
|
||||
time_t timeout2_ms; /* in milliseconds */
|
||||
long response_time= (data->set.server_response_timeout)?
|
||||
data->set.server_response_timeout: pp->response_time;
|
||||
|
||||
/* if CURLOPT_SERVER_RESPONSE_TIMEOUT is set, use that to determine
|
||||
remaining time, or use pp->response because SERVER_RESPONSE_TIMEOUT is
|
||||
supposed to govern the response for any given server response, not for
|
||||
the time from connect to the given server response. */
|
||||
|
||||
/* Without a requested timeout, we only wait 'response_time' seconds for the
|
||||
full response to arrive before we bail out */
|
||||
timeout_ms = response_time -
|
||||
Curl_tvdiff(Curl_tvnow(), pp->response); /* spent time */
|
||||
|
||||
if(data->set.timeout) {
|
||||
/* if timeout is requested, find out how much remaining time we have */
|
||||
timeout2_ms = data->set.timeout - /* timeout time */
|
||||
Curl_tvdiff(Curl_tvnow(), conn->now); /* spent time */
|
||||
|
||||
/* pick the lowest number */
|
||||
timeout_ms = CURLMIN(timeout_ms, timeout2_ms);
|
||||
}
|
||||
|
||||
return timeout_ms;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_pp_statemach()
|
||||
*/
|
||||
CURLcode Curl_pp_statemach(struct pingpong *pp, bool block)
|
||||
{
|
||||
struct connectdata *conn = pp->conn;
|
||||
curl_socket_t sock = conn->sock[FIRSTSOCKET];
|
||||
int rc;
|
||||
time_t interval_ms;
|
||||
time_t timeout_ms = Curl_pp_state_timeout(pp);
|
||||
struct Curl_easy *data=conn->data;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(timeout_ms <=0) {
|
||||
failf(data, "server response timeout");
|
||||
return CURLE_OPERATION_TIMEDOUT; /* already too little time */
|
||||
}
|
||||
|
||||
if(block) {
|
||||
interval_ms = 1000; /* use 1 second timeout intervals */
|
||||
if(timeout_ms < interval_ms)
|
||||
interval_ms = timeout_ms;
|
||||
}
|
||||
else
|
||||
interval_ms = 0; /* immediate */
|
||||
|
||||
if(Curl_ssl_data_pending(conn, FIRSTSOCKET))
|
||||
rc = 1;
|
||||
else if(Curl_pp_moredata(pp))
|
||||
/* We are receiving and there is data in the cache so just read it */
|
||||
rc = 1;
|
||||
else if(!pp->sendleft && Curl_ssl_data_pending(conn, FIRSTSOCKET))
|
||||
/* We are receiving and there is data ready in the SSL library */
|
||||
rc = 1;
|
||||
else
|
||||
rc = Curl_socket_check(pp->sendleft?CURL_SOCKET_BAD:sock, /* reading */
|
||||
CURL_SOCKET_BAD,
|
||||
pp->sendleft?sock:CURL_SOCKET_BAD, /* writing */
|
||||
interval_ms);
|
||||
|
||||
if(block) {
|
||||
/* if we didn't wait, we don't have to spend time on this now */
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
else
|
||||
result = Curl_speedcheck(data, Curl_tvnow());
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
if(rc == -1) {
|
||||
failf(data, "select/poll error");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else if(rc)
|
||||
result = pp->statemach_act(conn);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* initialize stuff to prepare for reading a fresh new response */
|
||||
void Curl_pp_init(struct pingpong *pp)
|
||||
{
|
||||
struct connectdata *conn = pp->conn;
|
||||
pp->nread_resp = 0;
|
||||
pp->linestart_resp = conn->data->state.buffer;
|
||||
pp->pending_resp = TRUE;
|
||||
pp->response = Curl_tvnow(); /* start response time-out now! */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Curl_pp_vsendf()
|
||||
*
|
||||
* Send the formated string as a command to a pingpong server. Note that
|
||||
* the string should not have any CRLF appended, as this function will
|
||||
* append the necessary things itself.
|
||||
*
|
||||
* made to never block
|
||||
*/
|
||||
CURLcode Curl_pp_vsendf(struct pingpong *pp,
|
||||
const char *fmt,
|
||||
va_list args)
|
||||
{
|
||||
ssize_t bytes_written;
|
||||
size_t write_len;
|
||||
char *fmt_crlf;
|
||||
char *s;
|
||||
CURLcode result;
|
||||
struct connectdata *conn = pp->conn;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
enum protection_level data_sec = conn->data_prot;
|
||||
#endif
|
||||
|
||||
DEBUGASSERT(pp->sendleft == 0);
|
||||
DEBUGASSERT(pp->sendsize == 0);
|
||||
DEBUGASSERT(pp->sendthis == NULL);
|
||||
|
||||
fmt_crlf = aprintf("%s\r\n", fmt); /* append a trailing CRLF */
|
||||
if(!fmt_crlf)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
s = vaprintf(fmt_crlf, args); /* trailing CRLF appended */
|
||||
free(fmt_crlf);
|
||||
if(!s)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
bytes_written = 0;
|
||||
write_len = strlen(s);
|
||||
|
||||
Curl_pp_init(pp);
|
||||
|
||||
result = Curl_convert_to_network(data, s, write_len);
|
||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||
if(result) {
|
||||
free(s);
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
conn->data_prot = PROT_CMD;
|
||||
#endif
|
||||
result = Curl_write(conn, conn->sock[FIRSTSOCKET], s, write_len,
|
||||
&bytes_written);
|
||||
#ifdef HAVE_GSSAPI
|
||||
DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
|
||||
conn->data_prot = data_sec;
|
||||
#endif
|
||||
|
||||
if(result) {
|
||||
free(s);
|
||||
return result;
|
||||
}
|
||||
|
||||
if(conn->data->set.verbose)
|
||||
Curl_debug(conn->data, CURLINFO_HEADER_OUT,
|
||||
s, (size_t)bytes_written, conn);
|
||||
|
||||
if(bytes_written != (ssize_t)write_len) {
|
||||
/* the whole chunk was not sent, keep it around and adjust sizes */
|
||||
pp->sendthis = s;
|
||||
pp->sendsize = write_len;
|
||||
pp->sendleft = write_len - bytes_written;
|
||||
}
|
||||
else {
|
||||
free(s);
|
||||
pp->sendthis = NULL;
|
||||
pp->sendleft = pp->sendsize = 0;
|
||||
pp->response = Curl_tvnow();
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Curl_pp_sendf()
|
||||
*
|
||||
* Send the formated string as a command to a pingpong server. Note that
|
||||
* the string should not have any CRLF appended, as this function will
|
||||
* append the necessary things itself.
|
||||
*
|
||||
* made to never block
|
||||
*/
|
||||
CURLcode Curl_pp_sendf(struct pingpong *pp,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
CURLcode result;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
result = Curl_pp_vsendf(pp, fmt, ap);
|
||||
|
||||
va_end(ap);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_pp_readresp()
|
||||
*
|
||||
* Reads a piece of a server response.
|
||||
*/
|
||||
CURLcode Curl_pp_readresp(curl_socket_t sockfd,
|
||||
struct pingpong *pp,
|
||||
int *code, /* return the server code if done */
|
||||
size_t *size) /* size of the response */
|
||||
{
|
||||
ssize_t perline; /* count bytes per line */
|
||||
bool keepon=TRUE;
|
||||
ssize_t gotbytes;
|
||||
char *ptr;
|
||||
struct connectdata *conn = pp->conn;
|
||||
struct Curl_easy *data = conn->data;
|
||||
char * const buf = data->state.buffer;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
*code = 0; /* 0 for errors or not done */
|
||||
*size = 0;
|
||||
|
||||
ptr=buf + pp->nread_resp;
|
||||
|
||||
/* number of bytes in the current line, so far */
|
||||
perline = (ssize_t)(ptr-pp->linestart_resp);
|
||||
|
||||
while((pp->nread_resp<BUFSIZE) && (keepon && !result)) {
|
||||
|
||||
if(pp->cache) {
|
||||
/* we had data in the "cache", copy that instead of doing an actual
|
||||
* read
|
||||
*
|
||||
* pp->cache_size is cast to ssize_t here. This should be safe, because
|
||||
* it would have been populated with something of size int to begin
|
||||
* with, even though its datatype may be larger than an int.
|
||||
*/
|
||||
DEBUGASSERT((ptr+pp->cache_size) <= (buf+BUFSIZE+1));
|
||||
memcpy(ptr, pp->cache, pp->cache_size);
|
||||
gotbytes = (ssize_t)pp->cache_size;
|
||||
free(pp->cache); /* free the cache */
|
||||
pp->cache = NULL; /* clear the pointer */
|
||||
pp->cache_size = 0; /* zero the size just in case */
|
||||
}
|
||||
else {
|
||||
#ifdef HAVE_GSSAPI
|
||||
enum protection_level prot = conn->data_prot;
|
||||
conn->data_prot = PROT_CLEAR;
|
||||
#endif
|
||||
DEBUGASSERT((ptr+BUFSIZE-pp->nread_resp) <= (buf+BUFSIZE+1));
|
||||
result = Curl_read(conn, sockfd, ptr, BUFSIZE-pp->nread_resp,
|
||||
&gotbytes);
|
||||
#ifdef HAVE_GSSAPI
|
||||
DEBUGASSERT(prot > PROT_NONE && prot < PROT_LAST);
|
||||
conn->data_prot = prot;
|
||||
#endif
|
||||
if(result == CURLE_AGAIN)
|
||||
return CURLE_OK; /* return */
|
||||
|
||||
if(!result && (gotbytes > 0))
|
||||
/* convert from the network encoding */
|
||||
result = Curl_convert_from_network(data, ptr, gotbytes);
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
|
||||
if(result)
|
||||
/* Set outer result variable to this error. */
|
||||
keepon = FALSE;
|
||||
}
|
||||
|
||||
if(!keepon)
|
||||
;
|
||||
else if(gotbytes <= 0) {
|
||||
keepon = FALSE;
|
||||
result = CURLE_RECV_ERROR;
|
||||
failf(data, "response reading failed");
|
||||
}
|
||||
else {
|
||||
/* we got a whole chunk of data, which can be anything from one
|
||||
* byte to a set of lines and possible just a piece of the last
|
||||
* line */
|
||||
ssize_t i;
|
||||
ssize_t clipamount = 0;
|
||||
bool restart = FALSE;
|
||||
|
||||
data->req.headerbytecount += (long)gotbytes;
|
||||
|
||||
pp->nread_resp += gotbytes;
|
||||
for(i = 0; i < gotbytes; ptr++, i++) {
|
||||
perline++;
|
||||
if(*ptr=='\n') {
|
||||
/* a newline is CRLF in pp-talk, so the CR is ignored as
|
||||
the line isn't really terminated until the LF comes */
|
||||
|
||||
/* output debug output if that is requested */
|
||||
#ifdef HAVE_GSSAPI
|
||||
if(!conn->sec_complete)
|
||||
#endif
|
||||
if(data->set.verbose)
|
||||
Curl_debug(data, CURLINFO_HEADER_IN,
|
||||
pp->linestart_resp, (size_t)perline, conn);
|
||||
|
||||
/*
|
||||
* We pass all response-lines to the callback function registered
|
||||
* for "headers". The response lines can be seen as a kind of
|
||||
* headers.
|
||||
*/
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER,
|
||||
pp->linestart_resp, perline);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(pp->endofresp(conn, pp->linestart_resp, perline, code)) {
|
||||
/* This is the end of the last line, copy the last line to the
|
||||
start of the buffer and zero terminate, for old times sake */
|
||||
size_t n = ptr - pp->linestart_resp;
|
||||
memmove(buf, pp->linestart_resp, n);
|
||||
buf[n]=0; /* zero terminate */
|
||||
keepon=FALSE;
|
||||
pp->linestart_resp = ptr+1; /* advance pointer */
|
||||
i++; /* skip this before getting out */
|
||||
|
||||
*size = pp->nread_resp; /* size of the response */
|
||||
pp->nread_resp = 0; /* restart */
|
||||
break;
|
||||
}
|
||||
perline=0; /* line starts over here */
|
||||
pp->linestart_resp = ptr+1;
|
||||
}
|
||||
}
|
||||
|
||||
if(!keepon && (i != gotbytes)) {
|
||||
/* We found the end of the response lines, but we didn't parse the
|
||||
full chunk of data we have read from the server. We therefore need
|
||||
to store the rest of the data to be checked on the next invoke as
|
||||
it may actually contain another end of response already! */
|
||||
clipamount = gotbytes - i;
|
||||
restart = TRUE;
|
||||
DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing "
|
||||
"server response left\n",
|
||||
(int)clipamount));
|
||||
}
|
||||
else if(keepon) {
|
||||
|
||||
if((perline == gotbytes) && (gotbytes > BUFSIZE/2)) {
|
||||
/* We got an excessive line without newlines and we need to deal
|
||||
with it. We keep the first bytes of the line then we throw
|
||||
away the rest. */
|
||||
infof(data, "Excessive server response line length received, "
|
||||
"%zd bytes. Stripping\n", gotbytes);
|
||||
restart = TRUE;
|
||||
|
||||
/* we keep 40 bytes since all our pingpong protocols are only
|
||||
interested in the first piece */
|
||||
clipamount = 40;
|
||||
}
|
||||
else if(pp->nread_resp > BUFSIZE/2) {
|
||||
/* We got a large chunk of data and there's potentially still
|
||||
trailing data to take care of, so we put any such part in the
|
||||
"cache", clear the buffer to make space and restart. */
|
||||
clipamount = perline;
|
||||
restart = TRUE;
|
||||
}
|
||||
}
|
||||
else if(i == gotbytes)
|
||||
restart = TRUE;
|
||||
|
||||
if(clipamount) {
|
||||
pp->cache_size = clipamount;
|
||||
pp->cache = malloc(pp->cache_size);
|
||||
if(pp->cache)
|
||||
memcpy(pp->cache, pp->linestart_resp, pp->cache_size);
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
if(restart) {
|
||||
/* now reset a few variables to start over nicely from the start of
|
||||
the big buffer */
|
||||
pp->nread_resp = 0; /* start over from scratch in the buffer */
|
||||
ptr = pp->linestart_resp = buf;
|
||||
perline = 0;
|
||||
}
|
||||
|
||||
} /* there was data */
|
||||
|
||||
} /* while there's buffer left and loop is requested */
|
||||
|
||||
pp->pending_resp = FALSE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int Curl_pp_getsock(struct pingpong *pp,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
{
|
||||
struct connectdata *conn = pp->conn;
|
||||
|
||||
if(!numsocks)
|
||||
return GETSOCK_BLANK;
|
||||
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
|
||||
if(pp->sendleft) {
|
||||
/* write mode */
|
||||
return GETSOCK_WRITESOCK(0);
|
||||
}
|
||||
|
||||
/* read mode */
|
||||
return GETSOCK_READSOCK(0);
|
||||
}
|
||||
|
||||
CURLcode Curl_pp_flushsend(struct pingpong *pp)
|
||||
{
|
||||
/* we have a piece of a command still left to send */
|
||||
struct connectdata *conn = pp->conn;
|
||||
ssize_t written;
|
||||
curl_socket_t sock = conn->sock[FIRSTSOCKET];
|
||||
CURLcode result = Curl_write(conn, sock, pp->sendthis + pp->sendsize -
|
||||
pp->sendleft, pp->sendleft, &written);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(written != (ssize_t)pp->sendleft) {
|
||||
/* only a fraction was sent */
|
||||
pp->sendleft -= written;
|
||||
}
|
||||
else {
|
||||
free(pp->sendthis);
|
||||
pp->sendthis=NULL;
|
||||
pp->sendleft = pp->sendsize = 0;
|
||||
pp->response = Curl_tvnow();
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_pp_disconnect(struct pingpong *pp)
|
||||
{
|
||||
free(pp->cache);
|
||||
pp->cache = NULL;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
bool Curl_pp_moredata(struct pingpong *pp)
|
||||
{
|
||||
return (!pp->sendleft && pp->cache && pp->nread_resp < pp->cache_size) ?
|
||||
TRUE : FALSE;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,150 +0,0 @@
|
||||
#ifndef HEADER_CURL_PINGPONG_H
|
||||
#define HEADER_CURL_PINGPONG_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_FTP) || \
|
||||
!defined(CURL_DISABLE_POP3) || !defined(CURL_DISABLE_SMTP)
|
||||
#define USE_PINGPONG
|
||||
#endif
|
||||
|
||||
/* forward-declaration, this is defined in urldata.h */
|
||||
struct connectdata;
|
||||
|
||||
typedef enum {
|
||||
FTPTRANSFER_BODY, /* yes do transfer a body */
|
||||
FTPTRANSFER_INFO, /* do still go through to get info/headers */
|
||||
FTPTRANSFER_NONE, /* don't get anything and don't get info */
|
||||
FTPTRANSFER_LAST /* end of list marker, never used */
|
||||
} curl_pp_transfer;
|
||||
|
||||
/*
|
||||
* 'pingpong' is the generic struct used for protocols doing server<->client
|
||||
* conversations in a back-and-forth style such as FTP, IMAP, POP3, SMTP etc.
|
||||
*
|
||||
* It holds response cache and non-blocking sending data.
|
||||
*/
|
||||
struct pingpong {
|
||||
char *cache; /* data cache between getresponse()-calls */
|
||||
size_t cache_size; /* size of cache in bytes */
|
||||
size_t nread_resp; /* number of bytes currently read of a server response */
|
||||
char *linestart_resp; /* line start pointer for the server response
|
||||
reader function */
|
||||
bool pending_resp; /* set TRUE when a server response is pending or in
|
||||
progress, and is cleared once the last response is
|
||||
read */
|
||||
char *sendthis; /* allocated pointer to a buffer that is to be sent to the
|
||||
server */
|
||||
size_t sendleft; /* number of bytes left to send from the sendthis buffer */
|
||||
size_t sendsize; /* total size of the sendthis buffer */
|
||||
struct timeval response; /* set to Curl_tvnow() when a command has been sent
|
||||
off, used to time-out response reading */
|
||||
long response_time; /* When no timeout is given, this is the amount of
|
||||
milliseconds we await for a server response. */
|
||||
|
||||
struct connectdata *conn; /* points to the connectdata struct that this
|
||||
belongs to */
|
||||
|
||||
/* Function pointers the protocols MUST implement and provide for the
|
||||
pingpong layer to function */
|
||||
|
||||
CURLcode (*statemach_act)(struct connectdata *conn);
|
||||
|
||||
bool (*endofresp)(struct connectdata *conn, char *ptr, size_t len,
|
||||
int *code);
|
||||
};
|
||||
|
||||
/*
|
||||
* Curl_pp_statemach()
|
||||
*
|
||||
* called repeatedly until done. Set 'wait' to make it wait a while on the
|
||||
* socket if there's no traffic.
|
||||
*/
|
||||
CURLcode Curl_pp_statemach(struct pingpong *pp, bool block);
|
||||
|
||||
/* initialize stuff to prepare for reading a fresh new response */
|
||||
void Curl_pp_init(struct pingpong *pp);
|
||||
|
||||
/* Returns timeout in ms. 0 or negative number means the timeout has already
|
||||
triggered */
|
||||
time_t Curl_pp_state_timeout(struct pingpong *pp);
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Curl_pp_sendf()
|
||||
*
|
||||
* Send the formated string as a command to a pingpong server. Note that
|
||||
* the string should not have any CRLF appended, as this function will
|
||||
* append the necessary things itself.
|
||||
*
|
||||
* made to never block
|
||||
*/
|
||||
CURLcode Curl_pp_sendf(struct pingpong *pp,
|
||||
const char *fmt, ...);
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Curl_pp_vsendf()
|
||||
*
|
||||
* Send the formated string as a command to a pingpong server. Note that
|
||||
* the string should not have any CRLF appended, as this function will
|
||||
* append the necessary things itself.
|
||||
*
|
||||
* made to never block
|
||||
*/
|
||||
CURLcode Curl_pp_vsendf(struct pingpong *pp,
|
||||
const char *fmt,
|
||||
va_list args);
|
||||
|
||||
/*
|
||||
* Curl_pp_readresp()
|
||||
*
|
||||
* Reads a piece of a server response.
|
||||
*/
|
||||
CURLcode Curl_pp_readresp(curl_socket_t sockfd,
|
||||
struct pingpong *pp,
|
||||
int *code, /* return the server code if done */
|
||||
size_t *size); /* size of the response */
|
||||
|
||||
|
||||
CURLcode Curl_pp_flushsend(struct pingpong *pp);
|
||||
|
||||
/* call this when a pingpong connection is disconnected */
|
||||
CURLcode Curl_pp_disconnect(struct pingpong *pp);
|
||||
|
||||
int Curl_pp_getsock(struct pingpong *pp, curl_socket_t *socks,
|
||||
int numsocks);
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Curl_pp_moredata()
|
||||
*
|
||||
* Returns whether there are still more data in the cache and so a call
|
||||
* to Curl_pp_readresp() will not block.
|
||||
*/
|
||||
bool Curl_pp_moredata(struct pingpong *pp);
|
||||
|
||||
#endif /* HEADER_CURL_PINGPONG_H */
|
||||
@@ -1,439 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
* Copyright (C) 2013-2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "url.h"
|
||||
#include "progress.h"
|
||||
#include "multiif.h"
|
||||
#include "pipeline.h"
|
||||
#include "sendf.h"
|
||||
#include "strcase.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
struct site_blacklist_entry {
|
||||
char *hostname;
|
||||
unsigned short port;
|
||||
};
|
||||
|
||||
static void site_blacklist_llist_dtor(void *user, void *element)
|
||||
{
|
||||
struct site_blacklist_entry *entry = element;
|
||||
(void)user;
|
||||
|
||||
Curl_safefree(entry->hostname);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
static void server_blacklist_llist_dtor(void *user, void *element)
|
||||
{
|
||||
(void)user;
|
||||
free(element);
|
||||
}
|
||||
|
||||
bool Curl_pipeline_penalized(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
if(data) {
|
||||
bool penalized = FALSE;
|
||||
curl_off_t penalty_size =
|
||||
Curl_multi_content_length_penalty_size(data->multi);
|
||||
curl_off_t chunk_penalty_size =
|
||||
Curl_multi_chunk_length_penalty_size(data->multi);
|
||||
curl_off_t recv_size = -2; /* Make it easy to spot in the log */
|
||||
|
||||
/* Find the head of the recv pipe, if any */
|
||||
if(conn->recv_pipe && conn->recv_pipe->head) {
|
||||
struct Curl_easy *recv_handle = conn->recv_pipe->head->ptr;
|
||||
|
||||
recv_size = recv_handle->req.size;
|
||||
|
||||
if(penalty_size > 0 && recv_size > penalty_size)
|
||||
penalized = TRUE;
|
||||
}
|
||||
|
||||
if(chunk_penalty_size > 0 &&
|
||||
(curl_off_t)conn->chunk.datasize > chunk_penalty_size)
|
||||
penalized = TRUE;
|
||||
|
||||
infof(data, "Conn: %ld (%p) Receive pipe weight: (%"
|
||||
CURL_FORMAT_CURL_OFF_T "/%zu), penalized: %s\n",
|
||||
conn->connection_id, (void *)conn, recv_size,
|
||||
conn->chunk.datasize, penalized?"TRUE":"FALSE");
|
||||
return penalized;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static CURLcode addHandleToPipeline(struct Curl_easy *data,
|
||||
struct curl_llist *pipeline)
|
||||
{
|
||||
if(!Curl_llist_insert_next(pipeline, pipeline->tail, data))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct curl_llist_element *sendhead = conn->send_pipe->head;
|
||||
struct curl_llist *pipeline;
|
||||
CURLcode result;
|
||||
|
||||
pipeline = conn->send_pipe;
|
||||
|
||||
result = addHandleToPipeline(handle, pipeline);
|
||||
|
||||
if(pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) {
|
||||
/* this is a new one as head, expire it */
|
||||
Curl_pipeline_leave_write(conn); /* not in use yet */
|
||||
Curl_expire(conn->send_pipe->head->ptr, 0);
|
||||
}
|
||||
|
||||
#if 0 /* enable for pipeline debugging */
|
||||
print_pipeline(conn);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Move this transfer from the sending list to the receiving list.
|
||||
|
||||
Pay special attention to the new sending list "leader" as it needs to get
|
||||
checked to update what sockets it acts on.
|
||||
|
||||
*/
|
||||
void Curl_move_handle_from_send_to_recv_pipe(struct Curl_easy *handle,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct curl_llist_element *curr;
|
||||
|
||||
curr = conn->send_pipe->head;
|
||||
while(curr) {
|
||||
if(curr->ptr == handle) {
|
||||
Curl_llist_move(conn->send_pipe, curr,
|
||||
conn->recv_pipe, conn->recv_pipe->tail);
|
||||
|
||||
if(conn->send_pipe->head) {
|
||||
/* Since there's a new easy handle at the start of the send pipeline,
|
||||
set its timeout value to 1ms to make it trigger instantly */
|
||||
Curl_pipeline_leave_write(conn); /* not used now */
|
||||
#ifdef DEBUGBUILD
|
||||
infof(conn->data, "%p is at send pipe head B!\n",
|
||||
(void *)conn->send_pipe->head->ptr);
|
||||
#endif
|
||||
Curl_expire(conn->send_pipe->head->ptr, 0);
|
||||
}
|
||||
|
||||
/* The receiver's list is not really interesting here since either this
|
||||
handle is now first in the list and we'll deal with it soon, or
|
||||
another handle is already first and thus is already taken care of */
|
||||
|
||||
break; /* we're done! */
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
|
||||
bool Curl_pipeline_site_blacklisted(struct Curl_easy *handle,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
if(handle->multi) {
|
||||
struct curl_llist *blacklist =
|
||||
Curl_multi_pipelining_site_bl(handle->multi);
|
||||
|
||||
if(blacklist) {
|
||||
struct curl_llist_element *curr;
|
||||
|
||||
curr = blacklist->head;
|
||||
while(curr) {
|
||||
struct site_blacklist_entry *site;
|
||||
|
||||
site = curr->ptr;
|
||||
if(strcasecompare(site->hostname, conn->host.name) &&
|
||||
site->port == conn->remote_port) {
|
||||
infof(handle, "Site %s:%d is pipeline blacklisted\n",
|
||||
conn->host.name, conn->remote_port);
|
||||
return TRUE;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
|
||||
struct curl_llist **list_ptr)
|
||||
{
|
||||
struct curl_llist *old_list = *list_ptr;
|
||||
struct curl_llist *new_list = NULL;
|
||||
|
||||
if(sites) {
|
||||
new_list = Curl_llist_alloc((curl_llist_dtor) site_blacklist_llist_dtor);
|
||||
if(!new_list)
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
|
||||
/* Parse the URLs and populate the list */
|
||||
while(*sites) {
|
||||
char *hostname;
|
||||
char *port;
|
||||
struct site_blacklist_entry *entry;
|
||||
|
||||
hostname = strdup(*sites);
|
||||
if(!hostname) {
|
||||
Curl_llist_destroy(new_list, NULL);
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
entry = malloc(sizeof(struct site_blacklist_entry));
|
||||
if(!entry) {
|
||||
free(hostname);
|
||||
Curl_llist_destroy(new_list, NULL);
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
port = strchr(hostname, ':');
|
||||
if(port) {
|
||||
*port = '\0';
|
||||
port++;
|
||||
entry->port = (unsigned short)strtol(port, NULL, 10);
|
||||
}
|
||||
else {
|
||||
/* Default port number for HTTP */
|
||||
entry->port = 80;
|
||||
}
|
||||
|
||||
entry->hostname = hostname;
|
||||
|
||||
if(!Curl_llist_insert_next(new_list, new_list->tail, entry)) {
|
||||
site_blacklist_llist_dtor(NULL, entry);
|
||||
Curl_llist_destroy(new_list, NULL);
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
sites++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the old list */
|
||||
if(old_list) {
|
||||
Curl_llist_destroy(old_list, NULL);
|
||||
}
|
||||
|
||||
/* This might be NULL if sites == NULL, i.e the blacklist is cleared */
|
||||
*list_ptr = new_list;
|
||||
|
||||
return CURLM_OK;
|
||||
}
|
||||
|
||||
bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle,
|
||||
char *server_name)
|
||||
{
|
||||
if(handle->multi && server_name) {
|
||||
struct curl_llist *blacklist =
|
||||
Curl_multi_pipelining_server_bl(handle->multi);
|
||||
|
||||
if(blacklist) {
|
||||
struct curl_llist_element *curr;
|
||||
|
||||
curr = blacklist->head;
|
||||
while(curr) {
|
||||
char *bl_server_name;
|
||||
|
||||
bl_server_name = curr->ptr;
|
||||
if(strncasecompare(bl_server_name, server_name,
|
||||
strlen(bl_server_name))) {
|
||||
infof(handle, "Server %s is blacklisted\n", server_name);
|
||||
return TRUE;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUGF(infof(handle, "Server %s is not blacklisted\n", server_name));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
|
||||
struct curl_llist **list_ptr)
|
||||
{
|
||||
struct curl_llist *old_list = *list_ptr;
|
||||
struct curl_llist *new_list = NULL;
|
||||
|
||||
if(servers) {
|
||||
new_list = Curl_llist_alloc((curl_llist_dtor) server_blacklist_llist_dtor);
|
||||
if(!new_list)
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
|
||||
/* Parse the URLs and populate the list */
|
||||
while(*servers) {
|
||||
char *server_name;
|
||||
|
||||
server_name = strdup(*servers);
|
||||
if(!server_name) {
|
||||
Curl_llist_destroy(new_list, NULL);
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(!Curl_llist_insert_next(new_list, new_list->tail, server_name)) {
|
||||
Curl_llist_destroy(new_list, NULL);
|
||||
Curl_safefree(server_name);
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
servers++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the old list */
|
||||
if(old_list) {
|
||||
Curl_llist_destroy(old_list, NULL);
|
||||
}
|
||||
|
||||
/* This might be NULL if sites == NULL, i.e the blacklist is cleared */
|
||||
*list_ptr = new_list;
|
||||
|
||||
return CURLM_OK;
|
||||
}
|
||||
|
||||
static bool pipe_head(struct Curl_easy *data,
|
||||
struct curl_llist *pipeline)
|
||||
{
|
||||
if(pipeline) {
|
||||
struct curl_llist_element *curr = pipeline->head;
|
||||
if(curr)
|
||||
return (curr->ptr == data) ? TRUE : FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* returns TRUE if the given handle is head of the recv pipe */
|
||||
bool Curl_recvpipe_head(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
return pipe_head(data, conn->recv_pipe);
|
||||
}
|
||||
|
||||
/* returns TRUE if the given handle is head of the send pipe */
|
||||
bool Curl_sendpipe_head(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
return pipe_head(data, conn->send_pipe);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check if the write channel is available and this handle as at the head,
|
||||
* then grab the channel and return TRUE.
|
||||
*
|
||||
* If not available, return FALSE.
|
||||
*/
|
||||
|
||||
bool Curl_pipeline_checkget_write(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
if(conn->bits.multiplex)
|
||||
/* when multiplexing, we can use it at once */
|
||||
return TRUE;
|
||||
|
||||
if(!conn->writechannel_inuse && Curl_sendpipe_head(data, conn)) {
|
||||
/* Grab the channel */
|
||||
conn->writechannel_inuse = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check if the read channel is available and this handle as at the head, then
|
||||
* grab the channel and return TRUE.
|
||||
*
|
||||
* If not available, return FALSE.
|
||||
*/
|
||||
|
||||
bool Curl_pipeline_checkget_read(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
if(conn->bits.multiplex)
|
||||
/* when multiplexing, we can use it at once */
|
||||
return TRUE;
|
||||
|
||||
if(!conn->readchannel_inuse && Curl_recvpipe_head(data, conn)) {
|
||||
/* Grab the channel */
|
||||
conn->readchannel_inuse = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* The current user of the pipeline write channel gives it up.
|
||||
*/
|
||||
void Curl_pipeline_leave_write(struct connectdata *conn)
|
||||
{
|
||||
conn->writechannel_inuse = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* The current user of the pipeline read channel gives it up.
|
||||
*/
|
||||
void Curl_pipeline_leave_read(struct connectdata *conn)
|
||||
{
|
||||
conn->readchannel_inuse = FALSE;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void print_pipeline(struct connectdata *conn)
|
||||
{
|
||||
struct curl_llist_element *curr;
|
||||
struct connectbundle *cb_ptr;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
cb_ptr = conn->bundle;
|
||||
|
||||
if(cb_ptr) {
|
||||
curr = cb_ptr->conn_list->head;
|
||||
while(curr) {
|
||||
conn = curr->ptr;
|
||||
infof(data, "- Conn %ld (%p) send_pipe: %zu, recv_pipe: %zu\n",
|
||||
conn->connection_id,
|
||||
(void *)conn,
|
||||
conn->send_pipe->size,
|
||||
conn->recv_pipe->size);
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,56 +0,0 @@
|
||||
#ifndef HEADER_CURL_PIPELINE_H
|
||||
#define HEADER_CURL_PIPELINE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2013 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle,
|
||||
struct connectdata *conn);
|
||||
void Curl_move_handle_from_send_to_recv_pipe(struct Curl_easy *handle,
|
||||
struct connectdata *conn);
|
||||
bool Curl_pipeline_penalized(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
bool Curl_pipeline_site_blacklisted(struct Curl_easy *handle,
|
||||
struct connectdata *conn);
|
||||
|
||||
CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
|
||||
struct curl_llist **list_ptr);
|
||||
|
||||
bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle,
|
||||
char *server_name);
|
||||
|
||||
CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
|
||||
struct curl_llist **list_ptr);
|
||||
|
||||
bool Curl_pipeline_checkget_write(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
bool Curl_pipeline_checkget_read(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
void Curl_pipeline_leave_write(struct connectdata *conn);
|
||||
void Curl_pipeline_leave_read(struct connectdata *conn);
|
||||
bool Curl_recvpipe_head(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
bool Curl_sendpipe_head(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
#endif /* HEADER_CURL_PIPELINE_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,95 +0,0 @@
|
||||
#ifndef HEADER_CURL_POP3_H
|
||||
#define HEADER_CURL_POP3_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2009 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "pingpong.h"
|
||||
#include "curl_sasl.h"
|
||||
|
||||
/****************************************************************************
|
||||
* POP3 unique setup
|
||||
***************************************************************************/
|
||||
typedef enum {
|
||||
POP3_STOP, /* do nothing state, stops the state machine */
|
||||
POP3_SERVERGREET, /* waiting for the initial greeting immediately after
|
||||
a connect */
|
||||
POP3_CAPA,
|
||||
POP3_STARTTLS,
|
||||
POP3_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS
|
||||
(multi mode only) */
|
||||
POP3_AUTH,
|
||||
POP3_APOP,
|
||||
POP3_USER,
|
||||
POP3_PASS,
|
||||
POP3_COMMAND,
|
||||
POP3_QUIT,
|
||||
POP3_LAST /* never used */
|
||||
} pop3state;
|
||||
|
||||
/* This POP3 struct is used in the Curl_easy. All POP3 data that is
|
||||
connection-oriented must be in pop3_conn to properly deal with the fact that
|
||||
perhaps the Curl_easy is changed between the times the connection is
|
||||
used. */
|
||||
struct POP3 {
|
||||
curl_pp_transfer transfer;
|
||||
char *id; /* Message ID */
|
||||
char *custom; /* Custom Request */
|
||||
};
|
||||
|
||||
/* pop3_conn is used for struct connection-oriented data in the connectdata
|
||||
struct */
|
||||
struct pop3_conn {
|
||||
struct pingpong pp;
|
||||
pop3state state; /* Always use pop3.c:state() to change state! */
|
||||
bool ssldone; /* Is connect() over SSL done? */
|
||||
size_t eob; /* Number of bytes of the EOB (End Of Body) that
|
||||
have been received so far */
|
||||
size_t strip; /* Number of bytes from the start to ignore as
|
||||
non-body */
|
||||
struct SASL sasl; /* SASL-related storage */
|
||||
unsigned int authtypes; /* Accepted authentication types */
|
||||
unsigned int preftype; /* Preferred authentication type */
|
||||
char *apoptimestamp; /* APOP timestamp from the server greeting */
|
||||
bool tls_supported; /* StartTLS capability supported by server */
|
||||
};
|
||||
|
||||
extern const struct Curl_handler Curl_handler_pop3;
|
||||
extern const struct Curl_handler Curl_handler_pop3s;
|
||||
|
||||
/* Authentication type flags */
|
||||
#define POP3_TYPE_CLEARTEXT (1 << 0)
|
||||
#define POP3_TYPE_APOP (1 << 1)
|
||||
#define POP3_TYPE_SASL (1 << 2)
|
||||
|
||||
/* Authentication type values */
|
||||
#define POP3_TYPE_NONE 0
|
||||
#define POP3_TYPE_ANY ~0U
|
||||
|
||||
/* This is the 5-bytes End-Of-Body marker for POP3 */
|
||||
#define POP3_EOB "\x0d\x0a\x2e\x0d\x0a"
|
||||
#define POP3_EOB_LEN 5
|
||||
|
||||
/* This function scans the body after the end-of-body and writes everything
|
||||
* until the end is found */
|
||||
CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread);
|
||||
|
||||
#endif /* HEADER_CURL_POP3_H */
|
||||
@@ -1,567 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "progress.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero
|
||||
byte) */
|
||||
static void time2str(char *r, curl_off_t seconds)
|
||||
{
|
||||
curl_off_t d, h, m, s;
|
||||
if(seconds <= 0) {
|
||||
strcpy(r, "--:--:--");
|
||||
return;
|
||||
}
|
||||
h = seconds / CURL_OFF_T_C(3600);
|
||||
if(h <= CURL_OFF_T_C(99)) {
|
||||
m = (seconds - (h*CURL_OFF_T_C(3600))) / CURL_OFF_T_C(60);
|
||||
s = (seconds - (h*CURL_OFF_T_C(3600))) - (m*CURL_OFF_T_C(60));
|
||||
snprintf(r, 9, "%2" CURL_FORMAT_CURL_OFF_T ":%02" CURL_FORMAT_CURL_OFF_T
|
||||
":%02" CURL_FORMAT_CURL_OFF_T, h, m, s);
|
||||
}
|
||||
else {
|
||||
/* this equals to more than 99 hours, switch to a more suitable output
|
||||
format to fit within the limits. */
|
||||
d = seconds / CURL_OFF_T_C(86400);
|
||||
h = (seconds - (d*CURL_OFF_T_C(86400))) / CURL_OFF_T_C(3600);
|
||||
if(d <= CURL_OFF_T_C(999))
|
||||
snprintf(r, 9, "%3" CURL_FORMAT_CURL_OFF_T
|
||||
"d %02" CURL_FORMAT_CURL_OFF_T "h", d, h);
|
||||
else
|
||||
snprintf(r, 9, "%7" CURL_FORMAT_CURL_OFF_T "d", d);
|
||||
}
|
||||
}
|
||||
|
||||
/* The point of this function would be to return a string of the input data,
|
||||
but never longer than 5 columns (+ one zero byte).
|
||||
Add suffix k, M, G when suitable... */
|
||||
static char *max5data(curl_off_t bytes, char *max5)
|
||||
{
|
||||
#define ONE_KILOBYTE CURL_OFF_T_C(1024)
|
||||
#define ONE_MEGABYTE (CURL_OFF_T_C(1024) * ONE_KILOBYTE)
|
||||
#define ONE_GIGABYTE (CURL_OFF_T_C(1024) * ONE_MEGABYTE)
|
||||
#define ONE_TERABYTE (CURL_OFF_T_C(1024) * ONE_GIGABYTE)
|
||||
#define ONE_PETABYTE (CURL_OFF_T_C(1024) * ONE_TERABYTE)
|
||||
|
||||
if(bytes < CURL_OFF_T_C(100000))
|
||||
snprintf(max5, 6, "%5" CURL_FORMAT_CURL_OFF_T, bytes);
|
||||
|
||||
else if(bytes < CURL_OFF_T_C(10000) * ONE_KILOBYTE)
|
||||
snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "k", bytes/ONE_KILOBYTE);
|
||||
|
||||
else if(bytes < CURL_OFF_T_C(100) * ONE_MEGABYTE)
|
||||
/* 'XX.XM' is good as long as we're less than 100 megs */
|
||||
snprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0"
|
||||
CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE,
|
||||
(bytes%ONE_MEGABYTE) / (ONE_MEGABYTE/CURL_OFF_T_C(10)) );
|
||||
|
||||
#if (CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
|
||||
else if(bytes < CURL_OFF_T_C(10000) * ONE_MEGABYTE)
|
||||
/* 'XXXXM' is good until we're at 10000MB or above */
|
||||
snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE);
|
||||
|
||||
else if(bytes < CURL_OFF_T_C(100) * ONE_GIGABYTE)
|
||||
/* 10000 MB - 100 GB, we show it as XX.XG */
|
||||
snprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0"
|
||||
CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE,
|
||||
(bytes%ONE_GIGABYTE) / (ONE_GIGABYTE/CURL_OFF_T_C(10)) );
|
||||
|
||||
else if(bytes < CURL_OFF_T_C(10000) * ONE_GIGABYTE)
|
||||
/* up to 10000GB, display without decimal: XXXXG */
|
||||
snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE);
|
||||
|
||||
else if(bytes < CURL_OFF_T_C(10000) * ONE_TERABYTE)
|
||||
/* up to 10000TB, display without decimal: XXXXT */
|
||||
snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "T", bytes/ONE_TERABYTE);
|
||||
|
||||
else
|
||||
/* up to 10000PB, display without decimal: XXXXP */
|
||||
snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "P", bytes/ONE_PETABYTE);
|
||||
|
||||
/* 16384 petabytes (16 exabytes) is the maximum a 64 bit unsigned number
|
||||
can hold, but our data type is signed so 8192PB will be the maximum. */
|
||||
|
||||
#else
|
||||
|
||||
else
|
||||
snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE);
|
||||
|
||||
#endif
|
||||
|
||||
return max5;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
New proposed interface, 9th of February 2000:
|
||||
|
||||
pgrsStartNow() - sets start time
|
||||
pgrsSetDownloadSize(x) - known expected download size
|
||||
pgrsSetUploadSize(x) - known expected upload size
|
||||
pgrsSetDownloadCounter() - amount of data currently downloaded
|
||||
pgrsSetUploadCounter() - amount of data currently uploaded
|
||||
pgrsUpdate() - show progress
|
||||
pgrsDone() - transfer complete
|
||||
|
||||
*/
|
||||
|
||||
int Curl_pgrsDone(struct connectdata *conn)
|
||||
{
|
||||
int rc;
|
||||
struct Curl_easy *data = conn->data;
|
||||
data->progress.lastshow=0;
|
||||
rc = Curl_pgrsUpdate(conn); /* the final (forced) update */
|
||||
if(rc)
|
||||
return rc;
|
||||
|
||||
if(!(data->progress.flags & PGRS_HIDE) &&
|
||||
!data->progress.callback)
|
||||
/* only output if we don't use a progress callback and we're not
|
||||
* hidden */
|
||||
fprintf(data->set.err, "\n");
|
||||
|
||||
data->progress.speeder_c = 0; /* reset the progress meter display */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* reset all times except redirect, and reset the known transfer sizes */
|
||||
void Curl_pgrsResetTimesSizes(struct Curl_easy *data)
|
||||
{
|
||||
data->progress.t_nslookup = 0.0;
|
||||
data->progress.t_connect = 0.0;
|
||||
data->progress.t_pretransfer = 0.0;
|
||||
data->progress.t_starttransfer = 0.0;
|
||||
|
||||
Curl_pgrsSetDownloadSize(data, -1);
|
||||
Curl_pgrsSetUploadSize(data, -1);
|
||||
}
|
||||
|
||||
void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
|
||||
{
|
||||
struct timeval now = Curl_tvnow();
|
||||
|
||||
switch(timer) {
|
||||
default:
|
||||
case TIMER_NONE:
|
||||
/* mistake filter */
|
||||
break;
|
||||
case TIMER_STARTOP:
|
||||
/* This is set at the start of a transfer */
|
||||
data->progress.t_startop = now;
|
||||
break;
|
||||
case TIMER_STARTSINGLE:
|
||||
/* This is set at the start of each single fetch */
|
||||
data->progress.t_startsingle = now;
|
||||
break;
|
||||
|
||||
case TIMER_STARTACCEPT:
|
||||
data->progress.t_acceptdata = Curl_tvnow();
|
||||
break;
|
||||
|
||||
case TIMER_NAMELOOKUP:
|
||||
data->progress.t_nslookup =
|
||||
Curl_tvdiff_secs(now, data->progress.t_startsingle);
|
||||
break;
|
||||
case TIMER_CONNECT:
|
||||
data->progress.t_connect =
|
||||
Curl_tvdiff_secs(now, data->progress.t_startsingle);
|
||||
break;
|
||||
case TIMER_APPCONNECT:
|
||||
data->progress.t_appconnect =
|
||||
Curl_tvdiff_secs(now, data->progress.t_startsingle);
|
||||
break;
|
||||
case TIMER_PRETRANSFER:
|
||||
data->progress.t_pretransfer =
|
||||
Curl_tvdiff_secs(now, data->progress.t_startsingle);
|
||||
break;
|
||||
case TIMER_STARTTRANSFER:
|
||||
data->progress.t_starttransfer =
|
||||
Curl_tvdiff_secs(now, data->progress.t_startsingle);
|
||||
break;
|
||||
case TIMER_POSTRANSFER:
|
||||
/* this is the normal end-of-transfer thing */
|
||||
break;
|
||||
case TIMER_REDIRECT:
|
||||
data->progress.t_redirect = Curl_tvdiff_secs(now, data->progress.start);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_pgrsStartNow(struct Curl_easy *data)
|
||||
{
|
||||
data->progress.speeder_c = 0; /* reset the progress meter display */
|
||||
data->progress.start = Curl_tvnow();
|
||||
data->progress.ul_limit_start.tv_sec = 0;
|
||||
data->progress.ul_limit_start.tv_usec = 0;
|
||||
data->progress.dl_limit_start.tv_sec = 0;
|
||||
data->progress.dl_limit_start.tv_usec = 0;
|
||||
/* clear all bits except HIDE and HEADERS_OUT */
|
||||
data->progress.flags &= PGRS_HIDE|PGRS_HEADERS_OUT;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is used to handle speed limits, calculating how much milliseconds we
|
||||
* need to wait until we're back under the speed limit, if needed.
|
||||
*
|
||||
* The way it works is by having a "starting point" (time & amount of data
|
||||
* transfered by then) used in the speed computation, to be used instead of the
|
||||
* start of the transfer.
|
||||
* This starting point is regularly moved as transfer goes on, to keep getting
|
||||
* accurate values (instead of average over the entire tranfer).
|
||||
*
|
||||
* This function takes the current amount of data transfered, the amount at the
|
||||
* starting point, the limit (in bytes/s), the time of the starting point and
|
||||
* the current time.
|
||||
*
|
||||
* Returns -1 if no waiting is needed (not enough data transfered since
|
||||
* starting point yet), 0 when no waiting is needed but the starting point
|
||||
* should be reset (to current), or the number of milliseconds to wait to get
|
||||
* back under the speed limit.
|
||||
*/
|
||||
long Curl_pgrsLimitWaitTime(curl_off_t cursize,
|
||||
curl_off_t startsize,
|
||||
curl_off_t limit,
|
||||
struct timeval start,
|
||||
struct timeval now)
|
||||
{
|
||||
curl_off_t size = cursize - startsize;
|
||||
time_t minimum;
|
||||
time_t actual;
|
||||
|
||||
/* we don't have a starting point yet -- return 0 so it gets (re)set */
|
||||
if(start.tv_sec == 0 && start.tv_usec == 0)
|
||||
return 0;
|
||||
|
||||
/* not enough data yet */
|
||||
if(size < limit)
|
||||
return -1;
|
||||
|
||||
minimum = (time_t) (CURL_OFF_T_C(1000) * size / limit);
|
||||
actual = Curl_tvdiff(now, start);
|
||||
|
||||
if(actual < minimum)
|
||||
/* this is a conversion on some systems (64bit time_t => 32bit long) */
|
||||
return (long)(minimum - actual);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size)
|
||||
{
|
||||
struct timeval now = Curl_tvnow();
|
||||
|
||||
data->progress.downloaded = size;
|
||||
|
||||
/* download speed limit */
|
||||
if((data->set.max_recv_speed > 0) &&
|
||||
(Curl_pgrsLimitWaitTime(data->progress.downloaded,
|
||||
data->progress.dl_limit_size,
|
||||
data->set.max_recv_speed,
|
||||
data->progress.dl_limit_start,
|
||||
now) == 0)) {
|
||||
data->progress.dl_limit_start = now;
|
||||
data->progress.dl_limit_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size)
|
||||
{
|
||||
struct timeval now = Curl_tvnow();
|
||||
|
||||
data->progress.uploaded = size;
|
||||
|
||||
/* upload speed limit */
|
||||
if((data->set.max_send_speed > 0) &&
|
||||
(Curl_pgrsLimitWaitTime(data->progress.uploaded,
|
||||
data->progress.ul_limit_size,
|
||||
data->set.max_send_speed,
|
||||
data->progress.ul_limit_start,
|
||||
now) == 0)) {
|
||||
data->progress.ul_limit_start = now;
|
||||
data->progress.ul_limit_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size)
|
||||
{
|
||||
if(size >= 0) {
|
||||
data->progress.size_dl = size;
|
||||
data->progress.flags |= PGRS_DL_SIZE_KNOWN;
|
||||
}
|
||||
else {
|
||||
data->progress.size_dl = 0;
|
||||
data->progress.flags &= ~PGRS_DL_SIZE_KNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size)
|
||||
{
|
||||
if(size >= 0) {
|
||||
data->progress.size_ul = size;
|
||||
data->progress.flags |= PGRS_UL_SIZE_KNOWN;
|
||||
}
|
||||
else {
|
||||
data->progress.size_ul = 0;
|
||||
data->progress.flags &= ~PGRS_UL_SIZE_KNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_pgrsUpdate() returns 0 for success or the value returned by the
|
||||
* progress callback!
|
||||
*/
|
||||
int Curl_pgrsUpdate(struct connectdata *conn)
|
||||
{
|
||||
struct timeval now;
|
||||
int result;
|
||||
char max5[6][10];
|
||||
curl_off_t dlpercen=0;
|
||||
curl_off_t ulpercen=0;
|
||||
curl_off_t total_percen=0;
|
||||
curl_off_t total_transfer;
|
||||
curl_off_t total_expected_transfer;
|
||||
curl_off_t timespent;
|
||||
struct Curl_easy *data = conn->data;
|
||||
int nowindex = data->progress.speeder_c% CURR_TIME;
|
||||
int checkindex;
|
||||
int countindex; /* amount of seconds stored in the speeder array */
|
||||
char time_left[10];
|
||||
char time_total[10];
|
||||
char time_spent[10];
|
||||
curl_off_t ulestimate=0;
|
||||
curl_off_t dlestimate=0;
|
||||
curl_off_t total_estimate;
|
||||
bool shownow=FALSE;
|
||||
|
||||
now = Curl_tvnow(); /* what time is it */
|
||||
|
||||
/* The time spent so far (from the start) */
|
||||
data->progress.timespent = curlx_tvdiff_secs(now, data->progress.start);
|
||||
timespent = (curl_off_t)data->progress.timespent;
|
||||
|
||||
/* The average download speed this far */
|
||||
data->progress.dlspeed = (curl_off_t)
|
||||
((double)data->progress.downloaded/
|
||||
(data->progress.timespent>0?data->progress.timespent:1));
|
||||
|
||||
/* The average upload speed this far */
|
||||
data->progress.ulspeed = (curl_off_t)
|
||||
((double)data->progress.uploaded/
|
||||
(data->progress.timespent>0?data->progress.timespent:1));
|
||||
|
||||
/* Calculations done at most once a second, unless end is reached */
|
||||
if(data->progress.lastshow != now.tv_sec) {
|
||||
shownow = TRUE;
|
||||
|
||||
data->progress.lastshow = now.tv_sec;
|
||||
|
||||
/* Let's do the "current speed" thing, which should use the fastest
|
||||
of the dl/ul speeds. Store the faster speed at entry 'nowindex'. */
|
||||
data->progress.speeder[ nowindex ] =
|
||||
data->progress.downloaded>data->progress.uploaded?
|
||||
data->progress.downloaded:data->progress.uploaded;
|
||||
|
||||
/* remember the exact time for this moment */
|
||||
data->progress.speeder_time [ nowindex ] = now;
|
||||
|
||||
/* advance our speeder_c counter, which is increased every time we get
|
||||
here and we expect it to never wrap as 2^32 is a lot of seconds! */
|
||||
data->progress.speeder_c++;
|
||||
|
||||
/* figure out how many index entries of data we have stored in our speeder
|
||||
array. With N_ENTRIES filled in, we have about N_ENTRIES-1 seconds of
|
||||
transfer. Imagine, after one second we have filled in two entries,
|
||||
after two seconds we've filled in three entries etc. */
|
||||
countindex = ((data->progress.speeder_c>=CURR_TIME)?
|
||||
CURR_TIME:data->progress.speeder_c) - 1;
|
||||
|
||||
/* first of all, we don't do this if there's no counted seconds yet */
|
||||
if(countindex) {
|
||||
time_t span_ms;
|
||||
|
||||
/* Get the index position to compare with the 'nowindex' position.
|
||||
Get the oldest entry possible. While we have less than CURR_TIME
|
||||
entries, the first entry will remain the oldest. */
|
||||
checkindex = (data->progress.speeder_c>=CURR_TIME)?
|
||||
data->progress.speeder_c%CURR_TIME:0;
|
||||
|
||||
/* Figure out the exact time for the time span */
|
||||
span_ms = Curl_tvdiff(now,
|
||||
data->progress.speeder_time[checkindex]);
|
||||
if(0 == span_ms)
|
||||
span_ms=1; /* at least one millisecond MUST have passed */
|
||||
|
||||
/* Calculate the average speed the last 'span_ms' milliseconds */
|
||||
{
|
||||
curl_off_t amount = data->progress.speeder[nowindex]-
|
||||
data->progress.speeder[checkindex];
|
||||
|
||||
if(amount > CURL_OFF_T_C(4294967) /* 0xffffffff/1000 */)
|
||||
/* the 'amount' value is bigger than would fit in 32 bits if
|
||||
multiplied with 1000, so we use the double math for this */
|
||||
data->progress.current_speed = (curl_off_t)
|
||||
((double)amount/((double)span_ms/1000.0));
|
||||
else
|
||||
/* the 'amount' value is small enough to fit within 32 bits even
|
||||
when multiplied with 1000 */
|
||||
data->progress.current_speed = amount*CURL_OFF_T_C(1000)/span_ms;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* the first second we use the main average */
|
||||
data->progress.current_speed =
|
||||
(data->progress.ulspeed>data->progress.dlspeed)?
|
||||
data->progress.ulspeed:data->progress.dlspeed;
|
||||
|
||||
} /* Calculations end */
|
||||
|
||||
if(!(data->progress.flags & PGRS_HIDE)) {
|
||||
/* progress meter has not been shut off */
|
||||
|
||||
if(data->set.fxferinfo) {
|
||||
/* There's a callback set, call that */
|
||||
result= data->set.fxferinfo(data->set.progress_client,
|
||||
data->progress.size_dl,
|
||||
data->progress.downloaded,
|
||||
data->progress.size_ul,
|
||||
data->progress.uploaded);
|
||||
if(result)
|
||||
failf(data, "Callback aborted");
|
||||
return result;
|
||||
}
|
||||
else if(data->set.fprogress) {
|
||||
/* The older deprecated callback is set, call that */
|
||||
result= data->set.fprogress(data->set.progress_client,
|
||||
(double)data->progress.size_dl,
|
||||
(double)data->progress.downloaded,
|
||||
(double)data->progress.size_ul,
|
||||
(double)data->progress.uploaded);
|
||||
if(result)
|
||||
failf(data, "Callback aborted");
|
||||
return result;
|
||||
}
|
||||
|
||||
if(!shownow)
|
||||
/* only show the internal progress meter once per second */
|
||||
return 0;
|
||||
|
||||
/* If there's no external callback set, use internal code to show
|
||||
progress */
|
||||
|
||||
if(!(data->progress.flags & PGRS_HEADERS_OUT)) {
|
||||
if(data->state.resume_from) {
|
||||
fprintf(data->set.err,
|
||||
"** Resuming transfer from byte position %"
|
||||
CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from);
|
||||
}
|
||||
fprintf(data->set.err,
|
||||
" %% Total %% Received %% Xferd Average Speed "
|
||||
"Time Time Time Current\n"
|
||||
" Dload Upload "
|
||||
"Total Spent Left Speed\n");
|
||||
data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */
|
||||
}
|
||||
|
||||
/* Figure out the estimated time of arrival for the upload */
|
||||
if((data->progress.flags & PGRS_UL_SIZE_KNOWN) &&
|
||||
(data->progress.ulspeed > CURL_OFF_T_C(0))) {
|
||||
ulestimate = data->progress.size_ul / data->progress.ulspeed;
|
||||
|
||||
if(data->progress.size_ul > CURL_OFF_T_C(10000))
|
||||
ulpercen = data->progress.uploaded /
|
||||
(data->progress.size_ul/CURL_OFF_T_C(100));
|
||||
else if(data->progress.size_ul > CURL_OFF_T_C(0))
|
||||
ulpercen = (data->progress.uploaded*100) /
|
||||
data->progress.size_ul;
|
||||
}
|
||||
|
||||
/* ... and the download */
|
||||
if((data->progress.flags & PGRS_DL_SIZE_KNOWN) &&
|
||||
(data->progress.dlspeed > CURL_OFF_T_C(0))) {
|
||||
dlestimate = data->progress.size_dl / data->progress.dlspeed;
|
||||
|
||||
if(data->progress.size_dl > CURL_OFF_T_C(10000))
|
||||
dlpercen = data->progress.downloaded /
|
||||
(data->progress.size_dl/CURL_OFF_T_C(100));
|
||||
else if(data->progress.size_dl > CURL_OFF_T_C(0))
|
||||
dlpercen = (data->progress.downloaded*100) /
|
||||
data->progress.size_dl;
|
||||
}
|
||||
|
||||
/* Now figure out which of them is slower and use that one for the
|
||||
total estimate! */
|
||||
total_estimate = ulestimate>dlestimate?ulestimate:dlestimate;
|
||||
|
||||
/* create the three time strings */
|
||||
time2str(time_left, total_estimate > 0?(total_estimate - timespent):0);
|
||||
time2str(time_total, total_estimate);
|
||||
time2str(time_spent, timespent);
|
||||
|
||||
/* Get the total amount of data expected to get transferred */
|
||||
total_expected_transfer =
|
||||
(data->progress.flags & PGRS_UL_SIZE_KNOWN?
|
||||
data->progress.size_ul:data->progress.uploaded)+
|
||||
(data->progress.flags & PGRS_DL_SIZE_KNOWN?
|
||||
data->progress.size_dl:data->progress.downloaded);
|
||||
|
||||
/* We have transferred this much so far */
|
||||
total_transfer = data->progress.downloaded + data->progress.uploaded;
|
||||
|
||||
/* Get the percentage of data transferred so far */
|
||||
if(total_expected_transfer > CURL_OFF_T_C(10000))
|
||||
total_percen = total_transfer /
|
||||
(total_expected_transfer/CURL_OFF_T_C(100));
|
||||
else if(total_expected_transfer > CURL_OFF_T_C(0))
|
||||
total_percen = (total_transfer*100) / total_expected_transfer;
|
||||
|
||||
fprintf(data->set.err,
|
||||
"\r"
|
||||
"%3" CURL_FORMAT_CURL_OFF_T " %s "
|
||||
"%3" CURL_FORMAT_CURL_OFF_T " %s "
|
||||
"%3" CURL_FORMAT_CURL_OFF_T " %s %s %s %s %s %s %s",
|
||||
total_percen, /* 3 letters */ /* total % */
|
||||
max5data(total_expected_transfer, max5[2]), /* total size */
|
||||
dlpercen, /* 3 letters */ /* rcvd % */
|
||||
max5data(data->progress.downloaded, max5[0]), /* rcvd size */
|
||||
ulpercen, /* 3 letters */ /* xfer % */
|
||||
max5data(data->progress.uploaded, max5[1]), /* xfer size */
|
||||
max5data(data->progress.dlspeed, max5[3]), /* avrg dl speed */
|
||||
max5data(data->progress.ulspeed, max5[4]), /* avrg ul speed */
|
||||
time_total, /* 8 letters */ /* total time */
|
||||
time_spent, /* 8 letters */ /* time spent */
|
||||
time_left, /* 8 letters */ /* time left */
|
||||
max5data(data->progress.current_speed, max5[5]) /* current speed */
|
||||
);
|
||||
|
||||
/* we flush the output stream to make it appear as soon as possible */
|
||||
fflush(data->set.err);
|
||||
|
||||
} /* !(data->progress.flags & PGRS_HIDE) */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
#ifndef HEADER_CURL_PROGRESS_H
|
||||
#define HEADER_CURL_PROGRESS_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "timeval.h"
|
||||
|
||||
|
||||
typedef enum {
|
||||
TIMER_NONE,
|
||||
TIMER_STARTOP,
|
||||
TIMER_STARTSINGLE,
|
||||
TIMER_NAMELOOKUP,
|
||||
TIMER_CONNECT,
|
||||
TIMER_APPCONNECT,
|
||||
TIMER_PRETRANSFER,
|
||||
TIMER_STARTTRANSFER,
|
||||
TIMER_POSTRANSFER,
|
||||
TIMER_STARTACCEPT,
|
||||
TIMER_REDIRECT,
|
||||
TIMER_LAST /* must be last */
|
||||
} timerid;
|
||||
|
||||
int Curl_pgrsDone(struct connectdata *);
|
||||
void Curl_pgrsStartNow(struct Curl_easy *data);
|
||||
void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size);
|
||||
void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size);
|
||||
void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size);
|
||||
void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size);
|
||||
int Curl_pgrsUpdate(struct connectdata *);
|
||||
void Curl_pgrsResetTimesSizes(struct Curl_easy *data);
|
||||
void Curl_pgrsTime(struct Curl_easy *data, timerid timer);
|
||||
long Curl_pgrsLimitWaitTime(curl_off_t cursize,
|
||||
curl_off_t startsize,
|
||||
curl_off_t limit,
|
||||
struct timeval start,
|
||||
struct timeval now);
|
||||
|
||||
/* Don't show progress for sizes smaller than: */
|
||||
#define LEAST_SIZE_PROGRESS BUFSIZE
|
||||
|
||||
#define PROGRESS_DOWNLOAD (1<<0)
|
||||
#define PROGRESS_UPLOAD (1<<1)
|
||||
#define PROGRESS_DOWN_AND_UP (PROGRESS_UPLOAD | PROGRESS_DOWNLOAD)
|
||||
|
||||
#define PGRS_SHOW_DL (1<<0)
|
||||
#define PGRS_SHOW_UL (1<<1)
|
||||
#define PGRS_DONE_DL (1<<2)
|
||||
#define PGRS_DONE_UL (1<<3)
|
||||
#define PGRS_HIDE (1<<4)
|
||||
#define PGRS_UL_SIZE_KNOWN (1<<5)
|
||||
#define PGRS_DL_SIZE_KNOWN (1<<6)
|
||||
|
||||
#define PGRS_HEADERS_OUT (1<<7) /* set when the headers have been written */
|
||||
|
||||
|
||||
#endif /* HEADER_CURL_PROGRESS_H */
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "vtls/vtls.h"
|
||||
#include "sendf.h"
|
||||
#include "rand.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
|
||||
{
|
||||
unsigned int r;
|
||||
CURLcode result = CURLE_OK;
|
||||
static unsigned int randseed;
|
||||
static bool seeded = FALSE;
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
char *force_entropy = getenv("CURL_ENTROPY");
|
||||
if(force_entropy) {
|
||||
if(!seeded) {
|
||||
size_t elen = strlen(force_entropy);
|
||||
size_t clen = sizeof(randseed);
|
||||
size_t min = elen < clen ? elen : clen;
|
||||
memcpy((char *)&randseed, force_entropy, min);
|
||||
seeded = TRUE;
|
||||
}
|
||||
else
|
||||
randseed++;
|
||||
*rnd = randseed;
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* data may be NULL! */
|
||||
result = Curl_ssl_random(data, (unsigned char *)rnd, sizeof(*rnd));
|
||||
if(result != CURLE_NOT_BUILT_IN)
|
||||
/* only if there is no random funtion in the TLS backend do the non crypto
|
||||
version, otherwise return result */
|
||||
return result;
|
||||
|
||||
/* ---- non-cryptographic version following ---- */
|
||||
|
||||
#ifdef RANDOM_FILE
|
||||
if(!seeded) {
|
||||
/* if there's a random file to read a seed from, use it */
|
||||
int fd = open(RANDOM_FILE, O_RDONLY);
|
||||
if(fd > -1) {
|
||||
/* read random data into the randseed variable */
|
||||
ssize_t nread = read(fd, &randseed, sizeof(randseed));
|
||||
if(nread == sizeof(randseed))
|
||||
seeded = TRUE;
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!seeded) {
|
||||
struct timeval now = curlx_tvnow();
|
||||
infof(data, "WARNING: Using weak random seed\n");
|
||||
randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec;
|
||||
randseed = randseed * 1103515245 + 12345;
|
||||
randseed = randseed * 1103515245 + 12345;
|
||||
randseed = randseed * 1103515245 + 12345;
|
||||
seeded = TRUE;
|
||||
}
|
||||
|
||||
/* Return an unsigned 32-bit pseudo-random number. */
|
||||
r = randseed = randseed * 1103515245 + 12345;
|
||||
*rnd = (r << 16) | ((r >> 16) & 0xFFFF);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_rand() stores 'num' number of random unsigned integers in the buffer
|
||||
* 'rndptr' points to.
|
||||
*
|
||||
* If libcurl is built without TLS support or with a TLS backend that lacks a
|
||||
* proper random API (Gskit, PolarSSL or mbedTLS), this function will use
|
||||
* "weak" random.
|
||||
*
|
||||
* When built *with* TLS support and a backend that offers strong random, it
|
||||
* will return error if it cannot provide strong random values.
|
||||
*
|
||||
* NOTE: 'data' may be passed in as NULL when coming from external API without
|
||||
* easy handle!
|
||||
*
|
||||
*/
|
||||
|
||||
CURLcode Curl_rand(struct Curl_easy *data, unsigned int *rndptr,
|
||||
unsigned int num)
|
||||
{
|
||||
CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
unsigned int i;
|
||||
|
||||
assert(num > 0);
|
||||
|
||||
for(i = 0; i < num; i++) {
|
||||
result = randit(data, rndptr++);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
#ifndef HEADER_CURL_RAND_H
|
||||
#define HEADER_CURL_RAND_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* Curl_rand() stores 'num' number of random unsigned integers in the buffer
|
||||
* 'rnd' points to.
|
||||
*
|
||||
* If libcurl is built without TLS support or with a TLS backend that lacks a
|
||||
* proper random API (Gskit, PolarSSL or mbedTLS), this function will use
|
||||
* "weak" random.
|
||||
*
|
||||
* When built *with* TLS support and a backend that offers strong random, it
|
||||
* will return error if it cannot provide strong random values.
|
||||
*
|
||||
* NOTE: 'data' may be passed in as NULL when coming from external API without
|
||||
* easy handle!
|
||||
*
|
||||
*/
|
||||
CURLcode Curl_rand(struct Curl_easy *data, unsigned int *rnd,
|
||||
unsigned int num);
|
||||
|
||||
#endif /* HEADER_CURL_RAND_H */
|
||||
@@ -1,819 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_RTSP
|
||||
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
#include "sendf.h"
|
||||
#include "multiif.h"
|
||||
#include "http.h"
|
||||
#include "url.h"
|
||||
#include "progress.h"
|
||||
#include "rtsp.h"
|
||||
#include "strcase.h"
|
||||
#include "select.h"
|
||||
#include "connect.h"
|
||||
#include "strdup.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* TODO (general)
|
||||
* -incoming server requests
|
||||
* -server CSeq counter
|
||||
* -digest authentication
|
||||
* -connect thru proxy
|
||||
* -pipelining?
|
||||
*/
|
||||
|
||||
|
||||
#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]))))
|
||||
|
||||
/* protocol-specific functions set up to be called by the main engine */
|
||||
static CURLcode rtsp_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode rtsp_done(struct connectdata *conn, CURLcode, bool premature);
|
||||
static CURLcode rtsp_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead);
|
||||
|
||||
static int rtsp_getsock_do(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
|
||||
/*
|
||||
* Parse and write out any available RTP data.
|
||||
*
|
||||
* nread: amount of data left after k->str. will be modified if RTP
|
||||
* data is parsed and k->str is moved up
|
||||
* readmore: whether or not the RTP parser needs more data right away
|
||||
*/
|
||||
static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
ssize_t *nread,
|
||||
bool *readmore);
|
||||
|
||||
static CURLcode rtsp_setup_connection(struct connectdata *conn);
|
||||
|
||||
|
||||
/* this returns the socket to wait for in the DO and DOING state for the multi
|
||||
interface and then we're always _sending_ a request and thus we wait for
|
||||
the single socket to become writable only */
|
||||
static int rtsp_getsock_do(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
{
|
||||
/* write mode */
|
||||
(void)numsocks; /* unused, we trust it to be at least 1 */
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
return GETSOCK_WRITESOCK(0);
|
||||
}
|
||||
|
||||
static
|
||||
CURLcode rtp_client_write(struct connectdata *conn, char *ptr, size_t len);
|
||||
|
||||
|
||||
/*
|
||||
* RTSP handler interface.
|
||||
*/
|
||||
const struct Curl_handler Curl_handler_rtsp = {
|
||||
"RTSP", /* scheme */
|
||||
rtsp_setup_connection, /* setup_connection */
|
||||
rtsp_do, /* do_it */
|
||||
rtsp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
rtsp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
rtsp_getsock_do, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtsp_disconnect, /* disconnect */
|
||||
rtsp_rtp_readwrite, /* readwrite */
|
||||
PORT_RTSP, /* defport */
|
||||
CURLPROTO_RTSP, /* protocol */
|
||||
PROTOPT_NONE /* flags */
|
||||
};
|
||||
|
||||
|
||||
static CURLcode rtsp_setup_connection(struct connectdata *conn)
|
||||
{
|
||||
struct RTSP *rtsp;
|
||||
|
||||
conn->data->req.protop = rtsp = calloc(1, sizeof(struct RTSP));
|
||||
if(!rtsp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The server may send us RTP data at any point, and RTSPREQ_RECEIVE does not
|
||||
* want to block the application forever while receiving a stream. Therefore,
|
||||
* we cannot assume that an RTSP socket is dead just because it is readable.
|
||||
*
|
||||
* Instead, if it is readable, run Curl_connalive() to peek at the socket
|
||||
* and distinguish between closed and data.
|
||||
*/
|
||||
bool Curl_rtsp_connisdead(struct connectdata *check)
|
||||
{
|
||||
int sval;
|
||||
bool ret_val = TRUE;
|
||||
|
||||
sval = SOCKET_READABLE(check->sock[FIRSTSOCKET], 0);
|
||||
if(sval == 0) {
|
||||
/* timeout */
|
||||
ret_val = FALSE;
|
||||
}
|
||||
else if(sval & CURL_CSELECT_ERR) {
|
||||
/* socket is in an error state */
|
||||
ret_val = TRUE;
|
||||
}
|
||||
else if(sval & CURL_CSELECT_IN) {
|
||||
/* readable with no error. could still be closed */
|
||||
ret_val = !Curl_connalive(check);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static CURLcode rtsp_connect(struct connectdata *conn, bool *done)
|
||||
{
|
||||
CURLcode httpStatus;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
httpStatus = Curl_http_connect(conn, done);
|
||||
|
||||
/* Initialize the CSeq if not already done */
|
||||
if(data->state.rtsp_next_client_CSeq == 0)
|
||||
data->state.rtsp_next_client_CSeq = 1;
|
||||
if(data->state.rtsp_next_server_CSeq == 0)
|
||||
data->state.rtsp_next_server_CSeq = 1;
|
||||
|
||||
conn->proto.rtspc.rtp_channel = -1;
|
||||
|
||||
return httpStatus;
|
||||
}
|
||||
|
||||
static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead)
|
||||
{
|
||||
(void) dead;
|
||||
Curl_safefree(conn->proto.rtspc.rtp_buf);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
static CURLcode rtsp_done(struct connectdata *conn,
|
||||
CURLcode status, bool premature)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct RTSP *rtsp = data->req.protop;
|
||||
CURLcode httpStatus;
|
||||
long CSeq_sent;
|
||||
long CSeq_recv;
|
||||
|
||||
/* Bypass HTTP empty-reply checks on receive */
|
||||
if(data->set.rtspreq == RTSPREQ_RECEIVE)
|
||||
premature = TRUE;
|
||||
|
||||
httpStatus = Curl_http_done(conn, status, premature);
|
||||
|
||||
if(rtsp) {
|
||||
/* Check the sequence numbers */
|
||||
CSeq_sent = rtsp->CSeq_sent;
|
||||
CSeq_recv = rtsp->CSeq_recv;
|
||||
if((data->set.rtspreq != RTSPREQ_RECEIVE) && (CSeq_sent != CSeq_recv)) {
|
||||
failf(data,
|
||||
"The CSeq of this request %ld did not match the response %ld",
|
||||
CSeq_sent, CSeq_recv);
|
||||
return CURLE_RTSP_CSEQ_ERROR;
|
||||
}
|
||||
else if(data->set.rtspreq == RTSPREQ_RECEIVE &&
|
||||
(conn->proto.rtspc.rtp_channel == -1)) {
|
||||
infof(data, "Got an RTP Receive with a CSeq of %ld\n", CSeq_recv);
|
||||
/* TODO CPC: Server -> Client logic here */
|
||||
}
|
||||
}
|
||||
|
||||
return httpStatus;
|
||||
}
|
||||
|
||||
static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
CURLcode result=CURLE_OK;
|
||||
Curl_RtspReq rtspreq = data->set.rtspreq;
|
||||
struct RTSP *rtsp = data->req.protop;
|
||||
struct HTTP *http;
|
||||
Curl_send_buffer *req_buffer;
|
||||
curl_off_t postsize = 0; /* for ANNOUNCE and SET_PARAMETER */
|
||||
curl_off_t putsize = 0; /* for ANNOUNCE and SET_PARAMETER */
|
||||
|
||||
const char *p_request = NULL;
|
||||
const char *p_session_id = NULL;
|
||||
const char *p_accept = NULL;
|
||||
const char *p_accept_encoding = NULL;
|
||||
const char *p_range = NULL;
|
||||
const char *p_referrer = NULL;
|
||||
const char *p_stream_uri = NULL;
|
||||
const char *p_transport = NULL;
|
||||
const char *p_uagent = NULL;
|
||||
const char *p_proxyuserpwd = NULL;
|
||||
const char *p_userpwd = NULL;
|
||||
|
||||
*done = TRUE;
|
||||
|
||||
http = &(rtsp->http_wrapper);
|
||||
/* Assert that no one has changed the RTSP struct in an evil way */
|
||||
DEBUGASSERT((void *)http == (void *)rtsp);
|
||||
|
||||
rtsp->CSeq_sent = data->state.rtsp_next_client_CSeq;
|
||||
rtsp->CSeq_recv = 0;
|
||||
|
||||
/* Setup the 'p_request' pointer to the proper p_request string
|
||||
* Since all RTSP requests are included here, there is no need to
|
||||
* support custom requests like HTTP.
|
||||
**/
|
||||
data->set.opt_no_body = TRUE; /* most requests don't contain a body */
|
||||
switch(rtspreq) {
|
||||
default:
|
||||
failf(data, "Got invalid RTSP request");
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
case RTSPREQ_OPTIONS:
|
||||
p_request = "OPTIONS";
|
||||
break;
|
||||
case RTSPREQ_DESCRIBE:
|
||||
p_request = "DESCRIBE";
|
||||
data->set.opt_no_body = FALSE;
|
||||
break;
|
||||
case RTSPREQ_ANNOUNCE:
|
||||
p_request = "ANNOUNCE";
|
||||
break;
|
||||
case RTSPREQ_SETUP:
|
||||
p_request = "SETUP";
|
||||
break;
|
||||
case RTSPREQ_PLAY:
|
||||
p_request = "PLAY";
|
||||
break;
|
||||
case RTSPREQ_PAUSE:
|
||||
p_request = "PAUSE";
|
||||
break;
|
||||
case RTSPREQ_TEARDOWN:
|
||||
p_request = "TEARDOWN";
|
||||
break;
|
||||
case RTSPREQ_GET_PARAMETER:
|
||||
/* GET_PARAMETER's no_body status is determined later */
|
||||
p_request = "GET_PARAMETER";
|
||||
data->set.opt_no_body = FALSE;
|
||||
break;
|
||||
case RTSPREQ_SET_PARAMETER:
|
||||
p_request = "SET_PARAMETER";
|
||||
break;
|
||||
case RTSPREQ_RECORD:
|
||||
p_request = "RECORD";
|
||||
break;
|
||||
case RTSPREQ_RECEIVE:
|
||||
p_request = "";
|
||||
/* Treat interleaved RTP as body*/
|
||||
data->set.opt_no_body = FALSE;
|
||||
break;
|
||||
case RTSPREQ_LAST:
|
||||
failf(data, "Got invalid RTSP request: RTSPREQ_LAST");
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
|
||||
if(rtspreq == RTSPREQ_RECEIVE) {
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
|
||||
&http->readbytecount, -1, NULL);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
p_session_id = data->set.str[STRING_RTSP_SESSION_ID];
|
||||
if(!p_session_id &&
|
||||
(rtspreq & ~(RTSPREQ_OPTIONS | RTSPREQ_DESCRIBE | RTSPREQ_SETUP))) {
|
||||
failf(data, "Refusing to issue an RTSP request [%s] without a session ID.",
|
||||
p_request);
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
|
||||
/* TODO: proxy? */
|
||||
|
||||
/* Stream URI. Default to server '*' if not specified */
|
||||
if(data->set.str[STRING_RTSP_STREAM_URI]) {
|
||||
p_stream_uri = data->set.str[STRING_RTSP_STREAM_URI];
|
||||
}
|
||||
else {
|
||||
p_stream_uri = "*";
|
||||
}
|
||||
|
||||
/* Transport Header for SETUP requests */
|
||||
p_transport = Curl_checkheaders(conn, "Transport:");
|
||||
if(rtspreq == RTSPREQ_SETUP && !p_transport) {
|
||||
/* New Transport: setting? */
|
||||
if(data->set.str[STRING_RTSP_TRANSPORT]) {
|
||||
Curl_safefree(conn->allocptr.rtsp_transport);
|
||||
|
||||
conn->allocptr.rtsp_transport =
|
||||
aprintf("Transport: %s\r\n",
|
||||
data->set.str[STRING_RTSP_TRANSPORT]);
|
||||
if(!conn->allocptr.rtsp_transport)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else {
|
||||
failf(data,
|
||||
"Refusing to issue an RTSP SETUP without a Transport: header.");
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
|
||||
p_transport = conn->allocptr.rtsp_transport;
|
||||
}
|
||||
|
||||
/* Accept Headers for DESCRIBE requests */
|
||||
if(rtspreq == RTSPREQ_DESCRIBE) {
|
||||
/* Accept Header */
|
||||
p_accept = Curl_checkheaders(conn, "Accept:")?
|
||||
NULL:"Accept: application/sdp\r\n";
|
||||
|
||||
/* Accept-Encoding header */
|
||||
if(!Curl_checkheaders(conn, "Accept-Encoding:") &&
|
||||
data->set.str[STRING_ENCODING]) {
|
||||
Curl_safefree(conn->allocptr.accept_encoding);
|
||||
conn->allocptr.accept_encoding =
|
||||
aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
|
||||
|
||||
if(!conn->allocptr.accept_encoding)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
p_accept_encoding = conn->allocptr.accept_encoding;
|
||||
}
|
||||
}
|
||||
|
||||
/* The User-Agent string might have been allocated in url.c already, because
|
||||
it might have been used in the proxy connect, but if we have got a header
|
||||
with the user-agent string specified, we erase the previously made string
|
||||
here. */
|
||||
if(Curl_checkheaders(conn, "User-Agent:") && conn->allocptr.uagent) {
|
||||
Curl_safefree(conn->allocptr.uagent);
|
||||
conn->allocptr.uagent = NULL;
|
||||
}
|
||||
else if(!Curl_checkheaders(conn, "User-Agent:") &&
|
||||
data->set.str[STRING_USERAGENT]) {
|
||||
p_uagent = conn->allocptr.uagent;
|
||||
}
|
||||
|
||||
/* setup the authentication headers */
|
||||
result = Curl_http_output_auth(conn, p_request, p_stream_uri, FALSE);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
p_proxyuserpwd = conn->allocptr.proxyuserpwd;
|
||||
p_userpwd = conn->allocptr.userpwd;
|
||||
|
||||
/* Referrer */
|
||||
Curl_safefree(conn->allocptr.ref);
|
||||
if(data->change.referer && !Curl_checkheaders(conn, "Referer:"))
|
||||
conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
|
||||
else
|
||||
conn->allocptr.ref = NULL;
|
||||
|
||||
p_referrer = conn->allocptr.ref;
|
||||
|
||||
/*
|
||||
* Range Header
|
||||
* Only applies to PLAY, PAUSE, RECORD
|
||||
*
|
||||
* Go ahead and use the Range stuff supplied for HTTP
|
||||
*/
|
||||
if(data->state.use_range &&
|
||||
(rtspreq & (RTSPREQ_PLAY | RTSPREQ_PAUSE | RTSPREQ_RECORD))) {
|
||||
|
||||
/* Check to see if there is a range set in the custom headers */
|
||||
if(!Curl_checkheaders(conn, "Range:") && data->state.range) {
|
||||
Curl_safefree(conn->allocptr.rangeline);
|
||||
conn->allocptr.rangeline = aprintf("Range: %s\r\n", data->state.range);
|
||||
p_range = conn->allocptr.rangeline;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sanity check the custom headers
|
||||
*/
|
||||
if(Curl_checkheaders(conn, "CSeq:")) {
|
||||
failf(data, "CSeq cannot be set as a custom header.");
|
||||
return CURLE_RTSP_CSEQ_ERROR;
|
||||
}
|
||||
if(Curl_checkheaders(conn, "Session:")) {
|
||||
failf(data, "Session ID cannot be set as a custom header.");
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
|
||||
/* Initialize a dynamic send buffer */
|
||||
req_buffer = Curl_add_buffer_init();
|
||||
|
||||
if(!req_buffer)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
result =
|
||||
Curl_add_bufferf(req_buffer,
|
||||
"%s %s RTSP/1.0\r\n" /* Request Stream-URI RTSP/1.0 */
|
||||
"CSeq: %ld\r\n", /* CSeq */
|
||||
p_request, p_stream_uri, rtsp->CSeq_sent);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/*
|
||||
* Rather than do a normal alloc line, keep the session_id unformatted
|
||||
* to make comparison easier
|
||||
*/
|
||||
if(p_session_id) {
|
||||
result = Curl_add_bufferf(req_buffer, "Session: %s\r\n", p_session_id);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Shared HTTP-like options
|
||||
*/
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"%s" /* transport */
|
||||
"%s" /* accept */
|
||||
"%s" /* accept-encoding */
|
||||
"%s" /* range */
|
||||
"%s" /* referrer */
|
||||
"%s" /* user-agent */
|
||||
"%s" /* proxyuserpwd */
|
||||
"%s" /* userpwd */
|
||||
,
|
||||
p_transport ? p_transport : "",
|
||||
p_accept ? p_accept : "",
|
||||
p_accept_encoding ? p_accept_encoding : "",
|
||||
p_range ? p_range : "",
|
||||
p_referrer ? p_referrer : "",
|
||||
p_uagent ? p_uagent : "",
|
||||
p_proxyuserpwd ? p_proxyuserpwd : "",
|
||||
p_userpwd ? p_userpwd : "");
|
||||
|
||||
/*
|
||||
* Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
|
||||
* with basic and digest, it will be freed anyway by the next request
|
||||
*/
|
||||
Curl_safefree(conn->allocptr.userpwd);
|
||||
conn->allocptr.userpwd = NULL;
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if((rtspreq == RTSPREQ_SETUP) || (rtspreq == RTSPREQ_DESCRIBE)) {
|
||||
result = Curl_add_timecondition(data, req_buffer);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
result = Curl_add_custom_headers(conn, FALSE, req_buffer);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(rtspreq == RTSPREQ_ANNOUNCE ||
|
||||
rtspreq == RTSPREQ_SET_PARAMETER ||
|
||||
rtspreq == RTSPREQ_GET_PARAMETER) {
|
||||
|
||||
if(data->set.upload) {
|
||||
putsize = data->state.infilesize;
|
||||
data->set.httpreq = HTTPREQ_PUT;
|
||||
|
||||
}
|
||||
else {
|
||||
postsize = (data->state.infilesize != -1)?
|
||||
data->state.infilesize:
|
||||
(data->set.postfields? (curl_off_t)strlen(data->set.postfields):0);
|
||||
data->set.httpreq = HTTPREQ_POST;
|
||||
}
|
||||
|
||||
if(putsize > 0 || postsize > 0) {
|
||||
/* As stated in the http comments, it is probably not wise to
|
||||
* actually set a custom Content-Length in the headers */
|
||||
if(!Curl_checkheaders(conn, "Content-Length:")) {
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
|
||||
(data->set.upload ? putsize : postsize));
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
if(rtspreq == RTSPREQ_SET_PARAMETER ||
|
||||
rtspreq == RTSPREQ_GET_PARAMETER) {
|
||||
if(!Curl_checkheaders(conn, "Content-Type:")) {
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"Content-Type: text/parameters\r\n");
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if(rtspreq == RTSPREQ_ANNOUNCE) {
|
||||
if(!Curl_checkheaders(conn, "Content-Type:")) {
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"Content-Type: application/sdp\r\n");
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
data->state.expect100header = FALSE; /* RTSP posts are simple/small */
|
||||
}
|
||||
else if(rtspreq == RTSPREQ_GET_PARAMETER) {
|
||||
/* Check for an empty GET_PARAMETER (heartbeat) request */
|
||||
data->set.httpreq = HTTPREQ_HEAD;
|
||||
data->set.opt_no_body = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* RTSP never allows chunked transfer */
|
||||
data->req.forbidchunk = TRUE;
|
||||
/* Finish the request buffer */
|
||||
result = Curl_add_buffer(req_buffer, "\r\n", 2);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(postsize > 0) {
|
||||
result = Curl_add_buffer(req_buffer, data->set.postfields,
|
||||
(size_t)postsize);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* issue the request */
|
||||
result = Curl_add_buffer_send(req_buffer, conn,
|
||||
&data->info.request_size, 0, FIRSTSOCKET);
|
||||
if(result) {
|
||||
failf(data, "Failed sending RTSP request");
|
||||
return result;
|
||||
}
|
||||
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
|
||||
putsize?FIRSTSOCKET:-1,
|
||||
putsize?&http->writebytecount:NULL);
|
||||
|
||||
/* Increment the CSeq on success */
|
||||
data->state.rtsp_next_client_CSeq++;
|
||||
|
||||
if(http->writebytecount) {
|
||||
/* if a request-body has been sent off, we make sure this progress is
|
||||
noted properly */
|
||||
Curl_pgrsSetUploadCounter(data, http->writebytecount);
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
ssize_t *nread,
|
||||
bool *readmore) {
|
||||
struct SingleRequest *k = &data->req;
|
||||
struct rtsp_conn *rtspc = &(conn->proto.rtspc);
|
||||
|
||||
char *rtp; /* moving pointer to rtp data */
|
||||
ssize_t rtp_dataleft; /* how much data left to parse in this round */
|
||||
char *scratch;
|
||||
CURLcode result;
|
||||
|
||||
if(rtspc->rtp_buf) {
|
||||
/* There was some leftover data the last time. Merge buffers */
|
||||
char *newptr = Curl_saferealloc(rtspc->rtp_buf,
|
||||
rtspc->rtp_bufsize + *nread);
|
||||
if(!newptr) {
|
||||
rtspc->rtp_buf = NULL;
|
||||
rtspc->rtp_bufsize = 0;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
rtspc->rtp_buf = newptr;
|
||||
memcpy(rtspc->rtp_buf + rtspc->rtp_bufsize, k->str, *nread);
|
||||
rtspc->rtp_bufsize += *nread;
|
||||
rtp = rtspc->rtp_buf;
|
||||
rtp_dataleft = rtspc->rtp_bufsize;
|
||||
}
|
||||
else {
|
||||
/* Just parse the request buffer directly */
|
||||
rtp = k->str;
|
||||
rtp_dataleft = *nread;
|
||||
}
|
||||
|
||||
while((rtp_dataleft > 0) &&
|
||||
(rtp[0] == '$')) {
|
||||
if(rtp_dataleft > 4) {
|
||||
int rtp_length;
|
||||
|
||||
/* Parse the header */
|
||||
/* The channel identifier immediately follows and is 1 byte */
|
||||
rtspc->rtp_channel = RTP_PKT_CHANNEL(rtp);
|
||||
|
||||
/* The length is two bytes */
|
||||
rtp_length = RTP_PKT_LENGTH(rtp);
|
||||
|
||||
if(rtp_dataleft < rtp_length + 4) {
|
||||
/* Need more - incomplete payload*/
|
||||
*readmore = TRUE;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
/* We have the full RTP interleaved packet
|
||||
* Write out the header including the leading '$' */
|
||||
DEBUGF(infof(data, "RTP write channel %d rtp_length %d\n",
|
||||
rtspc->rtp_channel, rtp_length));
|
||||
result = rtp_client_write(conn, &rtp[0], rtp_length + 4);
|
||||
if(result) {
|
||||
failf(data, "Got an error writing an RTP packet");
|
||||
*readmore = FALSE;
|
||||
Curl_safefree(rtspc->rtp_buf);
|
||||
rtspc->rtp_buf = NULL;
|
||||
rtspc->rtp_bufsize = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Move forward in the buffer */
|
||||
rtp_dataleft -= rtp_length + 4;
|
||||
rtp += rtp_length + 4;
|
||||
|
||||
if(data->set.rtspreq == RTSPREQ_RECEIVE) {
|
||||
/* If we are in a passive receive, give control back
|
||||
* to the app as often as we can.
|
||||
*/
|
||||
k->keepon &= ~KEEP_RECV;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Need more - incomplete header */
|
||||
*readmore = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(rtp_dataleft != 0 && rtp[0] == '$') {
|
||||
DEBUGF(infof(data, "RTP Rewinding %zd %s\n", rtp_dataleft,
|
||||
*readmore ? "(READMORE)" : ""));
|
||||
|
||||
/* Store the incomplete RTP packet for a "rewind" */
|
||||
scratch = malloc(rtp_dataleft);
|
||||
if(!scratch) {
|
||||
Curl_safefree(rtspc->rtp_buf);
|
||||
rtspc->rtp_buf = NULL;
|
||||
rtspc->rtp_bufsize = 0;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
memcpy(scratch, rtp, rtp_dataleft);
|
||||
Curl_safefree(rtspc->rtp_buf);
|
||||
rtspc->rtp_buf = scratch;
|
||||
rtspc->rtp_bufsize = rtp_dataleft;
|
||||
|
||||
/* As far as the transfer is concerned, this data is consumed */
|
||||
*nread = 0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
else {
|
||||
/* Fix up k->str to point just after the last RTP packet */
|
||||
k->str += *nread - rtp_dataleft;
|
||||
|
||||
/* either all of the data has been read or...
|
||||
* rtp now points at the next byte to parse
|
||||
*/
|
||||
if(rtp_dataleft > 0)
|
||||
DEBUGASSERT(k->str[0] == rtp[0]);
|
||||
|
||||
DEBUGASSERT(rtp_dataleft <= *nread); /* sanity check */
|
||||
|
||||
*nread = rtp_dataleft;
|
||||
}
|
||||
|
||||
/* If we get here, we have finished with the leftover/merge buffer */
|
||||
Curl_safefree(rtspc->rtp_buf);
|
||||
rtspc->rtp_buf = NULL;
|
||||
rtspc->rtp_bufsize = 0;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static
|
||||
CURLcode rtp_client_write(struct connectdata *conn, char *ptr, size_t len)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
size_t wrote;
|
||||
curl_write_callback writeit;
|
||||
|
||||
if(len == 0) {
|
||||
failf(data, "Cannot write a 0 size RTP packet.");
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
|
||||
writeit = data->set.fwrite_rtp?data->set.fwrite_rtp:data->set.fwrite_func;
|
||||
wrote = writeit(ptr, 1, len, data->set.rtp_out);
|
||||
|
||||
if(CURL_WRITEFUNC_PAUSE == wrote) {
|
||||
failf(data, "Cannot pause RTP");
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
|
||||
if(wrote != len) {
|
||||
failf(data, "Failed writing RTP data");
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_rtsp_parseheader(struct connectdata *conn,
|
||||
char *header)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
long CSeq = 0;
|
||||
|
||||
if(checkprefix("CSeq:", header)) {
|
||||
/* Store the received CSeq. Match is verified in rtsp_done */
|
||||
int nc = sscanf(&header[4], ": %ld", &CSeq);
|
||||
if(nc == 1) {
|
||||
struct RTSP *rtsp = data->req.protop;
|
||||
rtsp->CSeq_recv = CSeq; /* mark the request */
|
||||
data->state.rtsp_CSeq_recv = CSeq; /* update the handle */
|
||||
}
|
||||
else {
|
||||
failf(data, "Unable to read the CSeq header: [%s]", header);
|
||||
return CURLE_RTSP_CSEQ_ERROR;
|
||||
}
|
||||
}
|
||||
else if(checkprefix("Session:", header)) {
|
||||
char *start;
|
||||
|
||||
/* Find the first non-space letter */
|
||||
start = header + 8;
|
||||
while(*start && ISSPACE(*start))
|
||||
start++;
|
||||
|
||||
if(!*start) {
|
||||
failf(data, "Got a blank Session ID");
|
||||
}
|
||||
else if(data->set.str[STRING_RTSP_SESSION_ID]) {
|
||||
/* If the Session ID is set, then compare */
|
||||
if(strncmp(start, data->set.str[STRING_RTSP_SESSION_ID],
|
||||
strlen(data->set.str[STRING_RTSP_SESSION_ID])) != 0) {
|
||||
failf(data, "Got RTSP Session ID Line [%s], but wanted ID [%s]",
|
||||
start, data->set.str[STRING_RTSP_SESSION_ID]);
|
||||
return CURLE_RTSP_SESSION_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* If the Session ID is not set, and we find it in a response, then set
|
||||
* it.
|
||||
*
|
||||
* Allow any non whitespace content, up to the field seperator or end of
|
||||
* line. RFC 2326 isn't 100% clear on the session ID and for example
|
||||
* gstreamer does url-encoded session ID's not covered by the standard.
|
||||
*/
|
||||
char *end = start;
|
||||
while(*end && *end != ';' && !ISSPACE(*end))
|
||||
end++;
|
||||
|
||||
/* Copy the id substring into a new buffer */
|
||||
data->set.str[STRING_RTSP_SESSION_ID] = malloc(end - start + 1);
|
||||
if(data->set.str[STRING_RTSP_SESSION_ID] == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
memcpy(data->set.str[STRING_RTSP_SESSION_ID], start, end - start);
|
||||
(data->set.str[STRING_RTSP_SESSION_ID])[end - start] = '\0';
|
||||
}
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif /* CURL_DISABLE_RTSP */
|
||||
@@ -1,69 +0,0 @@
|
||||
#ifndef HEADER_CURL_RTSP_H
|
||||
#define HEADER_CURL_RTSP_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 https://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.
|
||||
*
|
||||
***************************************************************************/
|
||||
#ifndef CURL_DISABLE_RTSP
|
||||
|
||||
extern const struct Curl_handler Curl_handler_rtsp;
|
||||
|
||||
bool Curl_rtsp_connisdead(struct connectdata *check);
|
||||
CURLcode Curl_rtsp_parseheader(struct connectdata *conn, char *header);
|
||||
|
||||
#else
|
||||
/* disabled */
|
||||
#define Curl_rtsp_parseheader(x,y) CURLE_NOT_BUILT_IN
|
||||
#define Curl_rtsp_connisdead(x) TRUE
|
||||
|
||||
#endif /* CURL_DISABLE_RTSP */
|
||||
|
||||
/*
|
||||
* RTSP Connection data
|
||||
*
|
||||
* Currently, only used for tracking incomplete RTP data reads
|
||||
*/
|
||||
struct rtsp_conn {
|
||||
char *rtp_buf;
|
||||
ssize_t rtp_bufsize;
|
||||
int rtp_channel;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* RTSP unique setup
|
||||
***************************************************************************/
|
||||
struct RTSP {
|
||||
/*
|
||||
* http_wrapper MUST be the first element of this structure for the wrap
|
||||
* logic to work. In this way, we get a cheap polymorphism because
|
||||
* &(data->state.proto.rtsp) == &(data->state.proto.http) per the C spec
|
||||
*
|
||||
* HTTP functions can safely treat this as an HTTP struct, but RTSP aware
|
||||
* functions can also index into the later elements.
|
||||
*/
|
||||
struct HTTP http_wrapper; /*wrap HTTP to do the heavy lifting */
|
||||
|
||||
long CSeq_sent; /* CSeq of this request */
|
||||
long CSeq_recv; /* CSeq received */
|
||||
};
|
||||
|
||||
|
||||
#endif /* HEADER_CURL_RTSP_H */
|
||||
|
||||
@@ -1,584 +0,0 @@
|
||||
/* This source code was modified by Martin Hedenfalk <mhe@stacken.kth.se> for
|
||||
* use in Curl. His latest changes were done 2000-09-18.
|
||||
*
|
||||
* It has since been patched and modified a lot by Daniel Stenberg
|
||||
* <daniel@haxx.se> to make it better applied to curl conditions, and to make
|
||||
* it not use globals, pollute name space and more. This source code awaits a
|
||||
* rewrite to work around the paragraph 2 in the BSD licenses as explained
|
||||
* below.
|
||||
*
|
||||
* Copyright (c) 1998, 1999 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
*
|
||||
* Copyright (C) 2001 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE. */
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
#ifdef HAVE_GSSAPI
|
||||
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "curl_base64.h"
|
||||
#include "curl_memory.h"
|
||||
#include "curl_sec.h"
|
||||
#include "ftp.h"
|
||||
#include "sendf.h"
|
||||
#include "strcase.h"
|
||||
#include "warnless.h"
|
||||
#include "strdup.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
static const struct {
|
||||
enum protection_level level;
|
||||
const char *name;
|
||||
} level_names[] = {
|
||||
{ PROT_CLEAR, "clear" },
|
||||
{ PROT_SAFE, "safe" },
|
||||
{ PROT_CONFIDENTIAL, "confidential" },
|
||||
{ PROT_PRIVATE, "private" }
|
||||
};
|
||||
|
||||
static enum protection_level
|
||||
name_to_level(const char *name)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++)
|
||||
if(checkprefix(name, level_names[i].name))
|
||||
return level_names[i].level;
|
||||
return PROT_NONE;
|
||||
}
|
||||
|
||||
/* Convert a protocol |level| to its char representation.
|
||||
We take an int to catch programming mistakes. */
|
||||
static char level_to_char(int level)
|
||||
{
|
||||
switch(level) {
|
||||
case PROT_CLEAR:
|
||||
return 'C';
|
||||
case PROT_SAFE:
|
||||
return 'S';
|
||||
case PROT_CONFIDENTIAL:
|
||||
return 'E';
|
||||
case PROT_PRIVATE:
|
||||
return 'P';
|
||||
case PROT_CMD:
|
||||
/* Fall through */
|
||||
default:
|
||||
/* Those 2 cases should not be reached! */
|
||||
break;
|
||||
}
|
||||
DEBUGASSERT(0);
|
||||
/* Default to the most secure alternative. */
|
||||
return 'P';
|
||||
}
|
||||
|
||||
/* Send an FTP command defined by |message| and the optional arguments. The
|
||||
function returns the ftp_code. If an error occurs, -1 is returned. */
|
||||
static int ftp_send_command(struct connectdata *conn, const char *message, ...)
|
||||
{
|
||||
int ftp_code;
|
||||
ssize_t nread=0;
|
||||
va_list args;
|
||||
char print_buffer[50];
|
||||
|
||||
va_start(args, message);
|
||||
vsnprintf(print_buffer, sizeof(print_buffer), message, args);
|
||||
va_end(args);
|
||||
|
||||
if(Curl_ftpsend(conn, print_buffer)) {
|
||||
ftp_code = -1;
|
||||
}
|
||||
else {
|
||||
if(Curl_GetFTPResponse(&nread, conn, &ftp_code))
|
||||
ftp_code = -1;
|
||||
}
|
||||
|
||||
(void)nread; /* Unused */
|
||||
return ftp_code;
|
||||
}
|
||||
|
||||
/* Read |len| from the socket |fd| and store it in |to|. Return a CURLcode
|
||||
saying whether an error occurred or CURLE_OK if |len| was read. */
|
||||
static CURLcode
|
||||
socket_read(curl_socket_t fd, void *to, size_t len)
|
||||
{
|
||||
char *to_p = to;
|
||||
CURLcode result;
|
||||
ssize_t nread;
|
||||
|
||||
while(len > 0) {
|
||||
result = Curl_read_plain(fd, to_p, len, &nread);
|
||||
if(!result) {
|
||||
len -= nread;
|
||||
to_p += nread;
|
||||
}
|
||||
else {
|
||||
/* FIXME: We are doing a busy wait */
|
||||
if(result == CURLE_AGAIN)
|
||||
continue;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Write |len| bytes from the buffer |to| to the socket |fd|. Return a
|
||||
CURLcode saying whether an error occurred or CURLE_OK if |len| was
|
||||
written. */
|
||||
static CURLcode
|
||||
socket_write(struct connectdata *conn, curl_socket_t fd, const void *to,
|
||||
size_t len)
|
||||
{
|
||||
const char *to_p = to;
|
||||
CURLcode result;
|
||||
ssize_t written;
|
||||
|
||||
while(len > 0) {
|
||||
result = Curl_write_plain(conn, fd, to_p, len, &written);
|
||||
if(!result) {
|
||||
len -= written;
|
||||
to_p += written;
|
||||
}
|
||||
else {
|
||||
/* FIXME: We are doing a busy wait */
|
||||
if(result == CURLE_AGAIN)
|
||||
continue;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode read_data(struct connectdata *conn,
|
||||
curl_socket_t fd,
|
||||
struct krb5buffer *buf)
|
||||
{
|
||||
int len;
|
||||
void *tmp = NULL;
|
||||
CURLcode result;
|
||||
|
||||
result = socket_read(fd, &len, sizeof(len));
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(len) {
|
||||
/* only realloc if there was a length */
|
||||
len = ntohl(len);
|
||||
tmp = Curl_saferealloc(buf->data, len);
|
||||
}
|
||||
if(tmp == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
buf->data = tmp;
|
||||
result = socket_read(fd, buf->data, len);
|
||||
if(result)
|
||||
return result;
|
||||
buf->size = conn->mech->decode(conn->app_data, buf->data, len,
|
||||
conn->data_prot, conn);
|
||||
buf->index = 0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static size_t
|
||||
buffer_read(struct krb5buffer *buf, void *data, size_t len)
|
||||
{
|
||||
if(buf->size - buf->index < len)
|
||||
len = buf->size - buf->index;
|
||||
memcpy(data, (char *)buf->data + buf->index, len);
|
||||
buf->index += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Matches Curl_recv signature */
|
||||
static ssize_t sec_recv(struct connectdata *conn, int sockindex,
|
||||
char *buffer, size_t len, CURLcode *err)
|
||||
{
|
||||
size_t bytes_read;
|
||||
size_t total_read = 0;
|
||||
curl_socket_t fd = conn->sock[sockindex];
|
||||
|
||||
*err = CURLE_OK;
|
||||
|
||||
/* Handle clear text response. */
|
||||
if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR)
|
||||
return read(fd, buffer, len);
|
||||
|
||||
if(conn->in_buffer.eof_flag) {
|
||||
conn->in_buffer.eof_flag = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bytes_read = buffer_read(&conn->in_buffer, buffer, len);
|
||||
len -= bytes_read;
|
||||
total_read += bytes_read;
|
||||
buffer += bytes_read;
|
||||
|
||||
while(len > 0) {
|
||||
if(read_data(conn, fd, &conn->in_buffer))
|
||||
return -1;
|
||||
if(conn->in_buffer.size == 0) {
|
||||
if(bytes_read > 0)
|
||||
conn->in_buffer.eof_flag = 1;
|
||||
return bytes_read;
|
||||
}
|
||||
bytes_read = buffer_read(&conn->in_buffer, buffer, len);
|
||||
len -= bytes_read;
|
||||
total_read += bytes_read;
|
||||
buffer += bytes_read;
|
||||
}
|
||||
/* FIXME: Check for overflow */
|
||||
return total_read;
|
||||
}
|
||||
|
||||
/* Send |length| bytes from |from| to the |fd| socket taking care of encoding
|
||||
and negociating with the server. |from| can be NULL. */
|
||||
/* FIXME: We don't check for errors nor report any! */
|
||||
static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
|
||||
const char *from, int length)
|
||||
{
|
||||
int bytes, htonl_bytes; /* 32-bit integers for htonl */
|
||||
char *buffer = NULL;
|
||||
char *cmd_buffer;
|
||||
size_t cmd_size = 0;
|
||||
CURLcode error;
|
||||
enum protection_level prot_level = conn->data_prot;
|
||||
bool iscmd = (prot_level == PROT_CMD)?TRUE:FALSE;
|
||||
|
||||
DEBUGASSERT(prot_level > PROT_NONE && prot_level < PROT_LAST);
|
||||
|
||||
if(iscmd) {
|
||||
if(!strncmp(from, "PASS ", 5) || !strncmp(from, "ACCT ", 5))
|
||||
prot_level = PROT_PRIVATE;
|
||||
else
|
||||
prot_level = conn->command_prot;
|
||||
}
|
||||
bytes = conn->mech->encode(conn->app_data, from, length, prot_level,
|
||||
(void **)&buffer);
|
||||
if(!buffer || bytes <= 0)
|
||||
return; /* error */
|
||||
|
||||
if(iscmd) {
|
||||
error = Curl_base64_encode(conn->data, buffer, curlx_sitouz(bytes),
|
||||
&cmd_buffer, &cmd_size);
|
||||
if(error) {
|
||||
free(buffer);
|
||||
return; /* error */
|
||||
}
|
||||
if(cmd_size > 0) {
|
||||
static const char *enc = "ENC ";
|
||||
static const char *mic = "MIC ";
|
||||
if(prot_level == PROT_PRIVATE)
|
||||
socket_write(conn, fd, enc, 4);
|
||||
else
|
||||
socket_write(conn, fd, mic, 4);
|
||||
|
||||
socket_write(conn, fd, cmd_buffer, cmd_size);
|
||||
socket_write(conn, fd, "\r\n", 2);
|
||||
infof(conn->data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic,
|
||||
cmd_buffer);
|
||||
free(cmd_buffer);
|
||||
}
|
||||
}
|
||||
else {
|
||||
htonl_bytes = htonl(bytes);
|
||||
socket_write(conn, fd, &htonl_bytes, sizeof(htonl_bytes));
|
||||
socket_write(conn, fd, buffer, curlx_sitouz(bytes));
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd,
|
||||
const char *buffer, size_t length)
|
||||
{
|
||||
ssize_t tx = 0, len = conn->buffer_size;
|
||||
|
||||
len -= conn->mech->overhead(conn->app_data, conn->data_prot,
|
||||
curlx_sztosi(len));
|
||||
if(len <= 0)
|
||||
len = length;
|
||||
while(length) {
|
||||
if(length < (size_t)len)
|
||||
len = length;
|
||||
|
||||
do_sec_send(conn, fd, buffer, curlx_sztosi(len));
|
||||
length -= len;
|
||||
buffer += len;
|
||||
tx += len;
|
||||
}
|
||||
return tx;
|
||||
}
|
||||
|
||||
/* Matches Curl_send signature */
|
||||
static ssize_t sec_send(struct connectdata *conn, int sockindex,
|
||||
const void *buffer, size_t len, CURLcode *err)
|
||||
{
|
||||
curl_socket_t fd = conn->sock[sockindex];
|
||||
*err = CURLE_OK;
|
||||
return sec_write(conn, fd, buffer, len);
|
||||
}
|
||||
|
||||
int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
|
||||
enum protection_level level)
|
||||
{
|
||||
/* decoded_len should be size_t or ssize_t but conn->mech->decode returns an
|
||||
int */
|
||||
int decoded_len;
|
||||
char *buf;
|
||||
int ret_code = 0;
|
||||
size_t decoded_sz = 0;
|
||||
CURLcode error;
|
||||
|
||||
DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
|
||||
|
||||
error = Curl_base64_decode(buffer + 4, (unsigned char **)&buf, &decoded_sz);
|
||||
if(error || decoded_sz == 0)
|
||||
return -1;
|
||||
|
||||
if(decoded_sz > (size_t)INT_MAX) {
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
decoded_len = curlx_uztosi(decoded_sz);
|
||||
|
||||
decoded_len = conn->mech->decode(conn->app_data, buf, decoded_len,
|
||||
level, conn);
|
||||
if(decoded_len <= 0) {
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(conn->data->set.verbose) {
|
||||
buf[decoded_len] = '\n';
|
||||
Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1, conn);
|
||||
}
|
||||
|
||||
buf[decoded_len] = '\0';
|
||||
if(decoded_len <= 3)
|
||||
/* suspiciously short */
|
||||
return 0;
|
||||
|
||||
if(buf[3] != '-')
|
||||
/* safe to ignore return code */
|
||||
(void)sscanf(buf, "%d", &ret_code);
|
||||
|
||||
if(buf[decoded_len - 1] == '\n')
|
||||
buf[decoded_len - 1] = '\0';
|
||||
/* FIXME: Is |buffer| length always greater than |decoded_len|? */
|
||||
strcpy(buffer, buf);
|
||||
free(buf);
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
/* FIXME: The error code returned here is never checked. */
|
||||
static int sec_set_protection_level(struct connectdata *conn)
|
||||
{
|
||||
int code;
|
||||
char *pbsz;
|
||||
static unsigned int buffer_size = 1 << 20; /* 1048576 */
|
||||
enum protection_level level = conn->request_data_prot;
|
||||
|
||||
DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
|
||||
|
||||
if(!conn->sec_complete) {
|
||||
infof(conn->data, "Trying to change the protection level after the"
|
||||
"completion of the data exchange.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Bail out if we try to set up the same level */
|
||||
if(conn->data_prot == level)
|
||||
return 0;
|
||||
|
||||
if(level) {
|
||||
code = ftp_send_command(conn, "PBSZ %u", buffer_size);
|
||||
if(code < 0)
|
||||
return -1;
|
||||
|
||||
if(code/100 != 2) {
|
||||
failf(conn->data, "Failed to set the protection's buffer size.");
|
||||
return -1;
|
||||
}
|
||||
conn->buffer_size = buffer_size;
|
||||
|
||||
pbsz = strstr(conn->data->state.buffer, "PBSZ=");
|
||||
if(pbsz) {
|
||||
/* ignore return code, use default value if it fails */
|
||||
(void)sscanf(pbsz, "PBSZ=%u", &buffer_size);
|
||||
if(buffer_size < conn->buffer_size)
|
||||
conn->buffer_size = buffer_size;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now try to negiociate the protection level. */
|
||||
code = ftp_send_command(conn, "PROT %c", level_to_char(level));
|
||||
|
||||
if(code < 0)
|
||||
return -1;
|
||||
|
||||
if(code/100 != 2) {
|
||||
failf(conn->data, "Failed to set the protection level.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
conn->data_prot = level;
|
||||
if(level == PROT_PRIVATE)
|
||||
conn->command_prot = level;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Curl_sec_request_prot(struct connectdata *conn, const char *level)
|
||||
{
|
||||
enum protection_level l = name_to_level(level);
|
||||
if(l == PROT_NONE)
|
||||
return -1;
|
||||
DEBUGASSERT(l > PROT_NONE && l < PROT_LAST);
|
||||
conn->request_data_prot = l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CURLcode choose_mech(struct connectdata *conn)
|
||||
{
|
||||
int ret;
|
||||
struct Curl_easy *data = conn->data;
|
||||
void *tmp_allocation;
|
||||
const struct Curl_sec_client_mech *mech = &Curl_krb5_client_mech;
|
||||
|
||||
tmp_allocation = realloc(conn->app_data, mech->size);
|
||||
if(tmp_allocation == NULL) {
|
||||
failf(data, "Failed realloc of size %u", mech->size);
|
||||
mech = NULL;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
conn->app_data = tmp_allocation;
|
||||
|
||||
if(mech->init) {
|
||||
ret = mech->init(conn->app_data);
|
||||
if(ret) {
|
||||
infof(data, "Failed initialization for %s. Skipping it.\n",
|
||||
mech->name);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
infof(data, "Trying mechanism %s...\n", mech->name);
|
||||
ret = ftp_send_command(conn, "AUTH %s", mech->name);
|
||||
if(ret < 0)
|
||||
/* FIXME: This error is too generic but it is OK for now. */
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
|
||||
if(ret/100 != 3) {
|
||||
switch(ret) {
|
||||
case 504:
|
||||
infof(data, "Mechanism %s is not supported by the server (server "
|
||||
"returned ftp code: 504).\n", mech->name);
|
||||
break;
|
||||
case 534:
|
||||
infof(data, "Mechanism %s was rejected by the server (server returned "
|
||||
"ftp code: 534).\n", mech->name);
|
||||
break;
|
||||
default:
|
||||
if(ret/100 == 5) {
|
||||
infof(data, "server does not support the security extensions\n");
|
||||
return CURLE_USE_SSL_FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return CURLE_LOGIN_DENIED;
|
||||
}
|
||||
|
||||
/* Authenticate */
|
||||
ret = mech->auth(conn->app_data, conn);
|
||||
|
||||
if(ret != AUTH_CONTINUE) {
|
||||
if(ret != AUTH_OK) {
|
||||
/* Mechanism has dumped the error to stderr, don't error here. */
|
||||
return -1;
|
||||
}
|
||||
DEBUGASSERT(ret == AUTH_OK);
|
||||
|
||||
conn->mech = mech;
|
||||
conn->sec_complete = 1;
|
||||
conn->recv[FIRSTSOCKET] = sec_recv;
|
||||
conn->send[FIRSTSOCKET] = sec_send;
|
||||
conn->recv[SECONDARYSOCKET] = sec_recv;
|
||||
conn->send[SECONDARYSOCKET] = sec_send;
|
||||
conn->command_prot = PROT_SAFE;
|
||||
/* Set the requested protection level */
|
||||
/* BLOCKING */
|
||||
(void)sec_set_protection_level(conn);
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode
|
||||
Curl_sec_login(struct connectdata *conn)
|
||||
{
|
||||
return choose_mech(conn);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Curl_sec_end(struct connectdata *conn)
|
||||
{
|
||||
if(conn->mech != NULL && conn->mech->end)
|
||||
conn->mech->end(conn->app_data);
|
||||
free(conn->app_data);
|
||||
conn->app_data = NULL;
|
||||
if(conn->in_buffer.data) {
|
||||
free(conn->in_buffer.data);
|
||||
conn->in_buffer.data = NULL;
|
||||
conn->in_buffer.size = 0;
|
||||
conn->in_buffer.index = 0;
|
||||
/* FIXME: Is this really needed? */
|
||||
conn->in_buffer.eof_flag = 0;
|
||||
}
|
||||
conn->sec_complete = 0;
|
||||
conn->data_prot = PROT_CLEAR;
|
||||
conn->mech = NULL;
|
||||
}
|
||||
|
||||
#endif /* HAVE_GSSAPI */
|
||||
|
||||
#endif /* CURL_DISABLE_FTP */
|
||||
@@ -1,583 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_SELECT) && !defined(HAVE_POLL_FINE)
|
||||
#error "We can't compile without select() or poll() support."
|
||||
#endif
|
||||
|
||||
#if defined(__BEOS__) && !defined(__HAIKU__)
|
||||
/* BeOS has FD_SET defined in socket.h */
|
||||
#include <socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef MSDOS
|
||||
#include <dos.h> /* delay() */
|
||||
#endif
|
||||
|
||||
#ifdef __VXWORKS__
|
||||
#include <strings.h> /* bzero() in FD_SET */
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "connect.h"
|
||||
#include "select.h"
|
||||
#include "warnless.h"
|
||||
|
||||
/* Convenience local macros */
|
||||
#define ELAPSED_MS() (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
|
||||
|
||||
int Curl_ack_eintr = 0;
|
||||
#define ERROR_NOT_EINTR(error) (Curl_ack_eintr || error != EINTR)
|
||||
|
||||
/*
|
||||
* Internal function used for waiting a specific amount of ms
|
||||
* in Curl_socket_check() and Curl_poll() when no file descriptor
|
||||
* is provided to wait on, just being used to delay execution.
|
||||
* WinSock select() and poll() timeout mechanisms need a valid
|
||||
* socket descriptor in a not null file descriptor set to work.
|
||||
* Waiting indefinitely with this function is not allowed, a
|
||||
* zero or negative timeout value will return immediately.
|
||||
* Timeout resolution, accuracy, as well as maximum supported
|
||||
* value is system dependent, neither factor is a citical issue
|
||||
* for the intended use of this function in the library.
|
||||
*
|
||||
* Return values:
|
||||
* -1 = system call error, invalid timeout value, or interrupted
|
||||
* 0 = specified timeout has elapsed
|
||||
*/
|
||||
int Curl_wait_ms(int timeout_ms)
|
||||
{
|
||||
#if !defined(MSDOS) && !defined(USE_WINSOCK)
|
||||
#ifndef HAVE_POLL_FINE
|
||||
struct timeval pending_tv;
|
||||
#endif
|
||||
struct timeval initial_tv;
|
||||
int pending_ms;
|
||||
int error;
|
||||
#endif
|
||||
int r = 0;
|
||||
|
||||
if(!timeout_ms)
|
||||
return 0;
|
||||
if(timeout_ms < 0) {
|
||||
SET_SOCKERRNO(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
#if defined(MSDOS)
|
||||
delay(timeout_ms);
|
||||
#elif defined(USE_WINSOCK)
|
||||
Sleep(timeout_ms);
|
||||
#else
|
||||
pending_ms = timeout_ms;
|
||||
initial_tv = curlx_tvnow();
|
||||
do {
|
||||
#if defined(HAVE_POLL_FINE)
|
||||
r = poll(NULL, 0, pending_ms);
|
||||
#else
|
||||
pending_tv.tv_sec = pending_ms / 1000;
|
||||
pending_tv.tv_usec = (pending_ms % 1000) * 1000;
|
||||
r = select(0, NULL, NULL, NULL, &pending_tv);
|
||||
#endif /* HAVE_POLL_FINE */
|
||||
if(r != -1)
|
||||
break;
|
||||
error = SOCKERRNO;
|
||||
if(error && ERROR_NOT_EINTR(error))
|
||||
break;
|
||||
pending_ms = timeout_ms - ELAPSED_MS();
|
||||
if(pending_ms <= 0) {
|
||||
r = 0; /* Simulate a "call timed out" case */
|
||||
break;
|
||||
}
|
||||
} while(r == -1);
|
||||
#endif /* USE_WINSOCK */
|
||||
if(r)
|
||||
r = -1;
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for read or write events on a set of file descriptors. It uses poll()
|
||||
* when a fine poll() is available, in order to avoid limits with FD_SETSIZE,
|
||||
* otherwise select() is used. An error is returned if select() is being used
|
||||
* and a file descriptor is too large for FD_SETSIZE.
|
||||
*
|
||||
* A negative timeout value makes this function wait indefinitely,
|
||||
* unles no valid file descriptor is given, when this happens the
|
||||
* negative timeout is ignored and the function times out immediately.
|
||||
*
|
||||
* Return values:
|
||||
* -1 = system call error or fd >= FD_SETSIZE
|
||||
* 0 = timeout
|
||||
* [bitmask] = action as described below
|
||||
*
|
||||
* CURL_CSELECT_IN - first socket is readable
|
||||
* CURL_CSELECT_IN2 - second socket is readable
|
||||
* CURL_CSELECT_OUT - write socket is writable
|
||||
* CURL_CSELECT_ERR - an error condition occurred
|
||||
*/
|
||||
int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
|
||||
curl_socket_t readfd1,
|
||||
curl_socket_t writefd, /* socket to write to */
|
||||
time_t timeout_ms) /* milliseconds to wait */
|
||||
{
|
||||
#ifdef HAVE_POLL_FINE
|
||||
struct pollfd pfd[3];
|
||||
int num;
|
||||
#else
|
||||
struct timeval pending_tv;
|
||||
struct timeval *ptimeout;
|
||||
fd_set fds_read;
|
||||
fd_set fds_write;
|
||||
fd_set fds_err;
|
||||
curl_socket_t maxfd;
|
||||
#endif
|
||||
struct timeval initial_tv = {0, 0};
|
||||
int pending_ms = 0;
|
||||
int error;
|
||||
int r;
|
||||
int ret;
|
||||
|
||||
#if SIZEOF_LONG != SIZEOF_INT
|
||||
/* wrap-around precaution */
|
||||
if(timeout_ms >= INT_MAX)
|
||||
timeout_ms = INT_MAX;
|
||||
#endif
|
||||
|
||||
if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
|
||||
(writefd == CURL_SOCKET_BAD)) {
|
||||
/* no sockets, just wait */
|
||||
r = Curl_wait_ms((int)timeout_ms);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
|
||||
time in this function does not need to be measured. This happens
|
||||
when function is called with a zero timeout or a negative timeout
|
||||
value indicating a blocking call should be performed. */
|
||||
|
||||
if(timeout_ms > 0) {
|
||||
pending_ms = (int)timeout_ms;
|
||||
initial_tv = curlx_tvnow();
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLL_FINE
|
||||
|
||||
num = 0;
|
||||
if(readfd0 != CURL_SOCKET_BAD) {
|
||||
pfd[num].fd = readfd0;
|
||||
pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
|
||||
pfd[num].revents = 0;
|
||||
num++;
|
||||
}
|
||||
if(readfd1 != CURL_SOCKET_BAD) {
|
||||
pfd[num].fd = readfd1;
|
||||
pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
|
||||
pfd[num].revents = 0;
|
||||
num++;
|
||||
}
|
||||
if(writefd != CURL_SOCKET_BAD) {
|
||||
pfd[num].fd = writefd;
|
||||
pfd[num].events = POLLWRNORM|POLLOUT;
|
||||
pfd[num].revents = 0;
|
||||
num++;
|
||||
}
|
||||
|
||||
do {
|
||||
if(timeout_ms < 0)
|
||||
pending_ms = -1;
|
||||
else if(!timeout_ms)
|
||||
pending_ms = 0;
|
||||
r = poll(pfd, num, pending_ms);
|
||||
if(r != -1)
|
||||
break;
|
||||
error = SOCKERRNO;
|
||||
if(error && ERROR_NOT_EINTR(error))
|
||||
break;
|
||||
if(timeout_ms > 0) {
|
||||
pending_ms = (int)(timeout_ms - ELAPSED_MS());
|
||||
if(pending_ms <= 0) {
|
||||
r = 0; /* Simulate a "call timed out" case */
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(r == -1);
|
||||
|
||||
if(r < 0)
|
||||
return -1;
|
||||
if(r == 0)
|
||||
return 0;
|
||||
|
||||
ret = 0;
|
||||
num = 0;
|
||||
if(readfd0 != CURL_SOCKET_BAD) {
|
||||
if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
|
||||
ret |= CURL_CSELECT_IN;
|
||||
if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
|
||||
ret |= CURL_CSELECT_ERR;
|
||||
num++;
|
||||
}
|
||||
if(readfd1 != CURL_SOCKET_BAD) {
|
||||
if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
|
||||
ret |= CURL_CSELECT_IN2;
|
||||
if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
|
||||
ret |= CURL_CSELECT_ERR;
|
||||
num++;
|
||||
}
|
||||
if(writefd != CURL_SOCKET_BAD) {
|
||||
if(pfd[num].revents & (POLLWRNORM|POLLOUT))
|
||||
ret |= CURL_CSELECT_OUT;
|
||||
if(pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL))
|
||||
ret |= CURL_CSELECT_ERR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
#else /* HAVE_POLL_FINE */
|
||||
|
||||
FD_ZERO(&fds_err);
|
||||
maxfd = (curl_socket_t)-1;
|
||||
|
||||
FD_ZERO(&fds_read);
|
||||
if(readfd0 != CURL_SOCKET_BAD) {
|
||||
VERIFY_SOCK(readfd0);
|
||||
FD_SET(readfd0, &fds_read);
|
||||
FD_SET(readfd0, &fds_err);
|
||||
maxfd = readfd0;
|
||||
}
|
||||
if(readfd1 != CURL_SOCKET_BAD) {
|
||||
VERIFY_SOCK(readfd1);
|
||||
FD_SET(readfd1, &fds_read);
|
||||
FD_SET(readfd1, &fds_err);
|
||||
if(readfd1 > maxfd)
|
||||
maxfd = readfd1;
|
||||
}
|
||||
|
||||
FD_ZERO(&fds_write);
|
||||
if(writefd != CURL_SOCKET_BAD) {
|
||||
VERIFY_SOCK(writefd);
|
||||
FD_SET(writefd, &fds_write);
|
||||
FD_SET(writefd, &fds_err);
|
||||
if(writefd > maxfd)
|
||||
maxfd = writefd;
|
||||
}
|
||||
|
||||
ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
|
||||
|
||||
do {
|
||||
if(timeout_ms > 0) {
|
||||
pending_tv.tv_sec = pending_ms / 1000;
|
||||
pending_tv.tv_usec = (pending_ms % 1000) * 1000;
|
||||
}
|
||||
else if(!timeout_ms) {
|
||||
pending_tv.tv_sec = 0;
|
||||
pending_tv.tv_usec = 0;
|
||||
}
|
||||
|
||||
/* WinSock select() must not be called with an fd_set that contains zero
|
||||
fd flags, or it will return WSAEINVAL. But, it also can't be called
|
||||
with no fd_sets at all! From the documentation:
|
||||
|
||||
Any two of the parameters, readfds, writefds, or exceptfds, can be
|
||||
given as null. At least one must be non-null, and any non-null
|
||||
descriptor set must contain at least one handle to a socket.
|
||||
|
||||
We know that we have at least one bit set in at least two fd_sets in
|
||||
this case, but we may have no bits set in either fds_read or fd_write,
|
||||
so check for that and handle it. Luckily, with WinSock, we can _also_
|
||||
ask how many bits are set on an fd_set.
|
||||
|
||||
It is unclear why WinSock doesn't just handle this for us instead of
|
||||
calling this an error.
|
||||
|
||||
Note also that WinSock ignores the first argument, so we don't worry
|
||||
about the fact that maxfd is computed incorrectly with WinSock (since
|
||||
curl_socket_t is unsigned in such cases and thus -1 is the largest
|
||||
value).
|
||||
*/
|
||||
#ifdef USE_WINSOCK
|
||||
r = select((int)maxfd + 1,
|
||||
fds_read.fd_count ? &fds_read : NULL,
|
||||
fds_write.fd_count ? &fds_write : NULL,
|
||||
&fds_err, ptimeout);
|
||||
#else
|
||||
r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
|
||||
#endif
|
||||
|
||||
if(r != -1)
|
||||
break;
|
||||
error = SOCKERRNO;
|
||||
if(error && ERROR_NOT_EINTR(error))
|
||||
break;
|
||||
if(timeout_ms > 0) {
|
||||
pending_ms = (int)(timeout_ms - ELAPSED_MS());
|
||||
if(pending_ms <= 0) {
|
||||
r = 0; /* Simulate a "call timed out" case */
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(r == -1);
|
||||
|
||||
if(r < 0)
|
||||
return -1;
|
||||
if(r == 0)
|
||||
return 0;
|
||||
|
||||
ret = 0;
|
||||
if(readfd0 != CURL_SOCKET_BAD) {
|
||||
if(FD_ISSET(readfd0, &fds_read))
|
||||
ret |= CURL_CSELECT_IN;
|
||||
if(FD_ISSET(readfd0, &fds_err))
|
||||
ret |= CURL_CSELECT_ERR;
|
||||
}
|
||||
if(readfd1 != CURL_SOCKET_BAD) {
|
||||
if(FD_ISSET(readfd1, &fds_read))
|
||||
ret |= CURL_CSELECT_IN2;
|
||||
if(FD_ISSET(readfd1, &fds_err))
|
||||
ret |= CURL_CSELECT_ERR;
|
||||
}
|
||||
if(writefd != CURL_SOCKET_BAD) {
|
||||
if(FD_ISSET(writefd, &fds_write))
|
||||
ret |= CURL_CSELECT_OUT;
|
||||
if(FD_ISSET(writefd, &fds_err))
|
||||
ret |= CURL_CSELECT_ERR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
#endif /* HAVE_POLL_FINE */
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a wrapper around poll(). If poll() does not exist, then
|
||||
* select() is used instead. An error is returned if select() is
|
||||
* being used and a file descriptor is too large for FD_SETSIZE.
|
||||
* A negative timeout value makes this function wait indefinitely,
|
||||
* unles no valid file descriptor is given, when this happens the
|
||||
* negative timeout is ignored and the function times out immediately.
|
||||
*
|
||||
* Return values:
|
||||
* -1 = system call error or fd >= FD_SETSIZE
|
||||
* 0 = timeout
|
||||
* N = number of structures with non zero revent fields
|
||||
*/
|
||||
int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
|
||||
{
|
||||
#ifndef HAVE_POLL_FINE
|
||||
struct timeval pending_tv;
|
||||
struct timeval *ptimeout;
|
||||
fd_set fds_read;
|
||||
fd_set fds_write;
|
||||
fd_set fds_err;
|
||||
curl_socket_t maxfd;
|
||||
#endif
|
||||
struct timeval initial_tv = {0, 0};
|
||||
bool fds_none = TRUE;
|
||||
unsigned int i;
|
||||
int pending_ms = 0;
|
||||
int error;
|
||||
int r;
|
||||
|
||||
if(ufds) {
|
||||
for(i = 0; i < nfds; i++) {
|
||||
if(ufds[i].fd != CURL_SOCKET_BAD) {
|
||||
fds_none = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(fds_none) {
|
||||
r = Curl_wait_ms(timeout_ms);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
|
||||
time in this function does not need to be measured. This happens
|
||||
when function is called with a zero timeout or a negative timeout
|
||||
value indicating a blocking call should be performed. */
|
||||
|
||||
if(timeout_ms > 0) {
|
||||
pending_ms = timeout_ms;
|
||||
initial_tv = curlx_tvnow();
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLL_FINE
|
||||
|
||||
do {
|
||||
if(timeout_ms < 0)
|
||||
pending_ms = -1;
|
||||
else if(!timeout_ms)
|
||||
pending_ms = 0;
|
||||
r = poll(ufds, nfds, pending_ms);
|
||||
if(r != -1)
|
||||
break;
|
||||
error = SOCKERRNO;
|
||||
if(error && ERROR_NOT_EINTR(error))
|
||||
break;
|
||||
if(timeout_ms > 0) {
|
||||
pending_ms = (int)(timeout_ms - ELAPSED_MS());
|
||||
if(pending_ms <= 0) {
|
||||
r = 0; /* Simulate a "call timed out" case */
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(r == -1);
|
||||
|
||||
if(r < 0)
|
||||
return -1;
|
||||
if(r == 0)
|
||||
return 0;
|
||||
|
||||
for(i = 0; i < nfds; i++) {
|
||||
if(ufds[i].fd == CURL_SOCKET_BAD)
|
||||
continue;
|
||||
if(ufds[i].revents & POLLHUP)
|
||||
ufds[i].revents |= POLLIN;
|
||||
if(ufds[i].revents & POLLERR)
|
||||
ufds[i].revents |= (POLLIN|POLLOUT);
|
||||
}
|
||||
|
||||
#else /* HAVE_POLL_FINE */
|
||||
|
||||
FD_ZERO(&fds_read);
|
||||
FD_ZERO(&fds_write);
|
||||
FD_ZERO(&fds_err);
|
||||
maxfd = (curl_socket_t)-1;
|
||||
|
||||
for(i = 0; i < nfds; i++) {
|
||||
ufds[i].revents = 0;
|
||||
if(ufds[i].fd == CURL_SOCKET_BAD)
|
||||
continue;
|
||||
VERIFY_SOCK(ufds[i].fd);
|
||||
if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
|
||||
POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
|
||||
if(ufds[i].fd > maxfd)
|
||||
maxfd = ufds[i].fd;
|
||||
if(ufds[i].events & (POLLRDNORM|POLLIN))
|
||||
FD_SET(ufds[i].fd, &fds_read);
|
||||
if(ufds[i].events & (POLLWRNORM|POLLOUT))
|
||||
FD_SET(ufds[i].fd, &fds_write);
|
||||
if(ufds[i].events & (POLLRDBAND|POLLPRI))
|
||||
FD_SET(ufds[i].fd, &fds_err);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
/* WinSock select() can't handle zero events. See the comment about this in
|
||||
Curl_check_socket(). */
|
||||
if(fds_read.fd_count == 0 && fds_write.fd_count == 0
|
||||
&& fds_err.fd_count == 0) {
|
||||
r = Curl_wait_ms(timeout_ms);
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
|
||||
|
||||
do {
|
||||
if(timeout_ms > 0) {
|
||||
pending_tv.tv_sec = pending_ms / 1000;
|
||||
pending_tv.tv_usec = (pending_ms % 1000) * 1000;
|
||||
}
|
||||
else if(!timeout_ms) {
|
||||
pending_tv.tv_sec = 0;
|
||||
pending_tv.tv_usec = 0;
|
||||
}
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
r = select((int)maxfd + 1,
|
||||
/* WinSock select() can't handle fd_sets with zero bits set, so
|
||||
don't give it such arguments. See the comment about this in
|
||||
Curl_check_socket().
|
||||
*/
|
||||
fds_read.fd_count ? &fds_read : NULL,
|
||||
fds_write.fd_count ? &fds_write : NULL,
|
||||
fds_err.fd_count ? &fds_err : NULL, ptimeout);
|
||||
#else
|
||||
r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
|
||||
#endif
|
||||
if(r != -1)
|
||||
break;
|
||||
error = SOCKERRNO;
|
||||
if(error && ERROR_NOT_EINTR(error))
|
||||
break;
|
||||
if(timeout_ms > 0) {
|
||||
pending_ms = timeout_ms - ELAPSED_MS();
|
||||
if(pending_ms <= 0) {
|
||||
r = 0; /* Simulate a "call timed out" case */
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(r == -1);
|
||||
|
||||
if(r < 0)
|
||||
return -1;
|
||||
if(r == 0)
|
||||
return 0;
|
||||
|
||||
r = 0;
|
||||
for(i = 0; i < nfds; i++) {
|
||||
ufds[i].revents = 0;
|
||||
if(ufds[i].fd == CURL_SOCKET_BAD)
|
||||
continue;
|
||||
if(FD_ISSET(ufds[i].fd, &fds_read))
|
||||
ufds[i].revents |= POLLIN;
|
||||
if(FD_ISSET(ufds[i].fd, &fds_write))
|
||||
ufds[i].revents |= POLLOUT;
|
||||
if(FD_ISSET(ufds[i].fd, &fds_err))
|
||||
ufds[i].revents |= POLLPRI;
|
||||
if(ufds[i].revents != 0)
|
||||
r++;
|
||||
}
|
||||
|
||||
#endif /* HAVE_POLL_FINE */
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef TPF
|
||||
/*
|
||||
* This is a replacement for select() on the TPF platform.
|
||||
* It is used whenever libcurl calls select().
|
||||
* The call below to tpf_process_signals() is required because
|
||||
* TPF's select calls are not signal interruptible.
|
||||
*
|
||||
* Return values are the same as select's.
|
||||
*/
|
||||
int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
|
||||
fd_set* excepts, struct timeval* tv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
|
||||
tpf_process_signals();
|
||||
return rc;
|
||||
}
|
||||
#endif /* TPF */
|
||||
@@ -1,115 +0,0 @@
|
||||
#ifndef HEADER_CURL_SELECT_H
|
||||
#define HEADER_CURL_SELECT_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_SYS_POLL_H
|
||||
#include <sys/poll.h>
|
||||
#elif defined(HAVE_POLL_H)
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Definition of pollfd struct and constants for platforms lacking them.
|
||||
*/
|
||||
|
||||
#if !defined(HAVE_STRUCT_POLLFD) && \
|
||||
!defined(HAVE_SYS_POLL_H) && \
|
||||
!defined(HAVE_POLL_H)
|
||||
|
||||
#define POLLIN 0x01
|
||||
#define POLLPRI 0x02
|
||||
#define POLLOUT 0x04
|
||||
#define POLLERR 0x08
|
||||
#define POLLHUP 0x10
|
||||
#define POLLNVAL 0x20
|
||||
|
||||
struct pollfd
|
||||
{
|
||||
curl_socket_t fd;
|
||||
short events;
|
||||
short revents;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef POLLRDNORM
|
||||
#define POLLRDNORM POLLIN
|
||||
#endif
|
||||
|
||||
#ifndef POLLWRNORM
|
||||
#define POLLWRNORM POLLOUT
|
||||
#endif
|
||||
|
||||
#ifndef POLLRDBAND
|
||||
#define POLLRDBAND POLLPRI
|
||||
#endif
|
||||
|
||||
/* there are three CSELECT defines that are defined in the public header that
|
||||
are exposed to users, but this *IN2 bit is only ever used internally and
|
||||
therefore defined here */
|
||||
#define CURL_CSELECT_IN2 (CURL_CSELECT_ERR << 1)
|
||||
|
||||
int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
|
||||
curl_socket_t writefd,
|
||||
time_t timeout_ms);
|
||||
|
||||
#define SOCKET_READABLE(x,z) \
|
||||
Curl_socket_check(x, CURL_SOCKET_BAD, CURL_SOCKET_BAD, z)
|
||||
#define SOCKET_WRITABLE(x,z) \
|
||||
Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, x, z)
|
||||
|
||||
int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
|
||||
|
||||
/* On non-DOS and non-Winsock platforms, when Curl_ack_eintr is set,
|
||||
* EINTR condition is honored and function might exit early without
|
||||
* awaiting full timeout. Otherwise EINTR will be ignored and full
|
||||
* timeout will elapse. */
|
||||
extern int Curl_ack_eintr;
|
||||
|
||||
int Curl_wait_ms(int timeout_ms);
|
||||
|
||||
#ifdef TPF
|
||||
int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
|
||||
fd_set* excepts, struct timeval* tv);
|
||||
#endif
|
||||
|
||||
/* Winsock and TPF sockets are not in range [0..FD_SETSIZE-1], which
|
||||
unfortunately makes it impossible for us to easily check if they're valid
|
||||
*/
|
||||
#if defined(USE_WINSOCK) || defined(TPF)
|
||||
#define VALID_SOCK(x) 1
|
||||
#define VERIFY_SOCK(x) Curl_nop_stmt
|
||||
#else
|
||||
#define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE))
|
||||
#define VERIFY_SOCK(x) do { \
|
||||
if(!VALID_SOCK(x)) { \
|
||||
SET_SOCKERRNO(EINVAL); \
|
||||
return -1; \
|
||||
} \
|
||||
} WHILE_FALSE
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_SELECT_H */
|
||||
|
||||
@@ -1,839 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "connect.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "ssh.h"
|
||||
#include "multiif.h"
|
||||
#include "non-ascii.h"
|
||||
#include "strerror.h"
|
||||
#include "select.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef CURL_DO_LINEEND_CONV
|
||||
/*
|
||||
* convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
|
||||
* (\n), with special processing for CRLF sequences that are split between two
|
||||
* blocks of data. Remaining, bare CRs are changed to LFs. The possibly new
|
||||
* size of the data is returned.
|
||||
*/
|
||||
static size_t convert_lineends(struct Curl_easy *data,
|
||||
char *startPtr, size_t size)
|
||||
{
|
||||
char *inPtr, *outPtr;
|
||||
|
||||
/* sanity check */
|
||||
if((startPtr == NULL) || (size < 1)) {
|
||||
return size;
|
||||
}
|
||||
|
||||
if(data->state.prev_block_had_trailing_cr) {
|
||||
/* The previous block of incoming data
|
||||
had a trailing CR, which was turned into a LF. */
|
||||
if(*startPtr == '\n') {
|
||||
/* This block of incoming data starts with the
|
||||
previous block's LF so get rid of it */
|
||||
memmove(startPtr, startPtr+1, size-1);
|
||||
size--;
|
||||
/* and it wasn't a bare CR but a CRLF conversion instead */
|
||||
data->state.crlf_conversions++;
|
||||
}
|
||||
data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
|
||||
}
|
||||
|
||||
/* find 1st CR, if any */
|
||||
inPtr = outPtr = memchr(startPtr, '\r', size);
|
||||
if(inPtr) {
|
||||
/* at least one CR, now look for CRLF */
|
||||
while(inPtr < (startPtr+size-1)) {
|
||||
/* note that it's size-1, so we'll never look past the last byte */
|
||||
if(memcmp(inPtr, "\r\n", 2) == 0) {
|
||||
/* CRLF found, bump past the CR and copy the NL */
|
||||
inPtr++;
|
||||
*outPtr = *inPtr;
|
||||
/* keep track of how many CRLFs we converted */
|
||||
data->state.crlf_conversions++;
|
||||
}
|
||||
else {
|
||||
if(*inPtr == '\r') {
|
||||
/* lone CR, move LF instead */
|
||||
*outPtr = '\n';
|
||||
}
|
||||
else {
|
||||
/* not a CRLF nor a CR, just copy whatever it is */
|
||||
*outPtr = *inPtr;
|
||||
}
|
||||
}
|
||||
outPtr++;
|
||||
inPtr++;
|
||||
} /* end of while loop */
|
||||
|
||||
if(inPtr < startPtr+size) {
|
||||
/* handle last byte */
|
||||
if(*inPtr == '\r') {
|
||||
/* deal with a CR at the end of the buffer */
|
||||
*outPtr = '\n'; /* copy a NL instead */
|
||||
/* note that a CRLF might be split across two blocks */
|
||||
data->state.prev_block_had_trailing_cr = TRUE;
|
||||
}
|
||||
else {
|
||||
/* copy last byte */
|
||||
*outPtr = *inPtr;
|
||||
}
|
||||
outPtr++;
|
||||
}
|
||||
if(outPtr < startPtr+size)
|
||||
/* tidy up by null terminating the now shorter data */
|
||||
*outPtr = '\0';
|
||||
|
||||
return (outPtr - startPtr);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
#endif /* CURL_DO_LINEEND_CONV */
|
||||
|
||||
#ifdef USE_RECV_BEFORE_SEND_WORKAROUND
|
||||
bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
struct postponed_data * const psnd = &(conn->postponed[sockindex]);
|
||||
return psnd->buffer && psnd->allocated_size &&
|
||||
psnd->recv_size > psnd->recv_processed;
|
||||
}
|
||||
|
||||
static void pre_receive_plain(struct connectdata *conn, int num)
|
||||
{
|
||||
const curl_socket_t sockfd = conn->sock[num];
|
||||
struct postponed_data * const psnd = &(conn->postponed[num]);
|
||||
size_t bytestorecv = psnd->allocated_size - psnd->recv_size;
|
||||
/* WinSock will destroy unread received data if send() is
|
||||
failed.
|
||||
To avoid lossage of received data, recv() must be
|
||||
performed before every send() if any incoming data is
|
||||
available. However, skip this, if buffer is already full. */
|
||||
if((conn->handler->protocol&PROTO_FAMILY_HTTP) != 0 &&
|
||||
conn->recv[num] == Curl_recv_plain &&
|
||||
(!psnd->buffer || bytestorecv)) {
|
||||
const int readymask = Curl_socket_check(sockfd, CURL_SOCKET_BAD,
|
||||
CURL_SOCKET_BAD, 0);
|
||||
if(readymask != -1 && (readymask & CURL_CSELECT_IN) != 0) {
|
||||
/* Have some incoming data */
|
||||
if(!psnd->buffer) {
|
||||
/* Use buffer double default size for intermediate buffer */
|
||||
psnd->allocated_size = 2 * BUFSIZE;
|
||||
psnd->buffer = malloc(psnd->allocated_size);
|
||||
psnd->recv_size = 0;
|
||||
psnd->recv_processed = 0;
|
||||
#ifdef DEBUGBUILD
|
||||
psnd->bindsock = sockfd; /* Used only for DEBUGASSERT */
|
||||
#endif /* DEBUGBUILD */
|
||||
bytestorecv = psnd->allocated_size;
|
||||
}
|
||||
if(psnd->buffer) {
|
||||
ssize_t recvedbytes;
|
||||
DEBUGASSERT(psnd->bindsock == sockfd);
|
||||
recvedbytes = sread(sockfd, psnd->buffer + psnd->recv_size,
|
||||
bytestorecv);
|
||||
if(recvedbytes > 0)
|
||||
psnd->recv_size += recvedbytes;
|
||||
}
|
||||
else
|
||||
psnd->allocated_size = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t get_pre_recved(struct connectdata *conn, int num, char *buf,
|
||||
size_t len)
|
||||
{
|
||||
struct postponed_data * const psnd = &(conn->postponed[num]);
|
||||
size_t copysize;
|
||||
if(!psnd->buffer)
|
||||
return 0;
|
||||
|
||||
DEBUGASSERT(psnd->allocated_size > 0);
|
||||
DEBUGASSERT(psnd->recv_size <= psnd->allocated_size);
|
||||
DEBUGASSERT(psnd->recv_processed <= psnd->recv_size);
|
||||
/* Check and process data that already received and storied in internal
|
||||
intermediate buffer */
|
||||
if(psnd->recv_size > psnd->recv_processed) {
|
||||
DEBUGASSERT(psnd->bindsock == conn->sock[num]);
|
||||
copysize = CURLMIN(len, psnd->recv_size - psnd->recv_processed);
|
||||
memcpy(buf, psnd->buffer + psnd->recv_processed, copysize);
|
||||
psnd->recv_processed += copysize;
|
||||
}
|
||||
else
|
||||
copysize = 0; /* buffer was allocated, but nothing was received */
|
||||
|
||||
/* Free intermediate buffer if it has no unprocessed data */
|
||||
if(psnd->recv_processed == psnd->recv_size) {
|
||||
free(psnd->buffer);
|
||||
psnd->buffer = NULL;
|
||||
psnd->allocated_size = 0;
|
||||
psnd->recv_size = 0;
|
||||
psnd->recv_processed = 0;
|
||||
#ifdef DEBUGBUILD
|
||||
psnd->bindsock = CURL_SOCKET_BAD;
|
||||
#endif /* DEBUGBUILD */
|
||||
}
|
||||
return (ssize_t)copysize;
|
||||
}
|
||||
#else /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
|
||||
/* Use "do-nothing" macros instead of functions when workaround not used */
|
||||
bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
(void)conn;
|
||||
(void)sockindex;
|
||||
return false;
|
||||
}
|
||||
#define pre_receive_plain(c,n) do {} WHILE_FALSE
|
||||
#define get_pre_recved(c,n,b,l) 0
|
||||
#endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
|
||||
|
||||
/* Curl_infof() is for info message along the way */
|
||||
|
||||
void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
if(data && data->set.verbose) {
|
||||
va_list ap;
|
||||
size_t len;
|
||||
char print_buffer[2048 + 1];
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
|
||||
va_end(ap);
|
||||
len = strlen(print_buffer);
|
||||
Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Curl_failf() is for messages stating why we failed.
|
||||
* The message SHALL NOT include any LF or CR.
|
||||
*/
|
||||
|
||||
void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
size_t len;
|
||||
va_start(ap, fmt);
|
||||
|
||||
vsnprintf(data->state.buffer, BUFSIZE, fmt, ap);
|
||||
|
||||
if(data->set.errorbuffer && !data->state.errorbuf) {
|
||||
snprintf(data->set.errorbuffer, CURL_ERROR_SIZE, "%s", data->state.buffer);
|
||||
data->state.errorbuf = TRUE; /* wrote error string */
|
||||
}
|
||||
if(data->set.verbose) {
|
||||
len = strlen(data->state.buffer);
|
||||
if(len < BUFSIZE - 1) {
|
||||
data->state.buffer[len] = '\n';
|
||||
data->state.buffer[++len] = '\0';
|
||||
}
|
||||
Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL);
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/* Curl_sendf() sends formated data to the server */
|
||||
CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
ssize_t bytes_written;
|
||||
size_t write_len;
|
||||
CURLcode result = CURLE_OK;
|
||||
char *s;
|
||||
char *sptr;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
s = vaprintf(fmt, ap); /* returns an allocated string */
|
||||
va_end(ap);
|
||||
if(!s)
|
||||
return CURLE_OUT_OF_MEMORY; /* failure */
|
||||
|
||||
bytes_written=0;
|
||||
write_len = strlen(s);
|
||||
sptr = s;
|
||||
|
||||
for(;;) {
|
||||
/* Write the buffer to the socket */
|
||||
result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
|
||||
|
||||
if(result)
|
||||
break;
|
||||
|
||||
if(data->set.verbose)
|
||||
Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn);
|
||||
|
||||
if((size_t)bytes_written != write_len) {
|
||||
/* if not all was written at once, we must advance the pointer, decrease
|
||||
the size left and try again! */
|
||||
write_len -= bytes_written;
|
||||
sptr += bytes_written;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
free(s); /* free the output string */
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_write() is an internal write function that sends data to the
|
||||
* server. Works with plain sockets, SCP, SSL or kerberos.
|
||||
*
|
||||
* If the write would block (CURLE_AGAIN), we return CURLE_OK and
|
||||
* (*written == 0). Otherwise we return regular CURLcode value.
|
||||
*/
|
||||
CURLcode Curl_write(struct connectdata *conn,
|
||||
curl_socket_t sockfd,
|
||||
const void *mem,
|
||||
size_t len,
|
||||
ssize_t *written)
|
||||
{
|
||||
ssize_t bytes_written;
|
||||
CURLcode result = CURLE_OK;
|
||||
int num = (sockfd == conn->sock[SECONDARYSOCKET]);
|
||||
|
||||
bytes_written = conn->send[num](conn, num, mem, len, &result);
|
||||
|
||||
*written = bytes_written;
|
||||
if(bytes_written >= 0)
|
||||
/* we completely ignore the curlcode value when subzero is not returned */
|
||||
return CURLE_OK;
|
||||
|
||||
/* handle CURLE_AGAIN or a send failure */
|
||||
switch(result) {
|
||||
case CURLE_AGAIN:
|
||||
*written = 0;
|
||||
return CURLE_OK;
|
||||
|
||||
case CURLE_OK:
|
||||
/* general send failure */
|
||||
return CURLE_SEND_ERROR;
|
||||
|
||||
default:
|
||||
/* we got a specific curlcode, forward it */
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t Curl_send_plain(struct connectdata *conn, int num,
|
||||
const void *mem, size_t len, CURLcode *code)
|
||||
{
|
||||
curl_socket_t sockfd = conn->sock[num];
|
||||
ssize_t bytes_written;
|
||||
/* WinSock will destroy unread received data if send() is
|
||||
failed.
|
||||
To avoid lossage of received data, recv() must be
|
||||
performed before every send() if any incoming data is
|
||||
available. */
|
||||
pre_receive_plain(conn, num);
|
||||
|
||||
#ifdef MSG_FASTOPEN /* Linux */
|
||||
if(conn->bits.tcp_fastopen) {
|
||||
bytes_written = sendto(sockfd, mem, len, MSG_FASTOPEN,
|
||||
conn->ip_addr->ai_addr, conn->ip_addr->ai_addrlen);
|
||||
conn->bits.tcp_fastopen = FALSE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
bytes_written = swrite(sockfd, mem, len);
|
||||
|
||||
*code = CURLE_OK;
|
||||
if(-1 == bytes_written) {
|
||||
int err = SOCKERRNO;
|
||||
|
||||
if(
|
||||
#ifdef WSAEWOULDBLOCK
|
||||
/* This is how Windows does it */
|
||||
(WSAEWOULDBLOCK == err)
|
||||
#else
|
||||
/* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
|
||||
due to its inability to send off data without blocking. We therefor
|
||||
treat both error codes the same here */
|
||||
(EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) ||
|
||||
(EINPROGRESS == err)
|
||||
#endif
|
||||
) {
|
||||
/* this is just a case of EWOULDBLOCK */
|
||||
bytes_written=0;
|
||||
*code = CURLE_AGAIN;
|
||||
}
|
||||
else {
|
||||
failf(conn->data, "Send failure: %s",
|
||||
Curl_strerror(conn, err));
|
||||
conn->data->state.os_errno = err;
|
||||
*code = CURLE_SEND_ERROR;
|
||||
}
|
||||
}
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_write_plain() is an internal write function that sends data to the
|
||||
* server using plain sockets only. Otherwise meant to have the exact same
|
||||
* proto as Curl_write()
|
||||
*/
|
||||
CURLcode Curl_write_plain(struct connectdata *conn,
|
||||
curl_socket_t sockfd,
|
||||
const void *mem,
|
||||
size_t len,
|
||||
ssize_t *written)
|
||||
{
|
||||
ssize_t bytes_written;
|
||||
CURLcode result;
|
||||
int num = (sockfd == conn->sock[SECONDARYSOCKET]);
|
||||
|
||||
bytes_written = Curl_send_plain(conn, num, mem, len, &result);
|
||||
|
||||
*written = bytes_written;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
|
||||
size_t len, CURLcode *code)
|
||||
{
|
||||
curl_socket_t sockfd = conn->sock[num];
|
||||
ssize_t nread;
|
||||
/* Check and return data that already received and storied in internal
|
||||
intermediate buffer */
|
||||
nread = get_pre_recved(conn, num, buf, len);
|
||||
if(nread > 0) {
|
||||
*code = CURLE_OK;
|
||||
return nread;
|
||||
}
|
||||
|
||||
nread = sread(sockfd, buf, len);
|
||||
|
||||
*code = CURLE_OK;
|
||||
if(-1 == nread) {
|
||||
int err = SOCKERRNO;
|
||||
|
||||
if(
|
||||
#ifdef WSAEWOULDBLOCK
|
||||
/* This is how Windows does it */
|
||||
(WSAEWOULDBLOCK == err)
|
||||
#else
|
||||
/* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
|
||||
due to its inability to send off data without blocking. We therefor
|
||||
treat both error codes the same here */
|
||||
(EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
|
||||
#endif
|
||||
) {
|
||||
/* this is just a case of EWOULDBLOCK */
|
||||
*code = CURLE_AGAIN;
|
||||
}
|
||||
else {
|
||||
failf(conn->data, "Recv failure: %s",
|
||||
Curl_strerror(conn, err));
|
||||
conn->data->state.os_errno = err;
|
||||
*code = CURLE_RECV_ERROR;
|
||||
}
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
|
||||
static CURLcode pausewrite(struct Curl_easy *data,
|
||||
int type, /* what type of data */
|
||||
const char *ptr,
|
||||
size_t len)
|
||||
{
|
||||
/* signalled to pause sending on this connection, but since we have data
|
||||
we want to send we need to dup it to save a copy for when the sending
|
||||
is again enabled */
|
||||
struct SingleRequest *k = &data->req;
|
||||
char *dupl = malloc(len);
|
||||
if(!dupl)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
memcpy(dupl, ptr, len);
|
||||
|
||||
/* store this information in the state struct for later use */
|
||||
data->state.tempwrite = dupl;
|
||||
data->state.tempwritesize = len;
|
||||
data->state.tempwritetype = type;
|
||||
|
||||
/* mark the connection as RECV paused */
|
||||
k->keepon |= KEEP_RECV_PAUSE;
|
||||
|
||||
DEBUGF(infof(data, "Pausing with %zu bytes in buffer for type %02x\n",
|
||||
len, type));
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Curl_client_chop_write() writes chunks of data not larger than
|
||||
* CURL_MAX_WRITE_SIZE via client write callback(s) and
|
||||
* takes care of pause requests from the callbacks.
|
||||
*/
|
||||
CURLcode Curl_client_chop_write(struct connectdata *conn,
|
||||
int type,
|
||||
char *ptr,
|
||||
size_t len)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
curl_write_callback writeheader = NULL;
|
||||
curl_write_callback writebody = NULL;
|
||||
|
||||
if(!len)
|
||||
return CURLE_OK;
|
||||
|
||||
/* If reading is actually paused, we're forced to append this chunk of data
|
||||
to the already held data, but only if it is the same type as otherwise it
|
||||
can't work and it'll return error instead. */
|
||||
if(data->req.keepon & KEEP_RECV_PAUSE) {
|
||||
size_t newlen;
|
||||
char *newptr;
|
||||
if(type != data->state.tempwritetype)
|
||||
/* major internal confusion */
|
||||
return CURLE_RECV_ERROR;
|
||||
|
||||
DEBUGASSERT(data->state.tempwrite);
|
||||
|
||||
/* figure out the new size of the data to save */
|
||||
newlen = len + data->state.tempwritesize;
|
||||
/* allocate the new memory area */
|
||||
newptr = realloc(data->state.tempwrite, newlen);
|
||||
if(!newptr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
/* copy the new data to the end of the new area */
|
||||
memcpy(newptr + data->state.tempwritesize, ptr, len);
|
||||
/* update the pointer and the size */
|
||||
data->state.tempwrite = newptr;
|
||||
data->state.tempwritesize = newlen;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* Determine the callback(s) to use. */
|
||||
if(type & CLIENTWRITE_BODY)
|
||||
writebody = data->set.fwrite_func;
|
||||
if((type & CLIENTWRITE_HEADER) &&
|
||||
(data->set.fwrite_header || data->set.writeheader)) {
|
||||
/*
|
||||
* Write headers to the same callback or to the especially setup
|
||||
* header callback function (added after version 7.7.1).
|
||||
*/
|
||||
writeheader =
|
||||
data->set.fwrite_header? data->set.fwrite_header: data->set.fwrite_func;
|
||||
}
|
||||
|
||||
/* Chop data, write chunks. */
|
||||
while(len) {
|
||||
size_t chunklen = len <= CURL_MAX_WRITE_SIZE? len: CURL_MAX_WRITE_SIZE;
|
||||
|
||||
if(writebody) {
|
||||
size_t wrote = writebody(ptr, 1, chunklen, data->set.out);
|
||||
|
||||
if(CURL_WRITEFUNC_PAUSE == wrote) {
|
||||
if(conn->handler->flags & PROTOPT_NONETWORK) {
|
||||
/* Protocols that work without network cannot be paused. This is
|
||||
actually only FILE:// just now, and it can't pause since the
|
||||
transfer isn't done using the "normal" procedure. */
|
||||
failf(data, "Write callback asked for PAUSE when not supported!");
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
else
|
||||
return pausewrite(data, type, ptr, len);
|
||||
}
|
||||
else if(wrote != chunklen) {
|
||||
failf(data, "Failed writing body (%zu != %zu)", wrote, chunklen);
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if(writeheader) {
|
||||
size_t wrote = writeheader(ptr, 1, chunklen, data->set.writeheader);
|
||||
|
||||
if(CURL_WRITEFUNC_PAUSE == wrote)
|
||||
/* here we pass in the HEADER bit only since if this was body as well
|
||||
then it was passed already and clearly that didn't trigger the
|
||||
pause, so this is saved for later with the HEADER bit only */
|
||||
return pausewrite(data, CLIENTWRITE_HEADER, ptr, len);
|
||||
|
||||
if(wrote != chunklen) {
|
||||
failf(data, "Failed writing header");
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ptr += chunklen;
|
||||
len -= chunklen;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Curl_client_write() sends data to the write callback(s)
|
||||
|
||||
The bit pattern defines to what "streams" to write to. Body and/or header.
|
||||
The defines are in sendf.h of course.
|
||||
|
||||
If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the
|
||||
local character encoding. This is a problem and should be changed in
|
||||
the future to leave the original data alone.
|
||||
*/
|
||||
CURLcode Curl_client_write(struct connectdata *conn,
|
||||
int type,
|
||||
char *ptr,
|
||||
size_t len)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
if(0 == len)
|
||||
len = strlen(ptr);
|
||||
|
||||
/* FTP data may need conversion. */
|
||||
if((type & CLIENTWRITE_BODY) &&
|
||||
(conn->handler->protocol & PROTO_FAMILY_FTP) &&
|
||||
conn->proto.ftpc.transfertype == 'A') {
|
||||
/* convert from the network encoding */
|
||||
CURLcode result = Curl_convert_from_network(data, ptr, len);
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
#ifdef CURL_DO_LINEEND_CONV
|
||||
/* convert end-of-line markers */
|
||||
len = convert_lineends(data, ptr, len);
|
||||
#endif /* CURL_DO_LINEEND_CONV */
|
||||
}
|
||||
|
||||
return Curl_client_chop_write(conn, type, ptr, len);
|
||||
}
|
||||
|
||||
CURLcode Curl_read_plain(curl_socket_t sockfd,
|
||||
char *buf,
|
||||
size_t bytesfromsocket,
|
||||
ssize_t *n)
|
||||
{
|
||||
ssize_t nread = sread(sockfd, buf, bytesfromsocket);
|
||||
|
||||
if(-1 == nread) {
|
||||
int err = SOCKERRNO;
|
||||
int return_error;
|
||||
#ifdef USE_WINSOCK
|
||||
return_error = WSAEWOULDBLOCK == err;
|
||||
#else
|
||||
return_error = EWOULDBLOCK == err || EAGAIN == err || EINTR == err;
|
||||
#endif
|
||||
if(return_error)
|
||||
return CURLE_AGAIN;
|
||||
else
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
/* we only return number of bytes read when we return OK */
|
||||
*n = nread;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal read-from-socket function. This is meant to deal with plain
|
||||
* sockets, SSL sockets and kerberos sockets.
|
||||
*
|
||||
* Returns a regular CURLcode value.
|
||||
*/
|
||||
CURLcode Curl_read(struct connectdata *conn, /* connection data */
|
||||
curl_socket_t sockfd, /* read from this socket */
|
||||
char *buf, /* store read data here */
|
||||
size_t sizerequested, /* max amount to read */
|
||||
ssize_t *n) /* amount bytes read */
|
||||
{
|
||||
CURLcode result = CURLE_RECV_ERROR;
|
||||
ssize_t nread = 0;
|
||||
size_t bytesfromsocket = 0;
|
||||
char *buffertofill = NULL;
|
||||
|
||||
/* if HTTP/1 pipelining is both wanted and possible */
|
||||
bool pipelining = Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1) &&
|
||||
(conn->bundle->multiuse == BUNDLE_PIPELINING);
|
||||
|
||||
/* Set 'num' to 0 or 1, depending on which socket that has been sent here.
|
||||
If it is the second socket, we set num to 1. Otherwise to 0. This lets
|
||||
us use the correct ssl handle. */
|
||||
int num = (sockfd == conn->sock[SECONDARYSOCKET]);
|
||||
|
||||
*n=0; /* reset amount to zero */
|
||||
|
||||
/* If session can pipeline, check connection buffer */
|
||||
if(pipelining) {
|
||||
size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos,
|
||||
sizerequested);
|
||||
|
||||
/* Copy from our master buffer first if we have some unread data there*/
|
||||
if(bytestocopy > 0) {
|
||||
memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
|
||||
conn->read_pos += bytestocopy;
|
||||
conn->bits.stream_was_rewound = FALSE;
|
||||
|
||||
*n = (ssize_t)bytestocopy;
|
||||
return CURLE_OK;
|
||||
}
|
||||
/* If we come here, it means that there is no data to read from the buffer,
|
||||
* so we read from the socket */
|
||||
bytesfromsocket = CURLMIN(sizerequested, BUFSIZE * sizeof(char));
|
||||
buffertofill = conn->master_buffer;
|
||||
}
|
||||
else {
|
||||
bytesfromsocket = CURLMIN((long)sizerequested,
|
||||
conn->data->set.buffer_size ?
|
||||
conn->data->set.buffer_size : BUFSIZE);
|
||||
buffertofill = buf;
|
||||
}
|
||||
|
||||
nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &result);
|
||||
if(nread < 0)
|
||||
return result;
|
||||
|
||||
if(pipelining) {
|
||||
memcpy(buf, conn->master_buffer, nread);
|
||||
conn->buf_len = nread;
|
||||
conn->read_pos = nread;
|
||||
}
|
||||
|
||||
*n += nread;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* return 0 on success */
|
||||
static int showit(struct Curl_easy *data, curl_infotype type,
|
||||
char *ptr, size_t size)
|
||||
{
|
||||
static const char s_infotype[CURLINFO_END][3] = {
|
||||
"* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
char buf[BUFSIZE+1];
|
||||
size_t conv_size = 0;
|
||||
|
||||
switch(type) {
|
||||
case CURLINFO_HEADER_OUT:
|
||||
/* assume output headers are ASCII */
|
||||
/* copy the data into my buffer so the original is unchanged */
|
||||
if(size > BUFSIZE) {
|
||||
size = BUFSIZE; /* truncate if necessary */
|
||||
buf[BUFSIZE] = '\0';
|
||||
}
|
||||
conv_size = size;
|
||||
memcpy(buf, ptr, size);
|
||||
/* Special processing is needed for this block if it
|
||||
* contains both headers and data (separated by CRLFCRLF).
|
||||
* We want to convert just the headers, leaving the data as-is.
|
||||
*/
|
||||
if(size > 4) {
|
||||
size_t i;
|
||||
for(i = 0; i < size-4; i++) {
|
||||
if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
|
||||
/* convert everything through this CRLFCRLF but no further */
|
||||
conv_size = i + 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Curl_convert_from_network(data, buf, conv_size);
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
/* we might as well continue even if it fails... */
|
||||
ptr = buf; /* switch pointer to use my buffer instead */
|
||||
break;
|
||||
default:
|
||||
/* leave everything else as-is */
|
||||
break;
|
||||
}
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
if(data->set.fdebug)
|
||||
return (*data->set.fdebug)(data, type, ptr, size,
|
||||
data->set.debugdata);
|
||||
|
||||
switch(type) {
|
||||
case CURLINFO_TEXT:
|
||||
case CURLINFO_HEADER_OUT:
|
||||
case CURLINFO_HEADER_IN:
|
||||
fwrite(s_infotype[type], 2, 1, data->set.err);
|
||||
fwrite(ptr, size, 1, data->set.err);
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
if(size != conv_size) {
|
||||
/* we had untranslated data so we need an explicit newline */
|
||||
fwrite("\n", 1, 1, data->set.err);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default: /* nada */
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Curl_debug(struct Curl_easy *data, curl_infotype type,
|
||||
char *ptr, size_t size,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
int rc;
|
||||
if(data->set.printhost && conn && conn->host.dispname) {
|
||||
char buffer[160];
|
||||
const char *t=NULL;
|
||||
const char *w="Data";
|
||||
switch(type) {
|
||||
case CURLINFO_HEADER_IN:
|
||||
w = "Header";
|
||||
/* FALLTHROUGH */
|
||||
case CURLINFO_DATA_IN:
|
||||
t = "from";
|
||||
break;
|
||||
case CURLINFO_HEADER_OUT:
|
||||
w = "Header";
|
||||
/* FALLTHROUGH */
|
||||
case CURLINFO_DATA_OUT:
|
||||
t = "to";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(t) {
|
||||
snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t,
|
||||
conn->host.dispname);
|
||||
rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
|
||||
if(rc)
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
rc = showit(data, type, ptr, size);
|
||||
return rc;
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
#ifndef HEADER_CURL_SENDF_H
|
||||
#define HEADER_CURL_SENDF_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *,
|
||||
const char *fmt, ...);
|
||||
void Curl_infof(struct Curl_easy *, const char *fmt, ...);
|
||||
void Curl_failf(struct Curl_easy *, const char *fmt, ...);
|
||||
|
||||
#if defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
|
||||
#if defined(HAVE_VARIADIC_MACROS_C99)
|
||||
#define infof(...) Curl_nop_stmt
|
||||
#elif defined(HAVE_VARIADIC_MACROS_GCC)
|
||||
#define infof(x...) Curl_nop_stmt
|
||||
#else
|
||||
#define infof (void)
|
||||
#endif
|
||||
|
||||
#else /* CURL_DISABLE_VERBOSE_STRINGS */
|
||||
|
||||
#define infof Curl_infof
|
||||
|
||||
#endif /* CURL_DISABLE_VERBOSE_STRINGS */
|
||||
|
||||
#define failf Curl_failf
|
||||
|
||||
#define CLIENTWRITE_BODY (1<<0)
|
||||
#define CLIENTWRITE_HEADER (1<<1)
|
||||
#define CLIENTWRITE_BOTH (CLIENTWRITE_BODY|CLIENTWRITE_HEADER)
|
||||
|
||||
CURLcode Curl_client_chop_write(struct connectdata *conn, int type, char *ptr,
|
||||
size_t len) WARN_UNUSED_RESULT;
|
||||
CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr,
|
||||
size_t len) WARN_UNUSED_RESULT;
|
||||
|
||||
bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex);
|
||||
|
||||
/* internal read-function, does plain socket only */
|
||||
CURLcode Curl_read_plain(curl_socket_t sockfd,
|
||||
char *buf,
|
||||
size_t bytesfromsocket,
|
||||
ssize_t *n);
|
||||
|
||||
ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
|
||||
size_t len, CURLcode *code);
|
||||
ssize_t Curl_send_plain(struct connectdata *conn, int num,
|
||||
const void *mem, size_t len, CURLcode *code);
|
||||
|
||||
/* internal read-function, does plain socket, SSL and krb4 */
|
||||
CURLcode Curl_read(struct connectdata *conn, curl_socket_t sockfd,
|
||||
char *buf, size_t buffersize,
|
||||
ssize_t *n);
|
||||
/* internal write-function, does plain socket, SSL, SCP, SFTP and krb4 */
|
||||
CURLcode Curl_write(struct connectdata *conn,
|
||||
curl_socket_t sockfd,
|
||||
const void *mem, size_t len,
|
||||
ssize_t *written);
|
||||
|
||||
/* internal write-function, does plain sockets ONLY */
|
||||
CURLcode Curl_write_plain(struct connectdata *conn,
|
||||
curl_socket_t sockfd,
|
||||
const void *mem, size_t len,
|
||||
ssize_t *written);
|
||||
|
||||
/* the function used to output verbose information */
|
||||
int Curl_debug(struct Curl_easy *handle, curl_infotype type,
|
||||
char *data, size_t size,
|
||||
struct connectdata *conn);
|
||||
|
||||
|
||||
#endif /* HEADER_CURL_SENDF_H */
|
||||
@@ -1,223 +0,0 @@
|
||||
#ifndef HEADER_CURL_SETUP_OS400_H
|
||||
#define HEADER_CURL_SETUP_OS400_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/* OS/400 netdb.h does not define NI_MAXHOST. */
|
||||
#define NI_MAXHOST 1025
|
||||
|
||||
/* OS/400 netdb.h does not define NI_MAXSERV. */
|
||||
#define NI_MAXSERV 32
|
||||
|
||||
/* No OS/400 header file defines u_int32_t. */
|
||||
typedef unsigned long u_int32_t;
|
||||
|
||||
|
||||
/* System API wrapper prototypes & definitions to support ASCII parameters. */
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <gskssl.h>
|
||||
#include <qsoasync.h>
|
||||
#include <gssapi.h>
|
||||
|
||||
extern int Curl_getaddrinfo_a(const char *nodename,
|
||||
const char *servname,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res);
|
||||
#define getaddrinfo Curl_getaddrinfo_a
|
||||
|
||||
|
||||
extern int Curl_getnameinfo_a(const struct sockaddr *sa,
|
||||
curl_socklen_t salen,
|
||||
char *nodename, curl_socklen_t nodenamelen,
|
||||
char *servname, curl_socklen_t servnamelen,
|
||||
int flags);
|
||||
#define getnameinfo Curl_getnameinfo_a
|
||||
|
||||
|
||||
/* GSKit wrappers. */
|
||||
|
||||
extern int Curl_gsk_environment_open(gsk_handle * my_env_handle);
|
||||
#define gsk_environment_open Curl_gsk_environment_open
|
||||
|
||||
extern int Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
|
||||
gsk_handle * my_session_handle);
|
||||
#define gsk_secure_soc_open Curl_gsk_secure_soc_open
|
||||
|
||||
extern int Curl_gsk_environment_close(gsk_handle * my_env_handle);
|
||||
#define gsk_environment_close Curl_gsk_environment_close
|
||||
|
||||
extern int Curl_gsk_secure_soc_close(gsk_handle * my_session_handle);
|
||||
#define gsk_secure_soc_close Curl_gsk_secure_soc_close
|
||||
|
||||
extern int Curl_gsk_environment_init(gsk_handle my_env_handle);
|
||||
#define gsk_environment_init Curl_gsk_environment_init
|
||||
|
||||
extern int Curl_gsk_secure_soc_init(gsk_handle my_session_handle);
|
||||
#define gsk_secure_soc_init Curl_gsk_secure_soc_init
|
||||
|
||||
extern int Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle,
|
||||
GSK_BUF_ID bufID,
|
||||
const char *buffer,
|
||||
int bufSize);
|
||||
#define gsk_attribute_set_buffer Curl_gsk_attribute_set_buffer_a
|
||||
|
||||
extern int Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle,
|
||||
GSK_ENUM_ID enumID,
|
||||
GSK_ENUM_VALUE enumValue);
|
||||
#define gsk_attribute_set_enum Curl_gsk_attribute_set_enum
|
||||
|
||||
extern int Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
|
||||
GSK_NUM_ID numID,
|
||||
int numValue);
|
||||
#define gsk_attribute_set_numeric_value Curl_gsk_attribute_set_numeric_value
|
||||
|
||||
extern int Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
|
||||
GSK_CALLBACK_ID callBackID,
|
||||
void *callBackAreaPtr);
|
||||
#define gsk_attribute_set_callback Curl_gsk_attribute_set_callback
|
||||
|
||||
extern int Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle,
|
||||
GSK_BUF_ID bufID,
|
||||
const char **buffer,
|
||||
int *bufSize);
|
||||
#define gsk_attribute_get_buffer Curl_gsk_attribute_get_buffer_a
|
||||
|
||||
extern int Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle,
|
||||
GSK_ENUM_ID enumID,
|
||||
GSK_ENUM_VALUE *enumValue);
|
||||
#define gsk_attribute_get_enum Curl_gsk_attribute_get_enum
|
||||
|
||||
extern int Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
|
||||
GSK_NUM_ID numID,
|
||||
int *numValue);
|
||||
#define gsk_attribute_get_numeric_value Curl_gsk_attribute_get_numeric_value
|
||||
|
||||
extern int Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
|
||||
GSK_CERT_ID certID,
|
||||
const gsk_cert_data_elem **certDataElem,
|
||||
int *certDataElementCount);
|
||||
#define gsk_attribute_get_cert_info Curl_gsk_attribute_get_cert_info
|
||||
|
||||
extern int Curl_gsk_secure_soc_misc(gsk_handle my_session_handle,
|
||||
GSK_MISC_ID miscID);
|
||||
#define gsk_secure_soc_misc Curl_gsk_secure_soc_misc
|
||||
|
||||
extern int Curl_gsk_secure_soc_read(gsk_handle my_session_handle,
|
||||
char *readBuffer,
|
||||
int readBufSize, int *amtRead);
|
||||
#define gsk_secure_soc_read Curl_gsk_secure_soc_read
|
||||
|
||||
extern int Curl_gsk_secure_soc_write(gsk_handle my_session_handle,
|
||||
char *writeBuffer,
|
||||
int writeBufSize, int *amtWritten);
|
||||
#define gsk_secure_soc_write Curl_gsk_secure_soc_write
|
||||
|
||||
extern const char * Curl_gsk_strerror_a(int gsk_return_value);
|
||||
#define gsk_strerror Curl_gsk_strerror_a
|
||||
|
||||
extern int Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
|
||||
int IOCompletionPort,
|
||||
Qso_OverlappedIO_t * communicationsArea);
|
||||
#define gsk_secure_soc_startInit Curl_gsk_secure_soc_startInit
|
||||
|
||||
|
||||
/* GSSAPI wrappers. */
|
||||
|
||||
extern OM_uint32 Curl_gss_import_name_a(OM_uint32 * minor_status,
|
||||
gss_buffer_t in_name,
|
||||
gss_OID in_name_type,
|
||||
gss_name_t * out_name);
|
||||
#define gss_import_name Curl_gss_import_name_a
|
||||
|
||||
|
||||
extern OM_uint32 Curl_gss_display_status_a(OM_uint32 * minor_status,
|
||||
OM_uint32 status_value,
|
||||
int status_type, gss_OID mech_type,
|
||||
gss_msg_ctx_t * message_context,
|
||||
gss_buffer_t status_string);
|
||||
#define gss_display_status Curl_gss_display_status_a
|
||||
|
||||
|
||||
extern OM_uint32 Curl_gss_init_sec_context_a(OM_uint32 * minor_status,
|
||||
gss_cred_id_t cred_handle,
|
||||
gss_ctx_id_t * context_handle,
|
||||
gss_name_t target_name,
|
||||
gss_OID mech_type,
|
||||
gss_flags_t req_flags,
|
||||
OM_uint32 time_req,
|
||||
gss_channel_bindings_t
|
||||
input_chan_bindings,
|
||||
gss_buffer_t input_token,
|
||||
gss_OID * actual_mech_type,
|
||||
gss_buffer_t output_token,
|
||||
gss_flags_t * ret_flags,
|
||||
OM_uint32 * time_rec);
|
||||
#define gss_init_sec_context Curl_gss_init_sec_context_a
|
||||
|
||||
|
||||
extern OM_uint32 Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
|
||||
gss_ctx_id_t * context_handle,
|
||||
gss_buffer_t output_token);
|
||||
#define gss_delete_sec_context Curl_gss_delete_sec_context_a
|
||||
|
||||
|
||||
/* LDAP wrappers. */
|
||||
|
||||
#define BerValue struct berval
|
||||
|
||||
#define ldap_url_parse ldap_url_parse_utf8
|
||||
#define ldap_init Curl_ldap_init_a
|
||||
#define ldap_simple_bind_s Curl_ldap_simple_bind_s_a
|
||||
#define ldap_search_s Curl_ldap_search_s_a
|
||||
#define ldap_get_values_len Curl_ldap_get_values_len_a
|
||||
#define ldap_err2string Curl_ldap_err2string_a
|
||||
#define ldap_get_dn Curl_ldap_get_dn_a
|
||||
#define ldap_first_attribute Curl_ldap_first_attribute_a
|
||||
#define ldap_next_attribute Curl_ldap_next_attribute_a
|
||||
|
||||
/* Some socket functions must be wrapped to process textual addresses
|
||||
like AF_UNIX. */
|
||||
|
||||
extern int Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen);
|
||||
extern int Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen);
|
||||
extern int Curl_os400_sendto(int sd, char *buffer, int buflen, int flags,
|
||||
struct sockaddr * dstaddr, int addrlen);
|
||||
extern int Curl_os400_recvfrom(int sd, char *buffer, int buflen, int flags,
|
||||
struct sockaddr *fromaddr, int *addrlen);
|
||||
|
||||
#define connect Curl_os400_connect
|
||||
#define bind Curl_os400_bind
|
||||
#define sendto Curl_os400_sendto
|
||||
#define recvfrom Curl_os400_recvfrom
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
#define zlibVersion Curl_os400_zlibVersion
|
||||
#define inflateInit_ Curl_os400_inflateInit_
|
||||
#define inflateInit2_ Curl_os400_inflateInit2_
|
||||
#define inflate Curl_os400_inflate
|
||||
#define inflateEnd Curl_os400_inflateEnd
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_SETUP_OS400_H */
|
||||
@@ -1,443 +0,0 @@
|
||||
#ifndef HEADER_CURL_SETUP_VMS_H
|
||||
#define HEADER_CURL_SETUP_VMS_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* */
|
||||
/* JEM, 12/30/12, VMS now generates config.h, so only define wrappers for */
|
||||
/* getenv(), getpwuid() and provide is_vms_shell() */
|
||||
/* Also need upper case symbols for system services, and */
|
||||
/* OpenSSL, and some Kerberos image */
|
||||
|
||||
#ifdef __DECC
|
||||
#pragma message save
|
||||
#pragma message disable dollarid
|
||||
#endif
|
||||
|
||||
/* Hide the stuff we are overriding */
|
||||
#define getenv decc_getenv
|
||||
#ifdef __DECC
|
||||
# if __INITIAL_POINTER_SIZE != 64
|
||||
# define getpwuid decc_getpwuid
|
||||
# endif
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
char *decc$getenv(const char *__name);
|
||||
#include <pwd.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unixlib.h>
|
||||
|
||||
#undef getenv
|
||||
#undef getpwuid
|
||||
#define getenv vms_getenv
|
||||
#define getpwuid vms_getpwuid
|
||||
|
||||
/* VAX needs these in upper case when compiling exact case */
|
||||
#define sys$assign SYS$ASSIGN
|
||||
#define sys$dassgn SYS$DASSGN
|
||||
#define sys$qiow SYS$QIOW
|
||||
|
||||
#ifdef __DECC
|
||||
# if __INITIAL_POINTER_SIZE
|
||||
# pragma __pointer_size __save
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if __USE_LONG_GID_T
|
||||
# define decc_getpwuid DECC$__LONG_GID_GETPWUID
|
||||
#else
|
||||
# if __INITIAL_POINTER_SIZE
|
||||
# define decc_getpwuid decc$__32_getpwuid
|
||||
# else
|
||||
# define decc_getpwuid decc$getpwuid
|
||||
# endif
|
||||
#endif
|
||||
|
||||
struct passwd * decc_getpwuid(uid_t uid);
|
||||
|
||||
#ifdef __DECC
|
||||
# if __INITIAL_POINTER_SIZE == 32
|
||||
/* Translate the path, but only if the path is a VMS file specification */
|
||||
/* The translation is usually only needed for older versions of VMS */
|
||||
static char *vms_translate_path(const char *path)
|
||||
{
|
||||
char *unix_path;
|
||||
char *test_str;
|
||||
|
||||
/* See if the result is in VMS format, if not, we are done */
|
||||
/* Assume that this is a PATH, not just some data */
|
||||
test_str = strpbrk(path, ":[<^");
|
||||
if(test_str == NULL) {
|
||||
return (char *)path;
|
||||
}
|
||||
|
||||
unix_path = decc$translate_vms(path);
|
||||
|
||||
if((int)unix_path <= 0) {
|
||||
/* We can not translate it, so return the original string */
|
||||
return (char *)path;
|
||||
}
|
||||
}
|
||||
# else
|
||||
/* VMS translate path is actually not needed on the current 64 bit */
|
||||
/* VMS platforms, so instead of figuring out the pointer settings */
|
||||
/* Change it to a noop */
|
||||
# define vms_translate_path(__path) __path
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __DECC
|
||||
# if __INITIAL_POINTER_SIZE
|
||||
# pragma __pointer_size __restore
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static char *vms_getenv(const char *envvar)
|
||||
{
|
||||
char *result;
|
||||
char *vms_path;
|
||||
|
||||
/* first use the DECC getenv() function */
|
||||
result = decc$getenv(envvar);
|
||||
if(result == NULL) {
|
||||
return result;
|
||||
}
|
||||
|
||||
vms_path = result;
|
||||
result = vms_translate_path(vms_path);
|
||||
|
||||
/* note that if you backport this to use VAX C RTL, that the VAX C RTL */
|
||||
/* may do a malloc(2048) for each call to getenv(), so you will need */
|
||||
/* to add a free(vms_path) */
|
||||
/* Do not do a free() for DEC C RTL builds, which should be used for */
|
||||
/* VMS 5.5-2 and later, even if using GCC */
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static struct passwd vms_passwd_cache;
|
||||
|
||||
static struct passwd * vms_getpwuid(uid_t uid)
|
||||
{
|
||||
struct passwd * my_passwd;
|
||||
|
||||
/* Hack needed to support 64 bit builds, decc_getpwnam is 32 bit only */
|
||||
#ifdef __DECC
|
||||
# if __INITIAL_POINTER_SIZE
|
||||
__char_ptr32 unix_path;
|
||||
# else
|
||||
char *unix_path;
|
||||
# endif
|
||||
#else
|
||||
char *unix_path;
|
||||
#endif
|
||||
|
||||
my_passwd = decc_getpwuid(uid);
|
||||
if(my_passwd == NULL) {
|
||||
return my_passwd;
|
||||
}
|
||||
|
||||
unix_path = vms_translate_path(my_passwd->pw_dir);
|
||||
|
||||
if((long)unix_path <= 0) {
|
||||
/* We can not translate it, so return the original string */
|
||||
return my_passwd;
|
||||
}
|
||||
|
||||
/* If no changes needed just return it */
|
||||
if(unix_path == my_passwd->pw_dir) {
|
||||
return my_passwd;
|
||||
}
|
||||
|
||||
/* Need to copy the structure returned */
|
||||
/* Since curl is only using pw_dir, no need to fix up */
|
||||
/* the pw_shell when running under Bash */
|
||||
vms_passwd_cache.pw_name = my_passwd->pw_name;
|
||||
vms_passwd_cache.pw_uid = my_passwd->pw_uid;
|
||||
vms_passwd_cache.pw_gid = my_passwd->pw_uid;
|
||||
vms_passwd_cache.pw_dir = unix_path;
|
||||
vms_passwd_cache.pw_shell = my_passwd->pw_shell;
|
||||
|
||||
return &vms_passwd_cache;
|
||||
}
|
||||
|
||||
#ifdef __DECC
|
||||
#pragma message restore
|
||||
#endif
|
||||
|
||||
/* Bug - VMS OpenSSL and Kerberos universal symbols are in uppercase only */
|
||||
/* VMS libraries should have universal symbols in exact and uppercase */
|
||||
|
||||
#define ASN1_INTEGER_get ASN1_INTEGER_GET
|
||||
#define ASN1_STRING_data ASN1_STRING_DATA
|
||||
#define ASN1_STRING_length ASN1_STRING_LENGTH
|
||||
#define ASN1_STRING_print ASN1_STRING_PRINT
|
||||
#define ASN1_STRING_to_UTF8 ASN1_STRING_TO_UTF8
|
||||
#define ASN1_STRING_type ASN1_STRING_TYPE
|
||||
#define BIO_ctrl BIO_CTRL
|
||||
#define BIO_free BIO_FREE
|
||||
#define BIO_new BIO_NEW
|
||||
#define BIO_s_mem BIO_S_MEM
|
||||
#define BN_bn2bin BN_BN2BIN
|
||||
#define BN_num_bits BN_NUM_BITS
|
||||
#define CRYPTO_cleanup_all_ex_data CRYPTO_CLEANUP_ALL_EX_DATA
|
||||
#define CRYPTO_free CRYPTO_FREE
|
||||
#define CRYPTO_malloc CRYPTO_MALLOC
|
||||
#define CONF_modules_load_file CONF_MODULES_LOAD_FILE
|
||||
#ifdef __VAX
|
||||
# ifdef VMS_OLD_SSL
|
||||
/* Ancient OpenSSL on VAX/VMS missing this constant */
|
||||
# define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10
|
||||
# undef CONF_modules_load_file
|
||||
static int CONF_modules_load_file(const char *filename,
|
||||
const char *appname,
|
||||
unsigned long flags) {
|
||||
return 1;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
#define DES_ecb_encrypt DES_ECB_ENCRYPT
|
||||
#define DES_set_key DES_SET_KEY
|
||||
#define DES_set_odd_parity DES_SET_ODD_PARITY
|
||||
#define ENGINE_ctrl ENGINE_CTRL
|
||||
#define ENGINE_ctrl_cmd ENGINE_CTRL_CMD
|
||||
#define ENGINE_finish ENGINE_FINISH
|
||||
#define ENGINE_free ENGINE_FREE
|
||||
#define ENGINE_get_first ENGINE_GET_FIRST
|
||||
#define ENGINE_get_id ENGINE_GET_ID
|
||||
#define ENGINE_get_next ENGINE_GET_NEXT
|
||||
#define ENGINE_init ENGINE_INIT
|
||||
#define ENGINE_load_builtin_engines ENGINE_LOAD_BUILTIN_ENGINES
|
||||
#define ENGINE_load_private_key ENGINE_LOAD_PRIVATE_KEY
|
||||
#define ENGINE_set_default ENGINE_SET_DEFAULT
|
||||
#define ERR_clear_error ERR_CLEAR_ERROR
|
||||
#define ERR_error_string ERR_ERROR_STRING
|
||||
#define ERR_error_string_n ERR_ERROR_STRING_N
|
||||
#define ERR_free_strings ERR_FREE_STRINGS
|
||||
#define ERR_get_error ERR_GET_ERROR
|
||||
#define ERR_peek_error ERR_PEEK_ERROR
|
||||
#define ERR_remove_state ERR_REMOVE_STATE
|
||||
#define EVP_PKEY_copy_parameters EVP_PKEY_COPY_PARAMETERS
|
||||
#define EVP_PKEY_free EVP_PKEY_FREE
|
||||
#define EVP_cleanup EVP_CLEANUP
|
||||
#define GENERAL_NAMES_free GENERAL_NAMES_FREE
|
||||
#define i2d_X509_PUBKEY I2D_X509_PUBKEY
|
||||
#define MD4_Final MD4_FINAL
|
||||
#define MD4_Init MD4_INIT
|
||||
#define MD4_Update MD4_UPDATE
|
||||
#define MD5_Final MD5_FINAL
|
||||
#define MD5_Init MD5_INIT
|
||||
#define MD5_Update MD5_UPDATE
|
||||
#define OPENSSL_add_all_algo_noconf OPENSSL_ADD_ALL_ALGO_NOCONF
|
||||
#ifndef __VAX
|
||||
#define OPENSSL_load_builtin_modules OPENSSL_LOAD_BUILTIN_MODULES
|
||||
#endif
|
||||
#define PEM_read_X509 PEM_READ_X509
|
||||
#define PEM_write_bio_X509 PEM_WRITE_BIO_X509
|
||||
#define PKCS12_PBE_add PKCS12_PBE_ADD
|
||||
#define PKCS12_free PKCS12_FREE
|
||||
#define PKCS12_parse PKCS12_PARSE
|
||||
#define RAND_add RAND_ADD
|
||||
#define RAND_bytes RAND_BYTES
|
||||
#define RAND_egd RAND_EGD
|
||||
#define RAND_file_name RAND_FILE_NAME
|
||||
#define RAND_load_file RAND_LOAD_FILE
|
||||
#define RAND_status RAND_STATUS
|
||||
#define SSL_CIPHER_get_name SSL_CIPHER_GET_NAME
|
||||
#define SSL_CTX_add_client_CA SSL_CTX_ADD_CLIENT_CA
|
||||
#define SSL_CTX_callback_ctrl SSL_CTX_CALLBACK_CTRL
|
||||
#define SSL_CTX_check_private_key SSL_CTX_CHECK_PRIVATE_KEY
|
||||
#define SSL_CTX_ctrl SSL_CTX_CTRL
|
||||
#define SSL_CTX_free SSL_CTX_FREE
|
||||
#define SSL_CTX_get_cert_store SSL_CTX_GET_CERT_STORE
|
||||
#define SSL_CTX_load_verify_locations SSL_CTX_LOAD_VERIFY_LOCATIONS
|
||||
#define SSL_CTX_new SSL_CTX_NEW
|
||||
#define SSL_CTX_set_cipher_list SSL_CTX_SET_CIPHER_LIST
|
||||
#define SSL_CTX_set_def_passwd_cb_ud SSL_CTX_SET_DEF_PASSWD_CB_UD
|
||||
#define SSL_CTX_set_default_passwd_cb SSL_CTX_SET_DEFAULT_PASSWD_CB
|
||||
#define SSL_CTX_set_msg_callback SSL_CTX_SET_MSG_CALLBACK
|
||||
#define SSL_CTX_set_verify SSL_CTX_SET_VERIFY
|
||||
#define SSL_CTX_use_PrivateKey SSL_CTX_USE_PRIVATEKEY
|
||||
#define SSL_CTX_use_PrivateKey_file SSL_CTX_USE_PRIVATEKEY_FILE
|
||||
#define SSL_CTX_use_cert_chain_file SSL_CTX_USE_CERT_CHAIN_FILE
|
||||
#define SSL_CTX_use_certificate SSL_CTX_USE_CERTIFICATE
|
||||
#define SSL_CTX_use_certificate_file SSL_CTX_USE_CERTIFICATE_FILE
|
||||
#define SSL_SESSION_free SSL_SESSION_FREE
|
||||
#define SSL_connect SSL_CONNECT
|
||||
#define SSL_free SSL_FREE
|
||||
#define SSL_get1_session SSL_GET1_SESSION
|
||||
#define SSL_get_certificate SSL_GET_CERTIFICATE
|
||||
#define SSL_get_current_cipher SSL_GET_CURRENT_CIPHER
|
||||
#define SSL_get_error SSL_GET_ERROR
|
||||
#define SSL_get_peer_cert_chain SSL_GET_PEER_CERT_CHAIN
|
||||
#define SSL_get_peer_certificate SSL_GET_PEER_CERTIFICATE
|
||||
#define SSL_get_privatekey SSL_GET_PRIVATEKEY
|
||||
#define SSL_get_session SSL_GET_SESSION
|
||||
#define SSL_get_shutdown SSL_GET_SHUTDOWN
|
||||
#define SSL_get_verify_result SSL_GET_VERIFY_RESULT
|
||||
#define SSL_library_init SSL_LIBRARY_INIT
|
||||
#define SSL_load_error_strings SSL_LOAD_ERROR_STRINGS
|
||||
#define SSL_new SSL_NEW
|
||||
#define SSL_peek SSL_PEEK
|
||||
#define SSL_pending SSL_PENDING
|
||||
#define SSL_read SSL_READ
|
||||
#define SSL_set_connect_state SSL_SET_CONNECT_STATE
|
||||
#define SSL_set_fd SSL_SET_FD
|
||||
#define SSL_set_session SSL_SET_SESSION
|
||||
#define SSL_shutdown SSL_SHUTDOWN
|
||||
#define SSL_version SSL_VERSION
|
||||
#define SSL_write SSL_WRITE
|
||||
#define SSLeay SSLEAY
|
||||
#define SSLv23_client_method SSLV23_CLIENT_METHOD
|
||||
#define SSLv3_client_method SSLV3_CLIENT_METHOD
|
||||
#define TLSv1_client_method TLSV1_CLIENT_METHOD
|
||||
#define UI_create_method UI_CREATE_METHOD
|
||||
#define UI_destroy_method UI_DESTROY_METHOD
|
||||
#define UI_get0_user_data UI_GET0_USER_DATA
|
||||
#define UI_get_input_flags UI_GET_INPUT_FLAGS
|
||||
#define UI_get_string_type UI_GET_STRING_TYPE
|
||||
#define UI_create_method UI_CREATE_METHOD
|
||||
#define UI_destroy_method UI_DESTROY_METHOD
|
||||
#define UI_method_get_closer UI_METHOD_GET_CLOSER
|
||||
#define UI_method_get_opener UI_METHOD_GET_OPENER
|
||||
#define UI_method_get_reader UI_METHOD_GET_READER
|
||||
#define UI_method_get_writer UI_METHOD_GET_WRITER
|
||||
#define UI_method_set_closer UI_METHOD_SET_CLOSER
|
||||
#define UI_method_set_opener UI_METHOD_SET_OPENER
|
||||
#define UI_method_set_reader UI_METHOD_SET_READER
|
||||
#define UI_method_set_writer UI_METHOD_SET_WRITER
|
||||
#define UI_OpenSSL UI_OPENSSL
|
||||
#define UI_set_result UI_SET_RESULT
|
||||
#define X509V3_EXT_print X509V3_EXT_PRINT
|
||||
#define X509_EXTENSION_get_critical X509_EXTENSION_GET_CRITICAL
|
||||
#define X509_EXTENSION_get_data X509_EXTENSION_GET_DATA
|
||||
#define X509_EXTENSION_get_object X509_EXTENSION_GET_OBJECT
|
||||
#define X509_LOOKUP_file X509_LOOKUP_FILE
|
||||
#define X509_NAME_ENTRY_get_data X509_NAME_ENTRY_GET_DATA
|
||||
#define X509_NAME_get_entry X509_NAME_GET_ENTRY
|
||||
#define X509_NAME_get_index_by_NID X509_NAME_GET_INDEX_BY_NID
|
||||
#define X509_NAME_print_ex X509_NAME_PRINT_EX
|
||||
#define X509_STORE_CTX_get_current_cert X509_STORE_CTX_GET_CURRENT_CERT
|
||||
#define X509_STORE_add_lookup X509_STORE_ADD_LOOKUP
|
||||
#define X509_STORE_set_flags X509_STORE_SET_FLAGS
|
||||
#define X509_check_issued X509_CHECK_ISSUED
|
||||
#define X509_free X509_FREE
|
||||
#define X509_get_ext_d2i X509_GET_EXT_D2I
|
||||
#define X509_get_issuer_name X509_GET_ISSUER_NAME
|
||||
#define X509_get_pubkey X509_GET_PUBKEY
|
||||
#define X509_get_serialNumber X509_GET_SERIALNUMBER
|
||||
#define X509_get_subject_name X509_GET_SUBJECT_NAME
|
||||
#define X509_load_crl_file X509_LOAD_CRL_FILE
|
||||
#define X509_verify_cert_error_string X509_VERIFY_CERT_ERROR_STRING
|
||||
#define d2i_PKCS12_fp D2I_PKCS12_FP
|
||||
#define i2t_ASN1_OBJECT I2T_ASN1_OBJECT
|
||||
#define sk_num SK_NUM
|
||||
#define sk_pop SK_POP
|
||||
#define sk_pop_free SK_POP_FREE
|
||||
#define sk_value SK_VALUE
|
||||
#ifdef __VAX
|
||||
#define OPENSSL_NO_SHA256
|
||||
#endif
|
||||
#define SHA256_Final SHA256_FINAL
|
||||
#define SHA256_Init SHA256_INIT
|
||||
#define SHA256_Update SHA256_UPDATE
|
||||
|
||||
#define USE_UPPERCASE_GSSAPI 1
|
||||
#define gss_seal GSS_SEAL
|
||||
#define gss_unseal GSS_UNSEAL
|
||||
|
||||
#define USE_UPPERCASE_KRBAPI 1
|
||||
|
||||
/* AI_NUMERICHOST needed for IP V6 support in Curl */
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#ifndef AI_NUMERICHOST
|
||||
#ifdef ENABLE_IPV6
|
||||
#undef ENABLE_IPV6
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* VAX symbols are always in uppercase */
|
||||
#ifdef __VAX
|
||||
#define inflate INFLATE
|
||||
#define inflateEnd INFLATEEND
|
||||
#define inflateInit2_ INFLATEINIT2_
|
||||
#define inflateInit_ INFLATEINIT_
|
||||
#define zlibVersion ZLIBVERSION
|
||||
#endif
|
||||
|
||||
/* Older VAX OpenSSL port defines these as Macros */
|
||||
/* Need to include the headers first and then redefine */
|
||||
/* that way a newer port will also work if some one has one */
|
||||
#ifdef __VAX
|
||||
|
||||
# if (OPENSSL_VERSION_NUMBER < 0x00907001L)
|
||||
# define des_set_odd_parity DES_SET_ODD_PARITY
|
||||
# define des_set_key DES_SET_KEY
|
||||
# define des_ecb_encrypt DES_ECB_ENCRYPT
|
||||
|
||||
# endif
|
||||
# include <openssl/evp.h>
|
||||
# ifndef OpenSSL_add_all_algorithms
|
||||
# define OpenSSL_add_all_algorithms OPENSSL_ADD_ALL_ALGORITHMS
|
||||
void OPENSSL_ADD_ALL_ALGORITHMS(void);
|
||||
# endif
|
||||
|
||||
/* Curl defines these to lower case and VAX needs them in upper case */
|
||||
/* So we need static routines */
|
||||
# if (OPENSSL_VERSION_NUMBER < 0x00907001L)
|
||||
|
||||
# undef des_set_odd_parity
|
||||
# undef DES_set_odd_parity
|
||||
# undef des_set_key
|
||||
# undef DES_set_key
|
||||
# undef des_ecb_encrypt
|
||||
# undef DES_ecb_encrypt
|
||||
|
||||
static void des_set_odd_parity(des_cblock *key) {
|
||||
DES_SET_ODD_PARITY(key);
|
||||
}
|
||||
|
||||
static int des_set_key(const_des_cblock *key,
|
||||
des_key_schedule schedule) {
|
||||
return DES_SET_KEY(key, schedule);
|
||||
}
|
||||
|
||||
static void des_ecb_encrypt(const_des_cblock *input,
|
||||
des_cblock *output,
|
||||
des_key_schedule ks, int enc) {
|
||||
DES_ECB_ENCRYPT(input, output, ks, enc);
|
||||
}
|
||||
#endif
|
||||
/* Need this to stop a macro redefinition error */
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00907000L
|
||||
# ifdef X509_STORE_set_flags
|
||||
# undef X509_STORE_set_flags
|
||||
# define X509_STORE_set_flags(x,y) Curl_nop_stmt
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_SETUP_VMS_H */
|
||||
@@ -1,244 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "share.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
struct Curl_share *
|
||||
curl_share_init(void)
|
||||
{
|
||||
struct Curl_share *share = calloc(1, sizeof(struct Curl_share));
|
||||
if(share) {
|
||||
share->specifier |= (1<<CURL_LOCK_DATA_SHARE);
|
||||
|
||||
if(Curl_mk_dnscache(&share->hostcache)) {
|
||||
free(share);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return share;
|
||||
}
|
||||
|
||||
#undef curl_share_setopt
|
||||
CURLSHcode
|
||||
curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...)
|
||||
{
|
||||
va_list param;
|
||||
int type;
|
||||
curl_lock_function lockfunc;
|
||||
curl_unlock_function unlockfunc;
|
||||
void *ptr;
|
||||
CURLSHcode res = CURLSHE_OK;
|
||||
|
||||
if(share->dirty)
|
||||
/* don't allow setting options while one or more handles are already
|
||||
using this share */
|
||||
return CURLSHE_IN_USE;
|
||||
|
||||
va_start(param, option);
|
||||
|
||||
switch(option) {
|
||||
case CURLSHOPT_SHARE:
|
||||
/* this is a type this share will share */
|
||||
type = va_arg(param, int);
|
||||
share->specifier |= (1<<type);
|
||||
switch(type) {
|
||||
case CURL_LOCK_DATA_DNS:
|
||||
break;
|
||||
|
||||
case CURL_LOCK_DATA_COOKIE:
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
|
||||
if(!share->cookies) {
|
||||
share->cookies = Curl_cookie_init(NULL, NULL, NULL, TRUE);
|
||||
if(!share->cookies)
|
||||
res = CURLSHE_NOMEM;
|
||||
}
|
||||
#else /* CURL_DISABLE_HTTP */
|
||||
res = CURLSHE_NOT_BUILT_IN;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case CURL_LOCK_DATA_SSL_SESSION:
|
||||
#ifdef USE_SSL
|
||||
if(!share->sslsession) {
|
||||
share->max_ssl_sessions = 8;
|
||||
share->sslsession = calloc(share->max_ssl_sessions,
|
||||
sizeof(struct curl_ssl_session));
|
||||
share->sessionage = 0;
|
||||
if(!share->sslsession)
|
||||
res = CURLSHE_NOMEM;
|
||||
}
|
||||
#else
|
||||
res = CURLSHE_NOT_BUILT_IN;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case CURL_LOCK_DATA_CONNECT: /* not supported (yet) */
|
||||
break;
|
||||
|
||||
default:
|
||||
res = CURLSHE_BAD_OPTION;
|
||||
}
|
||||
break;
|
||||
|
||||
case CURLSHOPT_UNSHARE:
|
||||
/* this is a type this share will no longer share */
|
||||
type = va_arg(param, int);
|
||||
share->specifier &= ~(1<<type);
|
||||
switch(type) {
|
||||
case CURL_LOCK_DATA_DNS:
|
||||
break;
|
||||
|
||||
case CURL_LOCK_DATA_COOKIE:
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
|
||||
if(share->cookies) {
|
||||
Curl_cookie_cleanup(share->cookies);
|
||||
share->cookies = NULL;
|
||||
}
|
||||
#else /* CURL_DISABLE_HTTP */
|
||||
res = CURLSHE_NOT_BUILT_IN;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case CURL_LOCK_DATA_SSL_SESSION:
|
||||
#ifdef USE_SSL
|
||||
Curl_safefree(share->sslsession);
|
||||
#else
|
||||
res = CURLSHE_NOT_BUILT_IN;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case CURL_LOCK_DATA_CONNECT:
|
||||
break;
|
||||
|
||||
default:
|
||||
res = CURLSHE_BAD_OPTION;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CURLSHOPT_LOCKFUNC:
|
||||
lockfunc = va_arg(param, curl_lock_function);
|
||||
share->lockfunc = lockfunc;
|
||||
break;
|
||||
|
||||
case CURLSHOPT_UNLOCKFUNC:
|
||||
unlockfunc = va_arg(param, curl_unlock_function);
|
||||
share->unlockfunc = unlockfunc;
|
||||
break;
|
||||
|
||||
case CURLSHOPT_USERDATA:
|
||||
ptr = va_arg(param, void *);
|
||||
share->clientdata = ptr;
|
||||
break;
|
||||
|
||||
default:
|
||||
res = CURLSHE_BAD_OPTION;
|
||||
break;
|
||||
}
|
||||
|
||||
va_end(param);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
CURLSHcode
|
||||
curl_share_cleanup(struct Curl_share *share)
|
||||
{
|
||||
if(share == NULL)
|
||||
return CURLSHE_INVALID;
|
||||
|
||||
if(share->lockfunc)
|
||||
share->lockfunc(NULL, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE,
|
||||
share->clientdata);
|
||||
|
||||
if(share->dirty) {
|
||||
if(share->unlockfunc)
|
||||
share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
|
||||
return CURLSHE_IN_USE;
|
||||
}
|
||||
|
||||
Curl_hash_destroy(&share->hostcache);
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
|
||||
Curl_cookie_cleanup(share->cookies);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SSL
|
||||
if(share->sslsession) {
|
||||
size_t i;
|
||||
for(i = 0; i < share->max_ssl_sessions; i++)
|
||||
Curl_ssl_kill_session(&(share->sslsession[i]));
|
||||
free(share->sslsession);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(share->unlockfunc)
|
||||
share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
|
||||
free(share);
|
||||
|
||||
return CURLSHE_OK;
|
||||
}
|
||||
|
||||
|
||||
CURLSHcode
|
||||
Curl_share_lock(struct Curl_easy *data, curl_lock_data type,
|
||||
curl_lock_access accesstype)
|
||||
{
|
||||
struct Curl_share *share = data->share;
|
||||
|
||||
if(share == NULL)
|
||||
return CURLSHE_INVALID;
|
||||
|
||||
if(share->specifier & (1<<type)) {
|
||||
if(share->lockfunc) /* only call this if set! */
|
||||
share->lockfunc(data, type, accesstype, share->clientdata);
|
||||
}
|
||||
/* else if we don't share this, pretend successful lock */
|
||||
|
||||
return CURLSHE_OK;
|
||||
}
|
||||
|
||||
CURLSHcode
|
||||
Curl_share_unlock(struct Curl_easy *data, curl_lock_data type)
|
||||
{
|
||||
struct Curl_share *share = data->share;
|
||||
|
||||
if(share == NULL)
|
||||
return CURLSHE_INVALID;
|
||||
|
||||
if(share->specifier & (1<<type)) {
|
||||
if(share->unlockfunc) /* only call this if set! */
|
||||
share->unlockfunc (data, type, share->clientdata);
|
||||
}
|
||||
|
||||
return CURLSHE_OK;
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
#ifndef HEADER_CURL_SHARE_H
|
||||
#define HEADER_CURL_SHARE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
#include <curl/curl.h>
|
||||
#include "cookie.h"
|
||||
#include "urldata.h"
|
||||
|
||||
/* SalfordC says "A structure member may not be volatile". Hence:
|
||||
*/
|
||||
#ifdef __SALFORDC__
|
||||
#define CURL_VOLATILE
|
||||
#else
|
||||
#define CURL_VOLATILE volatile
|
||||
#endif
|
||||
|
||||
/* this struct is libcurl-private, don't export details */
|
||||
struct Curl_share {
|
||||
unsigned int specifier;
|
||||
CURL_VOLATILE unsigned int dirty;
|
||||
|
||||
curl_lock_function lockfunc;
|
||||
curl_unlock_function unlockfunc;
|
||||
void *clientdata;
|
||||
|
||||
struct curl_hash hostcache;
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
|
||||
struct CookieInfo *cookies;
|
||||
#endif
|
||||
|
||||
struct curl_ssl_session *sslsession;
|
||||
size_t max_ssl_sessions;
|
||||
long sessionage;
|
||||
};
|
||||
|
||||
CURLSHcode Curl_share_lock(struct Curl_easy *, curl_lock_data,
|
||||
curl_lock_access);
|
||||
CURLSHcode Curl_share_unlock(struct Curl_easy *, curl_lock_data);
|
||||
|
||||
#endif /* HEADER_CURL_SHARE_H */
|
||||
@@ -1,78 +0,0 @@
|
||||
#ifndef HEADER_CURL_SIGPIPE_H
|
||||
#define HEADER_CURL_SIGPIPE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGACTION) && defined(USE_OPENSSL)
|
||||
#include <signal.h>
|
||||
|
||||
struct sigpipe_ignore {
|
||||
struct sigaction old_pipe_act;
|
||||
bool no_signal;
|
||||
};
|
||||
|
||||
#define SIGPIPE_VARIABLE(x) struct sigpipe_ignore x
|
||||
|
||||
/*
|
||||
* sigpipe_ignore() makes sure we ignore SIGPIPE while running libcurl
|
||||
* internals, and then sigpipe_restore() will restore the situation when we
|
||||
* return from libcurl again.
|
||||
*/
|
||||
static void sigpipe_ignore(struct Curl_easy *data,
|
||||
struct sigpipe_ignore *ig)
|
||||
{
|
||||
/* get a local copy of no_signal because the Curl_easy might not be
|
||||
around when we restore */
|
||||
ig->no_signal = data->set.no_signal;
|
||||
if(!data->set.no_signal) {
|
||||
struct sigaction action;
|
||||
/* first, extract the existing situation */
|
||||
memset(&ig->old_pipe_act, 0, sizeof(struct sigaction));
|
||||
sigaction(SIGPIPE, NULL, &ig->old_pipe_act);
|
||||
action = ig->old_pipe_act;
|
||||
/* ignore this signal */
|
||||
action.sa_handler = SIG_IGN;
|
||||
sigaction(SIGPIPE, &action, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sigpipe_restore() puts back the outside world's opinion of signal handler
|
||||
* and SIGPIPE handling. It MUST only be called after a corresponding
|
||||
* sigpipe_ignore() was used.
|
||||
*/
|
||||
static void sigpipe_restore(struct sigpipe_ignore *ig)
|
||||
{
|
||||
if(!ig->no_signal)
|
||||
/* restore the outside state */
|
||||
sigaction(SIGPIPE, &ig->old_pipe_act, NULL);
|
||||
}
|
||||
|
||||
#else
|
||||
/* for systems without sigaction */
|
||||
#define sigpipe_ignore(x,y) Curl_nop_stmt
|
||||
#define sigpipe_restore(x) Curl_nop_stmt
|
||||
#define SIGPIPE_VARIABLE(x)
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_SIGPIPE_H */
|
||||
@@ -1,145 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "slist.h"
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* returns last node in linked list */
|
||||
static struct curl_slist *slist_get_last(struct curl_slist *list)
|
||||
{
|
||||
struct curl_slist *item;
|
||||
|
||||
/* if caller passed us a NULL, return now */
|
||||
if(!list)
|
||||
return NULL;
|
||||
|
||||
/* loop through to find the last item */
|
||||
item = list;
|
||||
while(item->next) {
|
||||
item = item->next;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_slist_append_nodup() appends a string to the linked list. Rather than
|
||||
* copying the string in dynamic storage, it takes its ownership. The string
|
||||
* should have been malloc()ated. Curl_slist_append_nodup always returns
|
||||
* the address of the first record, so that you can use this function as an
|
||||
* initialization function as well as an append function.
|
||||
* If an error occurs, NULL is returned and the string argument is NOT
|
||||
* released.
|
||||
*/
|
||||
struct curl_slist *Curl_slist_append_nodup(struct curl_slist *list, char *data)
|
||||
{
|
||||
struct curl_slist *last;
|
||||
struct curl_slist *new_item;
|
||||
|
||||
DEBUGASSERT(data);
|
||||
|
||||
new_item = malloc(sizeof(struct curl_slist));
|
||||
if(!new_item)
|
||||
return NULL;
|
||||
|
||||
new_item->next = NULL;
|
||||
new_item->data = data;
|
||||
|
||||
/* if this is the first item, then new_item *is* the list */
|
||||
if(!list)
|
||||
return new_item;
|
||||
|
||||
last = slist_get_last(list);
|
||||
last->next = new_item;
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
* curl_slist_append() appends a string to the linked list. It always returns
|
||||
* the address of the first record, so that you can use this function as an
|
||||
* initialization function as well as an append function. If you find this
|
||||
* bothersome, then simply create a separate _init function and call it
|
||||
* appropriately from within the program.
|
||||
*/
|
||||
struct curl_slist *curl_slist_append(struct curl_slist *list,
|
||||
const char *data)
|
||||
{
|
||||
char *dupdata = strdup(data);
|
||||
|
||||
if(!dupdata)
|
||||
return NULL;
|
||||
|
||||
list = Curl_slist_append_nodup(list, dupdata);
|
||||
if(!list)
|
||||
free(dupdata);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_slist_duplicate() duplicates a linked list. It always returns the
|
||||
* address of the first record of the cloned list or NULL in case of an
|
||||
* error (or if the input list was NULL).
|
||||
*/
|
||||
struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist)
|
||||
{
|
||||
struct curl_slist *outlist = NULL;
|
||||
struct curl_slist *tmp;
|
||||
|
||||
while(inlist) {
|
||||
tmp = curl_slist_append(outlist, inlist->data);
|
||||
|
||||
if(!tmp) {
|
||||
curl_slist_free_all(outlist);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
outlist = tmp;
|
||||
inlist = inlist->next;
|
||||
}
|
||||
return outlist;
|
||||
}
|
||||
|
||||
/* be nice and clean up resources */
|
||||
void curl_slist_free_all(struct curl_slist *list)
|
||||
{
|
||||
struct curl_slist *next;
|
||||
struct curl_slist *item;
|
||||
|
||||
if(!list)
|
||||
return;
|
||||
|
||||
item = list;
|
||||
do {
|
||||
next = item->next;
|
||||
Curl_safefree(item->data);
|
||||
free(item);
|
||||
item = next;
|
||||
} while(next);
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
#ifndef HEADER_CURL_SLIST_H
|
||||
#define HEADER_CURL_SLIST_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* Curl_slist_duplicate() duplicates a linked list. It always returns the
|
||||
* address of the first record of the cloned list or NULL in case of an
|
||||
* error (or if the input list was NULL).
|
||||
*/
|
||||
struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist);
|
||||
|
||||
/*
|
||||
* Curl_slist_append_nodup() takes ownership of the given string and appends
|
||||
* it to the list.
|
||||
*/
|
||||
struct curl_slist *Curl_slist_append_nodup(struct curl_slist *list,
|
||||
char *data);
|
||||
|
||||
#endif /* HEADER_CURL_SLIST_H */
|
||||
|
||||
@@ -1,977 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
|
||||
* Copyright (C) 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
|
||||
(CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
|
||||
#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
|
||||
|
||||
#define BUILDING_CURL_SMB_C
|
||||
|
||||
#ifdef HAVE_PROCESS_H
|
||||
#include <process.h>
|
||||
#define getpid _getpid
|
||||
#endif
|
||||
|
||||
#include "smb.h"
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "multiif.h"
|
||||
#include "connect.h"
|
||||
#include "progress.h"
|
||||
#include "transfer.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "curl_ntlm_core.h"
|
||||
#include "escape.h"
|
||||
#include "curl_endian.h"
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* Local API functions */
|
||||
static CURLcode smb_setup_connection(struct connectdata *conn);
|
||||
static CURLcode smb_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode smb_connection_state(struct connectdata *conn, bool *done);
|
||||
static CURLcode smb_request_state(struct connectdata *conn, bool *done);
|
||||
static CURLcode smb_done(struct connectdata *conn, CURLcode status,
|
||||
bool premature);
|
||||
static CURLcode smb_disconnect(struct connectdata *conn, bool dead);
|
||||
static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
|
||||
int numsocks);
|
||||
static CURLcode smb_parse_url_path(struct connectdata *conn);
|
||||
|
||||
/*
|
||||
* SMB handler interface
|
||||
*/
|
||||
const struct Curl_handler Curl_handler_smb = {
|
||||
"SMB", /* scheme */
|
||||
smb_setup_connection, /* setup_connection */
|
||||
ZERO_NULL, /* do_it */
|
||||
smb_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
smb_connect, /* connect_it */
|
||||
smb_connection_state, /* connecting */
|
||||
smb_request_state, /* doing */
|
||||
smb_getsock, /* proto_getsock */
|
||||
smb_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
smb_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_SMB, /* defport */
|
||||
CURLPROTO_SMB, /* protocol */
|
||||
PROTOPT_NONE /* flags */
|
||||
};
|
||||
|
||||
#ifdef USE_SSL
|
||||
/*
|
||||
* SMBS handler interface
|
||||
*/
|
||||
const struct Curl_handler Curl_handler_smbs = {
|
||||
"SMBS", /* scheme */
|
||||
smb_setup_connection, /* setup_connection */
|
||||
ZERO_NULL, /* do_it */
|
||||
smb_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
smb_connect, /* connect_it */
|
||||
smb_connection_state, /* connecting */
|
||||
smb_request_state, /* doing */
|
||||
smb_getsock, /* proto_getsock */
|
||||
smb_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
smb_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_SMBS, /* defport */
|
||||
CURLPROTO_SMBS, /* protocol */
|
||||
PROTOPT_SSL /* flags */
|
||||
};
|
||||
#endif
|
||||
|
||||
#define MAX_PAYLOAD_SIZE 0x8000
|
||||
#define MAX_MESSAGE_SIZE (MAX_PAYLOAD_SIZE + 0x1000)
|
||||
#define CLIENTNAME "curl"
|
||||
#define SERVICENAME "?????"
|
||||
|
||||
/* Append a string to an SMB message */
|
||||
#define MSGCAT(str) \
|
||||
strcpy(p, (str)); \
|
||||
p += strlen(str);
|
||||
|
||||
/* Append a null-terminated string to an SMB message */
|
||||
#define MSGCATNULL(str) \
|
||||
strcpy(p, (str)); \
|
||||
p += strlen(str) + 1;
|
||||
|
||||
/* SMB is mostly little endian */
|
||||
#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
|
||||
defined(__OS400__)
|
||||
static unsigned short smb_swap16(unsigned short x)
|
||||
{
|
||||
return (unsigned short) ((x << 8) | ((x >> 8) & 0xff));
|
||||
}
|
||||
|
||||
static unsigned int smb_swap32(unsigned int x)
|
||||
{
|
||||
return (x << 24) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) |
|
||||
((x >> 24) & 0xff);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LONGLONG
|
||||
static unsigned long long smb_swap64(unsigned long long x)
|
||||
{
|
||||
return ((unsigned long long) smb_swap32((unsigned int) x) << 32) |
|
||||
smb_swap32((unsigned int) (x >> 32));
|
||||
}
|
||||
#else
|
||||
static unsigned __int64 smb_swap64(unsigned __int64 x)
|
||||
{
|
||||
return ((unsigned __int64) smb_swap32((unsigned int) x) << 32) |
|
||||
smb_swap32((unsigned int) (x >> 32));
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
# define smb_swap16(x) (x)
|
||||
# define smb_swap32(x) (x)
|
||||
# define smb_swap64(x) (x)
|
||||
#endif
|
||||
|
||||
/* SMB request state */
|
||||
enum smb_req_state {
|
||||
SMB_REQUESTING,
|
||||
SMB_TREE_CONNECT,
|
||||
SMB_OPEN,
|
||||
SMB_DOWNLOAD,
|
||||
SMB_UPLOAD,
|
||||
SMB_CLOSE,
|
||||
SMB_TREE_DISCONNECT,
|
||||
SMB_DONE
|
||||
};
|
||||
|
||||
/* SMB request data */
|
||||
struct smb_request {
|
||||
enum smb_req_state state;
|
||||
char *share;
|
||||
char *path;
|
||||
unsigned short tid; /* Even if we connect to the same tree as another */
|
||||
unsigned short fid; /* request, the tid will be different */
|
||||
CURLcode result;
|
||||
};
|
||||
|
||||
static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
|
||||
{
|
||||
struct smb_conn *smb = &conn->proto.smbc;
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
/* For debug purposes */
|
||||
static const char * const names[] = {
|
||||
"SMB_NOT_CONNECTED",
|
||||
"SMB_CONNECTING",
|
||||
"SMB_NEGOTIATE",
|
||||
"SMB_SETUP",
|
||||
"SMB_CONNECTED",
|
||||
/* LAST */
|
||||
};
|
||||
|
||||
if(smb->state != newstate)
|
||||
infof(conn->data, "SMB conn %p state change from %s to %s\n",
|
||||
(void *)smb, names[smb->state], names[newstate]);
|
||||
#endif
|
||||
|
||||
smb->state = newstate;
|
||||
}
|
||||
|
||||
static void request_state(struct connectdata *conn,
|
||||
enum smb_req_state newstate)
|
||||
{
|
||||
struct smb_request *req = conn->data->req.protop;
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
/* For debug purposes */
|
||||
static const char * const names[] = {
|
||||
"SMB_REQUESTING",
|
||||
"SMB_TREE_CONNECT",
|
||||
"SMB_OPEN",
|
||||
"SMB_DOWNLOAD",
|
||||
"SMB_UPLOAD",
|
||||
"SMB_CLOSE",
|
||||
"SMB_TREE_DISCONNECT",
|
||||
"SMB_DONE",
|
||||
/* LAST */
|
||||
};
|
||||
|
||||
if(req->state != newstate)
|
||||
infof(conn->data, "SMB request %p state change from %s to %s\n",
|
||||
(void *)req, names[req->state], names[newstate]);
|
||||
#endif
|
||||
|
||||
req->state = newstate;
|
||||
}
|
||||
|
||||
static CURLcode smb_setup_connection(struct connectdata *conn)
|
||||
{
|
||||
struct smb_request *req;
|
||||
|
||||
/* Initialize the request state */
|
||||
conn->data->req.protop = req = calloc(1, sizeof(struct smb_request));
|
||||
if(!req)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Parse the URL path */
|
||||
return smb_parse_url_path(conn);
|
||||
}
|
||||
|
||||
static CURLcode smb_connect(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
char *slash;
|
||||
|
||||
(void) done;
|
||||
|
||||
/* Check we have a username and password to authenticate with */
|
||||
if(!conn->bits.user_passwd)
|
||||
return CURLE_LOGIN_DENIED;
|
||||
|
||||
/* Initialize the connection state */
|
||||
memset(smbc, 0, sizeof(*smbc));
|
||||
smbc->state = SMB_CONNECTING;
|
||||
smbc->recv_buf = malloc(MAX_MESSAGE_SIZE);
|
||||
if(!smbc->recv_buf)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Multiple requests are allowed with this connection */
|
||||
connkeep(conn, "SMB default");
|
||||
|
||||
/* Parse the username, domain, and password */
|
||||
slash = strchr(conn->user, '/');
|
||||
if(!slash)
|
||||
slash = strchr(conn->user, '\\');
|
||||
|
||||
if(slash) {
|
||||
smbc->user = slash + 1;
|
||||
smbc->domain = strdup(conn->user);
|
||||
if(!smbc->domain)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
smbc->domain[slash - conn->user] = 0;
|
||||
}
|
||||
else {
|
||||
smbc->user = conn->user;
|
||||
smbc->domain = strdup(conn->host.name);
|
||||
if(!smbc->domain)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode smb_recv_message(struct connectdata *conn, void **msg)
|
||||
{
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
char *buf = smbc->recv_buf;
|
||||
ssize_t bytes_read;
|
||||
size_t nbt_size;
|
||||
size_t msg_size;
|
||||
size_t len = MAX_MESSAGE_SIZE - smbc->got;
|
||||
CURLcode result;
|
||||
|
||||
result = Curl_read(conn, FIRSTSOCKET, buf + smbc->got, len, &bytes_read);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(!bytes_read)
|
||||
return CURLE_OK;
|
||||
|
||||
smbc->got += bytes_read;
|
||||
|
||||
/* Check for a 32-bit nbt header */
|
||||
if(smbc->got < sizeof(unsigned int))
|
||||
return CURLE_OK;
|
||||
|
||||
nbt_size = Curl_read16_be((const unsigned char *)(buf +
|
||||
sizeof(unsigned short))) + sizeof(unsigned int);
|
||||
if(smbc->got < nbt_size)
|
||||
return CURLE_OK;
|
||||
|
||||
msg_size = sizeof(struct smb_header);
|
||||
if(nbt_size >= msg_size + 1) {
|
||||
/* Add the word count */
|
||||
msg_size += 1 + ((unsigned char) buf[msg_size]) * sizeof(unsigned short);
|
||||
if(nbt_size >= msg_size + sizeof(unsigned short)) {
|
||||
/* Add the byte count */
|
||||
msg_size += sizeof(unsigned short) +
|
||||
Curl_read16_le((const unsigned char *)&buf[msg_size]);
|
||||
if(nbt_size < msg_size)
|
||||
return CURLE_READ_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
*msg = buf;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void smb_pop_message(struct connectdata *conn)
|
||||
{
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
|
||||
smbc->got = 0;
|
||||
}
|
||||
|
||||
static void smb_format_message(struct connectdata *conn, struct smb_header *h,
|
||||
unsigned char cmd, size_t len)
|
||||
{
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
struct smb_request *req = conn->data->req.protop;
|
||||
unsigned int pid;
|
||||
|
||||
memset(h, 0, sizeof(*h));
|
||||
h->nbt_length = htons((unsigned short) (sizeof(*h) - sizeof(unsigned int) +
|
||||
len));
|
||||
memcpy((char *)h->magic, "\xffSMB", 4);
|
||||
h->command = cmd;
|
||||
h->flags = SMB_FLAGS_CANONICAL_PATHNAMES | SMB_FLAGS_CASELESS_PATHNAMES;
|
||||
h->flags2 = smb_swap16(SMB_FLAGS2_IS_LONG_NAME | SMB_FLAGS2_KNOWS_LONG_NAME);
|
||||
h->uid = smb_swap16(smbc->uid);
|
||||
h->tid = smb_swap16(req->tid);
|
||||
pid = getpid();
|
||||
h->pid_high = smb_swap16((unsigned short)(pid >> 16));
|
||||
h->pid = smb_swap16((unsigned short) pid);
|
||||
}
|
||||
|
||||
static CURLcode smb_send(struct connectdata *conn, ssize_t len,
|
||||
size_t upload_size)
|
||||
{
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
ssize_t bytes_written;
|
||||
CURLcode result;
|
||||
|
||||
result = Curl_write(conn, FIRSTSOCKET, conn->data->state.uploadbuffer,
|
||||
len, &bytes_written);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(bytes_written != len) {
|
||||
smbc->send_size = len;
|
||||
smbc->sent = bytes_written;
|
||||
}
|
||||
|
||||
smbc->upload_size = upload_size;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode smb_flush(struct connectdata *conn)
|
||||
{
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
ssize_t bytes_written;
|
||||
ssize_t len = smbc->send_size - smbc->sent;
|
||||
CURLcode result;
|
||||
|
||||
if(!smbc->send_size)
|
||||
return CURLE_OK;
|
||||
|
||||
result = Curl_write(conn, FIRSTSOCKET,
|
||||
conn->data->state.uploadbuffer + smbc->sent,
|
||||
len, &bytes_written);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(bytes_written != len)
|
||||
smbc->sent += bytes_written;
|
||||
else
|
||||
smbc->send_size = 0;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode smb_send_message(struct connectdata *conn, unsigned char cmd,
|
||||
const void *msg, size_t msg_len)
|
||||
{
|
||||
smb_format_message(conn, (struct smb_header *)conn->data->state.uploadbuffer,
|
||||
cmd, msg_len);
|
||||
memcpy(conn->data->state.uploadbuffer + sizeof(struct smb_header),
|
||||
msg, msg_len);
|
||||
|
||||
return smb_send(conn, sizeof(struct smb_header) + msg_len, 0);
|
||||
}
|
||||
|
||||
static CURLcode smb_send_negotiate(struct connectdata *conn)
|
||||
{
|
||||
const char *msg = "\x00\x0c\x00\x02NT LM 0.12";
|
||||
|
||||
return smb_send_message(conn, SMB_COM_NEGOTIATE, msg, 15);
|
||||
}
|
||||
|
||||
static CURLcode smb_send_setup(struct connectdata *conn)
|
||||
{
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
struct smb_setup msg;
|
||||
char *p = msg.bytes;
|
||||
unsigned char lm_hash[21];
|
||||
unsigned char lm[24];
|
||||
unsigned char nt_hash[21];
|
||||
unsigned char nt[24];
|
||||
|
||||
size_t byte_count = sizeof(lm) + sizeof(nt);
|
||||
byte_count += strlen(smbc->user) + strlen(smbc->domain);
|
||||
byte_count += strlen(OS) + strlen(CLIENTNAME) + 4; /* 4 null chars */
|
||||
if(byte_count > sizeof(msg.bytes))
|
||||
return CURLE_FILESIZE_EXCEEDED;
|
||||
|
||||
Curl_ntlm_core_mk_lm_hash(conn->data, conn->passwd, lm_hash);
|
||||
Curl_ntlm_core_lm_resp(lm_hash, smbc->challenge, lm);
|
||||
#if USE_NTRESPONSES
|
||||
Curl_ntlm_core_mk_nt_hash(conn->data, conn->passwd, nt_hash);
|
||||
Curl_ntlm_core_lm_resp(nt_hash, smbc->challenge, nt);
|
||||
#else
|
||||
memset(nt, 0, sizeof(nt));
|
||||
#endif
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.word_count = SMB_WC_SETUP_ANDX;
|
||||
msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
|
||||
msg.max_buffer_size = smb_swap16(MAX_MESSAGE_SIZE);
|
||||
msg.max_mpx_count = smb_swap16(1);
|
||||
msg.vc_number = smb_swap16(1);
|
||||
msg.session_key = smb_swap32(smbc->session_key);
|
||||
msg.capabilities = smb_swap32(SMB_CAP_LARGE_FILES);
|
||||
msg.lengths[0] = smb_swap16(sizeof(lm));
|
||||
msg.lengths[1] = smb_swap16(sizeof(nt));
|
||||
memcpy(p, lm, sizeof(lm));
|
||||
p += sizeof(lm);
|
||||
memcpy(p, nt, sizeof(nt));
|
||||
p += sizeof(nt);
|
||||
MSGCATNULL(smbc->user);
|
||||
MSGCATNULL(smbc->domain);
|
||||
MSGCATNULL(OS);
|
||||
MSGCATNULL(CLIENTNAME);
|
||||
byte_count = p - msg.bytes;
|
||||
msg.byte_count = smb_swap16((unsigned short)byte_count);
|
||||
|
||||
return smb_send_message(conn, SMB_COM_SETUP_ANDX, &msg,
|
||||
sizeof(msg) - sizeof(msg.bytes) + byte_count);
|
||||
}
|
||||
|
||||
static CURLcode smb_send_tree_connect(struct connectdata *conn)
|
||||
{
|
||||
struct smb_request *req = conn->data->req.protop;
|
||||
struct smb_tree_connect msg;
|
||||
char *p = msg.bytes;
|
||||
|
||||
size_t byte_count = strlen(conn->host.name) + strlen(req->share);
|
||||
byte_count += strlen(SERVICENAME) + 5; /* 2 nulls and 3 backslashes */
|
||||
if(byte_count > sizeof(msg.bytes))
|
||||
return CURLE_FILESIZE_EXCEEDED;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.word_count = SMB_WC_TREE_CONNECT_ANDX;
|
||||
msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
|
||||
msg.pw_len = 0;
|
||||
MSGCAT("\\\\");
|
||||
MSGCAT(conn->host.name);
|
||||
MSGCAT("\\");
|
||||
MSGCATNULL(req->share);
|
||||
MSGCATNULL(SERVICENAME); /* Match any type of service */
|
||||
byte_count = p - msg.bytes;
|
||||
msg.byte_count = smb_swap16((unsigned short)byte_count);
|
||||
|
||||
return smb_send_message(conn, SMB_COM_TREE_CONNECT_ANDX, &msg,
|
||||
sizeof(msg) - sizeof(msg.bytes) + byte_count);
|
||||
}
|
||||
|
||||
static CURLcode smb_send_open(struct connectdata *conn)
|
||||
{
|
||||
struct smb_request *req = conn->data->req.protop;
|
||||
struct smb_nt_create msg;
|
||||
size_t byte_count;
|
||||
|
||||
if((strlen(req->path) + 1) > sizeof(msg.bytes))
|
||||
return CURLE_FILESIZE_EXCEEDED;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.word_count = SMB_WC_NT_CREATE_ANDX;
|
||||
msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
|
||||
byte_count = strlen(req->path);
|
||||
msg.name_length = smb_swap16((unsigned short)byte_count);
|
||||
msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL);
|
||||
if(conn->data->set.upload) {
|
||||
msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE);
|
||||
msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF);
|
||||
}
|
||||
else {
|
||||
msg.access = smb_swap32(SMB_GENERIC_READ);
|
||||
msg.create_disposition = smb_swap32(SMB_FILE_OPEN);
|
||||
}
|
||||
msg.byte_count = smb_swap16((unsigned short) ++byte_count);
|
||||
strcpy(msg.bytes, req->path);
|
||||
|
||||
return smb_send_message(conn, SMB_COM_NT_CREATE_ANDX, &msg,
|
||||
sizeof(msg) - sizeof(msg.bytes) + byte_count);
|
||||
}
|
||||
|
||||
static CURLcode smb_send_close(struct connectdata *conn)
|
||||
{
|
||||
struct smb_request *req = conn->data->req.protop;
|
||||
struct smb_close msg;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.word_count = SMB_WC_CLOSE;
|
||||
msg.fid = smb_swap16(req->fid);
|
||||
|
||||
return smb_send_message(conn, SMB_COM_CLOSE, &msg, sizeof(msg));
|
||||
}
|
||||
|
||||
static CURLcode smb_send_tree_disconnect(struct connectdata *conn)
|
||||
{
|
||||
struct smb_tree_disconnect msg;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
|
||||
return smb_send_message(conn, SMB_COM_TREE_DISCONNECT, &msg, sizeof(msg));
|
||||
}
|
||||
|
||||
static CURLcode smb_send_read(struct connectdata *conn)
|
||||
{
|
||||
struct smb_request *req = conn->data->req.protop;
|
||||
curl_off_t offset = conn->data->req.offset;
|
||||
struct smb_read msg;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.word_count = SMB_WC_READ_ANDX;
|
||||
msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
|
||||
msg.fid = smb_swap16(req->fid);
|
||||
msg.offset = smb_swap32((unsigned int) offset);
|
||||
msg.offset_high = smb_swap32((unsigned int) (offset >> 32));
|
||||
msg.min_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
|
||||
msg.max_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
|
||||
|
||||
return smb_send_message(conn, SMB_COM_READ_ANDX, &msg, sizeof(msg));
|
||||
}
|
||||
|
||||
static CURLcode smb_send_write(struct connectdata *conn)
|
||||
{
|
||||
struct smb_write *msg = (struct smb_write *)conn->data->state.uploadbuffer;
|
||||
struct smb_request *req = conn->data->req.protop;
|
||||
curl_off_t offset = conn->data->req.offset;
|
||||
|
||||
curl_off_t upload_size = conn->data->req.size - conn->data->req.bytecount;
|
||||
if(upload_size >= MAX_PAYLOAD_SIZE - 1) /* There is one byte of padding */
|
||||
upload_size = MAX_PAYLOAD_SIZE - 1;
|
||||
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
msg->word_count = SMB_WC_WRITE_ANDX;
|
||||
msg->andx.command = SMB_COM_NO_ANDX_COMMAND;
|
||||
msg->fid = smb_swap16(req->fid);
|
||||
msg->offset = smb_swap32((unsigned int) offset);
|
||||
msg->offset_high = smb_swap32((unsigned int) (offset >> 32));
|
||||
msg->data_length = smb_swap16((unsigned short) upload_size);
|
||||
msg->data_offset = smb_swap16(sizeof(*msg) - sizeof(unsigned int));
|
||||
msg->byte_count = smb_swap16((unsigned short) (upload_size + 1));
|
||||
|
||||
smb_format_message(conn, &msg->h, SMB_COM_WRITE_ANDX,
|
||||
sizeof(*msg) - sizeof(msg->h) + (size_t) upload_size);
|
||||
|
||||
return smb_send(conn, sizeof(*msg), (size_t) upload_size);
|
||||
}
|
||||
|
||||
static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg)
|
||||
{
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
CURLcode result;
|
||||
|
||||
/* Check if there is data in the transfer buffer */
|
||||
if(!smbc->send_size && smbc->upload_size) {
|
||||
int nread = smbc->upload_size > BUFSIZE ? BUFSIZE :
|
||||
(int) smbc->upload_size;
|
||||
conn->data->req.upload_fromhere = conn->data->state.uploadbuffer;
|
||||
result = Curl_fillreadbuffer(conn, nread, &nread);
|
||||
if(result && result != CURLE_AGAIN)
|
||||
return result;
|
||||
if(!nread)
|
||||
return CURLE_OK;
|
||||
|
||||
smbc->upload_size -= nread;
|
||||
smbc->send_size = nread;
|
||||
smbc->sent = 0;
|
||||
}
|
||||
|
||||
/* Check if there is data to send */
|
||||
if(smbc->send_size) {
|
||||
result = smb_flush(conn);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Check if there is still data to be sent */
|
||||
if(smbc->send_size || smbc->upload_size)
|
||||
return CURLE_AGAIN;
|
||||
|
||||
return smb_recv_message(conn, msg);
|
||||
}
|
||||
|
||||
static CURLcode smb_connection_state(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
struct smb_negotiate_response *nrsp;
|
||||
struct smb_header *h;
|
||||
CURLcode result;
|
||||
void *msg = NULL;
|
||||
|
||||
if(smbc->state == SMB_CONNECTING) {
|
||||
#ifdef USE_SSL
|
||||
if((conn->handler->flags & PROTOPT_SSL)) {
|
||||
bool ssl_done;
|
||||
result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &ssl_done);
|
||||
if(result && result != CURLE_AGAIN)
|
||||
return result;
|
||||
if(!ssl_done)
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
result = smb_send_negotiate(conn);
|
||||
if(result) {
|
||||
connclose(conn, "SMB: failed to send negotiate message");
|
||||
return result;
|
||||
}
|
||||
|
||||
conn_state(conn, SMB_NEGOTIATE);
|
||||
}
|
||||
|
||||
/* Send the previous message and check for a response */
|
||||
result = smb_send_and_recv(conn, &msg);
|
||||
if(result && result != CURLE_AGAIN) {
|
||||
connclose(conn, "SMB: failed to communicate");
|
||||
return result;
|
||||
}
|
||||
|
||||
if(!msg)
|
||||
return CURLE_OK;
|
||||
|
||||
h = msg;
|
||||
|
||||
switch(smbc->state) {
|
||||
case SMB_NEGOTIATE:
|
||||
if(h->status || smbc->got < sizeof(*nrsp) + sizeof(smbc->challenge) - 1) {
|
||||
connclose(conn, "SMB: negotiation failed");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
nrsp = msg;
|
||||
memcpy(smbc->challenge, nrsp->bytes, sizeof(smbc->challenge));
|
||||
smbc->session_key = smb_swap32(nrsp->session_key);
|
||||
result = smb_send_setup(conn);
|
||||
if(result) {
|
||||
connclose(conn, "SMB: failed to send setup message");
|
||||
return result;
|
||||
}
|
||||
conn_state(conn, SMB_SETUP);
|
||||
break;
|
||||
|
||||
case SMB_SETUP:
|
||||
if(h->status) {
|
||||
connclose(conn, "SMB: authentication failed");
|
||||
return CURLE_LOGIN_DENIED;
|
||||
}
|
||||
smbc->uid = smb_swap16(h->uid);
|
||||
conn_state(conn, SMB_CONNECTED);
|
||||
*done = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
smb_pop_message(conn);
|
||||
return CURLE_OK; /* ignore */
|
||||
}
|
||||
|
||||
smb_pop_message(conn);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode smb_request_state(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct smb_request *req = conn->data->req.protop;
|
||||
struct smb_header *h;
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
enum smb_req_state next_state = SMB_DONE;
|
||||
unsigned short len;
|
||||
unsigned short off;
|
||||
CURLcode result;
|
||||
void *msg = NULL;
|
||||
|
||||
/* Start the request */
|
||||
if(req->state == SMB_REQUESTING) {
|
||||
result = smb_send_tree_connect(conn);
|
||||
if(result) {
|
||||
connclose(conn, "SMB: failed to send tree connect message");
|
||||
return result;
|
||||
}
|
||||
|
||||
request_state(conn, SMB_TREE_CONNECT);
|
||||
}
|
||||
|
||||
/* Send the previous message and check for a response */
|
||||
result = smb_send_and_recv(conn, &msg);
|
||||
if(result && result != CURLE_AGAIN) {
|
||||
connclose(conn, "SMB: failed to communicate");
|
||||
return result;
|
||||
}
|
||||
|
||||
if(!msg)
|
||||
return CURLE_OK;
|
||||
|
||||
h = msg;
|
||||
|
||||
switch(req->state) {
|
||||
case SMB_TREE_CONNECT:
|
||||
if(h->status) {
|
||||
req->result = CURLE_REMOTE_FILE_NOT_FOUND;
|
||||
if(h->status == smb_swap32(SMB_ERR_NOACCESS))
|
||||
req->result = CURLE_REMOTE_ACCESS_DENIED;
|
||||
break;
|
||||
}
|
||||
req->tid = smb_swap16(h->tid);
|
||||
next_state = SMB_OPEN;
|
||||
break;
|
||||
|
||||
case SMB_OPEN:
|
||||
if(h->status || smbc->got < sizeof(struct smb_nt_create_response)) {
|
||||
req->result = CURLE_REMOTE_FILE_NOT_FOUND;
|
||||
next_state = SMB_TREE_DISCONNECT;
|
||||
break;
|
||||
}
|
||||
req->fid = smb_swap16(((struct smb_nt_create_response *)msg)->fid);
|
||||
conn->data->req.offset = 0;
|
||||
if(conn->data->set.upload) {
|
||||
conn->data->req.size = conn->data->state.infilesize;
|
||||
Curl_pgrsSetUploadSize(conn->data, conn->data->req.size);
|
||||
next_state = SMB_UPLOAD;
|
||||
}
|
||||
else {
|
||||
conn->data->req.size =
|
||||
smb_swap64(((struct smb_nt_create_response *)msg)->end_of_file);
|
||||
Curl_pgrsSetDownloadSize(conn->data, conn->data->req.size);
|
||||
next_state = SMB_DOWNLOAD;
|
||||
}
|
||||
break;
|
||||
|
||||
case SMB_DOWNLOAD:
|
||||
if(h->status || smbc->got < sizeof(struct smb_header) + 14) {
|
||||
req->result = CURLE_RECV_ERROR;
|
||||
next_state = SMB_CLOSE;
|
||||
break;
|
||||
}
|
||||
len = Curl_read16_le(((const unsigned char *) msg) +
|
||||
sizeof(struct smb_header) + 11);
|
||||
off = Curl_read16_le(((const unsigned char *) msg) +
|
||||
sizeof(struct smb_header) + 13);
|
||||
if(len > 0) {
|
||||
if(off + sizeof(unsigned int) + len > smbc->got) {
|
||||
failf(conn->data, "Invalid input packet");
|
||||
result = CURLE_RECV_ERROR;
|
||||
}
|
||||
else
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY,
|
||||
(char *)msg + off + sizeof(unsigned int),
|
||||
len);
|
||||
if(result) {
|
||||
req->result = result;
|
||||
next_state = SMB_CLOSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
conn->data->req.bytecount += len;
|
||||
conn->data->req.offset += len;
|
||||
Curl_pgrsSetDownloadCounter(conn->data, conn->data->req.bytecount);
|
||||
next_state = (len < MAX_PAYLOAD_SIZE) ? SMB_CLOSE : SMB_DOWNLOAD;
|
||||
break;
|
||||
|
||||
case SMB_UPLOAD:
|
||||
if(h->status || smbc->got < sizeof(struct smb_header) + 6) {
|
||||
req->result = CURLE_UPLOAD_FAILED;
|
||||
next_state = SMB_CLOSE;
|
||||
break;
|
||||
}
|
||||
len = Curl_read16_le(((const unsigned char *) msg) +
|
||||
sizeof(struct smb_header) + 5);
|
||||
conn->data->req.bytecount += len;
|
||||
conn->data->req.offset += len;
|
||||
Curl_pgrsSetUploadCounter(conn->data, conn->data->req.bytecount);
|
||||
if(conn->data->req.bytecount >= conn->data->req.size)
|
||||
next_state = SMB_CLOSE;
|
||||
else
|
||||
next_state = SMB_UPLOAD;
|
||||
break;
|
||||
|
||||
case SMB_CLOSE:
|
||||
/* We don't care if the close failed, proceed to tree disconnect anyway */
|
||||
next_state = SMB_TREE_DISCONNECT;
|
||||
break;
|
||||
|
||||
case SMB_TREE_DISCONNECT:
|
||||
next_state = SMB_DONE;
|
||||
break;
|
||||
|
||||
default:
|
||||
smb_pop_message(conn);
|
||||
return CURLE_OK; /* ignore */
|
||||
}
|
||||
|
||||
smb_pop_message(conn);
|
||||
|
||||
switch(next_state) {
|
||||
case SMB_OPEN:
|
||||
result = smb_send_open(conn);
|
||||
break;
|
||||
|
||||
case SMB_DOWNLOAD:
|
||||
result = smb_send_read(conn);
|
||||
break;
|
||||
|
||||
case SMB_UPLOAD:
|
||||
result = smb_send_write(conn);
|
||||
break;
|
||||
|
||||
case SMB_CLOSE:
|
||||
result = smb_send_close(conn);
|
||||
break;
|
||||
|
||||
case SMB_TREE_DISCONNECT:
|
||||
result = smb_send_tree_disconnect(conn);
|
||||
break;
|
||||
|
||||
case SMB_DONE:
|
||||
result = req->result;
|
||||
*done = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(result) {
|
||||
connclose(conn, "SMB: failed to send message");
|
||||
return result;
|
||||
}
|
||||
|
||||
request_state(conn, next_state);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode smb_done(struct connectdata *conn, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
struct smb_request *req = conn->data->req.protop;
|
||||
|
||||
(void) premature;
|
||||
|
||||
Curl_safefree(req->share);
|
||||
Curl_safefree(conn->data->req.protop);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static CURLcode smb_disconnect(struct connectdata *conn, bool dead)
|
||||
{
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
struct smb_request *req = conn->data->req.protop;
|
||||
|
||||
(void) dead;
|
||||
|
||||
Curl_safefree(smbc->domain);
|
||||
Curl_safefree(smbc->recv_buf);
|
||||
|
||||
/* smb_done is not always called, so cleanup the request */
|
||||
if(req) {
|
||||
Curl_safefree(req->share);
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
|
||||
int numsocks)
|
||||
{
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
|
||||
if(!numsocks)
|
||||
return GETSOCK_BLANK;
|
||||
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
|
||||
if(smbc->send_size || smbc->upload_size)
|
||||
return GETSOCK_WRITESOCK(0);
|
||||
|
||||
return GETSOCK_READSOCK(0);
|
||||
}
|
||||
|
||||
static CURLcode smb_parse_url_path(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct smb_request *req = data->req.protop;
|
||||
char *path;
|
||||
char *slash;
|
||||
|
||||
/* URL decode the path */
|
||||
result = Curl_urldecode(data, data->state.path, 0, &path, NULL, TRUE);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Parse the path for the share */
|
||||
req->share = strdup((*path == '/' || *path == '\\') ? path + 1 : path);
|
||||
if(!req->share) {
|
||||
free(path);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
slash = strchr(req->share, '/');
|
||||
if(!slash)
|
||||
slash = strchr(req->share, '\\');
|
||||
|
||||
/* The share must be present */
|
||||
if(!slash) {
|
||||
free(path);
|
||||
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
/* Parse the path for the file path converting any forward slashes into
|
||||
backslashes */
|
||||
*slash++ = 0;
|
||||
req->path = slash;
|
||||
for(; *slash; slash++) {
|
||||
if(*slash == '/')
|
||||
*slash = '\\';
|
||||
}
|
||||
|
||||
free(path);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
|
||||
|
||||
#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */
|
||||
@@ -1,271 +0,0 @@
|
||||
#ifndef HEADER_CURL_SMB_H
|
||||
#define HEADER_CURL_SMB_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
enum smb_conn_state {
|
||||
SMB_NOT_CONNECTED = 0,
|
||||
SMB_CONNECTING,
|
||||
SMB_NEGOTIATE,
|
||||
SMB_SETUP,
|
||||
SMB_CONNECTED
|
||||
};
|
||||
|
||||
struct smb_conn {
|
||||
enum smb_conn_state state;
|
||||
char *user;
|
||||
char *domain;
|
||||
unsigned char challenge[8];
|
||||
unsigned int session_key;
|
||||
unsigned short uid;
|
||||
char *recv_buf;
|
||||
size_t upload_size;
|
||||
size_t send_size;
|
||||
size_t sent;
|
||||
size_t got;
|
||||
};
|
||||
|
||||
/*
|
||||
* Definitions for SMB protocol data structures
|
||||
*/
|
||||
#ifdef BUILDING_CURL_SMB_C
|
||||
|
||||
#if defined(_MSC_VER) || defined(__ILEC400__)
|
||||
# define PACK
|
||||
# pragma pack(push)
|
||||
# pragma pack(1)
|
||||
#elif defined(__GNUC__)
|
||||
# define PACK __attribute__((packed))
|
||||
#else
|
||||
# define PACK
|
||||
#endif
|
||||
|
||||
#define SMB_COM_CLOSE 0x04
|
||||
#define SMB_COM_READ_ANDX 0x2e
|
||||
#define SMB_COM_WRITE_ANDX 0x2f
|
||||
#define SMB_COM_TREE_DISCONNECT 0x71
|
||||
#define SMB_COM_NEGOTIATE 0x72
|
||||
#define SMB_COM_SETUP_ANDX 0x73
|
||||
#define SMB_COM_TREE_CONNECT_ANDX 0x75
|
||||
#define SMB_COM_NT_CREATE_ANDX 0xa2
|
||||
#define SMB_COM_NO_ANDX_COMMAND 0xff
|
||||
|
||||
#define SMB_WC_CLOSE 0x03
|
||||
#define SMB_WC_READ_ANDX 0x0c
|
||||
#define SMB_WC_WRITE_ANDX 0x0e
|
||||
#define SMB_WC_SETUP_ANDX 0x0d
|
||||
#define SMB_WC_TREE_CONNECT_ANDX 0x04
|
||||
#define SMB_WC_NT_CREATE_ANDX 0x18
|
||||
|
||||
#define SMB_FLAGS_CANONICAL_PATHNAMES 0x10
|
||||
#define SMB_FLAGS_CASELESS_PATHNAMES 0x08
|
||||
#define SMB_FLAGS2_UNICODE_STRINGS 0x8000
|
||||
#define SMB_FLAGS2_IS_LONG_NAME 0x0040
|
||||
#define SMB_FLAGS2_KNOWS_LONG_NAME 0x0001
|
||||
|
||||
#define SMB_CAP_LARGE_FILES 0x08
|
||||
#define SMB_GENERIC_WRITE 0x40000000
|
||||
#define SMB_GENERIC_READ 0x80000000
|
||||
#define SMB_FILE_SHARE_ALL 0x07
|
||||
#define SMB_FILE_OPEN 0x01
|
||||
#define SMB_FILE_OVERWRITE_IF 0x05
|
||||
|
||||
#define SMB_ERR_NOACCESS 0x00050001
|
||||
|
||||
struct smb_header {
|
||||
unsigned char nbt_type;
|
||||
unsigned char nbt_flags;
|
||||
unsigned short nbt_length;
|
||||
unsigned char magic[4];
|
||||
unsigned char command;
|
||||
unsigned int status;
|
||||
unsigned char flags;
|
||||
unsigned short flags2;
|
||||
unsigned short pid_high;
|
||||
unsigned char signature[8];
|
||||
unsigned short pad;
|
||||
unsigned short tid;
|
||||
unsigned short pid;
|
||||
unsigned short uid;
|
||||
unsigned short mid;
|
||||
} PACK;
|
||||
|
||||
struct smb_negotiate_response {
|
||||
struct smb_header h;
|
||||
unsigned char word_count;
|
||||
unsigned short dialect_index;
|
||||
unsigned char security_mode;
|
||||
unsigned short max_mpx_count;
|
||||
unsigned short max_number_vcs;
|
||||
unsigned int max_buffer_size;
|
||||
unsigned int max_raw_size;
|
||||
unsigned int session_key;
|
||||
unsigned int capabilities;
|
||||
unsigned int system_time_low;
|
||||
unsigned int system_time_high;
|
||||
unsigned short server_time_zone;
|
||||
unsigned char encryption_key_length;
|
||||
unsigned short byte_count;
|
||||
char bytes[1];
|
||||
} PACK;
|
||||
|
||||
struct andx {
|
||||
unsigned char command;
|
||||
unsigned char pad;
|
||||
unsigned short offset;
|
||||
} PACK;
|
||||
|
||||
struct smb_setup {
|
||||
unsigned char word_count;
|
||||
struct andx andx;
|
||||
unsigned short max_buffer_size;
|
||||
unsigned short max_mpx_count;
|
||||
unsigned short vc_number;
|
||||
unsigned int session_key;
|
||||
unsigned short lengths[2];
|
||||
unsigned int pad;
|
||||
unsigned int capabilities;
|
||||
unsigned short byte_count;
|
||||
char bytes[1024];
|
||||
} PACK;
|
||||
|
||||
struct smb_tree_connect {
|
||||
unsigned char word_count;
|
||||
struct andx andx;
|
||||
unsigned short flags;
|
||||
unsigned short pw_len;
|
||||
unsigned short byte_count;
|
||||
char bytes[1024];
|
||||
} PACK;
|
||||
|
||||
struct smb_nt_create {
|
||||
unsigned char word_count;
|
||||
struct andx andx;
|
||||
unsigned char pad;
|
||||
unsigned short name_length;
|
||||
unsigned int flags;
|
||||
unsigned int root_fid;
|
||||
unsigned int access;
|
||||
#ifdef HAVE_LONGLONG
|
||||
unsigned long long allocation_size;
|
||||
#else
|
||||
unsigned __int64 allocation_size;
|
||||
#endif
|
||||
unsigned int ext_file_attributes;
|
||||
unsigned int share_access;
|
||||
unsigned int create_disposition;
|
||||
unsigned int create_options;
|
||||
unsigned int impersonation_level;
|
||||
unsigned char security_flags;
|
||||
unsigned short byte_count;
|
||||
char bytes[1024];
|
||||
} PACK;
|
||||
|
||||
struct smb_nt_create_response {
|
||||
struct smb_header h;
|
||||
unsigned char word_count;
|
||||
struct andx andx;
|
||||
unsigned char op_lock_level;
|
||||
unsigned short fid;
|
||||
unsigned int create_disposition;
|
||||
#ifdef HAVE_LONGLONG
|
||||
unsigned long long create_time;
|
||||
unsigned long long last_access_time;
|
||||
unsigned long long last_write_time;
|
||||
unsigned long long last_change_time;
|
||||
#else
|
||||
unsigned __int64 create_time;
|
||||
unsigned __int64 last_access_time;
|
||||
unsigned __int64 last_write_time;
|
||||
unsigned __int64 last_change_time;
|
||||
#endif
|
||||
unsigned int ext_file_attributes;
|
||||
#ifdef HAVE_LONGLONG
|
||||
unsigned long long allocation_size;
|
||||
unsigned long long end_of_file;
|
||||
#else
|
||||
unsigned __int64 allocation_size;
|
||||
unsigned __int64 end_of_file;
|
||||
#endif
|
||||
} PACK;
|
||||
|
||||
struct smb_read {
|
||||
unsigned char word_count;
|
||||
struct andx andx;
|
||||
unsigned short fid;
|
||||
unsigned int offset;
|
||||
unsigned short max_bytes;
|
||||
unsigned short min_bytes;
|
||||
unsigned int timeout;
|
||||
unsigned short remaining;
|
||||
unsigned int offset_high;
|
||||
unsigned short byte_count;
|
||||
} PACK;
|
||||
|
||||
struct smb_write {
|
||||
struct smb_header h;
|
||||
unsigned char word_count;
|
||||
struct andx andx;
|
||||
unsigned short fid;
|
||||
unsigned int offset;
|
||||
unsigned int timeout;
|
||||
unsigned short write_mode;
|
||||
unsigned short remaining;
|
||||
unsigned short pad;
|
||||
unsigned short data_length;
|
||||
unsigned short data_offset;
|
||||
unsigned int offset_high;
|
||||
unsigned short byte_count;
|
||||
unsigned char pad2;
|
||||
} PACK;
|
||||
|
||||
struct smb_close {
|
||||
unsigned char word_count;
|
||||
unsigned short fid;
|
||||
unsigned int last_mtime;
|
||||
unsigned short byte_count;
|
||||
} PACK;
|
||||
|
||||
struct smb_tree_disconnect {
|
||||
unsigned char word_count;
|
||||
unsigned short byte_count;
|
||||
} PACK;
|
||||
|
||||
#if defined(_MSC_VER) || defined(__ILEC400__)
|
||||
# pragma pack(pop)
|
||||
#endif
|
||||
|
||||
#endif /* BUILDING_CURL_SMB_C */
|
||||
|
||||
#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
|
||||
(CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
|
||||
#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
|
||||
|
||||
extern const struct Curl_handler Curl_handler_smb;
|
||||
extern const struct Curl_handler Curl_handler_smbs;
|
||||
|
||||
#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
|
||||
|
||||
#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */
|
||||
|
||||
#endif /* HEADER_CURL_SMB_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,91 +0,0 @@
|
||||
#ifndef HEADER_CURL_SMTP_H
|
||||
#define HEADER_CURL_SMTP_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2009 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "pingpong.h"
|
||||
#include "curl_sasl.h"
|
||||
|
||||
/****************************************************************************
|
||||
* SMTP unique setup
|
||||
***************************************************************************/
|
||||
typedef enum {
|
||||
SMTP_STOP, /* do nothing state, stops the state machine */
|
||||
SMTP_SERVERGREET, /* waiting for the initial greeting immediately after
|
||||
a connect */
|
||||
SMTP_EHLO,
|
||||
SMTP_HELO,
|
||||
SMTP_STARTTLS,
|
||||
SMTP_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS
|
||||
(multi mode only) */
|
||||
SMTP_AUTH,
|
||||
SMTP_COMMAND, /* VRFY, EXPN, NOOP, RSET and HELP */
|
||||
SMTP_MAIL, /* MAIL FROM */
|
||||
SMTP_RCPT, /* RCPT TO */
|
||||
SMTP_DATA,
|
||||
SMTP_POSTDATA,
|
||||
SMTP_QUIT,
|
||||
SMTP_LAST /* never used */
|
||||
} smtpstate;
|
||||
|
||||
/* This SMTP struct is used in the Curl_easy. All SMTP data that is
|
||||
connection-oriented must be in smtp_conn to properly deal with the fact that
|
||||
perhaps the Curl_easy is changed between the times the connection is
|
||||
used. */
|
||||
struct SMTP {
|
||||
curl_pp_transfer transfer;
|
||||
char *custom; /* Custom Request */
|
||||
struct curl_slist *rcpt; /* Recipient list */
|
||||
size_t eob; /* Number of bytes of the EOB (End Of Body) that
|
||||
have been received so far */
|
||||
bool trailing_crlf; /* Specifies if the tailing CRLF is present */
|
||||
};
|
||||
|
||||
/* smtp_conn is used for struct connection-oriented data in the connectdata
|
||||
struct */
|
||||
struct smtp_conn {
|
||||
struct pingpong pp;
|
||||
smtpstate state; /* Always use smtp.c:state() to change state! */
|
||||
bool ssldone; /* Is connect() over SSL done? */
|
||||
char *domain; /* Client address/name to send in the EHLO */
|
||||
struct SASL sasl; /* SASL-related storage */
|
||||
bool tls_supported; /* StartTLS capability supported by server */
|
||||
bool size_supported; /* If server supports SIZE extension according to
|
||||
RFC 1870 */
|
||||
bool auth_supported; /* AUTH capability supported by server */
|
||||
};
|
||||
|
||||
extern const struct Curl_handler Curl_handler_smtp;
|
||||
extern const struct Curl_handler Curl_handler_smtps;
|
||||
|
||||
/* this is the 5-bytes End-Of-Body marker for SMTP */
|
||||
#define SMTP_EOB "\x0d\x0a\x2e\x0d\x0a"
|
||||
#define SMTP_EOB_LEN 5
|
||||
#define SMTP_EOB_FIND_LEN 3
|
||||
|
||||
/* if found in data, replace it with this string instead */
|
||||
#define SMTP_EOB_REPL "\x0d\x0a\x2e\x2e"
|
||||
#define SMTP_EOB_REPL_LEN 4
|
||||
|
||||
CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread);
|
||||
|
||||
#endif /* HEADER_CURL_SMTP_H */
|
||||
@@ -1,43 +0,0 @@
|
||||
#ifndef HEADER_CURL_SOCKADDR_H
|
||||
#define HEADER_CURL_SOCKADDR_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
struct Curl_sockaddr_storage {
|
||||
union {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in sa_in;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_in6 sa_in6;
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
|
||||
struct sockaddr_storage sa_stor;
|
||||
#else
|
||||
char cbuf[256]; /* this should be big enough to fit a lot */
|
||||
#endif
|
||||
} buffer;
|
||||
};
|
||||
|
||||
#endif /* HEADER_CURL_SOCKADDR_H */
|
||||
|
||||
@@ -1,784 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_PROXY)
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "select.h"
|
||||
#include "connect.h"
|
||||
#include "timeval.h"
|
||||
#include "socks.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* Helper read-from-socket functions. Does the same as Curl_read() but it
|
||||
* blocks until all bytes amount of buffersize will be read. No more, no less.
|
||||
*
|
||||
* This is STUPID BLOCKING behaviour which we frown upon, but right now this
|
||||
* is what we have...
|
||||
*/
|
||||
int Curl_blockread_all(struct connectdata *conn, /* connection data */
|
||||
curl_socket_t sockfd, /* read from this socket */
|
||||
char *buf, /* store read data here */
|
||||
ssize_t buffersize, /* max amount to read */
|
||||
ssize_t *n) /* amount bytes read */
|
||||
{
|
||||
ssize_t nread;
|
||||
ssize_t allread = 0;
|
||||
int result;
|
||||
time_t timeleft;
|
||||
*n = 0;
|
||||
for(;;) {
|
||||
timeleft = Curl_timeleft(conn->data, NULL, TRUE);
|
||||
if(timeleft < 0) {
|
||||
/* we already got the timeout */
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
break;
|
||||
}
|
||||
if(SOCKET_READABLE(sockfd, timeleft) <= 0) {
|
||||
result = ~CURLE_OK;
|
||||
break;
|
||||
}
|
||||
result = Curl_read_plain(sockfd, buf, buffersize, &nread);
|
||||
if(CURLE_AGAIN == result)
|
||||
continue;
|
||||
else if(result)
|
||||
break;
|
||||
|
||||
if(buffersize == nread) {
|
||||
allread += nread;
|
||||
*n = allread;
|
||||
result = CURLE_OK;
|
||||
break;
|
||||
}
|
||||
if(!nread) {
|
||||
result = ~CURLE_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
buffersize -= nread;
|
||||
buf += nread;
|
||||
allread += nread;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function logs in to a SOCKS4 proxy and sends the specifics to the final
|
||||
* destination server.
|
||||
*
|
||||
* Reference :
|
||||
* http://socks.permeo.com/protocol/socks4.protocol
|
||||
*
|
||||
* Note :
|
||||
* Set protocol4a=true for "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)"
|
||||
* Nonsupport "Identification Protocol (RFC1413)"
|
||||
*/
|
||||
CURLcode Curl_SOCKS4(const char *proxy_name,
|
||||
const char *hostname,
|
||||
int remote_port,
|
||||
int sockindex,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
const bool protocol4a =
|
||||
(conn->socks_proxy.proxytype == CURLPROXY_SOCKS4A) ? TRUE : FALSE;
|
||||
#define SOCKS4REQLEN 262
|
||||
unsigned char socksreq[SOCKS4REQLEN]; /* room for SOCKS4 request incl. user
|
||||
id */
|
||||
int result;
|
||||
CURLcode code;
|
||||
curl_socket_t sock = conn->sock[sockindex];
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
if(Curl_timeleft(data, NULL, TRUE) < 0) {
|
||||
/* time-out, bail out, go home */
|
||||
failf(data, "Connection time-out");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
|
||||
if(conn->bits.httpproxy)
|
||||
infof(conn->data, "SOCKS4%s: connecting to HTTP proxy %s port %d\n",
|
||||
protocol4a ? "a" : "", hostname, remote_port);
|
||||
|
||||
(void)curlx_nonblock(sock, FALSE);
|
||||
|
||||
infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port);
|
||||
|
||||
/*
|
||||
* Compose socks4 request
|
||||
*
|
||||
* Request format
|
||||
*
|
||||
* +----+----+----+----+----+----+----+----+----+----+....+----+
|
||||
* | VN | CD | DSTPORT | DSTIP | USERID |NULL|
|
||||
* +----+----+----+----+----+----+----+----+----+----+....+----+
|
||||
* # of bytes: 1 1 2 4 variable 1
|
||||
*/
|
||||
|
||||
socksreq[0] = 4; /* version (SOCKS4) */
|
||||
socksreq[1] = 1; /* connect */
|
||||
socksreq[2] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */
|
||||
socksreq[3] = (unsigned char)(remote_port & 0xff); /* PORT LSB */
|
||||
|
||||
/* DNS resolve only for SOCKS4, not SOCKS4a */
|
||||
if(!protocol4a) {
|
||||
struct Curl_dns_entry *dns;
|
||||
Curl_addrinfo *hp=NULL;
|
||||
int rc;
|
||||
|
||||
rc = Curl_resolv(conn, hostname, remote_port, &dns);
|
||||
|
||||
if(rc == CURLRESOLV_ERROR)
|
||||
return CURLE_COULDNT_RESOLVE_PROXY;
|
||||
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
/* ignores the return code, but 'dns' remains NULL on failure */
|
||||
(void)Curl_resolver_wait_resolv(conn, &dns);
|
||||
|
||||
/*
|
||||
* We cannot use 'hostent' as a struct that Curl_resolv() returns. It
|
||||
* returns a Curl_addrinfo pointer that may not always look the same.
|
||||
*/
|
||||
if(dns)
|
||||
hp=dns->addr;
|
||||
if(hp) {
|
||||
char buf[64];
|
||||
Curl_printable_address(hp, buf, sizeof(buf));
|
||||
|
||||
if(hp->ai_family == AF_INET) {
|
||||
struct sockaddr_in *saddr_in;
|
||||
|
||||
saddr_in = (struct sockaddr_in *)(void *)hp->ai_addr;
|
||||
socksreq[4] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[0];
|
||||
socksreq[5] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[1];
|
||||
socksreq[6] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[2];
|
||||
socksreq[7] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[3];
|
||||
|
||||
infof(data, "SOCKS4 connect to IPv4 %s (locally resolved)\n", buf);
|
||||
}
|
||||
else {
|
||||
hp = NULL; /* fail! */
|
||||
|
||||
failf(data, "SOCKS4 connection to %s not supported\n", buf);
|
||||
}
|
||||
|
||||
Curl_resolv_unlock(data, dns); /* not used anymore from now on */
|
||||
}
|
||||
if(!hp) {
|
||||
failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.",
|
||||
hostname);
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is currently not supporting "Identification Protocol (RFC1413)".
|
||||
*/
|
||||
socksreq[8] = 0; /* ensure empty userid is NUL-terminated */
|
||||
if(proxy_name) {
|
||||
size_t plen = strlen(proxy_name);
|
||||
if(plen >= sizeof(socksreq) - 8) {
|
||||
failf(data, "Too long SOCKS proxy name, can't use!\n");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
/* copy the proxy name WITH trailing zero */
|
||||
memcpy(socksreq + 8, proxy_name, plen+1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make connection
|
||||
*/
|
||||
{
|
||||
ssize_t actualread;
|
||||
ssize_t written;
|
||||
ssize_t hostnamelen = 0;
|
||||
int packetsize = 9 +
|
||||
(int)strlen((char *)socksreq + 8); /* size including NUL */
|
||||
|
||||
/* If SOCKS4a, set special invalid IP address 0.0.0.x */
|
||||
if(protocol4a) {
|
||||
socksreq[4] = 0;
|
||||
socksreq[5] = 0;
|
||||
socksreq[6] = 0;
|
||||
socksreq[7] = 1;
|
||||
/* If still enough room in buffer, also append hostname */
|
||||
hostnamelen = (ssize_t)strlen(hostname) + 1; /* length including NUL */
|
||||
if(packetsize + hostnamelen <= SOCKS4REQLEN)
|
||||
strcpy((char *)socksreq + packetsize, hostname);
|
||||
else
|
||||
hostnamelen = 0; /* Flag: hostname did not fit in buffer */
|
||||
}
|
||||
|
||||
/* Send request */
|
||||
code = Curl_write_plain(conn, sock, (char *)socksreq,
|
||||
packetsize + hostnamelen,
|
||||
&written);
|
||||
if(code || (written != packetsize + hostnamelen)) {
|
||||
failf(data, "Failed to send SOCKS4 connect request.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
if(protocol4a && hostnamelen == 0) {
|
||||
/* SOCKS4a with very long hostname - send that name separately */
|
||||
hostnamelen = (ssize_t)strlen(hostname) + 1;
|
||||
code = Curl_write_plain(conn, sock, (char *)hostname, hostnamelen,
|
||||
&written);
|
||||
if(code || (written != hostnamelen)) {
|
||||
failf(data, "Failed to send SOCKS4 connect request.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
}
|
||||
|
||||
packetsize = 8; /* receive data size */
|
||||
|
||||
/* Receive response */
|
||||
result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize,
|
||||
&actualread);
|
||||
if(result || (actualread != packetsize)) {
|
||||
failf(data, "Failed to receive SOCKS4 connect request ack.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Response format
|
||||
*
|
||||
* +----+----+----+----+----+----+----+----+
|
||||
* | VN | CD | DSTPORT | DSTIP |
|
||||
* +----+----+----+----+----+----+----+----+
|
||||
* # of bytes: 1 1 2 4
|
||||
*
|
||||
* VN is the version of the reply code and should be 0. CD is the result
|
||||
* code with one of the following values:
|
||||
*
|
||||
* 90: request granted
|
||||
* 91: request rejected or failed
|
||||
* 92: request rejected because SOCKS server cannot connect to
|
||||
* identd on the client
|
||||
* 93: request rejected because the client program and identd
|
||||
* report different user-ids
|
||||
*/
|
||||
|
||||
/* wrong version ? */
|
||||
if(socksreq[0] != 0) {
|
||||
failf(data,
|
||||
"SOCKS4 reply has wrong version, version should be 4.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
/* Result */
|
||||
switch(socksreq[1]) {
|
||||
case 90:
|
||||
infof(data, "SOCKS4%s request granted.\n", protocol4a?"a":"");
|
||||
break;
|
||||
case 91:
|
||||
failf(data,
|
||||
"Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
|
||||
", request rejected or failed.",
|
||||
(unsigned char)socksreq[4], (unsigned char)socksreq[5],
|
||||
(unsigned char)socksreq[6], (unsigned char)socksreq[7],
|
||||
(((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
|
||||
(unsigned char)socksreq[1]);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
case 92:
|
||||
failf(data,
|
||||
"Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
|
||||
", request rejected because SOCKS server cannot connect to "
|
||||
"identd on the client.",
|
||||
(unsigned char)socksreq[4], (unsigned char)socksreq[5],
|
||||
(unsigned char)socksreq[6], (unsigned char)socksreq[7],
|
||||
(((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
|
||||
(unsigned char)socksreq[1]);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
case 93:
|
||||
failf(data,
|
||||
"Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
|
||||
", request rejected because the client program and identd "
|
||||
"report different user-ids.",
|
||||
(unsigned char)socksreq[4], (unsigned char)socksreq[5],
|
||||
(unsigned char)socksreq[6], (unsigned char)socksreq[7],
|
||||
(((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
|
||||
(unsigned char)socksreq[1]);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
default:
|
||||
failf(data,
|
||||
"Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
|
||||
", Unknown.",
|
||||
(unsigned char)socksreq[4], (unsigned char)socksreq[5],
|
||||
(unsigned char)socksreq[6], (unsigned char)socksreq[7],
|
||||
(((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
|
||||
(unsigned char)socksreq[1]);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
}
|
||||
|
||||
(void)curlx_nonblock(sock, TRUE);
|
||||
|
||||
return CURLE_OK; /* Proxy was successful! */
|
||||
}
|
||||
|
||||
/*
|
||||
* This function logs in to a SOCKS5 proxy and sends the specifics to the final
|
||||
* destination server.
|
||||
*/
|
||||
CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
const char *proxy_password,
|
||||
const char *hostname,
|
||||
int remote_port,
|
||||
int sockindex,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
/*
|
||||
According to the RFC1928, section "6. Replies". This is what a SOCK5
|
||||
replies:
|
||||
|
||||
+----+-----+-------+------+----------+----------+
|
||||
|VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
|
||||
+----+-----+-------+------+----------+----------+
|
||||
| 1 | 1 | X'00' | 1 | Variable | 2 |
|
||||
+----+-----+-------+------+----------+----------+
|
||||
|
||||
Where:
|
||||
|
||||
o VER protocol version: X'05'
|
||||
o REP Reply field:
|
||||
o X'00' succeeded
|
||||
*/
|
||||
|
||||
unsigned char socksreq[600]; /* room for large user/pw (255 max each) */
|
||||
ssize_t actualread;
|
||||
ssize_t written;
|
||||
int result;
|
||||
CURLcode code;
|
||||
curl_socket_t sock = conn->sock[sockindex];
|
||||
struct Curl_easy *data = conn->data;
|
||||
time_t timeout;
|
||||
bool socks5_resolve_local =
|
||||
(conn->socks_proxy.proxytype == CURLPROXY_SOCKS5) ? TRUE : FALSE;
|
||||
const size_t hostname_len = strlen(hostname);
|
||||
ssize_t len = 0;
|
||||
|
||||
if(conn->bits.httpproxy)
|
||||
infof(conn->data, "SOCKS5: connecting to HTTP proxy %s port %d\n",
|
||||
hostname, remote_port);
|
||||
|
||||
/* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
|
||||
if(!socks5_resolve_local && hostname_len > 255) {
|
||||
infof(conn->data, "SOCKS5: server resolving disabled for hostnames of "
|
||||
"length > 255 [actual len=%zu]\n", hostname_len);
|
||||
socks5_resolve_local = TRUE;
|
||||
}
|
||||
|
||||
/* get timeout */
|
||||
timeout = Curl_timeleft(data, NULL, TRUE);
|
||||
|
||||
if(timeout < 0) {
|
||||
/* time-out, bail out, go home */
|
||||
failf(data, "Connection time-out");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
|
||||
(void)curlx_nonblock(sock, TRUE);
|
||||
|
||||
/* wait until socket gets connected */
|
||||
result = SOCKET_WRITABLE(sock, timeout);
|
||||
|
||||
if(-1 == result) {
|
||||
failf(conn->data, "SOCKS5: no connection here");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
else if(0 == result) {
|
||||
failf(conn->data, "SOCKS5: connection timeout");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
|
||||
if(result & CURL_CSELECT_ERR) {
|
||||
failf(conn->data, "SOCKS5: error occurred during connection");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
socksreq[0] = 5; /* version */
|
||||
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
|
||||
socksreq[1] = (char)(proxy_name ? 3 : 2); /* number of methods (below) */
|
||||
socksreq[2] = 0; /* no authentication */
|
||||
socksreq[3] = 1; /* GSS-API */
|
||||
socksreq[4] = 2; /* username/password */
|
||||
#else
|
||||
socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */
|
||||
socksreq[2] = 0; /* no authentication */
|
||||
socksreq[3] = 2; /* username/password */
|
||||
#endif
|
||||
|
||||
(void)curlx_nonblock(sock, FALSE);
|
||||
|
||||
infof(data, "SOCKS5 communication to %s:%d\n", hostname, remote_port);
|
||||
|
||||
code = Curl_write_plain(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
|
||||
&written);
|
||||
if(code || (written != (2 + (int)socksreq[1]))) {
|
||||
failf(data, "Unable to send initial SOCKS5 request.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
(void)curlx_nonblock(sock, TRUE);
|
||||
|
||||
result = SOCKET_READABLE(sock, timeout);
|
||||
|
||||
if(-1 == result) {
|
||||
failf(conn->data, "SOCKS5 nothing to read");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
else if(0 == result) {
|
||||
failf(conn->data, "SOCKS5 read timeout");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
|
||||
if(result & CURL_CSELECT_ERR) {
|
||||
failf(conn->data, "SOCKS5 read error occurred");
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
(void)curlx_nonblock(sock, FALSE);
|
||||
|
||||
result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
|
||||
if(result || (actualread != 2)) {
|
||||
failf(data, "Unable to receive initial SOCKS5 response.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
if(socksreq[0] != 5) {
|
||||
failf(data, "Received invalid version in initial SOCKS5 response.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
if(socksreq[1] == 0) {
|
||||
/* Nothing to do, no authentication needed */
|
||||
;
|
||||
}
|
||||
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
|
||||
else if(socksreq[1] == 1) {
|
||||
code = Curl_SOCKS5_gssapi_negotiate(sockindex, conn);
|
||||
if(code) {
|
||||
failf(data, "Unable to negotiate SOCKS5 GSS-API context.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if(socksreq[1] == 2) {
|
||||
/* Needs user name and password */
|
||||
size_t proxy_name_len, proxy_password_len;
|
||||
if(proxy_name && proxy_password) {
|
||||
proxy_name_len = strlen(proxy_name);
|
||||
proxy_password_len = strlen(proxy_password);
|
||||
}
|
||||
else {
|
||||
proxy_name_len = 0;
|
||||
proxy_password_len = 0;
|
||||
}
|
||||
|
||||
/* username/password request looks like
|
||||
* +----+------+----------+------+----------+
|
||||
* |VER | ULEN | UNAME | PLEN | PASSWD |
|
||||
* +----+------+----------+------+----------+
|
||||
* | 1 | 1 | 1 to 255 | 1 | 1 to 255 |
|
||||
* +----+------+----------+------+----------+
|
||||
*/
|
||||
len = 0;
|
||||
socksreq[len++] = 1; /* username/pw subnegotiation version */
|
||||
socksreq[len++] = (unsigned char) proxy_name_len;
|
||||
if(proxy_name && proxy_name_len)
|
||||
memcpy(socksreq + len, proxy_name, proxy_name_len);
|
||||
len += proxy_name_len;
|
||||
socksreq[len++] = (unsigned char) proxy_password_len;
|
||||
if(proxy_password && proxy_password_len)
|
||||
memcpy(socksreq + len, proxy_password, proxy_password_len);
|
||||
len += proxy_password_len;
|
||||
|
||||
code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
|
||||
if(code || (len != written)) {
|
||||
failf(data, "Failed to send SOCKS5 sub-negotiation request.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
|
||||
if(result || (actualread != 2)) {
|
||||
failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
/* ignore the first (VER) byte */
|
||||
if(socksreq[1] != 0) { /* status */
|
||||
failf(data, "User was rejected by the SOCKS5 server (%d %d).",
|
||||
socksreq[0], socksreq[1]);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
/* Everything is good so far, user was authenticated! */
|
||||
}
|
||||
else {
|
||||
/* error */
|
||||
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
|
||||
if(socksreq[1] == 255) {
|
||||
#else
|
||||
if(socksreq[1] == 1) {
|
||||
failf(data,
|
||||
"SOCKS5 GSSAPI per-message authentication is not supported.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
else if(socksreq[1] == 255) {
|
||||
#endif
|
||||
if(!proxy_name || !*proxy_name) {
|
||||
failf(data,
|
||||
"No authentication method was acceptable. (It is quite likely"
|
||||
" that the SOCKS5 server wanted a username/password, since none"
|
||||
" was supplied to the server on this connection.)");
|
||||
}
|
||||
else {
|
||||
failf(data, "No authentication method was acceptable.");
|
||||
}
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
else {
|
||||
failf(data,
|
||||
"Undocumented SOCKS5 mode attempted to be used by server.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Authentication is complete, now specify destination to the proxy */
|
||||
len = 0;
|
||||
socksreq[len++] = 5; /* version (SOCKS5) */
|
||||
socksreq[len++] = 1; /* connect */
|
||||
socksreq[len++] = 0; /* must be zero */
|
||||
|
||||
if(!socks5_resolve_local) {
|
||||
socksreq[len++] = 3; /* ATYP: domain name = 3 */
|
||||
socksreq[len++] = (char) hostname_len; /* address length */
|
||||
memcpy(&socksreq[len], hostname, hostname_len); /* address str w/o NULL */
|
||||
len += hostname_len;
|
||||
}
|
||||
else {
|
||||
struct Curl_dns_entry *dns;
|
||||
Curl_addrinfo *hp = NULL;
|
||||
int rc = Curl_resolv(conn, hostname, remote_port, &dns);
|
||||
|
||||
if(rc == CURLRESOLV_ERROR)
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
|
||||
if(rc == CURLRESOLV_PENDING) {
|
||||
/* this requires that we're in "wait for resolve" state */
|
||||
code = Curl_resolver_wait_resolv(conn, &dns);
|
||||
if(code)
|
||||
return code;
|
||||
}
|
||||
|
||||
/*
|
||||
* We cannot use 'hostent' as a struct that Curl_resolv() returns. It
|
||||
* returns a Curl_addrinfo pointer that may not always look the same.
|
||||
*/
|
||||
if(dns)
|
||||
hp=dns->addr;
|
||||
if(hp) {
|
||||
int i;
|
||||
char buf[64];
|
||||
Curl_printable_address(hp, buf, sizeof(buf));
|
||||
|
||||
if(hp->ai_family == AF_INET) {
|
||||
struct sockaddr_in *saddr_in;
|
||||
socksreq[len++] = 1; /* ATYP: IPv4 = 1 */
|
||||
|
||||
saddr_in = (struct sockaddr_in *)(void *)hp->ai_addr;
|
||||
for(i = 0; i < 4; i++) {
|
||||
socksreq[len++] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[i];
|
||||
}
|
||||
|
||||
infof(data, "SOCKS5 connect to IPv4 %s (locally resolved)\n", buf);
|
||||
}
|
||||
#ifdef ENABLE_IPV6
|
||||
else if(hp->ai_family == AF_INET6) {
|
||||
struct sockaddr_in6 *saddr_in6;
|
||||
socksreq[len++] = 4; /* ATYP: IPv6 = 4 */
|
||||
|
||||
saddr_in6 = (struct sockaddr_in6 *)(void *)hp->ai_addr;
|
||||
for(i = 0; i < 16; i++) {
|
||||
socksreq[len++] =
|
||||
((unsigned char *)&saddr_in6->sin6_addr.s6_addr)[i];
|
||||
}
|
||||
|
||||
infof(data, "SOCKS5 connect to IPv6 %s (locally resolved)\n", buf);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
hp = NULL; /* fail! */
|
||||
|
||||
failf(data, "SOCKS5 connection to %s not supported\n", buf);
|
||||
}
|
||||
|
||||
Curl_resolv_unlock(data, dns); /* not used anymore from now on */
|
||||
}
|
||||
if(!hp) {
|
||||
failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.",
|
||||
hostname);
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
}
|
||||
|
||||
socksreq[len++] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */
|
||||
socksreq[len++] = (unsigned char)(remote_port & 0xff); /* PORT LSB */
|
||||
|
||||
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
|
||||
if(conn->socks5_gssapi_enctype) {
|
||||
failf(data, "SOCKS5 GSS-API protection not yet implemented.");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
|
||||
|
||||
if(code || (len != written)) {
|
||||
failf(data, "Failed to send SOCKS5 connect request.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
len = 10; /* minimum packet size is 10 */
|
||||
|
||||
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
|
||||
if(conn->socks5_gssapi_enctype) {
|
||||
failf(data, "SOCKS5 GSS-API protection not yet implemented.");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
result = Curl_blockread_all(conn, sock, (char *)socksreq,
|
||||
len, &actualread);
|
||||
|
||||
if(result || (len != actualread)) {
|
||||
failf(data, "Failed to receive SOCKS5 connect request ack.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
if(socksreq[0] != 5) { /* version */
|
||||
failf(data,
|
||||
"SOCKS5 reply has wrong version, version should be 5.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
/* Fix: in general, returned BND.ADDR is variable length parameter by RFC
|
||||
1928, so the reply packet should be read until the end to avoid errors at
|
||||
subsequent protocol level.
|
||||
|
||||
+----+-----+-------+------+----------+----------+
|
||||
|VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
|
||||
+----+-----+-------+------+----------+----------+
|
||||
| 1 | 1 | X'00' | 1 | Variable | 2 |
|
||||
+----+-----+-------+------+----------+----------+
|
||||
|
||||
ATYP:
|
||||
o IP v4 address: X'01', BND.ADDR = 4 byte
|
||||
o domain name: X'03', BND.ADDR = [ 1 byte length, string ]
|
||||
o IP v6 address: X'04', BND.ADDR = 16 byte
|
||||
*/
|
||||
|
||||
/* Calculate real packet size */
|
||||
if(socksreq[3] == 3) {
|
||||
/* domain name */
|
||||
int addrlen = (int) socksreq[4];
|
||||
len = 5 + addrlen + 2;
|
||||
}
|
||||
else if(socksreq[3] == 4) {
|
||||
/* IPv6 */
|
||||
len = 4 + 16 + 2;
|
||||
}
|
||||
|
||||
/* At this point we already read first 10 bytes */
|
||||
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
|
||||
if(!conn->socks5_gssapi_enctype) {
|
||||
/* decrypt_gssapi_blockread already read the whole packet */
|
||||
#endif
|
||||
if(len > 10) {
|
||||
result = Curl_blockread_all(conn, sock, (char *)&socksreq[10],
|
||||
len - 10, &actualread);
|
||||
if(result || ((len - 10) != actualread)) {
|
||||
failf(data, "Failed to receive SOCKS5 connect request ack.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
}
|
||||
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
|
||||
}
|
||||
#endif
|
||||
|
||||
if(socksreq[1] != 0) { /* Anything besides 0 is an error */
|
||||
if(socksreq[3] == 1) {
|
||||
failf(data,
|
||||
"Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
|
||||
(unsigned char)socksreq[4], (unsigned char)socksreq[5],
|
||||
(unsigned char)socksreq[6], (unsigned char)socksreq[7],
|
||||
(((unsigned char)socksreq[8] << 8) |
|
||||
(unsigned char)socksreq[9]),
|
||||
(unsigned char)socksreq[1]);
|
||||
}
|
||||
else if(socksreq[3] == 3) {
|
||||
unsigned char port_upper = (unsigned char)socksreq[len - 2];
|
||||
socksreq[len - 2] = 0;
|
||||
failf(data,
|
||||
"Can't complete SOCKS5 connection to %s:%d. (%d)",
|
||||
(char *)&socksreq[5],
|
||||
((port_upper << 8) |
|
||||
(unsigned char)socksreq[len - 1]),
|
||||
(unsigned char)socksreq[1]);
|
||||
socksreq[len - 2] = port_upper;
|
||||
}
|
||||
else if(socksreq[3] == 4) {
|
||||
failf(data,
|
||||
"Can't complete SOCKS5 connection to %02x%02x:%02x%02x:"
|
||||
"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%d. (%d)",
|
||||
(unsigned char)socksreq[4], (unsigned char)socksreq[5],
|
||||
(unsigned char)socksreq[6], (unsigned char)socksreq[7],
|
||||
(unsigned char)socksreq[8], (unsigned char)socksreq[9],
|
||||
(unsigned char)socksreq[10], (unsigned char)socksreq[11],
|
||||
(unsigned char)socksreq[12], (unsigned char)socksreq[13],
|
||||
(unsigned char)socksreq[14], (unsigned char)socksreq[15],
|
||||
(unsigned char)socksreq[16], (unsigned char)socksreq[17],
|
||||
(unsigned char)socksreq[18], (unsigned char)socksreq[19],
|
||||
(((unsigned char)socksreq[20] << 8) |
|
||||
(unsigned char)socksreq[21]),
|
||||
(unsigned char)socksreq[1]);
|
||||
}
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
else {
|
||||
infof(data, "SOCKS5 request granted.\n");
|
||||
}
|
||||
|
||||
(void)curlx_nonblock(sock, TRUE);
|
||||
return CURLE_OK; /* Proxy was successful! */
|
||||
}
|
||||
|
||||
#endif /* CURL_DISABLE_PROXY */
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
#ifndef HEADER_CURL_SOCKS_H
|
||||
#define HEADER_CURL_SOCKS_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 https://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 "curl_setup.h"
|
||||
|
||||
#ifdef CURL_DISABLE_PROXY
|
||||
#define Curl_SOCKS4(a,b,c,d,e) CURLE_NOT_BUILT_IN
|
||||
#define Curl_SOCKS5(a,b,c,d,e,f) CURLE_NOT_BUILT_IN
|
||||
#else
|
||||
/*
|
||||
* Helper read-from-socket functions. Does the same as Curl_read() but it
|
||||
* blocks until all bytes amount of buffersize will be read. No more, no less.
|
||||
*
|
||||
* This is STUPID BLOCKING behaviour which we frown upon, but right now this
|
||||
* is what we have...
|
||||
*/
|
||||
int Curl_blockread_all(struct connectdata *conn,
|
||||
curl_socket_t sockfd,
|
||||
char *buf,
|
||||
ssize_t buffersize,
|
||||
ssize_t *n);
|
||||
|
||||
/*
|
||||
* This function logs in to a SOCKS4(a) proxy and sends the specifics to the
|
||||
* final destination server.
|
||||
*/
|
||||
CURLcode Curl_SOCKS4(const char *proxy_name,
|
||||
const char *hostname,
|
||||
int remote_port,
|
||||
int sockindex,
|
||||
struct connectdata *conn);
|
||||
|
||||
/*
|
||||
* This function logs in to a SOCKS5 proxy and sends the specifics to the
|
||||
* final destination server.
|
||||
*/
|
||||
CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
const char *proxy_password,
|
||||
const char *hostname,
|
||||
int remote_port,
|
||||
int sockindex,
|
||||
struct connectdata *conn);
|
||||
|
||||
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
|
||||
/*
|
||||
* This function handles the SOCKS5 GSS-API negotiation and initialisation
|
||||
*/
|
||||
CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
struct connectdata *conn);
|
||||
#endif
|
||||
|
||||
#endif /* CURL_DISABLE_PROXY */
|
||||
|
||||
#endif /* HEADER_CURL_SOCKS_H */
|
||||
|
||||
@@ -1,526 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com>
|
||||
* Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_PROXY)
|
||||
|
||||
#include "curl_gssapi.h"
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "connect.h"
|
||||
#include "timeval.h"
|
||||
#include "socks.h"
|
||||
#include "warnless.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
static gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
|
||||
|
||||
/*
|
||||
* Helper GSS-API error functions.
|
||||
*/
|
||||
static int check_gss_err(struct Curl_easy *data,
|
||||
OM_uint32 major_status,
|
||||
OM_uint32 minor_status,
|
||||
const char *function)
|
||||
{
|
||||
if(GSS_ERROR(major_status)) {
|
||||
OM_uint32 maj_stat, min_stat;
|
||||
OM_uint32 msg_ctx = 0;
|
||||
gss_buffer_desc status_string;
|
||||
char buf[1024];
|
||||
size_t len;
|
||||
|
||||
len = 0;
|
||||
msg_ctx = 0;
|
||||
while(!msg_ctx) {
|
||||
/* convert major status code (GSS-API error) to text */
|
||||
maj_stat = gss_display_status(&min_stat, major_status,
|
||||
GSS_C_GSS_CODE,
|
||||
GSS_C_NULL_OID,
|
||||
&msg_ctx, &status_string);
|
||||
if(maj_stat == GSS_S_COMPLETE) {
|
||||
if(sizeof(buf) > len + status_string.length + 1) {
|
||||
strcpy(buf+len, (char *) status_string.value);
|
||||
len += status_string.length;
|
||||
}
|
||||
gss_release_buffer(&min_stat, &status_string);
|
||||
break;
|
||||
}
|
||||
gss_release_buffer(&min_stat, &status_string);
|
||||
}
|
||||
if(sizeof(buf) > len + 3) {
|
||||
strcpy(buf+len, ".\n");
|
||||
len += 2;
|
||||
}
|
||||
msg_ctx = 0;
|
||||
while(!msg_ctx) {
|
||||
/* convert minor status code (underlying routine error) to text */
|
||||
maj_stat = gss_display_status(&min_stat, minor_status,
|
||||
GSS_C_MECH_CODE,
|
||||
GSS_C_NULL_OID,
|
||||
&msg_ctx, &status_string);
|
||||
if(maj_stat == GSS_S_COMPLETE) {
|
||||
if(sizeof(buf) > len + status_string.length)
|
||||
strcpy(buf+len, (char *) status_string.value);
|
||||
gss_release_buffer(&min_stat, &status_string);
|
||||
break;
|
||||
}
|
||||
gss_release_buffer(&min_stat, &status_string);
|
||||
}
|
||||
failf(data, "GSS-API error: %s failed:\n%s", function, buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
curl_socket_t sock = conn->sock[sockindex];
|
||||
CURLcode code;
|
||||
ssize_t actualread;
|
||||
ssize_t written;
|
||||
int result;
|
||||
OM_uint32 gss_major_status, gss_minor_status, gss_status;
|
||||
OM_uint32 gss_ret_flags;
|
||||
int gss_conf_state, gss_enc;
|
||||
gss_buffer_desc service = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc gss_send_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc gss_recv_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc gss_w_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc* gss_token = GSS_C_NO_BUFFER;
|
||||
gss_name_t server = GSS_C_NO_NAME;
|
||||
gss_name_t gss_client_name = GSS_C_NO_NAME;
|
||||
unsigned short us_length;
|
||||
char *user=NULL;
|
||||
unsigned char socksreq[4]; /* room for GSS-API exchange header only */
|
||||
const char *serviceptr = data->set.str[STRING_PROXY_SERVICE_NAME] ?
|
||||
data->set.str[STRING_PROXY_SERVICE_NAME] : "rcmd";
|
||||
const size_t serviceptr_length = strlen(serviceptr);
|
||||
|
||||
/* GSS-API request looks like
|
||||
* +----+------+-----+----------------+
|
||||
* |VER | MTYP | LEN | TOKEN |
|
||||
* +----+------+----------------------+
|
||||
* | 1 | 1 | 2 | up to 2^16 - 1 |
|
||||
* +----+------+-----+----------------+
|
||||
*/
|
||||
|
||||
/* prepare service name */
|
||||
if(strchr(serviceptr, '/')) {
|
||||
service.length = serviceptr_length;
|
||||
service.value = malloc(service.length);
|
||||
if(!service.value)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
memcpy(service.value, serviceptr, service.length);
|
||||
|
||||
gss_major_status = gss_import_name(&gss_minor_status, &service,
|
||||
(gss_OID) GSS_C_NULL_OID, &server);
|
||||
}
|
||||
else {
|
||||
service.value = malloc(serviceptr_length +
|
||||
strlen(conn->socks_proxy.host.name)+2);
|
||||
if(!service.value)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
service.length = serviceptr_length + strlen(conn->socks_proxy.host.name)+1;
|
||||
snprintf(service.value, service.length+1, "%s@%s",
|
||||
serviceptr, conn->socks_proxy.host.name);
|
||||
|
||||
gss_major_status = gss_import_name(&gss_minor_status, &service,
|
||||
GSS_C_NT_HOSTBASED_SERVICE, &server);
|
||||
}
|
||||
|
||||
gss_release_buffer(&gss_status, &service); /* clear allocated memory */
|
||||
|
||||
if(check_gss_err(data, gss_major_status,
|
||||
gss_minor_status, "gss_import_name()")) {
|
||||
failf(data, "Failed to create service name.");
|
||||
gss_release_name(&gss_status, &server);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
/* As long as we need to keep sending some context info, and there's no */
|
||||
/* errors, keep sending it... */
|
||||
for(;;) {
|
||||
gss_major_status = Curl_gss_init_sec_context(data,
|
||||
&gss_minor_status,
|
||||
&gss_context,
|
||||
server,
|
||||
&Curl_krb5_mech_oid,
|
||||
NULL,
|
||||
gss_token,
|
||||
&gss_send_token,
|
||||
TRUE,
|
||||
&gss_ret_flags);
|
||||
|
||||
if(gss_token != GSS_C_NO_BUFFER)
|
||||
gss_release_buffer(&gss_status, &gss_recv_token);
|
||||
if(check_gss_err(data, gss_major_status,
|
||||
gss_minor_status, "gss_init_sec_context")) {
|
||||
gss_release_name(&gss_status, &server);
|
||||
gss_release_buffer(&gss_status, &gss_recv_token);
|
||||
gss_release_buffer(&gss_status, &gss_send_token);
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
failf(data, "Failed to initial GSS-API token.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
if(gss_send_token.length != 0) {
|
||||
socksreq[0] = 1; /* GSS-API subnegotiation version */
|
||||
socksreq[1] = 1; /* authentication message type */
|
||||
us_length = htons((short)gss_send_token.length);
|
||||
memcpy(socksreq+2, &us_length, sizeof(short));
|
||||
|
||||
code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
|
||||
if(code || (4 != written)) {
|
||||
failf(data, "Failed to send GSS-API authentication request.");
|
||||
gss_release_name(&gss_status, &server);
|
||||
gss_release_buffer(&gss_status, &gss_recv_token);
|
||||
gss_release_buffer(&gss_status, &gss_send_token);
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
code = Curl_write_plain(conn, sock, (char *)gss_send_token.value,
|
||||
gss_send_token.length, &written);
|
||||
|
||||
if(code || ((ssize_t)gss_send_token.length != written)) {
|
||||
failf(data, "Failed to send GSS-API authentication token.");
|
||||
gss_release_name(&gss_status, &server);
|
||||
gss_release_buffer(&gss_status, &gss_recv_token);
|
||||
gss_release_buffer(&gss_status, &gss_send_token);
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
gss_release_buffer(&gss_status, &gss_send_token);
|
||||
gss_release_buffer(&gss_status, &gss_recv_token);
|
||||
if(gss_major_status != GSS_S_CONTINUE_NEEDED) break;
|
||||
|
||||
/* analyse response */
|
||||
|
||||
/* GSS-API response looks like
|
||||
* +----+------+-----+----------------+
|
||||
* |VER | MTYP | LEN | TOKEN |
|
||||
* +----+------+----------------------+
|
||||
* | 1 | 1 | 2 | up to 2^16 - 1 |
|
||||
* +----+------+-----+----------------+
|
||||
*/
|
||||
|
||||
result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
|
||||
if(result || (actualread != 4)) {
|
||||
failf(data, "Failed to receive GSS-API authentication response.");
|
||||
gss_release_name(&gss_status, &server);
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
/* ignore the first (VER) byte */
|
||||
if(socksreq[1] == 255) { /* status / message type */
|
||||
failf(data, "User was rejected by the SOCKS5 server (%d %d).",
|
||||
socksreq[0], socksreq[1]);
|
||||
gss_release_name(&gss_status, &server);
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
if(socksreq[1] != 1) { /* status / messgae type */
|
||||
failf(data, "Invalid GSS-API authentication response type (%d %d).",
|
||||
socksreq[0], socksreq[1]);
|
||||
gss_release_name(&gss_status, &server);
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
memcpy(&us_length, socksreq+2, sizeof(short));
|
||||
us_length = ntohs(us_length);
|
||||
|
||||
gss_recv_token.length=us_length;
|
||||
gss_recv_token.value=malloc(us_length);
|
||||
if(!gss_recv_token.value) {
|
||||
failf(data,
|
||||
"Could not allocate memory for GSS-API authentication "
|
||||
"response token.");
|
||||
gss_release_name(&gss_status, &server);
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
result=Curl_blockread_all(conn, sock, (char *)gss_recv_token.value,
|
||||
gss_recv_token.length, &actualread);
|
||||
|
||||
if(result || (actualread != us_length)) {
|
||||
failf(data, "Failed to receive GSS-API authentication token.");
|
||||
gss_release_name(&gss_status, &server);
|
||||
gss_release_buffer(&gss_status, &gss_recv_token);
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
gss_token = &gss_recv_token;
|
||||
}
|
||||
|
||||
gss_release_name(&gss_status, &server);
|
||||
|
||||
/* Everything is good so far, user was authenticated! */
|
||||
gss_major_status = gss_inquire_context(&gss_minor_status, gss_context,
|
||||
&gss_client_name, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL);
|
||||
if(check_gss_err(data, gss_major_status,
|
||||
gss_minor_status, "gss_inquire_context")) {
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
gss_release_name(&gss_status, &gss_client_name);
|
||||
failf(data, "Failed to determine user name.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
gss_major_status = gss_display_name(&gss_minor_status, gss_client_name,
|
||||
&gss_send_token, NULL);
|
||||
if(check_gss_err(data, gss_major_status,
|
||||
gss_minor_status, "gss_display_name")) {
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
gss_release_name(&gss_status, &gss_client_name);
|
||||
gss_release_buffer(&gss_status, &gss_send_token);
|
||||
failf(data, "Failed to determine user name.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
user=malloc(gss_send_token.length+1);
|
||||
if(!user) {
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
gss_release_name(&gss_status, &gss_client_name);
|
||||
gss_release_buffer(&gss_status, &gss_send_token);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
memcpy(user, gss_send_token.value, gss_send_token.length);
|
||||
user[gss_send_token.length] = '\0';
|
||||
gss_release_name(&gss_status, &gss_client_name);
|
||||
gss_release_buffer(&gss_status, &gss_send_token);
|
||||
infof(data, "SOCKS5 server authencticated user %s with GSS-API.\n",user);
|
||||
free(user);
|
||||
user=NULL;
|
||||
|
||||
/* Do encryption */
|
||||
socksreq[0] = 1; /* GSS-API subnegotiation version */
|
||||
socksreq[1] = 2; /* encryption message type */
|
||||
|
||||
gss_enc = 0; /* no data protection */
|
||||
/* do confidentiality protection if supported */
|
||||
if(gss_ret_flags & GSS_C_CONF_FLAG)
|
||||
gss_enc = 2;
|
||||
/* else do integrity protection */
|
||||
else if(gss_ret_flags & GSS_C_INTEG_FLAG)
|
||||
gss_enc = 1;
|
||||
|
||||
infof(data, "SOCKS5 server supports GSS-API %s data protection.\n",
|
||||
(gss_enc==0)?"no":((gss_enc==1)?"integrity":"confidentiality"));
|
||||
/* force for the moment to no data protection */
|
||||
gss_enc = 0;
|
||||
/*
|
||||
* Sending the encryption type in clear seems wrong. It should be
|
||||
* protected with gss_seal()/gss_wrap(). See RFC1961 extract below
|
||||
* The NEC reference implementations on which this is based is
|
||||
* therefore at fault
|
||||
*
|
||||
* +------+------+------+.......................+
|
||||
* + ver | mtyp | len | token |
|
||||
* +------+------+------+.......................+
|
||||
* + 0x01 | 0x02 | 0x02 | up to 2^16 - 1 octets |
|
||||
* +------+------+------+.......................+
|
||||
*
|
||||
* Where:
|
||||
*
|
||||
* - "ver" is the protocol version number, here 1 to represent the
|
||||
* first version of the SOCKS/GSS-API protocol
|
||||
*
|
||||
* - "mtyp" is the message type, here 2 to represent a protection
|
||||
* -level negotiation message
|
||||
*
|
||||
* - "len" is the length of the "token" field in octets
|
||||
*
|
||||
* - "token" is the GSS-API encapsulated protection level
|
||||
*
|
||||
* The token is produced by encapsulating an octet containing the
|
||||
* required protection level using gss_seal()/gss_wrap() with conf_req
|
||||
* set to FALSE. The token is verified using gss_unseal()/
|
||||
* gss_unwrap().
|
||||
*
|
||||
*/
|
||||
if(data->set.socks5_gssapi_nec) {
|
||||
us_length = htons((short)1);
|
||||
memcpy(socksreq+2, &us_length, sizeof(short));
|
||||
}
|
||||
else {
|
||||
gss_send_token.length = 1;
|
||||
gss_send_token.value = malloc(1);
|
||||
if(!gss_send_token.value) {
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
memcpy(gss_send_token.value, &gss_enc, 1);
|
||||
|
||||
gss_major_status = gss_wrap(&gss_minor_status, gss_context, 0,
|
||||
GSS_C_QOP_DEFAULT, &gss_send_token,
|
||||
&gss_conf_state, &gss_w_token);
|
||||
|
||||
if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_wrap")) {
|
||||
gss_release_buffer(&gss_status, &gss_send_token);
|
||||
gss_release_buffer(&gss_status, &gss_w_token);
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
failf(data, "Failed to wrap GSS-API encryption value into token.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
gss_release_buffer(&gss_status, &gss_send_token);
|
||||
|
||||
us_length = htons((short)gss_w_token.length);
|
||||
memcpy(socksreq+2, &us_length, sizeof(short));
|
||||
}
|
||||
|
||||
code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
|
||||
if(code || (4 != written)) {
|
||||
failf(data, "Failed to send GSS-API encryption request.");
|
||||
gss_release_buffer(&gss_status, &gss_w_token);
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
if(data->set.socks5_gssapi_nec) {
|
||||
memcpy(socksreq, &gss_enc, 1);
|
||||
code = Curl_write_plain(conn, sock, socksreq, 1, &written);
|
||||
if(code || ( 1 != written)) {
|
||||
failf(data, "Failed to send GSS-API encryption type.");
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
}
|
||||
else {
|
||||
code = Curl_write_plain(conn, sock, (char *)gss_w_token.value,
|
||||
gss_w_token.length, &written);
|
||||
if(code || ((ssize_t)gss_w_token.length != written)) {
|
||||
failf(data, "Failed to send GSS-API encryption type.");
|
||||
gss_release_buffer(&gss_status, &gss_w_token);
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
gss_release_buffer(&gss_status, &gss_w_token);
|
||||
}
|
||||
|
||||
result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
|
||||
if(result || (actualread != 4)) {
|
||||
failf(data, "Failed to receive GSS-API encryption response.");
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
/* ignore the first (VER) byte */
|
||||
if(socksreq[1] == 255) { /* status / message type */
|
||||
failf(data, "User was rejected by the SOCKS5 server (%d %d).",
|
||||
socksreq[0], socksreq[1]);
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
if(socksreq[1] != 2) { /* status / messgae type */
|
||||
failf(data, "Invalid GSS-API encryption response type (%d %d).",
|
||||
socksreq[0], socksreq[1]);
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
memcpy(&us_length, socksreq+2, sizeof(short));
|
||||
us_length = ntohs(us_length);
|
||||
|
||||
gss_recv_token.length= us_length;
|
||||
gss_recv_token.value=malloc(gss_recv_token.length);
|
||||
if(!gss_recv_token.value) {
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
result=Curl_blockread_all(conn, sock, (char *)gss_recv_token.value,
|
||||
gss_recv_token.length, &actualread);
|
||||
|
||||
if(result || (actualread != us_length)) {
|
||||
failf(data, "Failed to receive GSS-API encryptrion type.");
|
||||
gss_release_buffer(&gss_status, &gss_recv_token);
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
if(!data->set.socks5_gssapi_nec) {
|
||||
gss_major_status = gss_unwrap(&gss_minor_status, gss_context,
|
||||
&gss_recv_token, &gss_w_token,
|
||||
0, GSS_C_QOP_DEFAULT);
|
||||
|
||||
if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_unwrap")) {
|
||||
gss_release_buffer(&gss_status, &gss_recv_token);
|
||||
gss_release_buffer(&gss_status, &gss_w_token);
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
failf(data, "Failed to unwrap GSS-API encryption value into token.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
gss_release_buffer(&gss_status, &gss_recv_token);
|
||||
|
||||
if(gss_w_token.length != 1) {
|
||||
failf(data, "Invalid GSS-API encryption response length (%d).",
|
||||
gss_w_token.length);
|
||||
gss_release_buffer(&gss_status, &gss_w_token);
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
memcpy(socksreq, gss_w_token.value, gss_w_token.length);
|
||||
gss_release_buffer(&gss_status, &gss_w_token);
|
||||
}
|
||||
else {
|
||||
if(gss_recv_token.length != 1) {
|
||||
failf(data, "Invalid GSS-API encryption response length (%d).",
|
||||
gss_recv_token.length);
|
||||
gss_release_buffer(&gss_status, &gss_recv_token);
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
memcpy(socksreq, gss_recv_token.value, gss_recv_token.length);
|
||||
gss_release_buffer(&gss_status, &gss_recv_token);
|
||||
}
|
||||
|
||||
infof(data, "SOCKS5 access with%s protection granted.\n",
|
||||
(socksreq[0]==0)?"out GSS-API data":
|
||||
((socksreq[0]==1)?" GSS-API integrity":" GSS-API confidentiality"));
|
||||
|
||||
conn->socks5_gssapi_enctype = socksreq[0];
|
||||
if(socksreq[0] == 0)
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif /* HAVE_GSSAPI && !CURL_DISABLE_PROXY */
|
||||
@@ -1,605 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#if defined(USE_WINDOWS_SSPI) && !defined(CURL_DISABLE_PROXY)
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "connect.h"
|
||||
#include "strerror.h"
|
||||
#include "timeval.h"
|
||||
#include "socks.h"
|
||||
#include "curl_sspi.h"
|
||||
#include "curl_multibyte.h"
|
||||
#include "warnless.h"
|
||||
#include "strdup.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* Helper sspi error functions.
|
||||
*/
|
||||
static int check_sspi_err(struct connectdata *conn,
|
||||
SECURITY_STATUS status,
|
||||
const char *function)
|
||||
{
|
||||
if(status != SEC_E_OK &&
|
||||
status != SEC_I_COMPLETE_AND_CONTINUE &&
|
||||
status != SEC_I_COMPLETE_NEEDED &&
|
||||
status != SEC_I_CONTINUE_NEEDED) {
|
||||
failf(conn->data, "SSPI error: %s failed: %s", function,
|
||||
Curl_sspi_strerror(conn, status));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This is the SSPI-using version of this function */
|
||||
CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
curl_socket_t sock = conn->sock[sockindex];
|
||||
CURLcode code;
|
||||
ssize_t actualread;
|
||||
ssize_t written;
|
||||
int result;
|
||||
/* Needs GSS-API authentication */
|
||||
SECURITY_STATUS status;
|
||||
unsigned long sspi_ret_flags = 0;
|
||||
unsigned char gss_enc;
|
||||
SecBuffer sspi_send_token, sspi_recv_token, sspi_w_token[3];
|
||||
SecBufferDesc input_desc, output_desc, wrap_desc;
|
||||
SecPkgContext_Sizes sspi_sizes;
|
||||
CredHandle cred_handle;
|
||||
CtxtHandle sspi_context;
|
||||
PCtxtHandle context_handle = NULL;
|
||||
SecPkgCredentials_Names names;
|
||||
TimeStamp expiry;
|
||||
char *service_name = NULL;
|
||||
unsigned short us_length;
|
||||
unsigned long qop;
|
||||
unsigned char socksreq[4]; /* room for GSS-API exchange header only */
|
||||
const char *service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
|
||||
data->set.str[STRING_PROXY_SERVICE_NAME] : "rcmd";
|
||||
const size_t service_length = strlen(service);
|
||||
|
||||
/* GSS-API request looks like
|
||||
* +----+------+-----+----------------+
|
||||
* |VER | MTYP | LEN | TOKEN |
|
||||
* +----+------+----------------------+
|
||||
* | 1 | 1 | 2 | up to 2^16 - 1 |
|
||||
* +----+------+-----+----------------+
|
||||
*/
|
||||
|
||||
/* prepare service name */
|
||||
if(strchr(service, '/')) {
|
||||
service_name = strdup(service);
|
||||
if(!service_name)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else {
|
||||
service_name = malloc(service_length +
|
||||
strlen(conn->socks_proxy.host.name) + 2);
|
||||
if(!service_name)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
snprintf(service_name, service_length +
|
||||
strlen(conn->socks_proxy.host.name)+2, "%s/%s",
|
||||
service, conn->socks_proxy.host.name);
|
||||
}
|
||||
|
||||
input_desc.cBuffers = 1;
|
||||
input_desc.pBuffers = &sspi_recv_token;
|
||||
input_desc.ulVersion = SECBUFFER_VERSION;
|
||||
|
||||
sspi_recv_token.BufferType = SECBUFFER_TOKEN;
|
||||
sspi_recv_token.cbBuffer = 0;
|
||||
sspi_recv_token.pvBuffer = NULL;
|
||||
|
||||
output_desc.cBuffers = 1;
|
||||
output_desc.pBuffers = &sspi_send_token;
|
||||
output_desc.ulVersion = SECBUFFER_VERSION;
|
||||
|
||||
sspi_send_token.BufferType = SECBUFFER_TOKEN;
|
||||
sspi_send_token.cbBuffer = 0;
|
||||
sspi_send_token.pvBuffer = NULL;
|
||||
|
||||
wrap_desc.cBuffers = 3;
|
||||
wrap_desc.pBuffers = sspi_w_token;
|
||||
wrap_desc.ulVersion = SECBUFFER_VERSION;
|
||||
|
||||
cred_handle.dwLower = 0;
|
||||
cred_handle.dwUpper = 0;
|
||||
|
||||
status = s_pSecFn->AcquireCredentialsHandle(NULL,
|
||||
(TCHAR *) TEXT("Kerberos"),
|
||||
SECPKG_CRED_OUTBOUND,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&cred_handle,
|
||||
&expiry);
|
||||
|
||||
if(check_sspi_err(conn, status, "AcquireCredentialsHandle")) {
|
||||
failf(data, "Failed to acquire credentials.");
|
||||
free(service_name);
|
||||
s_pSecFn->FreeCredentialsHandle(&cred_handle);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
/* As long as we need to keep sending some context info, and there's no */
|
||||
/* errors, keep sending it... */
|
||||
for(;;) {
|
||||
TCHAR *sname;
|
||||
|
||||
sname = Curl_convert_UTF8_to_tchar(service_name);
|
||||
if(!sname)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
status = s_pSecFn->InitializeSecurityContext(&cred_handle,
|
||||
context_handle,
|
||||
sname,
|
||||
ISC_REQ_MUTUAL_AUTH |
|
||||
ISC_REQ_ALLOCATE_MEMORY |
|
||||
ISC_REQ_CONFIDENTIALITY |
|
||||
ISC_REQ_REPLAY_DETECT,
|
||||
0,
|
||||
SECURITY_NATIVE_DREP,
|
||||
&input_desc,
|
||||
0,
|
||||
&sspi_context,
|
||||
&output_desc,
|
||||
&sspi_ret_flags,
|
||||
&expiry);
|
||||
|
||||
Curl_unicodefree(sname);
|
||||
|
||||
if(sspi_recv_token.pvBuffer) {
|
||||
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
|
||||
sspi_recv_token.pvBuffer = NULL;
|
||||
sspi_recv_token.cbBuffer = 0;
|
||||
}
|
||||
|
||||
if(check_sspi_err(conn, status, "InitializeSecurityContext")) {
|
||||
free(service_name);
|
||||
s_pSecFn->FreeCredentialsHandle(&cred_handle);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
if(sspi_recv_token.pvBuffer)
|
||||
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
|
||||
failf(data, "Failed to initialise security context.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
if(sspi_send_token.cbBuffer != 0) {
|
||||
socksreq[0] = 1; /* GSS-API subnegotiation version */
|
||||
socksreq[1] = 1; /* authentication message type */
|
||||
us_length = htons((short)sspi_send_token.cbBuffer);
|
||||
memcpy(socksreq+2, &us_length, sizeof(short));
|
||||
|
||||
code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
|
||||
if(code || (4 != written)) {
|
||||
failf(data, "Failed to send SSPI authentication request.");
|
||||
free(service_name);
|
||||
if(sspi_send_token.pvBuffer)
|
||||
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
|
||||
if(sspi_recv_token.pvBuffer)
|
||||
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
|
||||
s_pSecFn->FreeCredentialsHandle(&cred_handle);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
|
||||
sspi_send_token.cbBuffer, &written);
|
||||
if(code || (sspi_send_token.cbBuffer != (size_t)written)) {
|
||||
failf(data, "Failed to send SSPI authentication token.");
|
||||
free(service_name);
|
||||
if(sspi_send_token.pvBuffer)
|
||||
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
|
||||
if(sspi_recv_token.pvBuffer)
|
||||
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
|
||||
s_pSecFn->FreeCredentialsHandle(&cred_handle);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(sspi_send_token.pvBuffer) {
|
||||
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
|
||||
sspi_send_token.pvBuffer = NULL;
|
||||
}
|
||||
sspi_send_token.cbBuffer = 0;
|
||||
|
||||
if(sspi_recv_token.pvBuffer) {
|
||||
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
|
||||
sspi_recv_token.pvBuffer = NULL;
|
||||
}
|
||||
sspi_recv_token.cbBuffer = 0;
|
||||
|
||||
if(status != SEC_I_CONTINUE_NEEDED)
|
||||
break;
|
||||
|
||||
/* analyse response */
|
||||
|
||||
/* GSS-API response looks like
|
||||
* +----+------+-----+----------------+
|
||||
* |VER | MTYP | LEN | TOKEN |
|
||||
* +----+------+----------------------+
|
||||
* | 1 | 1 | 2 | up to 2^16 - 1 |
|
||||
* +----+------+-----+----------------+
|
||||
*/
|
||||
|
||||
result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
|
||||
if(result || (actualread != 4)) {
|
||||
failf(data, "Failed to receive SSPI authentication response.");
|
||||
free(service_name);
|
||||
s_pSecFn->FreeCredentialsHandle(&cred_handle);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
/* ignore the first (VER) byte */
|
||||
if(socksreq[1] == 255) { /* status / message type */
|
||||
failf(data, "User was rejected by the SOCKS5 server (%u %u).",
|
||||
(unsigned int)socksreq[0], (unsigned int)socksreq[1]);
|
||||
free(service_name);
|
||||
s_pSecFn->FreeCredentialsHandle(&cred_handle);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
if(socksreq[1] != 1) { /* status / messgae type */
|
||||
failf(data, "Invalid SSPI authentication response type (%u %u).",
|
||||
(unsigned int)socksreq[0], (unsigned int)socksreq[1]);
|
||||
free(service_name);
|
||||
s_pSecFn->FreeCredentialsHandle(&cred_handle);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
memcpy(&us_length, socksreq+2, sizeof(short));
|
||||
us_length = ntohs(us_length);
|
||||
|
||||
sspi_recv_token.cbBuffer = us_length;
|
||||
sspi_recv_token.pvBuffer = malloc(us_length);
|
||||
|
||||
if(!sspi_recv_token.pvBuffer) {
|
||||
free(service_name);
|
||||
s_pSecFn->FreeCredentialsHandle(&cred_handle);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
result = Curl_blockread_all(conn, sock, (char *)sspi_recv_token.pvBuffer,
|
||||
sspi_recv_token.cbBuffer, &actualread);
|
||||
|
||||
if(result || (actualread != us_length)) {
|
||||
failf(data, "Failed to receive SSPI authentication token.");
|
||||
free(service_name);
|
||||
if(sspi_recv_token.pvBuffer)
|
||||
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
|
||||
s_pSecFn->FreeCredentialsHandle(&cred_handle);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
context_handle = &sspi_context;
|
||||
}
|
||||
|
||||
free(service_name);
|
||||
|
||||
/* Everything is good so far, user was authenticated! */
|
||||
status = s_pSecFn->QueryCredentialsAttributes(&cred_handle,
|
||||
SECPKG_CRED_ATTR_NAMES,
|
||||
&names);
|
||||
s_pSecFn->FreeCredentialsHandle(&cred_handle);
|
||||
if(check_sspi_err(conn, status, "QueryCredentialAttributes")) {
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
s_pSecFn->FreeContextBuffer(names.sUserName);
|
||||
failf(data, "Failed to determine user name.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
infof(data, "SOCKS5 server authencticated user %s with GSS-API.\n",
|
||||
names.sUserName);
|
||||
s_pSecFn->FreeContextBuffer(names.sUserName);
|
||||
|
||||
/* Do encryption */
|
||||
socksreq[0] = 1; /* GSS-API subnegotiation version */
|
||||
socksreq[1] = 2; /* encryption message type */
|
||||
|
||||
gss_enc = 0; /* no data protection */
|
||||
/* do confidentiality protection if supported */
|
||||
if(sspi_ret_flags & ISC_REQ_CONFIDENTIALITY)
|
||||
gss_enc = 2;
|
||||
/* else do integrity protection */
|
||||
else if(sspi_ret_flags & ISC_REQ_INTEGRITY)
|
||||
gss_enc = 1;
|
||||
|
||||
infof(data, "SOCKS5 server supports GSS-API %s data protection.\n",
|
||||
(gss_enc==0)?"no":((gss_enc==1)?"integrity":"confidentiality") );
|
||||
/* force to no data protection, avoid encryption/decryption for now */
|
||||
gss_enc = 0;
|
||||
/*
|
||||
* Sending the encryption type in clear seems wrong. It should be
|
||||
* protected with gss_seal()/gss_wrap(). See RFC1961 extract below
|
||||
* The NEC reference implementations on which this is based is
|
||||
* therefore at fault
|
||||
*
|
||||
* +------+------+------+.......................+
|
||||
* + ver | mtyp | len | token |
|
||||
* +------+------+------+.......................+
|
||||
* + 0x01 | 0x02 | 0x02 | up to 2^16 - 1 octets |
|
||||
* +------+------+------+.......................+
|
||||
*
|
||||
* Where:
|
||||
*
|
||||
* - "ver" is the protocol version number, here 1 to represent the
|
||||
* first version of the SOCKS/GSS-API protocol
|
||||
*
|
||||
* - "mtyp" is the message type, here 2 to represent a protection
|
||||
* -level negotiation message
|
||||
*
|
||||
* - "len" is the length of the "token" field in octets
|
||||
*
|
||||
* - "token" is the GSS-API encapsulated protection level
|
||||
*
|
||||
* The token is produced by encapsulating an octet containing the
|
||||
* required protection level using gss_seal()/gss_wrap() with conf_req
|
||||
* set to FALSE. The token is verified using gss_unseal()/
|
||||
* gss_unwrap().
|
||||
*
|
||||
*/
|
||||
|
||||
if(data->set.socks5_gssapi_nec) {
|
||||
us_length = htons((short)1);
|
||||
memcpy(socksreq+2, &us_length, sizeof(short));
|
||||
}
|
||||
else {
|
||||
status = s_pSecFn->QueryContextAttributes(&sspi_context,
|
||||
SECPKG_ATTR_SIZES,
|
||||
&sspi_sizes);
|
||||
if(check_sspi_err(conn, status, "QueryContextAttributes")) {
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
failf(data, "Failed to query security context attributes.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
sspi_w_token[0].cbBuffer = sspi_sizes.cbSecurityTrailer;
|
||||
sspi_w_token[0].BufferType = SECBUFFER_TOKEN;
|
||||
sspi_w_token[0].pvBuffer = malloc(sspi_sizes.cbSecurityTrailer);
|
||||
|
||||
if(!sspi_w_token[0].pvBuffer) {
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
sspi_w_token[1].cbBuffer = 1;
|
||||
sspi_w_token[1].pvBuffer = malloc(1);
|
||||
if(!sspi_w_token[1].pvBuffer) {
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
memcpy(sspi_w_token[1].pvBuffer, &gss_enc, 1);
|
||||
sspi_w_token[2].BufferType = SECBUFFER_PADDING;
|
||||
sspi_w_token[2].cbBuffer = sspi_sizes.cbBlockSize;
|
||||
sspi_w_token[2].pvBuffer = malloc(sspi_sizes.cbBlockSize);
|
||||
if(!sspi_w_token[2].pvBuffer) {
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
status = s_pSecFn->EncryptMessage(&sspi_context,
|
||||
KERB_WRAP_NO_ENCRYPT,
|
||||
&wrap_desc,
|
||||
0);
|
||||
if(check_sspi_err(conn, status, "EncryptMessage")) {
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
failf(data, "Failed to query security context attributes.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
sspi_send_token.cbBuffer = sspi_w_token[0].cbBuffer
|
||||
+ sspi_w_token[1].cbBuffer
|
||||
+ sspi_w_token[2].cbBuffer;
|
||||
sspi_send_token.pvBuffer = malloc(sspi_send_token.cbBuffer);
|
||||
if(!sspi_send_token.pvBuffer) {
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
memcpy(sspi_send_token.pvBuffer, sspi_w_token[0].pvBuffer,
|
||||
sspi_w_token[0].cbBuffer);
|
||||
memcpy((PUCHAR) sspi_send_token.pvBuffer +(int)sspi_w_token[0].cbBuffer,
|
||||
sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer);
|
||||
memcpy((PUCHAR) sspi_send_token.pvBuffer
|
||||
+sspi_w_token[0].cbBuffer
|
||||
+sspi_w_token[1].cbBuffer,
|
||||
sspi_w_token[2].pvBuffer, sspi_w_token[2].cbBuffer);
|
||||
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
|
||||
sspi_w_token[0].pvBuffer = NULL;
|
||||
sspi_w_token[0].cbBuffer = 0;
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
|
||||
sspi_w_token[1].pvBuffer = NULL;
|
||||
sspi_w_token[1].cbBuffer = 0;
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
|
||||
sspi_w_token[2].pvBuffer = NULL;
|
||||
sspi_w_token[2].cbBuffer = 0;
|
||||
|
||||
us_length = htons((short)sspi_send_token.cbBuffer);
|
||||
memcpy(socksreq+2, &us_length, sizeof(short));
|
||||
}
|
||||
|
||||
code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
|
||||
if(code || (4 != written)) {
|
||||
failf(data, "Failed to send SSPI encryption request.");
|
||||
if(sspi_send_token.pvBuffer)
|
||||
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
if(data->set.socks5_gssapi_nec) {
|
||||
memcpy(socksreq, &gss_enc, 1);
|
||||
code = Curl_write_plain(conn, sock, (char *)socksreq, 1, &written);
|
||||
if(code || (1 != written)) {
|
||||
failf(data, "Failed to send SSPI encryption type.");
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
}
|
||||
else {
|
||||
code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
|
||||
sspi_send_token.cbBuffer, &written);
|
||||
if(code || (sspi_send_token.cbBuffer != (size_t)written)) {
|
||||
failf(data, "Failed to send SSPI encryption type.");
|
||||
if(sspi_send_token.pvBuffer)
|
||||
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
if(sspi_send_token.pvBuffer)
|
||||
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
|
||||
}
|
||||
|
||||
result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
|
||||
if(result || (actualread != 4)) {
|
||||
failf(data, "Failed to receive SSPI encryption response.");
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
/* ignore the first (VER) byte */
|
||||
if(socksreq[1] == 255) { /* status / message type */
|
||||
failf(data, "User was rejected by the SOCKS5 server (%u %u).",
|
||||
(unsigned int)socksreq[0], (unsigned int)socksreq[1]);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
if(socksreq[1] != 2) { /* status / message type */
|
||||
failf(data, "Invalid SSPI encryption response type (%u %u).",
|
||||
(unsigned int)socksreq[0], (unsigned int)socksreq[1]);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
memcpy(&us_length, socksreq+2, sizeof(short));
|
||||
us_length = ntohs(us_length);
|
||||
|
||||
sspi_w_token[0].cbBuffer = us_length;
|
||||
sspi_w_token[0].pvBuffer = malloc(us_length);
|
||||
if(!sspi_w_token[0].pvBuffer) {
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
result = Curl_blockread_all(conn, sock, (char *)sspi_w_token[0].pvBuffer,
|
||||
sspi_w_token[0].cbBuffer, &actualread);
|
||||
|
||||
if(result || (actualread != us_length)) {
|
||||
failf(data, "Failed to receive SSPI encryption type.");
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
|
||||
if(!data->set.socks5_gssapi_nec) {
|
||||
wrap_desc.cBuffers = 2;
|
||||
sspi_w_token[0].BufferType = SECBUFFER_STREAM;
|
||||
sspi_w_token[1].BufferType = SECBUFFER_DATA;
|
||||
sspi_w_token[1].cbBuffer = 0;
|
||||
sspi_w_token[1].pvBuffer = NULL;
|
||||
|
||||
status = s_pSecFn->DecryptMessage(&sspi_context,
|
||||
&wrap_desc,
|
||||
0,
|
||||
&qop);
|
||||
|
||||
if(check_sspi_err(conn, status, "DecryptMessage")) {
|
||||
if(sspi_w_token[0].pvBuffer)
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
|
||||
if(sspi_w_token[1].pvBuffer)
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
failf(data, "Failed to query security context attributes.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
if(sspi_w_token[1].cbBuffer != 1) {
|
||||
failf(data, "Invalid SSPI encryption response length (%lu).",
|
||||
(unsigned long)sspi_w_token[1].cbBuffer);
|
||||
if(sspi_w_token[0].pvBuffer)
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
|
||||
if(sspi_w_token[1].pvBuffer)
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
memcpy(socksreq, sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer);
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
|
||||
}
|
||||
else {
|
||||
if(sspi_w_token[0].cbBuffer != 1) {
|
||||
failf(data, "Invalid SSPI encryption response length (%lu).",
|
||||
(unsigned long)sspi_w_token[0].cbBuffer);
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
memcpy(socksreq, sspi_w_token[0].pvBuffer, sspi_w_token[0].cbBuffer);
|
||||
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
|
||||
}
|
||||
|
||||
infof(data, "SOCKS5 access with%s protection granted.\n",
|
||||
(socksreq[0]==0)?"out GSS-API data":
|
||||
((socksreq[0]==1)?" GSS-API integrity":" GSS-API confidentiality"));
|
||||
|
||||
/* For later use if encryption is required
|
||||
conn->socks5_gssapi_enctype = socksreq[0];
|
||||
if(socksreq[0] != 0)
|
||||
conn->socks5_sspi_context = sspi_context;
|
||||
else {
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
conn->socks5_sspi_context = sspi_context;
|
||||
}
|
||||
*/
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif
|
||||
@@ -1,74 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "multiif.h"
|
||||
#include "speedcheck.h"
|
||||
|
||||
void Curl_speedinit(struct Curl_easy *data)
|
||||
{
|
||||
memset(&data->state.keeps_speed, 0, sizeof(struct timeval));
|
||||
}
|
||||
|
||||
CURLcode Curl_speedcheck(struct Curl_easy *data,
|
||||
struct timeval now)
|
||||
{
|
||||
if((data->progress.current_speed >= 0) &&
|
||||
data->set.low_speed_time &&
|
||||
(Curl_tvlong(data->state.keeps_speed) != 0) &&
|
||||
(data->progress.current_speed < data->set.low_speed_limit)) {
|
||||
time_t howlong = Curl_tvdiff(now, data->state.keeps_speed);
|
||||
time_t nextcheck = (data->set.low_speed_time * 1000) - howlong;
|
||||
|
||||
/* We are now below the "low speed limit". If we are below it
|
||||
for "low speed time" seconds we consider that enough reason
|
||||
to abort the download. */
|
||||
if(nextcheck <= 0) {
|
||||
/* we have been this slow for long enough, now die */
|
||||
failf(data,
|
||||
"Operation too slow. "
|
||||
"Less than %ld bytes/sec transferred the last %ld seconds",
|
||||
data->set.low_speed_limit,
|
||||
data->set.low_speed_time);
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
else {
|
||||
/* wait complete low_speed_time */
|
||||
Curl_expire_latest(data, nextcheck);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* we keep up the required speed all right */
|
||||
data->state.keeps_speed = now;
|
||||
|
||||
if(data->set.low_speed_limit)
|
||||
/* if there is a low speed limit enabled, we set the expire timer to
|
||||
make this connection's speed get checked again no later than when
|
||||
this time is up */
|
||||
Curl_expire_latest(data, data->set.low_speed_time*1000);
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#ifndef HEADER_CURL_SPEEDCHECK_H
|
||||
#define HEADER_CURL_SPEEDCHECK_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#include "timeval.h"
|
||||
|
||||
void Curl_speedinit(struct Curl_easy *data);
|
||||
CURLcode Curl_speedcheck(struct Curl_easy *data,
|
||||
struct timeval now);
|
||||
|
||||
#endif /* HEADER_CURL_SPEEDCHECK_H */
|
||||
@@ -1,288 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1997 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#include "splay.h"
|
||||
|
||||
/*
|
||||
* This macro compares two node keys i and j and returns:
|
||||
*
|
||||
* negative value: when i is smaller than j
|
||||
* zero : when i is equal to j
|
||||
* positive when : when i is larger than j
|
||||
*/
|
||||
#define compare(i,j) Curl_splaycomparekeys((i),(j))
|
||||
|
||||
/*
|
||||
* Splay using the key i (which may or may not be in the tree.) The starting
|
||||
* root is t.
|
||||
*/
|
||||
struct Curl_tree *Curl_splay(struct timeval i,
|
||||
struct Curl_tree *t)
|
||||
{
|
||||
struct Curl_tree N, *l, *r, *y;
|
||||
long comp;
|
||||
|
||||
if(t == NULL)
|
||||
return t;
|
||||
N.smaller = N.larger = NULL;
|
||||
l = r = &N;
|
||||
|
||||
for(;;) {
|
||||
comp = compare(i, t->key);
|
||||
if(comp < 0) {
|
||||
if(t->smaller == NULL)
|
||||
break;
|
||||
if(compare(i, t->smaller->key) < 0) {
|
||||
y = t->smaller; /* rotate smaller */
|
||||
t->smaller = y->larger;
|
||||
y->larger = t;
|
||||
t = y;
|
||||
if(t->smaller == NULL)
|
||||
break;
|
||||
}
|
||||
r->smaller = t; /* link smaller */
|
||||
r = t;
|
||||
t = t->smaller;
|
||||
}
|
||||
else if(comp > 0) {
|
||||
if(t->larger == NULL)
|
||||
break;
|
||||
if(compare(i, t->larger->key) > 0) {
|
||||
y = t->larger; /* rotate larger */
|
||||
t->larger = y->smaller;
|
||||
y->smaller = t;
|
||||
t = y;
|
||||
if(t->larger == NULL)
|
||||
break;
|
||||
}
|
||||
l->larger = t; /* link larger */
|
||||
l = t;
|
||||
t = t->larger;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
l->larger = t->smaller; /* assemble */
|
||||
r->smaller = t->larger;
|
||||
t->smaller = N.larger;
|
||||
t->larger = N.smaller;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Insert key i into the tree t. Return a pointer to the resulting tree or
|
||||
* NULL if something went wrong.
|
||||
*
|
||||
* @unittest: 1309
|
||||
*/
|
||||
struct Curl_tree *Curl_splayinsert(struct timeval i,
|
||||
struct Curl_tree *t,
|
||||
struct Curl_tree *node)
|
||||
{
|
||||
static const struct timeval KEY_NOTUSED = {-1, -1}; /* will *NEVER* appear */
|
||||
|
||||
if(node == NULL)
|
||||
return t;
|
||||
|
||||
if(t != NULL) {
|
||||
t = Curl_splay(i, t);
|
||||
if(compare(i, t->key)==0) {
|
||||
/* There already exists a node in the tree with the very same key. Build
|
||||
a linked list of nodes. We make the new 'node' struct the new master
|
||||
node and make the previous node the first one in the 'same' list. */
|
||||
|
||||
node->same = t;
|
||||
node->key = i;
|
||||
node->smaller = t->smaller;
|
||||
node->larger = t->larger;
|
||||
|
||||
t->smaller = node; /* in the sub node for this same key, we use the
|
||||
smaller pointer to point back to the master
|
||||
node */
|
||||
|
||||
t->key = KEY_NOTUSED; /* and we set the key in the sub node to NOTUSED
|
||||
to quickly identify this node as a subnode */
|
||||
|
||||
return node; /* new root node */
|
||||
}
|
||||
}
|
||||
|
||||
if(t == NULL) {
|
||||
node->smaller = node->larger = NULL;
|
||||
}
|
||||
else if(compare(i, t->key) < 0) {
|
||||
node->smaller = t->smaller;
|
||||
node->larger = t;
|
||||
t->smaller = NULL;
|
||||
|
||||
}
|
||||
else {
|
||||
node->larger = t->larger;
|
||||
node->smaller = t;
|
||||
t->larger = NULL;
|
||||
}
|
||||
node->key = i;
|
||||
|
||||
node->same = NULL; /* no identical node (yet) */
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Finds and deletes the best-fit node from the tree. Return a pointer to the
|
||||
resulting tree. best-fit means the node with the given or lower key */
|
||||
struct Curl_tree *Curl_splaygetbest(struct timeval i,
|
||||
struct Curl_tree *t,
|
||||
struct Curl_tree **removed)
|
||||
{
|
||||
struct Curl_tree *x;
|
||||
|
||||
if(!t) {
|
||||
*removed = NULL; /* none removed since there was no root */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
t = Curl_splay(i, t);
|
||||
if(compare(i, t->key) < 0) {
|
||||
/* too big node, try the smaller chain */
|
||||
if(t->smaller)
|
||||
t=Curl_splay(t->smaller->key, t);
|
||||
else {
|
||||
/* fail */
|
||||
*removed = NULL;
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
if(compare(i, t->key) >= 0) { /* found it */
|
||||
/* FIRST! Check if there is a list with identical keys */
|
||||
x = t->same;
|
||||
if(x) {
|
||||
/* there is, pick one from the list */
|
||||
|
||||
/* 'x' is the new root node */
|
||||
|
||||
x->key = t->key;
|
||||
x->larger = t->larger;
|
||||
x->smaller = t->smaller;
|
||||
|
||||
*removed = t;
|
||||
return x; /* new root */
|
||||
}
|
||||
|
||||
if(t->smaller == NULL) {
|
||||
x = t->larger;
|
||||
}
|
||||
else {
|
||||
x = Curl_splay(i, t->smaller);
|
||||
x->larger = t->larger;
|
||||
}
|
||||
*removed = t;
|
||||
|
||||
return x;
|
||||
}
|
||||
else {
|
||||
*removed = NULL; /* no match */
|
||||
return t; /* It wasn't there */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Deletes the very node we point out from the tree if it's there. Stores a
|
||||
* pointer to the new resulting tree in 'newroot'.
|
||||
*
|
||||
* Returns zero on success and non-zero on errors! TODO: document error codes.
|
||||
* When returning error, it does not touch the 'newroot' pointer.
|
||||
*
|
||||
* NOTE: when the last node of the tree is removed, there's no tree left so
|
||||
* 'newroot' will be made to point to NULL.
|
||||
*
|
||||
* @unittest: 1309
|
||||
*/
|
||||
int Curl_splayremovebyaddr(struct Curl_tree *t,
|
||||
struct Curl_tree *removenode,
|
||||
struct Curl_tree **newroot)
|
||||
{
|
||||
static const struct timeval KEY_NOTUSED = {-1, -1}; /* will *NEVER* appear */
|
||||
struct Curl_tree *x;
|
||||
|
||||
if(!t || !removenode)
|
||||
return 1;
|
||||
|
||||
if(compare(KEY_NOTUSED, removenode->key) == 0) {
|
||||
/* Key set to NOTUSED means it is a subnode within a 'same' linked list
|
||||
and thus we can unlink it easily. The 'smaller' link of a subnode
|
||||
links to the parent node. */
|
||||
if(removenode->smaller == NULL)
|
||||
return 3;
|
||||
|
||||
removenode->smaller->same = removenode->same;
|
||||
if(removenode->same)
|
||||
removenode->same->smaller = removenode->smaller;
|
||||
|
||||
/* Ensures that double-remove gets caught. */
|
||||
removenode->smaller = NULL;
|
||||
|
||||
/* voila, we're done! */
|
||||
*newroot = t; /* return the same root */
|
||||
return 0;
|
||||
}
|
||||
|
||||
t = Curl_splay(removenode->key, t);
|
||||
|
||||
/* First make sure that we got the same root node as the one we want
|
||||
to remove, as otherwise we might be trying to remove a node that
|
||||
isn't actually in the tree.
|
||||
|
||||
We cannot just compare the keys here as a double remove in quick
|
||||
succession of a node with key != KEY_NOTUSED && same != NULL
|
||||
could return the same key but a different node. */
|
||||
if(t != removenode)
|
||||
return 2;
|
||||
|
||||
/* Check if there is a list with identical sizes, as then we're trying to
|
||||
remove the root node of a list of nodes with identical keys. */
|
||||
x = t->same;
|
||||
if(x) {
|
||||
/* 'x' is the new root node, we just make it use the root node's
|
||||
smaller/larger links */
|
||||
|
||||
x->key = t->key;
|
||||
x->larger = t->larger;
|
||||
x->smaller = t->smaller;
|
||||
}
|
||||
else {
|
||||
/* Remove the root node */
|
||||
if(t->smaller == NULL)
|
||||
x = t->larger;
|
||||
else {
|
||||
x = Curl_splay(removenode->key, t->smaller);
|
||||
x->larger = t->larger;
|
||||
}
|
||||
}
|
||||
|
||||
*newroot = x; /* store new root pointer */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
#ifndef HEADER_CURL_SPLAY_H
|
||||
#define HEADER_CURL_SPLAY_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1997 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
struct Curl_tree {
|
||||
struct Curl_tree *smaller; /* smaller node */
|
||||
struct Curl_tree *larger; /* larger node */
|
||||
struct Curl_tree *same; /* points to a node with identical key */
|
||||
struct timeval key; /* this node's "sort" key */
|
||||
void *payload; /* data the splay code doesn't care about */
|
||||
};
|
||||
|
||||
struct Curl_tree *Curl_splay(struct timeval i,
|
||||
struct Curl_tree *t);
|
||||
|
||||
struct Curl_tree *Curl_splayinsert(struct timeval key,
|
||||
struct Curl_tree *t,
|
||||
struct Curl_tree *newnode);
|
||||
|
||||
#if 0
|
||||
struct Curl_tree *Curl_splayremove(struct timeval key,
|
||||
struct Curl_tree *t,
|
||||
struct Curl_tree **removed);
|
||||
#endif
|
||||
|
||||
struct Curl_tree *Curl_splaygetbest(struct timeval key,
|
||||
struct Curl_tree *t,
|
||||
struct Curl_tree **removed);
|
||||
|
||||
int Curl_splayremovebyaddr(struct Curl_tree *t,
|
||||
struct Curl_tree *removenode,
|
||||
struct Curl_tree **newroot);
|
||||
|
||||
#define Curl_splaycomparekeys(i,j) ( ((i.tv_sec) < (j.tv_sec)) ? -1 : \
|
||||
( ((i.tv_sec) > (j.tv_sec)) ? 1 : \
|
||||
( ((i.tv_usec) < (j.tv_usec)) ? -1 : \
|
||||
( ((i.tv_usec) > (j.tv_usec)) ? 1 : 0))))
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
void Curl_splayprint(struct Curl_tree * t, int d, char output);
|
||||
#else
|
||||
#define Curl_splayprint(x,y,z) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_SPLAY_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,198 +0,0 @@
|
||||
#ifndef HEADER_CURL_SSH_H
|
||||
#define HEADER_CURL_SSH_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_LIBSSH2_H
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
#endif /* HAVE_LIBSSH2_H */
|
||||
|
||||
/****************************************************************************
|
||||
* SSH unique setup
|
||||
***************************************************************************/
|
||||
typedef enum {
|
||||
SSH_NO_STATE = -1, /* Used for "nextState" so say there is none */
|
||||
SSH_STOP = 0, /* do nothing state, stops the state machine */
|
||||
|
||||
SSH_INIT, /* First state in SSH-CONNECT */
|
||||
SSH_S_STARTUP, /* Session startup */
|
||||
SSH_HOSTKEY, /* verify hostkey */
|
||||
SSH_AUTHLIST,
|
||||
SSH_AUTH_PKEY_INIT,
|
||||
SSH_AUTH_PKEY,
|
||||
SSH_AUTH_PASS_INIT,
|
||||
SSH_AUTH_PASS,
|
||||
SSH_AUTH_AGENT_INIT, /* initialize then wait for connection to agent */
|
||||
SSH_AUTH_AGENT_LIST, /* ask for list then wait for entire list to come */
|
||||
SSH_AUTH_AGENT, /* attempt one key at a time */
|
||||
SSH_AUTH_HOST_INIT,
|
||||
SSH_AUTH_HOST,
|
||||
SSH_AUTH_KEY_INIT,
|
||||
SSH_AUTH_KEY,
|
||||
SSH_AUTH_DONE,
|
||||
SSH_SFTP_INIT,
|
||||
SSH_SFTP_REALPATH, /* Last state in SSH-CONNECT */
|
||||
|
||||
SSH_SFTP_QUOTE_INIT, /* First state in SFTP-DO */
|
||||
SSH_SFTP_POSTQUOTE_INIT, /* (Possibly) First state in SFTP-DONE */
|
||||
SSH_SFTP_QUOTE,
|
||||
SSH_SFTP_NEXT_QUOTE,
|
||||
SSH_SFTP_QUOTE_STAT,
|
||||
SSH_SFTP_QUOTE_SETSTAT,
|
||||
SSH_SFTP_QUOTE_SYMLINK,
|
||||
SSH_SFTP_QUOTE_MKDIR,
|
||||
SSH_SFTP_QUOTE_RENAME,
|
||||
SSH_SFTP_QUOTE_RMDIR,
|
||||
SSH_SFTP_QUOTE_UNLINK,
|
||||
SSH_SFTP_QUOTE_STATVFS,
|
||||
SSH_SFTP_GETINFO,
|
||||
SSH_SFTP_FILETIME,
|
||||
SSH_SFTP_TRANS_INIT,
|
||||
SSH_SFTP_UPLOAD_INIT,
|
||||
SSH_SFTP_CREATE_DIRS_INIT,
|
||||
SSH_SFTP_CREATE_DIRS,
|
||||
SSH_SFTP_CREATE_DIRS_MKDIR,
|
||||
SSH_SFTP_READDIR_INIT,
|
||||
SSH_SFTP_READDIR,
|
||||
SSH_SFTP_READDIR_LINK,
|
||||
SSH_SFTP_READDIR_BOTTOM,
|
||||
SSH_SFTP_READDIR_DONE,
|
||||
SSH_SFTP_DOWNLOAD_INIT,
|
||||
SSH_SFTP_DOWNLOAD_STAT, /* Last state in SFTP-DO */
|
||||
SSH_SFTP_CLOSE, /* Last state in SFTP-DONE */
|
||||
SSH_SFTP_SHUTDOWN, /* First state in SFTP-DISCONNECT */
|
||||
SSH_SCP_TRANS_INIT, /* First state in SCP-DO */
|
||||
SSH_SCP_UPLOAD_INIT,
|
||||
SSH_SCP_DOWNLOAD_INIT,
|
||||
SSH_SCP_DONE,
|
||||
SSH_SCP_SEND_EOF,
|
||||
SSH_SCP_WAIT_EOF,
|
||||
SSH_SCP_WAIT_CLOSE,
|
||||
SSH_SCP_CHANNEL_FREE, /* Last state in SCP-DONE */
|
||||
SSH_SESSION_DISCONNECT, /* First state in SCP-DISCONNECT */
|
||||
SSH_SESSION_FREE, /* Last state in SCP/SFTP-DISCONNECT */
|
||||
SSH_QUIT,
|
||||
SSH_LAST /* never used */
|
||||
} sshstate;
|
||||
|
||||
/* this struct is used in the HandleData struct which is part of the
|
||||
Curl_easy, which means this is used on a per-easy handle basis.
|
||||
Everything that is strictly related to a connection is banned from this
|
||||
struct. */
|
||||
struct SSHPROTO {
|
||||
char *path; /* the path we operate on */
|
||||
};
|
||||
|
||||
/* ssh_conn is used for struct connection-oriented data in the connectdata
|
||||
struct */
|
||||
struct ssh_conn {
|
||||
const char *authlist; /* List of auth. methods, managed by libssh2 */
|
||||
#ifdef USE_LIBSSH2
|
||||
const char *passphrase; /* pass-phrase to use */
|
||||
char *rsa_pub; /* path name */
|
||||
char *rsa; /* path name */
|
||||
bool authed; /* the connection has been authenticated fine */
|
||||
sshstate state; /* always use ssh.c:state() to change state! */
|
||||
sshstate nextstate; /* the state to goto after stopping */
|
||||
CURLcode actualcode; /* the actual error code */
|
||||
struct curl_slist *quote_item; /* for the quote option */
|
||||
char *quote_path1; /* two generic pointers for the QUOTE stuff */
|
||||
char *quote_path2;
|
||||
LIBSSH2_SFTP_ATTRIBUTES quote_attrs; /* used by the SFTP_QUOTE state */
|
||||
bool acceptfail; /* used by the SFTP_QUOTE (continue if
|
||||
quote command fails) */
|
||||
char *homedir; /* when doing SFTP we figure out home dir in the
|
||||
connect phase */
|
||||
|
||||
/* Here's a set of struct members used by the SFTP_READDIR state */
|
||||
LIBSSH2_SFTP_ATTRIBUTES readdir_attrs;
|
||||
char *readdir_filename;
|
||||
char *readdir_longentry;
|
||||
int readdir_len, readdir_totalLen, readdir_currLen;
|
||||
char *readdir_line;
|
||||
char *readdir_linkPath;
|
||||
/* end of READDIR stuff */
|
||||
|
||||
int secondCreateDirs; /* counter use by the code to see if the
|
||||
second attempt has been made to change
|
||||
to/create a directory */
|
||||
char *slash_pos; /* used by the SFTP_CREATE_DIRS state */
|
||||
LIBSSH2_SESSION *ssh_session; /* Secure Shell session */
|
||||
LIBSSH2_CHANNEL *ssh_channel; /* Secure Shell channel handle */
|
||||
LIBSSH2_SFTP *sftp_session; /* SFTP handle */
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
int orig_waitfor; /* default READ/WRITE bits wait for */
|
||||
|
||||
#ifdef HAVE_LIBSSH2_AGENT_API
|
||||
LIBSSH2_AGENT *ssh_agent; /* proxy to ssh-agent/pageant */
|
||||
struct libssh2_agent_publickey *sshagent_identity,
|
||||
*sshagent_prev_identity;
|
||||
#endif
|
||||
|
||||
/* note that HAVE_LIBSSH2_KNOWNHOST_API is a define set in the libssh2.h
|
||||
header */
|
||||
#ifdef HAVE_LIBSSH2_KNOWNHOST_API
|
||||
LIBSSH2_KNOWNHOSTS *kh;
|
||||
#endif
|
||||
#endif /* USE_LIBSSH2 */
|
||||
};
|
||||
|
||||
#ifdef USE_LIBSSH2
|
||||
|
||||
/* Feature detection based on version numbers to better work with
|
||||
non-configure platforms */
|
||||
|
||||
#if !defined(LIBSSH2_VERSION_NUM) || (LIBSSH2_VERSION_NUM < 0x001000)
|
||||
# error "SCP/SFTP protocols require libssh2 0.16 or later"
|
||||
#endif
|
||||
|
||||
#if LIBSSH2_VERSION_NUM >= 0x010000
|
||||
#define HAVE_LIBSSH2_SFTP_SEEK64 1
|
||||
#endif
|
||||
|
||||
#if LIBSSH2_VERSION_NUM >= 0x010100
|
||||
#define HAVE_LIBSSH2_VERSION 1
|
||||
#endif
|
||||
|
||||
#if LIBSSH2_VERSION_NUM >= 0x010205
|
||||
#define HAVE_LIBSSH2_INIT 1
|
||||
#define HAVE_LIBSSH2_EXIT 1
|
||||
#endif
|
||||
|
||||
#if LIBSSH2_VERSION_NUM >= 0x010206
|
||||
#define HAVE_LIBSSH2_KNOWNHOST_CHECKP 1
|
||||
#define HAVE_LIBSSH2_SCP_SEND64 1
|
||||
#endif
|
||||
|
||||
#if LIBSSH2_VERSION_NUM >= 0x010208
|
||||
#define HAVE_LIBSSH2_SESSION_HANDSHAKE 1
|
||||
#endif
|
||||
|
||||
extern const struct Curl_handler Curl_handler_scp;
|
||||
extern const struct Curl_handler Curl_handler_sftp;
|
||||
|
||||
#endif /* USE_LIBSSH2 */
|
||||
|
||||
#endif /* HEADER_CURL_SSH_H */
|
||||
@@ -1,176 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "strcase.h"
|
||||
|
||||
/* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
|
||||
its behavior is altered by the current locale. */
|
||||
char Curl_raw_toupper(char in)
|
||||
{
|
||||
#if !defined(CURL_DOES_CONVERSIONS)
|
||||
if(in >= 'a' && in <= 'z')
|
||||
return (char)('A' + in - 'a');
|
||||
#else
|
||||
switch(in) {
|
||||
case 'a':
|
||||
return 'A';
|
||||
case 'b':
|
||||
return 'B';
|
||||
case 'c':
|
||||
return 'C';
|
||||
case 'd':
|
||||
return 'D';
|
||||
case 'e':
|
||||
return 'E';
|
||||
case 'f':
|
||||
return 'F';
|
||||
case 'g':
|
||||
return 'G';
|
||||
case 'h':
|
||||
return 'H';
|
||||
case 'i':
|
||||
return 'I';
|
||||
case 'j':
|
||||
return 'J';
|
||||
case 'k':
|
||||
return 'K';
|
||||
case 'l':
|
||||
return 'L';
|
||||
case 'm':
|
||||
return 'M';
|
||||
case 'n':
|
||||
return 'N';
|
||||
case 'o':
|
||||
return 'O';
|
||||
case 'p':
|
||||
return 'P';
|
||||
case 'q':
|
||||
return 'Q';
|
||||
case 'r':
|
||||
return 'R';
|
||||
case 's':
|
||||
return 'S';
|
||||
case 't':
|
||||
return 'T';
|
||||
case 'u':
|
||||
return 'U';
|
||||
case 'v':
|
||||
return 'V';
|
||||
case 'w':
|
||||
return 'W';
|
||||
case 'x':
|
||||
return 'X';
|
||||
case 'y':
|
||||
return 'Y';
|
||||
case 'z':
|
||||
return 'Z';
|
||||
}
|
||||
#endif
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant
|
||||
* to be locale independent and only compare strings we know are safe for
|
||||
* this. See https://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for
|
||||
* some further explanation to why this function is necessary.
|
||||
*
|
||||
* The function is capable of comparing a-z case insensitively even for
|
||||
* non-ascii.
|
||||
*
|
||||
* @unittest: 1301
|
||||
*/
|
||||
|
||||
int Curl_strcasecompare(const char *first, const char *second)
|
||||
{
|
||||
while(*first && *second) {
|
||||
if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second))
|
||||
/* get out of the loop as soon as they don't match */
|
||||
break;
|
||||
first++;
|
||||
second++;
|
||||
}
|
||||
/* we do the comparison here (possibly again), just to make sure that if the
|
||||
loop above is skipped because one of the strings reached zero, we must not
|
||||
return this as a successful match */
|
||||
return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second));
|
||||
}
|
||||
|
||||
int Curl_safe_strcasecompare(const char *first, const char *second)
|
||||
{
|
||||
if(first && second)
|
||||
/* both pointers point to something then compare them */
|
||||
return Curl_strcasecompare(first, second);
|
||||
else
|
||||
/* if both pointers are NULL then treat them as equal */
|
||||
return (NULL == first && NULL == second);
|
||||
}
|
||||
|
||||
/*
|
||||
* @unittest: 1301
|
||||
*/
|
||||
int Curl_strncasecompare(const char *first, const char *second, size_t max)
|
||||
{
|
||||
while(*first && *second && max) {
|
||||
if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) {
|
||||
break;
|
||||
}
|
||||
max--;
|
||||
first++;
|
||||
second++;
|
||||
}
|
||||
if(0 == max)
|
||||
return 1; /* they are equal this far */
|
||||
|
||||
return Curl_raw_toupper(*first) == Curl_raw_toupper(*second);
|
||||
}
|
||||
|
||||
/* Copy an upper case version of the string from src to dest. The
|
||||
* strings may overlap. No more than n characters of the string are copied
|
||||
* (including any NUL) and the destination string will NOT be
|
||||
* NUL-terminated if that limit is reached.
|
||||
*/
|
||||
void Curl_strntoupper(char *dest, const char *src, size_t n)
|
||||
{
|
||||
if(n < 1)
|
||||
return;
|
||||
|
||||
do {
|
||||
*dest++ = Curl_raw_toupper(*src);
|
||||
} while(*src++ && --n);
|
||||
}
|
||||
|
||||
/* --- public functions --- */
|
||||
|
||||
int curl_strequal(const char *first, const char *second)
|
||||
{
|
||||
return Curl_strcasecompare(first, second);
|
||||
}
|
||||
int curl_strnequal(const char *first, const char *second, size_t max)
|
||||
{
|
||||
return Curl_strncasecompare(first, second, max);
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
#ifndef HEADER_CURL_STRCASE_H
|
||||
#define HEADER_CURL_STRCASE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 <curl/curl.h>
|
||||
|
||||
/*
|
||||
* Only "raw" case insensitive strings. This is meant to be locale independent
|
||||
* and only compare strings we know are safe for this.
|
||||
*
|
||||
* The function is capable of comparing a-z case insensitively even for
|
||||
* non-ascii.
|
||||
*/
|
||||
|
||||
#define strcasecompare(a,b) Curl_strcasecompare(a,b)
|
||||
#define strncasecompare(a,b,c) Curl_strncasecompare(a,b,c)
|
||||
|
||||
int Curl_strcasecompare(const char *first, const char *second);
|
||||
int Curl_safe_strcasecompare(const char *first, const char *second);
|
||||
int Curl_strncasecompare(const char *first, const char *second, size_t max);
|
||||
|
||||
char Curl_raw_toupper(char in);
|
||||
|
||||
/* checkprefix() is a shorter version of the above, used when the first
|
||||
argument is zero-byte terminated */
|
||||
#define checkprefix(a,b) curl_strnequal(a,b,strlen(a))
|
||||
|
||||
void Curl_strntoupper(char *dest, const char *src, size_t n);
|
||||
char Curl_raw_toupper(char in);
|
||||
|
||||
#endif /* HEADER_CURL_STRCASE_H */
|
||||
@@ -1,100 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "strdup.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
char *curlx_strdup(const char *str)
|
||||
{
|
||||
size_t len;
|
||||
char *newstr;
|
||||
|
||||
if(!str)
|
||||
return (char *)NULL;
|
||||
|
||||
len = strlen(str);
|
||||
|
||||
if(len >= ((size_t)-1) / sizeof(char))
|
||||
return (char *)NULL;
|
||||
|
||||
newstr = malloc((len+1)*sizeof(char));
|
||||
if(!newstr)
|
||||
return (char *)NULL;
|
||||
|
||||
memcpy(newstr, str, (len+1)*sizeof(char));
|
||||
|
||||
return newstr;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* Curl_memdup(source, length)
|
||||
*
|
||||
* Copies the 'source' data to a newly allocated buffer (that is
|
||||
* returned). Copies 'length' bytes.
|
||||
*
|
||||
* Returns the new pointer or NULL on failure.
|
||||
*
|
||||
***************************************************************************/
|
||||
void *Curl_memdup(const void *src, size_t length)
|
||||
{
|
||||
void *buffer = malloc(length);
|
||||
if(!buffer)
|
||||
return NULL; /* fail */
|
||||
|
||||
memcpy(buffer, src, length);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* Curl_saferealloc(ptr, size)
|
||||
*
|
||||
* Does a normal realloc(), but will free the data pointer if the realloc
|
||||
* fails. If 'size' is zero, it will free the data and return a failure.
|
||||
*
|
||||
* This convenience function is provided and used to help us avoid a common
|
||||
* mistake pattern when we could pass in a zero, catch the NULL return and end
|
||||
* up free'ing the memory twice.
|
||||
*
|
||||
* Returns the new pointer or NULL on failure.
|
||||
*
|
||||
***************************************************************************/
|
||||
void *Curl_saferealloc(void *ptr, size_t size)
|
||||
{
|
||||
void *datap = realloc(ptr, size);
|
||||
if(size && !datap)
|
||||
/* only free 'ptr' if size was non-zero */
|
||||
free(ptr);
|
||||
return datap;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
#ifndef HEADER_CURL_STRDUP_H
|
||||
#define HEADER_CURL_STRDUP_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
extern char *curlx_strdup(const char *str);
|
||||
#endif
|
||||
void *Curl_memdup(const void *src, size_t buffer_length);
|
||||
void *Curl_saferealloc(void *ptr, size_t size);
|
||||
|
||||
#endif /* HEADER_CURL_STRDUP_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,37 +0,0 @@
|
||||
#ifndef HEADER_CURL_STRERROR_H
|
||||
#define HEADER_CURL_STRERROR_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "urldata.h"
|
||||
|
||||
const char *Curl_strerror (struct connectdata *conn, int err);
|
||||
|
||||
#ifdef USE_LIBIDN2
|
||||
const char *Curl_idn_strerror (struct connectdata *conn, int err);
|
||||
#endif
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
const char *Curl_sspi_strerror (struct connectdata *conn, int err);
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_STRERROR_H */
|
||||
@@ -1,66 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#ifndef HAVE_STRTOK_R
|
||||
#include <stddef.h>
|
||||
|
||||
#include "strtok.h"
|
||||
|
||||
char *
|
||||
Curl_strtok_r(char *ptr, const char *sep, char **end)
|
||||
{
|
||||
if(!ptr)
|
||||
/* we got NULL input so then we get our last position instead */
|
||||
ptr = *end;
|
||||
|
||||
/* pass all letters that are including in the separator string */
|
||||
while(*ptr && strchr(sep, *ptr))
|
||||
++ptr;
|
||||
|
||||
if(*ptr) {
|
||||
/* so this is where the next piece of string starts */
|
||||
char *start = ptr;
|
||||
|
||||
/* set the end pointer to the first byte after the start */
|
||||
*end = start + 1;
|
||||
|
||||
/* scan through the string to find where it ends, it ends on a
|
||||
null byte or a character that exists in the separator string */
|
||||
while(**end && !strchr(sep, **end))
|
||||
++*end;
|
||||
|
||||
if(**end) {
|
||||
/* the end is not a null byte */
|
||||
**end = '\0'; /* zero terminate it! */
|
||||
++*end; /* advance the last pointer to beyond the null byte */
|
||||
}
|
||||
|
||||
return start; /* return the position where the string starts */
|
||||
}
|
||||
|
||||
/* we ended up on a null byte, there are no more strings to find! */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* this was only compiled if strtok_r wasn't present */
|
||||
@@ -1,34 +0,0 @@
|
||||
#ifndef HEADER_CURL_STRTOK_H
|
||||
#define HEADER_CURL_STRTOK_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef HAVE_STRTOK_R
|
||||
char *Curl_strtok_r(char *s, const char *delim, char **last);
|
||||
#define strtok_r Curl_strtok_r
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_STRTOK_H */
|
||||
@@ -1,188 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#include "strtoofft.h"
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
*
|
||||
* In the ISO C standard (IEEE Std 1003.1), there is a strtoimax() function we
|
||||
* could use in case strtoll() doesn't exist... See
|
||||
* http://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html
|
||||
*/
|
||||
|
||||
#ifdef NEED_CURL_STRTOLL
|
||||
|
||||
/* Range tests can be used for alphanum decoding if characters are consecutive,
|
||||
like in ASCII. Else an array is scanned. Determine this condition now. */
|
||||
|
||||
#if('9' - '0') != 9 || ('Z' - 'A') != 25 || ('z' - 'a') != 25
|
||||
|
||||
#define NO_RANGE_TEST
|
||||
|
||||
static const char valchars[] =
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
#endif
|
||||
|
||||
static int get_char(char c, int base);
|
||||
|
||||
/**
|
||||
* Emulated version of the strtoll function. This extracts a long long
|
||||
* value from the given input string and returns it.
|
||||
*/
|
||||
curl_off_t
|
||||
curlx_strtoll(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
char *end;
|
||||
int is_negative = 0;
|
||||
int overflow;
|
||||
int i;
|
||||
curl_off_t value = 0;
|
||||
curl_off_t newval;
|
||||
|
||||
/* Skip leading whitespace. */
|
||||
end = (char *)nptr;
|
||||
while(ISSPACE(end[0])) {
|
||||
end++;
|
||||
}
|
||||
|
||||
/* Handle the sign, if any. */
|
||||
if(end[0] == '-') {
|
||||
is_negative = 1;
|
||||
end++;
|
||||
}
|
||||
else if(end[0] == '+') {
|
||||
end++;
|
||||
}
|
||||
else if(end[0] == '\0') {
|
||||
/* We had nothing but perhaps some whitespace -- there was no number. */
|
||||
if(endptr) {
|
||||
*endptr = end;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Handle special beginnings, if present and allowed. */
|
||||
if(end[0] == '0' && end[1] == 'x') {
|
||||
if(base == 16 || base == 0) {
|
||||
end += 2;
|
||||
base = 16;
|
||||
}
|
||||
}
|
||||
else if(end[0] == '0') {
|
||||
if(base == 8 || base == 0) {
|
||||
end++;
|
||||
base = 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* Matching strtol, if the base is 0 and it doesn't look like
|
||||
* the number is octal or hex, we assume it's base 10.
|
||||
*/
|
||||
if(base == 0) {
|
||||
base = 10;
|
||||
}
|
||||
|
||||
/* Loop handling digits. */
|
||||
value = 0;
|
||||
overflow = 0;
|
||||
for(i = get_char(end[0], base);
|
||||
i != -1;
|
||||
end++, i = get_char(end[0], base)) {
|
||||
newval = base * value + i;
|
||||
if(newval < value) {
|
||||
/* We've overflowed. */
|
||||
overflow = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
value = newval;
|
||||
}
|
||||
|
||||
if(!overflow) {
|
||||
if(is_negative) {
|
||||
/* Fix the sign. */
|
||||
value *= -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(is_negative)
|
||||
value = CURL_OFF_T_MIN;
|
||||
else
|
||||
value = CURL_OFF_T_MAX;
|
||||
|
||||
SET_ERRNO(ERANGE);
|
||||
}
|
||||
|
||||
if(endptr)
|
||||
*endptr = end;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of c in the given base, or -1 if c cannot
|
||||
* be interpreted properly in that base (i.e., is out of range,
|
||||
* is a null, etc.).
|
||||
*
|
||||
* @param c the character to interpret according to base
|
||||
* @param base the base in which to interpret c
|
||||
*
|
||||
* @return the value of c in base, or -1 if c isn't in range
|
||||
*/
|
||||
static int get_char(char c, int base)
|
||||
{
|
||||
#ifndef NO_RANGE_TEST
|
||||
int value = -1;
|
||||
if(c <= '9' && c >= '0') {
|
||||
value = c - '0';
|
||||
}
|
||||
else if(c <= 'Z' && c >= 'A') {
|
||||
value = c - 'A' + 10;
|
||||
}
|
||||
else if(c <= 'z' && c >= 'a') {
|
||||
value = c - 'a' + 10;
|
||||
}
|
||||
#else
|
||||
const char *cp;
|
||||
int value;
|
||||
|
||||
cp = memchr(valchars, c, 10 + 26 + 26);
|
||||
|
||||
if(!cp)
|
||||
return -1;
|
||||
|
||||
value = cp - valchars;
|
||||
|
||||
if(value >= 10 + 26)
|
||||
value -= 26; /* Lowercase. */
|
||||
#endif
|
||||
|
||||
if(value >= base) {
|
||||
value = -1;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
#endif /* Only present if we need strtoll, but don't have it. */
|
||||
@@ -1,75 +0,0 @@
|
||||
#ifndef HEADER_CURL_STRTOOFFT_H
|
||||
#define HEADER_CURL_STRTOOFFT_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
/*
|
||||
* Determine which string to integral data type conversion function we use
|
||||
* to implement string conversion to our curl_off_t integral data type.
|
||||
*
|
||||
* Notice that curl_off_t might be 64 or 32 bit wide, and that it might use
|
||||
* an underlying data type which might be 'long', 'int64_t', 'long long' or
|
||||
* '__int64' and more remotely other data types.
|
||||
*
|
||||
* On systems where the size of curl_off_t is greater than the size of 'long'
|
||||
* the conversion function to use is strtoll() if it is available, otherwise,
|
||||
* we emulate its functionality with our own clone.
|
||||
*
|
||||
* On systems where the size of curl_off_t is smaller or equal than the size
|
||||
* of 'long' the conversion function to use is strtol().
|
||||
*/
|
||||
|
||||
#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
|
||||
# ifdef HAVE_STRTOLL
|
||||
# define curlx_strtoofft strtoll
|
||||
# else
|
||||
# if defined(_MSC_VER) && (_MSC_VER >= 1300) && (_INTEGRAL_MAX_BITS >= 64)
|
||||
# if defined(_SAL_VERSION)
|
||||
_Check_return_ _CRTIMP __int64 __cdecl _strtoi64(
|
||||
_In_z_ const char *_String,
|
||||
_Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix);
|
||||
# else
|
||||
_CRTIMP __int64 __cdecl _strtoi64(const char *_String,
|
||||
char **_EndPtr, int _Radix);
|
||||
# endif
|
||||
# define curlx_strtoofft _strtoi64
|
||||
# else
|
||||
curl_off_t curlx_strtoll(const char *nptr, char **endptr, int base);
|
||||
# define curlx_strtoofft curlx_strtoll
|
||||
# define NEED_CURL_STRTOLL 1
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
# define curlx_strtoofft strtol
|
||||
#endif
|
||||
|
||||
#if (CURL_SIZEOF_CURL_OFF_T == 4)
|
||||
# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFF)
|
||||
#else
|
||||
/* assume CURL_SIZEOF_CURL_OFF_T == 8 */
|
||||
# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF)
|
||||
#endif
|
||||
#define CURL_OFF_T_MIN (-CURL_OFF_T_MAX - CURL_OFF_T_C(1))
|
||||
|
||||
#endif /* HEADER_CURL_STRTOOFFT_H */
|
||||
@@ -1,329 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2016, Steve Holme, <steve_holme@hotmail.com>.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "system_win32.h"
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#if defined(USE_WINDOWS_SSPI) || (!defined(CURL_DISABLE_TELNET) && \
|
||||
defined(USE_WINSOCK))
|
||||
|
||||
|
||||
#if !defined(LOAD_WITH_ALTERED_SEARCH_PATH)
|
||||
#define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008
|
||||
#endif
|
||||
|
||||
#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
|
||||
#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
|
||||
#endif
|
||||
|
||||
/* We use our own typedef here since some headers might lack these */
|
||||
typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD);
|
||||
|
||||
/* See function definitions in winbase.h */
|
||||
#ifdef UNICODE
|
||||
# ifdef _WIN32_WCE
|
||||
# define LOADLIBARYEX L"LoadLibraryExW"
|
||||
# else
|
||||
# define LOADLIBARYEX "LoadLibraryExW"
|
||||
# endif
|
||||
#else
|
||||
# define LOADLIBARYEX "LoadLibraryExA"
|
||||
#endif
|
||||
|
||||
#endif /* USE_WINDOWS_SSPI || (!CURL_DISABLE_TELNET && USE_WINSOCK) */
|
||||
|
||||
/*
|
||||
* Curl_verify_windows_version()
|
||||
*
|
||||
* This is used to verify if we are running on a specific windows version.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* majorVersion [in] - The major version number.
|
||||
* minorVersion [in] - The minor version number.
|
||||
* platform [in] - The optional platform identifer.
|
||||
* condition [in] - The test condition used to specifier whether we are
|
||||
* checking a version less then, equal to or greater than
|
||||
* what is specified in the major and minor version
|
||||
* numbers.
|
||||
*
|
||||
* Returns TRUE if matched; otherwise FALSE.
|
||||
*/
|
||||
bool Curl_verify_windows_version(const unsigned int majorVersion,
|
||||
const unsigned int minorVersion,
|
||||
const PlatformIdentifier platform,
|
||||
const VersionCondition condition)
|
||||
{
|
||||
bool matched = FALSE;
|
||||
|
||||
#if defined(CURL_WINDOWS_APP)
|
||||
/* We have no way to determine the Windows version from Windows apps,
|
||||
so let's assume we're running on the target Windows version. */
|
||||
const WORD fullVersion = MAKEWORD(minorVersion, majorVersion);
|
||||
const WORD targetVersion = (WORD)_WIN32_WINNT;
|
||||
|
||||
switch(condition) {
|
||||
case VERSION_LESS_THAN:
|
||||
matched = targetVersion < fullVersion;
|
||||
break;
|
||||
|
||||
case VERSION_LESS_THAN_EQUAL:
|
||||
matched = targetVersion <= fullVersion;
|
||||
break;
|
||||
|
||||
case VERSION_EQUAL:
|
||||
matched = targetVersion == fullVersion;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN_EQUAL:
|
||||
matched = targetVersion >= fullVersion;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN:
|
||||
matched = targetVersion > fullVersion;
|
||||
break;
|
||||
}
|
||||
|
||||
if(matched && (platform == PLATFORM_WINDOWS)) {
|
||||
/* we're always running on PLATFORM_WINNT */
|
||||
matched = FALSE;
|
||||
}
|
||||
#elif !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \
|
||||
(_WIN32_WINNT < _WIN32_WINNT_WIN2K)
|
||||
OSVERSIONINFO osver;
|
||||
|
||||
memset(&osver, 0, sizeof(osver));
|
||||
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||
|
||||
/* Find out Windows version */
|
||||
if(GetVersionEx(&osver)) {
|
||||
/* Verify the Operating System version number */
|
||||
switch(condition) {
|
||||
case VERSION_LESS_THAN:
|
||||
if(osver.dwMajorVersion < majorVersion ||
|
||||
(osver.dwMajorVersion == majorVersion &&
|
||||
osver.dwMinorVersion < minorVersion))
|
||||
matched = TRUE;
|
||||
break;
|
||||
|
||||
case VERSION_LESS_THAN_EQUAL:
|
||||
if(osver.dwMajorVersion <= majorVersion &&
|
||||
osver.dwMinorVersion <= minorVersion)
|
||||
matched = TRUE;
|
||||
break;
|
||||
|
||||
case VERSION_EQUAL:
|
||||
if(osver.dwMajorVersion == majorVersion &&
|
||||
osver.dwMinorVersion == minorVersion)
|
||||
matched = TRUE;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN_EQUAL:
|
||||
if(osver.dwMajorVersion >= majorVersion &&
|
||||
osver.dwMinorVersion >= minorVersion)
|
||||
matched = TRUE;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN:
|
||||
if(osver.dwMajorVersion > majorVersion ||
|
||||
(osver.dwMajorVersion == majorVersion &&
|
||||
osver.dwMinorVersion > minorVersion))
|
||||
matched = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Verify the platform identifier (if necessary) */
|
||||
if(matched) {
|
||||
switch(platform) {
|
||||
case PLATFORM_WINDOWS:
|
||||
if(osver.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)
|
||||
matched = FALSE;
|
||||
break;
|
||||
|
||||
case PLATFORM_WINNT:
|
||||
if(osver.dwPlatformId != VER_PLATFORM_WIN32_NT)
|
||||
matched = FALSE;
|
||||
|
||||
default: /* like platform == PLATFORM_DONT_CARE */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
ULONGLONG cm = 0;
|
||||
OSVERSIONINFOEX osver;
|
||||
BYTE majorCondition;
|
||||
BYTE minorCondition;
|
||||
BYTE spMajorCondition;
|
||||
BYTE spMinorCondition;
|
||||
|
||||
switch(condition) {
|
||||
case VERSION_LESS_THAN:
|
||||
majorCondition = VER_LESS;
|
||||
minorCondition = VER_LESS;
|
||||
spMajorCondition = VER_LESS_EQUAL;
|
||||
spMinorCondition = VER_LESS_EQUAL;
|
||||
break;
|
||||
|
||||
case VERSION_LESS_THAN_EQUAL:
|
||||
majorCondition = VER_LESS_EQUAL;
|
||||
minorCondition = VER_LESS_EQUAL;
|
||||
spMajorCondition = VER_LESS_EQUAL;
|
||||
spMinorCondition = VER_LESS_EQUAL;
|
||||
break;
|
||||
|
||||
case VERSION_EQUAL:
|
||||
majorCondition = VER_EQUAL;
|
||||
minorCondition = VER_EQUAL;
|
||||
spMajorCondition = VER_GREATER_EQUAL;
|
||||
spMinorCondition = VER_GREATER_EQUAL;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN_EQUAL:
|
||||
majorCondition = VER_GREATER_EQUAL;
|
||||
minorCondition = VER_GREATER_EQUAL;
|
||||
spMajorCondition = VER_GREATER_EQUAL;
|
||||
spMinorCondition = VER_GREATER_EQUAL;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN:
|
||||
majorCondition = VER_GREATER;
|
||||
minorCondition = VER_GREATER;
|
||||
spMajorCondition = VER_GREATER_EQUAL;
|
||||
spMinorCondition = VER_GREATER_EQUAL;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset(&osver, 0, sizeof(osver));
|
||||
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||
osver.dwMajorVersion = majorVersion;
|
||||
osver.dwMinorVersion = minorVersion;
|
||||
if(platform == PLATFORM_WINDOWS)
|
||||
osver.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;
|
||||
else if(platform == PLATFORM_WINNT)
|
||||
osver.dwPlatformId = VER_PLATFORM_WIN32_NT;
|
||||
|
||||
cm = VerSetConditionMask(cm, VER_MAJORVERSION, majorCondition);
|
||||
cm = VerSetConditionMask(cm, VER_MINORVERSION, minorCondition);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, spMajorCondition);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, spMinorCondition);
|
||||
if(platform != PLATFORM_DONT_CARE)
|
||||
cm = VerSetConditionMask(cm, VER_PLATFORMID, VER_EQUAL);
|
||||
|
||||
if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
|
||||
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
|
||||
cm))
|
||||
matched = TRUE;
|
||||
#endif
|
||||
|
||||
return matched;
|
||||
}
|
||||
|
||||
#if defined(USE_WINDOWS_SSPI) || (!defined(CURL_DISABLE_TELNET) && \
|
||||
defined(USE_WINSOCK))
|
||||
|
||||
/*
|
||||
* Curl_load_library()
|
||||
*
|
||||
* This is used to dynamically load DLLs using the most secure method available
|
||||
* for the version of Windows that we are running on.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* filename [in] - The filename or full path of the DLL to load. If only the
|
||||
* filename is passed then the DLL will be loaded from the
|
||||
* Windows system directory.
|
||||
*
|
||||
* Returns the handle of the module on success; otherwise NULL.
|
||||
*/
|
||||
HMODULE Curl_load_library(LPCTSTR filename)
|
||||
{
|
||||
HMODULE hModule = NULL;
|
||||
LOADLIBRARYEX_FN pLoadLibraryEx = NULL;
|
||||
|
||||
/* Get a handle to kernel32 so we can access it's functions at runtime */
|
||||
HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32"));
|
||||
if(!hKernel32)
|
||||
return NULL;
|
||||
|
||||
/* Attempt to find LoadLibraryEx() which is only available on Windows 2000
|
||||
and above */
|
||||
pLoadLibraryEx = (LOADLIBRARYEX_FN) GetProcAddress(hKernel32, LOADLIBARYEX);
|
||||
|
||||
/* Detect if there's already a path in the filename and load the library if
|
||||
there is. Note: Both back slashes and forward slashes have been supported
|
||||
since the earlier days of DOS at an API level although they are not
|
||||
supported by command prompt */
|
||||
if(_tcspbrk(filename, TEXT("\\/"))) {
|
||||
/** !checksrc! disable BANNEDFUNC 1 **/
|
||||
hModule = pLoadLibraryEx ?
|
||||
pLoadLibraryEx(filename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) :
|
||||
LoadLibrary(filename);
|
||||
}
|
||||
/* Detect if KB2533623 is installed, as LOAD_LIBARY_SEARCH_SYSTEM32 is only
|
||||
supported on Windows Vista, Windows Server 2008, Windows 7 and Windows
|
||||
Server 2008 R2 with this patch or natively on Windows 8 and above */
|
||||
else if(pLoadLibraryEx && GetProcAddress(hKernel32, "AddDllDirectory")) {
|
||||
/* Load the DLL from the Windows system directory */
|
||||
hModule = pLoadLibraryEx(filename, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
}
|
||||
else {
|
||||
/* Attempt to get the Windows system path */
|
||||
UINT systemdirlen = GetSystemDirectory(NULL, 0);
|
||||
if(systemdirlen) {
|
||||
/* Allocate space for the full DLL path (Room for the null terminator
|
||||
is included in systemdirlen) */
|
||||
size_t filenamelen = _tcslen(filename);
|
||||
TCHAR *path = malloc(sizeof(TCHAR) * (systemdirlen + 1 + filenamelen));
|
||||
if(path && GetSystemDirectory(path, systemdirlen)) {
|
||||
/* Calculate the full DLL path */
|
||||
_tcscpy(path + _tcslen(path), TEXT("\\"));
|
||||
_tcscpy(path + _tcslen(path), filename);
|
||||
|
||||
/* Load the DLL from the Windows system directory */
|
||||
/** !checksrc! disable BANNEDFUNC 1 **/
|
||||
hModule = pLoadLibraryEx ?
|
||||
pLoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) :
|
||||
LoadLibrary(path);
|
||||
|
||||
}
|
||||
free(path);
|
||||
}
|
||||
}
|
||||
|
||||
return hModule;
|
||||
}
|
||||
|
||||
#endif /* USE_WINDOWS_SSPI || (!CURL_DISABLE_TELNET && USE_WINSOCK) */
|
||||
|
||||
#endif /* WIN32 */
|
||||
@@ -1,61 +0,0 @@
|
||||
#ifndef HEADER_CURL_SYSTEM_WIN32_H
|
||||
#define HEADER_CURL_SYSTEM_WIN32_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2016, Steve Holme, <steve_holme@hotmail.com>.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
|
||||
/* Version condition */
|
||||
typedef enum {
|
||||
VERSION_LESS_THAN,
|
||||
VERSION_LESS_THAN_EQUAL,
|
||||
VERSION_EQUAL,
|
||||
VERSION_GREATER_THAN_EQUAL,
|
||||
VERSION_GREATER_THAN
|
||||
} VersionCondition;
|
||||
|
||||
/* Platform identifier */
|
||||
typedef enum {
|
||||
PLATFORM_DONT_CARE,
|
||||
PLATFORM_WINDOWS,
|
||||
PLATFORM_WINNT
|
||||
} PlatformIdentifier;
|
||||
|
||||
/* This is used to verify if we are running on a specific windows version */
|
||||
bool Curl_verify_windows_version(const unsigned int majorVersion,
|
||||
const unsigned int minorVersion,
|
||||
const PlatformIdentifier platform,
|
||||
const VersionCondition condition);
|
||||
|
||||
#if defined(USE_WINDOWS_SSPI) || (!defined(CURL_DISABLE_TELNET) && \
|
||||
defined(USE_WINSOCK))
|
||||
|
||||
/* This is used to dynamically load DLLs */
|
||||
HMODULE Curl_load_library(LPCTSTR filename);
|
||||
|
||||
#endif /* USE_WINDOWS_SSPI || (!CURL_DISABLE_TELNET && USE_WINSOCK) */
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
#endif /* HEADER_CURL_SYSTEM_WIN32_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,29 +0,0 @@
|
||||
#ifndef HEADER_CURL_TELNET_H
|
||||
#define HEADER_CURL_TELNET_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
***************************************************************************/
|
||||
#ifndef CURL_DISABLE_TELNET
|
||||
extern const struct Curl_handler Curl_handler_telnet;
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_TELNET_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,29 +0,0 @@
|
||||
#ifndef HEADER_CURL_TFTP_H
|
||||
#define HEADER_CURL_TFTP_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
***************************************************************************/
|
||||
#ifndef CURL_DISABLE_TFTP
|
||||
extern const struct Curl_handler Curl_handler_tftp;
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_TFTP_H */
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "timeval.h"
|
||||
|
||||
#if defined(WIN32) && !defined(MSDOS)
|
||||
|
||||
struct timeval curlx_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;
|
||||
#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
|
||||
(_WIN32_WINNT < _WIN32_WINNT_VISTA)
|
||||
DWORD milliseconds = GetTickCount();
|
||||
now.tv_sec = milliseconds / 1000;
|
||||
now.tv_usec = (milliseconds % 1000) * 1000;
|
||||
#else
|
||||
ULONGLONG milliseconds = GetTickCount64();
|
||||
now.tv_sec = (long) (milliseconds / 1000);
|
||||
now.tv_usec = (long) (milliseconds % 1000) * 1000;
|
||||
#endif
|
||||
|
||||
return now;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
|
||||
|
||||
struct timeval curlx_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 curlx_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 curlx_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. For large diffs it
|
||||
* returns 0x7fffffff on 32bit time_t systems.
|
||||
*/
|
||||
time_t curlx_tvdiff(struct timeval newer, struct timeval older)
|
||||
{
|
||||
#if SIZEOF_TIME_T < 8
|
||||
/* for 32bit time_t systems, add a precaution to avoid overflow for really
|
||||
big time differences */
|
||||
time_t diff = newer.tv_sec-older.tv_sec;
|
||||
if(diff >= (0x7fffffff/1000))
|
||||
return 0x7fffffff;
|
||||
#endif
|
||||
return (newer.tv_sec-older.tv_sec)*1000+
|
||||
(time_t)(newer.tv_usec-older.tv_usec)/1000;
|
||||
}
|
||||
|
||||
/*
|
||||
* Same as curlx_tvdiff but with full usec resolution.
|
||||
*
|
||||
* Returns: the time difference in seconds with subsecond resolution.
|
||||
*/
|
||||
double curlx_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 */
|
||||
time_t Curl_tvlong(struct timeval t1)
|
||||
{
|
||||
return t1.tv_sec;
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
#ifndef HEADER_CURL_TIMEVAL_H
|
||||
#define HEADER_CURL_TIMEVAL_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* CAUTION: this header is designed to work when included by the app-side
|
||||
* as well as the library. Do not mix with library internals!
|
||||
*/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
struct timeval curlx_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.
|
||||
*/
|
||||
time_t curlx_tvdiff(struct timeval t1, struct timeval t2);
|
||||
|
||||
/*
|
||||
* Same as curlx_tvdiff but with full usec resolution.
|
||||
*
|
||||
* Returns: the time difference in seconds with subsecond resolution.
|
||||
*/
|
||||
double curlx_tvdiff_secs(struct timeval t1, struct timeval t2);
|
||||
|
||||
time_t Curl_tvlong(struct timeval t1);
|
||||
|
||||
/* These two defines below exist to provide the older API for library
|
||||
internals only. */
|
||||
#define Curl_tvnow() curlx_tvnow()
|
||||
#define Curl_tvdiff(x,y) curlx_tvdiff(x,y)
|
||||
#define Curl_tvdiff_secs(x,y) curlx_tvdiff_secs(x,y)
|
||||
|
||||
#endif /* HEADER_CURL_TIMEVAL_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,68 +0,0 @@
|
||||
#ifndef HEADER_CURL_TRANSFER_H
|
||||
#define HEADER_CURL_TRANSFER_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
void Curl_init_CONNECT(struct Curl_easy *data);
|
||||
|
||||
CURLcode Curl_pretransfer(struct Curl_easy *data);
|
||||
CURLcode Curl_second_connect(struct connectdata *conn);
|
||||
CURLcode Curl_posttransfer(struct Curl_easy *data);
|
||||
|
||||
typedef enum {
|
||||
FOLLOW_NONE, /* not used within the function, just a placeholder to
|
||||
allow initing to this */
|
||||
FOLLOW_FAKE, /* only records stuff, not actually following */
|
||||
FOLLOW_RETRY, /* set if this is a request retry as opposed to a real
|
||||
redirect following */
|
||||
FOLLOW_REDIR, /* a full true redirect */
|
||||
FOLLOW_LAST /* never used */
|
||||
} followtype;
|
||||
|
||||
CURLcode Curl_follow(struct Curl_easy *data, char *newurl,
|
||||
followtype type);
|
||||
CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
struct Curl_easy *data, bool *done,
|
||||
bool *comeback);
|
||||
int Curl_single_getsock(const struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
CURLcode Curl_readrewind(struct connectdata *conn);
|
||||
CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp);
|
||||
CURLcode Curl_retry_request(struct connectdata *conn, char **url);
|
||||
bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc);
|
||||
|
||||
/* This sets up a forthcoming transfer */
|
||||
void
|
||||
Curl_setup_transfer (struct connectdata *data,
|
||||
int sockindex, /* socket index to read from or -1 */
|
||||
curl_off_t size, /* -1 if unknown at this point */
|
||||
bool getheader, /* TRUE if header parsing is wanted */
|
||||
curl_off_t *bytecountp, /* return number of bytes read */
|
||||
int writesockindex, /* socket index to write to, it may
|
||||
very well be the same we read from.
|
||||
-1 disables */
|
||||
curl_off_t *writecountp /* return number of bytes written */
|
||||
);
|
||||
|
||||
#endif /* HEADER_CURL_TRANSFER_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,93 +0,0 @@
|
||||
#ifndef HEADER_CURL_URL_H
|
||||
#define HEADER_CURL_URL_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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 "curl_setup.h"
|
||||
|
||||
/*
|
||||
* Prototypes for library-wide functions provided by url.c
|
||||
*/
|
||||
|
||||
CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn);
|
||||
CURLcode Curl_open(struct Curl_easy **curl);
|
||||
CURLcode Curl_init_userdefined(struct UserDefined *set);
|
||||
CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
|
||||
va_list arg);
|
||||
CURLcode Curl_dupset(struct Curl_easy * dst, struct Curl_easy * src);
|
||||
void Curl_freeset(struct Curl_easy * data);
|
||||
CURLcode Curl_close(struct Curl_easy *data); /* opposite of curl_open() */
|
||||
CURLcode Curl_connect(struct Curl_easy *, struct connectdata **,
|
||||
bool *async, bool *protocol_connect);
|
||||
CURLcode Curl_disconnect(struct connectdata *, bool dead_connection);
|
||||
CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_setup_conn(struct connectdata *conn,
|
||||
bool *protocol_done);
|
||||
void Curl_free_request_state(struct Curl_easy *data);
|
||||
|
||||
int Curl_protocol_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
int Curl_doing_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
|
||||
bool Curl_isPipeliningEnabled(const struct Curl_easy *handle);
|
||||
CURLcode Curl_addHandleToPipeline(struct Curl_easy *handle,
|
||||
struct curl_llist *pipeline);
|
||||
int Curl_removeHandleFromPipeline(struct Curl_easy *handle,
|
||||
struct curl_llist *pipeline);
|
||||
struct connectdata *
|
||||
Curl_oldest_idle_connection(struct Curl_easy *data);
|
||||
/* remove the specified connection from all (possible) pipelines and related
|
||||
queues */
|
||||
void Curl_getoff_all_pipelines(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
void Curl_close_connections(struct Curl_easy *data);
|
||||
|
||||
#define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */
|
||||
#define CURL_DEFAULT_HTTPS_PROXY_PORT 443 /* default https proxy port unless
|
||||
specified */
|
||||
|
||||
CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex);
|
||||
|
||||
#ifdef CURL_DISABLE_VERBOSE_STRINGS
|
||||
#define Curl_verboseconnect(x) Curl_nop_stmt
|
||||
#else
|
||||
void Curl_verboseconnect(struct connectdata *conn);
|
||||
#endif
|
||||
|
||||
#define CONNECT_PROXY_SSL()\
|
||||
(conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
|
||||
!conn->bits.proxy_ssl_connected[sockindex])
|
||||
|
||||
#define CONNECT_FIRSTSOCKET_PROXY_SSL()\
|
||||
(conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
|
||||
!conn->bits.proxy_ssl_connected[FIRSTSOCKET])
|
||||
|
||||
#define CONNECT_SECONDARYSOCKET_PROXY_SSL()\
|
||||
(conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
|
||||
!conn->bits.proxy_ssl_connected[SECONDARYSOCKET])
|
||||
|
||||
#endif /* HEADER_CURL_URL_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user