Compare commits

..

152 Commits

Author SHA1 Message Date
Daniel Stenberg
70812c2f32 THANKS: added contributors from the 7.32.0 release notes 2013-08-11 23:43:32 +02:00
Fabian Keil
a64bca68c7 test1228: add 'HTTP proxy' to the keywords 2013-08-11 19:56:23 +02:00
Fabian Keil
67633e1308 tests: add keywords for a couple of FILE tests 2013-08-11 19:56:14 +02:00
Fabian Keil
715ca7c5fe tests: add 'FAILURE' keywords to tests 1409 and 1410 2013-08-11 19:56:11 +02:00
Fabian Keil
001758760b tests: add keywords for a couple of HTTP tests 2013-08-11 19:56:05 +02:00
Fabian Keil
2f06265e39 tests: add keywords for a couple of FTP tests 2013-08-11 19:56:01 +02:00
Fabian Keil
432431368f test1511: consistently terminate headers with CRLF 2013-08-11 19:55:44 +02:00
Daniel Stenberg
4b0028f82d DISABLED: shut of test 1512 for now
It shows intermittent failures and I haven't been able to track them
down yet. Disable this test for now.
2013-08-10 23:55:10 +02:00
Daniel Stenberg
8c9236bb2c curl_multi_add_handle.3: ... that timer callback is for event-based 2013-08-09 23:53:51 +02:00
Daniel Stenberg
2af0b10c95 comments: remove old and wrong multi/easy interface statements 2013-08-09 23:39:09 +02:00
Daniel Stenberg
08adecc9a1 curl_multi_add_handle.3: mention the CURLMOPT_TIMERFUNCTION use 2013-08-09 23:27:43 +02:00
John E. Malmberg
015556d74c KNOWN_BUGS: 22 and 57 have been fixed and committed 2013-08-08 23:34:36 +02:00
Daniel Stenberg
4c40fe64b8 RELEASE-NOTES: synced with d20def2046 2013-08-08 16:37:17 +02:00
Daniel Stenberg
d20def2046 global dns cache: fix memory leak
The take down of the global dns cache didn't take CURLOPT_RESOLVE names
into account.
2013-08-08 16:28:46 +02:00
Daniel Stenberg
d2b36e466a global dns cache: didn't work [regression]
CURLOPT_DNS_USE_GLOBAL_CACHE broke in commit c43127414d (been
broken since the libcurl 7.29.0 release). While this option has been
documented as deprecated for almost a decade and nobody even reported
this bug, it should remain functional.

Added test case 1512 to verify
2013-08-08 16:28:46 +02:00
John Malmberg
27f8c93daf packages/vms: update VMS build files
VMS modified files either missing from a previous commit and changes
to remove references to CVS repositories.
2013-08-08 13:13:56 +02:00
Daniel Stenberg
058b86e6f3 FTP: renamed several local functions
The previous naming scheme ftp_state_post_XXXX() wasn't really helpful
as it wasn't always immediately after 'xxxx' and it wasn't easy to
understand what it does based on such a name.

This new one is instead ftp_state_yyyy() where yyyy describes what it
does or sends.
2013-08-08 12:19:01 +02:00
Daniel Stenberg
0018d6830e mk-ca-bundle.1: don't install on make install
Since the mk-ca-bundle tool itself isn't installed with make install,
there's no point in installing its documentation.

Bug: http://curl.haxx.se/mail/lib-2013-08/0057.html
Reported-by: Guenter Knauf
2013-08-08 09:45:51 +02:00
Yang Tse
59224a31fd packages/vms/Makefile.am: add latest file additions to EXTRA_DIST 2013-08-07 12:21:56 +02:00
John Malmberg
0994d737c8 Building_vms_pcsi_kit
These are the files needed to build VMS distribution packages known as
PCSI kits.

Also minor update to the existing files, mainly to the documentation and
file clean up code.
2013-08-07 12:16:08 +02:00
Daniel Stenberg
96749554fd LIBCURL-STRUCTS: new document
This is the first version of this new document, detailing the seven
perhaps most important internal structs in libcurl source code:

  1.1 SessionHandle
  1.2 connectdata
  1.3 Curl_multi
  1.4 Curl_handler
  1.5 conncache
  1.6 Curl_share
  1.7 CookieInfo
2013-08-06 14:13:33 +02:00
Daniel Stenberg
785749405f CONTRIBUTE: minor language polish 2013-08-06 14:12:45 +02:00
Daniel Stenberg
7cc00d9a83 FTP: when EPSV gets a 229 but fails to connect, retry with PASV
This is a regression as this logic used to work. It isn't clear when it
broke, but I'm assuming in 7.28.0 when we went all-multi internally.

This likely never worked with the multi interface. As the failed
connection is detected once the multi state has reached DO_MORE, the
Curl_do_more() function was now expanded somewhat so that the
ftp_do_more() function can request to go "back" to the previous state
when it makes another attempt - using PASV.

Added test case 1233 to verify this fix. It has the little issue that it
assumes no service is listening/accepting connections on port 1...

Reported-by: byte_bucket in the #curl IRC channel
2013-08-06 09:57:59 +02:00
Nick Zitzmann
230e16dc03 md5: remove use of CommonCrypto-to-OpenSSL macros for the benefit of Leopard
For some reason, OS X 10.5's GCC suddenly stopped working correctly with
macros that change MD5_Init etc. in the code to CC_MD5_Init etc., so I
worked around this by removing use of the macros and inserting static
functions that just call CommonCrypto's implementations of the functions
instead.
2013-08-05 19:47:56 -06:00
Guenter Knauf
0ce410a629 Simplify check for trusted certificates.
This changes the previous check for untrusted certs to a check for
certs explicitely marked as trusted.
The change is backward-compatible (tested with certdata.txt v1.80).
2013-08-05 13:02:27 +02:00
Daniel Stenberg
5d3cbde72e configure: warn on bad env variable use, don't error
Use XC_CHECK_BUILD_FLAGS instead XC_CHECK_USER_FLAGS.
2013-08-05 09:31:59 +02:00
Daniel Stenberg
8fe8fd2b17 Revert "configure: don't error out on variable confusions, just warn"
This reverts commit 6b27703b5f.
2013-08-05 09:28:44 +02:00
Daniel Stenberg
0ddc678927 formadd: wrong pointer for file name when CURLFORM_BUFFERPTR used
The internal function that's used to detect known file extensions for
the default Content-Type got the the wrong pointer passed in when
CURLFORM_BUFFER + CURLFORM_BUFFERPTR were used. This had the effect that
strlen() would be used which could lead to an out-of-bounds read (and
thus segfault). In most cases it would only lead to it not finding or
using the correct default content-type.

It also showed that test 554 and test 587 were testing for the
previous/wrong behavior and now they're updated as well.

Bug: http://curl.haxx.se/bug/view.cgi?id=1262
Reported-by: Konstantin Isakov
2013-08-04 23:32:36 +02:00
Guenter Knauf
51f0b798fa Skip more untrusted certificates.
Christian Heimes brought to our attention that the certdata.txt
format has recently changed [1], causing ca-bundle.crt created
with mk-ca-bundle.[pl|vbs] to include untrusted certs.

[1] http://lists.debian.org/debian-release/2012/11/msg00411.html
2013-08-04 21:30:11 +02:00
Daniel Stenberg
6b27703b5f configure: don't error out on variable confusions, just warn 2013-08-04 10:28:26 +02:00
Daniel Stenberg
045ccb59a4 configure: rephrase the notice in _XC_CHECK_VAR_*
Instead of claiming it is an error, we call it a "note" to reduce the
severity level. But the following text now says the [variable] "*should*
only be used to specify"... instead of previously having said "may".
2013-08-03 23:39:23 +02:00
Daniel Stenberg
784336deec multi: remove data->state.current_conn struct field
Not needed
2013-08-03 22:51:35 +02:00
Daniel Stenberg
eb41e8eebe multi: remove the one_easy struct field
Since the merge of SessionHandle with Curl_one_easy, this indirection
isn't used anymore.
2013-08-03 22:51:35 +02:00
Daniel Stenberg
3cd43bbfec multi: rename all Curl_one_easy to SessionHandle 2013-08-03 22:51:35 +02:00
Daniel Stenberg
204e340bcd multi: remove the multi_pos struct field
Since Curl_one_easy is really a SessionHandle now, this indirection
doesn't exist anymore.
2013-08-03 22:51:35 +02:00
Daniel Stenberg
37f2ba7e57 multi: remove easy_handle struct field
It isn't needed anymore
2013-08-03 22:51:35 +02:00
Daniel Stenberg
09b9fc9009 multi: remove 'Curl_one_easy' struct, phase 1
The motivation for having a separate struct that keep track of an easy
handle when using the multi handle was removed when we switched to
always using the multi interface internally. Now they were just two
separate struct that was always allocated for each easy handle.

This first step just moves the Curl_one_easy struct members into the
SessionHandle struct and hides this somehow (== keeps the source code
changes to a minimum) by defining Curl_one_easy to SessionHandle

The biggest changes in this commit are:

 1 - the linked list of easy handles had to be changed somewhat due
     to the new struct layout. This made the main linked list pointer
     get renamed to 'easyp' and there's also a new pointer to the last
     node, called easylp. It is no longer circular but ends with ->next
     pointing to NULL. New nodes are still added last.

 2 - easy->state is now called easy->mstate to avoid name collision
2013-08-03 22:51:35 +02:00
Steve Holme
7da3caaf95 Revert "DOCS: Added IMAP URL example for listing new messages"
This reverts commit 82ab5f1b0c as this was the wrong place to
document the complexity of IMAP URLs and Custom Requests.
2013-08-02 14:25:21 +01:00
Steve Holme
82ab5f1b0c DOCS: Added IMAP URL example for listing new messages
In addition to listing the folder contents, in the URL examples, added
an example to list the new messages waiting in the user's inbox.
2013-08-02 10:08:55 +01:00
Yang Tse
7ae64af368 packages/vms/Makefile.am: add latest file additions to EXTRA_DIST 2013-08-01 13:57:00 +02:00
John Malmberg
2ad688ed7c Add in the files needed to build libcurl shared images on VMS.
Update the packages/vms/readme file to be current.

Also some files for the GNV based build were either missing or needed an
update.

curl_crtl_init.c is a special file that is run before main() to
set up the proper C runtime behavior.

generate_vax_transfer.com generates the VAX transfer vector modules from
the gnv_libcurl_symbols.opt file.

gnv_conftest.c_first is a helper file needed for configure scripts to
come up with the expected answers on VMS.

gnv_libcurl_symbols.opt is the public symbols for the libcurl shared
image.

gnv_link_curl.com builds the shared libcurl image and rebuilds other
programs to use it.

macro32_exactcase.patch is a hack to make a local copy of the VMS Macro32
assembler case sensitive, which is needed to build the VAX transfer modules.

report_openssl_version.c is a tool for help verify that the libcurl
shared image is being built for a minium version of openssl.
2013-08-01 13:51:52 +02:00
Yang Tse
ca786233d2 curl: second follow-up for commit 5af2bfb9
Display progress-bar unconditionally on first call
2013-08-01 12:25:01 +02:00
Yang Tse
14a3139c4d curl: follow-up for commit 5af2bfb9
Use tvnow() and tvdiff() to avoid introducing new linkage issues
2013-07-31 15:36:56 +02:00
Daniel Stenberg
5af2bfb955 curl: --progress-bar max update frequency now at 5Hz 2013-07-31 13:41:00 +02:00
Daniel Stenberg
1691a31cab curl: make --progress-bar update the line less frequently
Also, use memset() instead of a lame loop.

The previous logic that tried to avoid too many updates were very
ineffective for really fast transfers, as then it could easily end up
doing hundreds of updates per second that would make a significant
impact in transfer performance!

Bug: http://curl.haxx.se/mail/archive-2013-07/0031.html
Reported-by: Marc Doughty
2013-07-31 13:41:00 +02:00
Nick Zitzmann
9dedcbf9ec darwinssl: added LFs to some strings passed into infof()
(This doesn't need to appear in the release notes.) I noticed a few places
where infof() was called, and there should've been an LF at the end of the
string, but there wasn't.
2013-07-30 20:32:18 -06:00
Nick Zitzmann
537ffc4c69 darwinssl: fix build error in crypto authentication under Snow Leopard
It turns out Snow Leopard not only has SecItemCopyMatching() defined in
a header not included by the omnibus header, but it won't work for our
purposes, because searching for SecIdentityRef objects wasn't added
to that API until Lion. So we now use the old SecKeychainSearch API
instead if the user is building under, or running under, Snow Leopard.

Bug: http://sourceforge.net/p/curl/bugs/1255/
Reported by: Edward Rudd
2013-07-30 20:25:38 -06:00
Nick Zitzmann
c3e7210548 md5 & metalink: use better build macros on Apple operating systems
Previously we used __MAC_10_X and __IPHONE_X to mark digest-generating
code that was specific to OS X and iOS. Now we use
__MAC_OS_X_VERSION_MAX_ALLOWED and __IPHONE_OS_VERSION_MAX_ALLOWED
instead of those macros.

Bug: http://sourceforge.net/p/curl/bugs/1255/
Reported by: Edward Rudd
2013-07-30 20:20:20 -06:00
Yang Tse
9a5c2d8373 tool_operhlp.c: fix add_file_name_to_url() OOM handling 2013-07-29 18:32:39 +02:00
Yang Tse
8693bbd8c4 tool_operate.c: fix brace placement for vi/emacs delimiter matching 2013-07-29 18:32:38 +02:00
Yang Tse
251dd03b88 tool_operate.c: move <fabdef.h> header inclusion location 2013-07-29 18:32:37 +02:00
Daniel Stenberg
55ea83d622 RELEASE-NOTES: synced with b5478a0e03 2013-07-29 14:51:09 +02:00
Daniel Stenberg
b5478a0e03 curl_easy_pause: on unpause, trigger mulit-socket handling
When the multi-socket API is used, we need the handle to be checked
again when it gets unpaused.

Bug: http://curl.haxx.se/mail/lib-2013-07/0239.html
Reported-by: Justin Karneges
2013-07-29 14:37:08 +02:00
John E. Malmberg
db2deba6b4 curl_formadd: fix file upload on VMS
For the standard VMS text file formats, VMS needs to read the file to
get the actual file size.

For the standard VMS binary file formats, VMS needs a special format of
fopen() call so that it stops reading at the logical end of file instead
of at the end of the blocks allocated to the file.

I structured the patch this way as I was not sure about changing the
structures or parameters to the routines, but would prefer to only call
the stat() function once and pass the information to where the fopen()
call is made.

Bug: https://sourceforge.net/p/curl/bugs/758/
2013-07-29 13:09:08 +02:00
Daniel Stenberg
41fb6443ce formadd: CURLFORM_FILECONTENT wrongly rejected some option combos
The code for CURLFORM_FILECONTENT had its check for duplicate options
wrong so that it would reject CURLFORM_PTRNAME if used in combination
with it (but not CURLFORM_COPYNAME)! The flags field used for this
purpose cannot be interpreted that broadly.

Bug: http://curl.haxx.se/mail/lib-2013-07/0258.html
Reported-by: Byrial Jensen
2013-07-26 23:45:01 +02:00
Yang Tse
e5dfe6c282 packages/vms/Makefile.am: add latest file additions to EXTRA_DIST 2013-07-25 13:18:50 +02:00
John E. Malmberg
e277e20a6d VMS: intial set of files to allow building using GNV toolkit. 2013-07-25 13:04:29 +02:00
Yang Tse
a23e56d109 string formatting: fix too many arguments for format 2013-07-24 17:06:28 +02:00
Yang Tse
ca89a0a092 string formatting: fix zero-length printf format string 2013-07-24 17:05:02 +02:00
Yang Tse
50a74be125 easy.c: curl_easy_getinfo() fix va_start/va_end matching 2013-07-24 16:46:26 +02:00
Yang Tse
8c1e3bb713 imap.c: imap_sendf() fix va_start/va_end matching 2013-07-24 16:46:25 +02:00
Yang Tse
4fad1943a2 string formatting: fix 15+ printf-style format strings 2013-07-24 16:46:24 +02:00
Patrick Monnerat
4d346673a2 OS400: sync ILE/RPG binding with current curl.h 2013-07-24 16:12:35 +02:00
Yang Tse
de052ca6fc string formatting: fix 25+ printf-style format strings 2013-07-24 01:21:26 +02:00
Daniel Stenberg
1a593191c2 Makefile.am: use LDFLAGS as well when linking libcurl
Linking on Solaris 10 x86 with Sun Studio 12 failed when we upgraded
automake for the release builds.

Bug: http://curl.haxx.se/bug/view.cgi?id=1217
Reported-by: Dagobert Michelsen
2013-07-23 21:51:12 +02:00
Fabian Keil
2c4ef997b9 url.c: Fix dot file path cleanup when using an HTTP proxy
Previously the path was cleaned, but the URL wasn't properly updated.
2013-07-23 20:51:15 +02:00
Fabian Keil
d020e2c381 tests: test1232 verifies dotdot removal from path with proxy 2013-07-23 20:51:15 +02:00
Fabian Keil
48fe9226a0 dotdot.c: Fix a RFC section number in a comment for Curl_dedotdotify() 2013-07-23 20:50:59 +02:00
John E. Malmberg
a77ac42e52 build_vms.com: fix debug and float options
In the reorganization of the build_vms.com the debug and float options
were not fixed up correctly.
2013-07-22 22:30:05 +02:00
John E. Malmberg
5880db8abd curl: fix upload of a zip file in OpenVMS
Two fixes:

1. Force output file format to be stream-lf so that partial downloads
can be continued.

This should have minor impact as if the file does not exist, it was
created with stream-lf format.  The only time this was an issue is if
there was already an existing file with a different format.

2. Fix file uploads are now fixed.

   a. VMS binary files such as ZIP archives are now uploaded
      correctly.

   b. VMS text files are read once to get the correct size
      and then converted to line-feed terminated records as
      they are read into curl.

The default VMS text formats do not contain either line-feed or
carriage-return terminated records.  Those delimiters are added by the
operating system file read calls if the application requests them.

Bug: http://curl.haxx.se/bug/view.cgi?id=496
2013-07-22 22:30:05 +02:00
Yang Tse
0f4ba89ffd libtest: fix data type of some *_setopt() 'long' arguments 2013-07-22 21:40:45 +02:00
Yang Tse
edeb1ae65f curl: fix symbolic names for CURL_NETRC_* enum in --libcurl output 2013-07-22 21:40:44 +02:00
Yang Tse
82232bbbaf curl: fix symbolic names for CURLUSESSL_* enum in --libcurl output 2013-07-22 21:40:43 +02:00
Yang Tse
bb2e0686ab tool_operate.c: fix passing curl_easy_setopt long arg on some x64 ABIs
We no longer pass our 'bool' data type variables nor constants as
an argument to my_setopt(), instead we use proper 1L or 0L values.

This also fixes macro used to pass string argument for CURLOPT_SSLCERT,
CURLOPT_SSLKEY and CURLOPT_EGDSOCKET using my_setopt_str() instead of
my_setopt().

This also casts enum or int argument data types to long when passed to
my_setopt_enum().
2013-07-22 21:40:43 +02:00
Daniel Stenberg
513e587c5e curl_multi_wait: fix revents
Commit 6d30f8ebed didn't work properly. First, it used the wrong
array index, but this fix also:

1 - only does the copying if indeed there was any activity

2 - makes sure to properly translate between internal and external
bitfields, which are not guaranteed to match

Reported-by: Evgeny Turnaev
2013-07-21 21:54:47 +02:00
Daniel Stenberg
6ed2bcc5f5 RELEASE-NOTES: synced with d529f3882b 2013-07-19 23:38:43 +02:00
Daniel Stenberg
d529f3882b curl_easy_perform: gradually increase the delay time
Instead of going 50,100,150 etc millisecond delay time when nothing has
been found to do or wait for, we now start lower and double each loop as
in 4,8,16,32 etc.

This lowers the minimum wait without sacrifizing the longer wait too
much with unnecessary CPU cycles burnt.

Bug: http://curl.haxx.se/mail/lib-2013-07/0103.html
Reported-by: Andreas Malzahn
2013-07-19 23:27:17 +02:00
Daniel Stenberg
e2e92486a7 ftp_do_more: consider DO_MORE complete when server connects back
In the case of an active connection when ftp_do_more() detects that the
server has connected back, it must make sure to mark it as complete so
that the multi_runsingle() function will detect this and move on to the
next state.

Bug: http://curl.haxx.se/mail/lib-2013-07/0115.html
Reported-by: Clemens Gruber
2013-07-19 23:02:30 +02:00
Yang Tse
2e5b3168d6 Makefile.b32: Borland makefile adjustments. Tested with BCC 5.5.1 2013-07-19 12:33:11 +02:00
Yang Tse
6bcacff1a5 WIN32 MemoryTracking: require UNICODE for wide strdup code support 2013-07-19 12:33:10 +02:00
Daniel Stenberg
12d01cb6fa CURLOPT_XFERINFOFUNCTION: introducing a new progress callback
CURLOPT_XFERINFOFUNCTION is now the preferred progress callback function
and CURLOPT_PROGRESSFUNCTION is considered deprecated.

This new callback uses pure 'curl_off_t' arguments to pass on full
resolution sizes. It otherwise retains the same characteristics: the
same call rate, the same meanings for the arguments and the return code
is used the same way.

The progressfunc.c example is updated to show how to use the new
callback for newer libcurls while supporting the older one if built with
an older libcurl or even built with a newer libcurl while running with
an older.
2013-07-18 23:44:06 +02:00
Yang Tse
90695fb2c5 Reinstate "WIN32 MemoryTracking: track wcsdup() _wcsdup() and _tcsdup() usage".
This reverts commit 7ed25cc, reinstating commit 8ec2cb5.

As of 18-jul-2013 we still do have code in libcurl that makes use of these
memory functions. Commit 8ec2cb5 comment still applies and is yet valid.

These memory functions are solely used in Windows builds, so all related
code is protected with '#ifdef WIN32' preprocessor conditional compilation
directives.

Specifically, wcsdup() _wcsdup() are used when building a Windows target with
UNICODE and USE_WINDOWS_SSPI preprocessor symbols defined. This is the case
when building a Windows UNICODE target with Windows native SSL/TLS support
enabled.

Realizing that wcsdup() _wcsdup() are used is a bit tricky given that usage
of these is hidden behind _tcsdup() which is MS way of dealing with code
that must tolerate UNICODE and non-UNICODE compilation. Additionally, MS
header files and those compatible from other compilers use this preprocessor
conditional compilation directive in order to select at compilation time
whether 'wide' or 'ansi' MS API functions are used.

Without this code, Windows build targets with Windows native SSL/TLS support
enabled and MemoryTracking support enabled misbehave in tracking memory usage,
regardless of being a UNICODE enabled build or not.
2013-07-18 23:37:33 +02:00
Yang Tse
dd17069c9e xc-am-iface.m4: comments refinement 2013-07-18 16:03:15 +02:00
Yang Tse
26b0cb6ae2 configure: fix 'subdir-objects' distclean related issue
See XC_AMEND_DISTCLEAN comments for details.
2013-07-18 04:48:33 +02:00
Evgeny Turnaev
6d30f8ebed curl_multi_wait: set revents for extra fds
Pass back the revents that happened for the user-provided file
descriptors.
2013-07-18 00:06:09 +02:00
Ben Greear
11220678c4 asyn-ares: Don't blank ares servers if none configured.
Best to just let c-ares use it's defaults if none are configured
in (lib)curl.

Signed-off-by: Ben Greear <greearb@candelatech.com>
2013-07-17 23:55:58 +02:00
Sergei Nikulov
448d55ef0a cmake: Fix for MSVC2010 project generation
Fixed issue with static build for MSVC2010.

After some investigation I've discovered known issue
http://public.kitware.com/Bug/view.php?id=11240 When .rc file is linked
to static lib it fails with following linker error

LINK : warning LNK4068: /MACHINE not specified; defaulting to X86
file.obj : fatal error LNK1112: module machine type 'x64' conflicts with
target machine type 'X86'

Fix add target property /MACHINE: for MSVC generation.

Also removed old workarounds - it caused errors during msvc build.

Bug: http://curl.haxx.se/mail/lib-2013-07/0046.html
2013-07-17 00:26:58 +02:00
Daniel Stenberg
7b115cc1e1 mk-ca-bundle.1: point out certdata.txt format docs 2013-07-17 00:06:16 +02:00
Yang Tse
a10d5e3851 slist.c: Curl_slist_append_nodup() OOM handling fix 2013-07-16 23:59:05 +02:00
Daniel Stenberg
1016637f5a test1414: FTP PORT download without SIZE support 2013-07-16 22:54:31 +02:00
Yang Tse
2e00872c04 tests/Makefile.am: add configurehelp.pm to DISTCLEANFILES 2013-07-16 22:51:35 +02:00
Patrick Monnerat
56ece42c81 curl_slist_append(): fix error detection 2013-07-15 19:49:30 +02:00
Patrick Monnerat
99924f6606 slist.c: fix indentation 2013-07-15 19:46:19 +02:00
Patrick Monnerat
0eba02fd41 OS400: new SSL backend GSKit 2013-07-15 19:00:36 +02:00
Patrick Monnerat
464c8693d2 OS400: add slist and certinfo EBCDIC support 2013-07-15 18:48:02 +02:00
Patrick Monnerat
50af17ef24 config-os400.h: enable system strdup(), strcmpi(), etc. 2013-07-15 18:38:17 +02:00
Patrick Monnerat
3a24cb7bc4 x509asn1.c,x509asn1.h: new module to support ASN.1/X509 parsing & info extract
Use from qssl backend
2013-07-15 18:16:13 +02:00
Patrick Monnerat
e839446c2a ssluse.c,sslgen.c,sslgen.h: move certinfo support to generic SSL 2013-07-15 17:26:59 +02:00
Patrick Monnerat
695931cf8e Merge branch 'master' of github.com:bagder/curl
Merge for resync
2013-07-15 16:55:30 +02:00
Patrick Monnerat
964a7600b9 slist.c, slist.h, cookie.c: new internal procedure Curl_slist_append_nodup() 2013-07-15 16:53:43 +02:00
Yang Tse
d4492f955d sslgen.c: fix Curl_rand() compiler warning
Use simple seeding method upon RANDOM_FILE seeding method failure.
2013-07-15 16:00:32 +02:00
Yang Tse
9c15325d34 sslgen.c: fix unreleased Curl_rand() infinite recursion 2013-07-15 13:22:08 +02:00
Dave Reisner
d8c04909fa src/tool: allow timeouts to accept decimal values
Implement wrappers around strtod to convert the user argument to a
double with sane error checking. Use this to allow --max-time and
--connect-timeout to accept decimal values instead of strictly integers.

The manpage is updated to make mention of this feature and,
additionally, forewarn that the actual timeout of the operation can
vary in its precision (particularly as the value increases in its
decimal precision).
2013-07-14 23:04:05 +02:00
Dave Reisner
c0a7a98aee curl.1: fix long line, found by checksrc.pl 2013-07-14 22:50:29 +02:00
Dave Reisner
f5005dd8d0 src/tool_paramhlp: try harder to catch negatives
strto* functions happily chomp off leading whitespace, so simply
checking for str[0] can lead to false negatives. Do the full parse and
check the out value instead.
2013-07-14 22:48:29 +02:00
John E. Malmberg
d3aaa68f55 build_vms.com: detect and use zlib shared image
Update the build_vms.com to detect and use zlib shared image installed
by the ZLIB kit produced by Jean-Francois Pieronne, and the also the
future ZLIB 1.2.8 kit in addition to the older ZLIB kits.

Also fix the indentation to match one of the common standards used for
VMS DCL command files and removed the hard tab characters.

Tested on OpenVMS 8.4 Alpha and IA64, and OpenVMS 7.3 VAX.
2013-07-14 17:37:49 +02:00
Yang Tse
cfc907e43d url.c: fix parse_url_login() OOM handling 2013-07-14 12:19:57 +02:00
Yang Tse
2af64c6432 http_digest.c: SIGSEGV and OOM handling fixes 2013-07-12 19:32:13 +02:00
Yang Tse
83f0dae129 url.c: fix parse_login_details() OOM handling 2013-07-12 12:17:31 +02:00
John E. Malmberg
65d53cf6ef setup-vms.h: sk_pop symbol tweak
Newer versions of curl are referencing a sk_pop symbol while the HP
OpenSSL library has the symbol in uppercase only.
2013-07-12 12:11:11 +02:00
Yang Tse
0d9e65f79f getinfo.c: fix enumerated type mixed with another type 2013-07-11 17:07:36 +02:00
Yang Tse
c983aa9efc test 1511: fix enumerated type mixed with another type 2013-07-11 17:01:02 +02:00
Yang Tse
b16b7f9d3a url.c: fix SIGSEGV 2013-07-11 13:31:08 +02:00
Yang Tse
5c6f12b9f2 dotdot.c: fix global declaration shadowing 2013-07-11 13:31:07 +02:00
Yang Tse
2022b10e50 easy.c: fix global declaration shadowing 2013-07-11 13:31:06 +02:00
Kamil Dudka
45339625bc Revert "curl.1: document the --time-cond option in the man page"
This reverts commit 3a0e931fc7 because
the documentation of --time-cond was duplicated by mistake.

Reported by: Dave Reisner
2013-07-09 15:46:49 +02:00
Kamil Dudka
20ff820ef2 curl.1: document the --sasl-ir option in the man page 2013-07-09 15:18:39 +02:00
Kamil Dudka
39e85d99fe curl.1: document the --post303 option in the man page 2013-07-09 15:18:39 +02:00
Kamil Dudka
3a0e931fc7 curl.1: document the --time-cond option in the man page 2013-07-09 15:18:39 +02:00
Yang Tse
fe7e3229f8 configure: automake 1.14 compatibility tweak (use XC_AUTOMAKE) 2013-07-09 00:10:38 +02:00
Yang Tse
ecf042ff3c xc-am-iface.m4: provide XC_AUTOMAKE macro 2013-07-09 00:07:26 +02:00
Guenter Knauf
aff245b360 Added winssl-zlib target to VC builds. 2013-07-08 17:46:15 +02:00
Guenter Knauf
e01469907a Synced Makefile.vc6 with recent changes.
Issue posted to the list by malinowsky AT FTW DOT at.
2013-07-08 15:05:10 +02:00
Guenter Knauf
b7a933154a Added libmetalink URL; added Android versions. 2013-07-04 04:35:22 +02:00
Dan Fandrich
54f18e5427 examples: Moved usercertinmem.c to COMPLICATED_EXAMPLES
This prevents it from being built during a "make check" since it
depends on OpenSSL.
2013-07-03 21:13:12 +02:00
Nick Zitzmann
833fba265d Merge branch 'master' of https://github.com/bagder/curl 2013-07-02 19:40:14 -06:00
Nick Zitzmann
d633052905 darwinssl: SSLv2 connections are aborted if unsupported by the OS
I just noticed that OS X no longer supports SSLv2. Other TLS engines return
an error if the requested protocol isn't supported by the underlying
engine, so we do that now for SSLv2 if the framework returns an error
when trying to turn on SSLv2 support. (Note: As always, SSLv2 support is
only enabled in curl when starting the app with the -2 argument; it's off
by default. SSLv2 is really old and insecure.)
2013-07-02 19:34:54 -06:00
Marc Hoersken
009d2336fe lib506.c: Fixed possible use of uninitialized variables 2013-07-01 21:42:15 +02:00
Kamil Dudka
abca89aaa0 url: restore the functionality of 'curl -u :'
This commit fixes a regression introduced in
fddb7b44a7.

Reported by: Markus Moeller
Bug: http://curl.haxx.se/mail/archive-2013-06/0052.html
2013-06-30 20:13:14 +02:00
Daniel Stenberg
d689376cb0 digest: append the timer to the random for the nonce 2013-06-25 11:37:27 +02:00
Daniel Stenberg
98b0d66eb4 digest: improve nonce generation
Use the new improved Curl_rand() to generate better random nonce for
Digest auth.
2013-06-25 11:28:22 +02:00
Daniel Stenberg
9c2853f2ae curl.1: fix typo in --xattr description
Bug: http://curl.haxx.se/bug/view.cgi?id=1252
Reported-by: Jean-Noël Rouvignac
2013-06-25 10:41:16 +02:00
Daniel Stenberg
aff7562922 RELEASE-NOTES: synced with 365c5ba395
The 10 first bug fixes for the pending release...
2013-06-25 10:35:21 +02:00
Daniel Stenberg
365c5ba395 formpost: better random boundaries
When doing multi-part formposts, libcurl used a pseudo-random value that
was seeded with time(). This turns out to be bad for users who formpost
data that is provided with users who then can guess how the boundary
string will look like and then they can forge a different formpost part
and trick the receiver.

My advice to such implementors is (still even after this change) to not
rely on the boundary strings being cryptographically strong. Fix your
code and logic to not depend on them that much!

I moved the Curl_rand() function into the sslgen.c source file now to be
able to take advantage of the SSL library's random function if it
provides one. If not, try to use the RANDOM_FILE for seeding and as a
last resort keep the old logic, just modified to also add microseconds
which makes it harder to properly guess the exact seed.

The formboundary() function in formdata.c is now using 64 bit entropy
for the boundary and therefore the string of dashes was reduced by 4
letters and there are 16 hex digits following it. The total length is
thus still the same.

Bug: http://curl.haxx.se/bug/view.cgi?id=1251
Reported-by: "Floris"
2013-06-25 09:55:49 +02:00
Daniel Stenberg
cb1aa8b0e3 printf: make sure %x are treated unsigned
When using %x, the number must be treated as unsigned as otherwise it
would get sign-extended on for example 64bit machines and do wrong
output. This problem showed when doing printf("%08x", 0xffeeddcc) on a
64bit host.
2013-06-25 09:55:49 +02:00
Daniel Stenberg
d3d5c4a40e tests: add test1395 to the tarball 2013-06-24 09:25:58 +02:00
Daniel Stenberg
6117d4025e SIGPIPE: don't use 'data' in sigpipe restore
Follow-up fix from 7d80ed64e4.

The SessionHandle may not be around to use when we restore the sigpipe
sighandler so we store the no_signal boolean in the local struct to know
if/how to restore.
2013-06-24 09:02:49 +02:00
Daniel Stenberg
d23745f7c9 TODO: 1.8 Modified buffer size approach
Thoughts around buffer sizes and what might be possible to do...
2013-06-23 22:49:06 +02:00
Daniel Stenberg
ad47d8e263 c-ares: improve error message on failed resolve
When the c-ares based resolver backend failed to resolve a name, it
tried to show the name that failed from existing structs. This caused
the wrong output and shown hostname when for example --interface
[hostname] was used and that name resolving failed.

Now we use the hostname used in the actual resolve attempt in the error
message as well.

Bug: http://curl.haxx.se/bug/view.cgi?id=1191
Reported-by: Kim Vandry
2013-06-23 20:25:38 +02:00
Daniel Stenberg
8a7a277c08 ossl_recv: check for an OpenSSL error, don't assume
When we recently started to treat a zero return code from SSL_read() as
an error we also got false positives - which primarily looks to be
because the OpenSSL documentation is wrong and a zero return code is not
at all an error case in many situations.

Now ossl_recv() will check with ERR_get_error() to see if there is a
stored error and only then consider it to be a true error if SSL_read()
returned zero.

Bug: http://curl.haxx.se/bug/view.cgi?id=1249
Reported-by: Nach M. S.
Patch-by: Nach M. S.
2013-06-23 12:05:21 +02:00
Nick Zitzmann
0030fbd382 Merge branch 'master' of https://github.com/bagder/curl 2013-06-22 15:16:05 -06:00
Nick Zitzmann
f3052c8a81 darwinssl: fix crash that started happening in Lion
Something (a recent security update maybe?) changed in Lion, and now it
has changed SSLCopyPeerTrust such that it may return noErr but also give
us a null trust, which caught us off guard and caused an eventual crash.
2013-06-22 15:13:36 -06:00
Daniel Stenberg
7d80ed64e4 SIGPIPE: ignored while inside the library
... and restore the ordinary handling again when it returns. This is
done for curl_easy_perform() and curl_easy_cleanup() only for now - and
only when built to use OpenSSL as backend as this is the known culprit
for the spurious SIGPIPEs people have received.

Bug: http://curl.haxx.se/bug/view.cgi?id=1180
Reported by: Lluís Batlle i Rossell
2013-06-22 22:35:06 +02:00
Daniel Stenberg
a2e0ce86ba KNOWN_BUGS: #83 unable to load non-default openssl engines 2013-06-22 22:24:36 +02:00
Daniel Stenberg
6fab0bd9f1 test1396: invoke the correct test tool!
This erroneously run unit test 1310 instead of 1396!
2013-06-22 22:20:31 +02:00
Kamil Dudka
02964ed630 test1230: avoid using hard-wired port number
... to prevent failure when a non-default -b option is given
2013-06-22 22:12:49 +02:00
Kamil Dudka
6f3e7aabdc curl-config.in: replace tabs by spaces 2013-06-22 22:08:42 +02:00
Nick Zitzmann
631e3e13a9 darwinssl: reform OS-specific #defines
This doesn't need to be in the release notes. I cleaned up a lot of the #if
lines in the code to use MAC_OS_X_VERSION_MIN_REQUIRED and
MAC_OS_X_VERSION_MAX_ALLOWED instead of checking for whether things like
__MAC_10_6 or whatever were defined, because for some SDKs Apple has released
they were defined out of place.
2013-06-22 12:23:26 -06:00
Alessandro Ghedini
832c195179 docs: fix typo in curl_easy_getinfo manpage 2013-06-22 18:28:18 +02:00
Daniel Stenberg
7877619f85 dotdot: introducing dot file path cleanup
RFC3986 details how a path part passed in as part of a URI should be
"cleaned" from dot sequences before getting used. The described
algorithm is now implemented in lib/dotdot.c with the accompanied test
case in test 1395.

Bug: http://curl.haxx.se/bug/view.cgi?id=1200
Reported-by: Alex Vinnik
2013-06-22 14:15:07 +02:00
Daniel Stenberg
ec248b590d bump: start working towards what most likely will become 7.32.0 2013-06-22 14:13:28 +02:00
Daniel Stenberg
4846b5e9fe THANKS: added 24 new contributors from the 7.31.0 release 2013-06-22 13:52:27 +02:00
215 changed files with 12599 additions and 1763 deletions

View File

@@ -148,12 +148,24 @@ vc-ssl-zlib: $(VC)
cd ..\src
nmake /f Makefile.$(VC) cfg=release-ssl-zlib
vc-winssl-zlib: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-winssl-zlib
cd ..\src
nmake /f Makefile.$(VC) cfg=release-winssl-zlib
vc-x64-ssl-zlib: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib
vc-x64-winssl-zlib: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl-zlib
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl-zlib
vc-ssl-dll: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-ssl-dll

View File

@@ -1,11 +1,11 @@
Curl and libcurl 7.31.0
Curl and libcurl 7.32.0
Public curl releases: 133
Public curl releases: 134
Command line options: 152
curl_easy_setopt() options: 199
Public functions in libcurl: 58
Known libcurl bindings: 42
Contributors: 1005
Contributors: 1049
***
krb4 support is up for removal. If you care about it at all, speak up
@@ -14,58 +14,56 @@ Curl and libcurl 7.31.0
This release includes the following changes:
o darwinssl: add TLS session resumption
o darwinssl: add TLS crypto authentication
o imap/pop3/smtp: Added support for ;auth=<mech> in the URL
o imap/pop3/smtp: Added support for ;auth=<mech> to CURLOPT_USERPWD
o usercertinmem.c: add example showing user cert in memory
o url: Added smtp and pop3 hostnames to the protocol detection list
o imap/pop3/smtp: Added support for enabling the SASL initial response [8]
o curl -E: allow to use ':' in certificate nicknames [10]
o curl: allow timeouts to accept decimal values
o OS400: add slist and certinfo EBCDIC support
o OS400: new SSL backend GSKit
o CURLOPT_XFERINFOFUNCTION: introducing a new progress callback
o LIBCURL-STRUCTS: new document
This release includes the following bugfixes:
o SECURITY VULNERABILITY: curl_easy_unescape() may parse data beyond the end
of the input buffer [26]
o FTP: access files in root dir correctly [1]
o configure: try pthread_create without -lpthread [2]
o FTP: handle a 230 welcome response [3]
o curl-config: don't output static libs when they are disabled
o CURL_CHECK_CA_BUNDLE: don't check for paths when cross-compiling [4]
o Various documentation updates
o getinfo.c: reset timecond when clearing session-info variables [5]
o FILE: prevent an artificial timeout event due to stale speed-check data [6]
o ftp_state_pasv_resp: connect through proxy also when set by env [7]
o sshserver: disable StrictHostKeyChecking
o ftpserver: Fixed imap logout confirmation data
o curl_easy_init: use less mallocs
o smtp: Fixed unknown percentage complete in progress bar
o smtp: Fixed sending of double CRLF caused by first in EOB
o bindlocal: move brace out of #ifdef [9]
o winssl: Fixed invalid memory access during SSL shutdown [11]
o OS X framework: fix invalid symbolic link
o OpenSSL: allow empty server certificate subject [12]
o axtls: prevent memleaks on SSL handshake failures
o cookies: only consider full path matches
o Revert win32 MemoryTracking: wcsdup() _wcsdup() and _tcsdup() [13]
o Curl_cookie_add: handle IPv6 hosts [14]
o ossl_send: SSL_write() returning 0 is an error too
o ossl_recv: SSL_read() returning 0 is an error too
o Digest auth: escape user names with \ or " in them [15]
o curl_formadd.3: fixed wrong "end-marker" syntax [16]
o libcurl-tutorial.3: fix incorrect backslash [17]
o curl_multi_wait: reduce timeout if the multi handle wants to [18]
o tests/Makefile: typo in the perlcheck target [19]
o axtls: honor disabled VERIFYHOST
o OpenSSL: avoid double free in the PKCS12 certificate code [20]
o multi_socket: reduce timeout inaccuracy margin [21]
o digest: support auth-int for empty entity body [22]
o axtls: now done non-blocking
o lib1900: use tutil_tvnow instead of gettimeofday
o curl_easy_perform: avoid busy-looping [23]
o CURLOPT_COOKIELIST: take cookie share lock [24]
o multi_socket: react on socket close immediately [25]
o dotdot: introducing dot file path cleanup [1]
o docs: fix typo in curl_easy_getinfo manpage
o test1230: avoid using hard-wired port number
o test1396: invoke the correct test tool
o SIGPIPE: ignored while inside the library [2]
o darwinssl: fix crash that started happening in Lion
o OpenSSL: check for read errors, don't assume [3]
o c-ares: improve error message on failed resolve [4]
o printf: make sure %x are treated unsigned
o formpost: better random boundaries [5]
o url: restore the functionality of 'curl -u :' [6]
o curl.1: fix typo in --xattr description [7]
o digest: improve nonce generation
o configure: automake 1.14 compatibility tweak
o curl.1: document the --post303 option in the man page
o curl.1: document the --sasl-ir option in the man page
o setup-vms.h: sk_pop symbol tweak
o tool_paramhlp: try harder to catch negatives
o cmake: Fix for MSVC2010 project generation [8]
o asyn-ares: Don't blank ares servers if none configured
o curl_multi_wait: set revents for extra fds
o Reinstate "WIN32 MemoryTracking: track wcsdup() _wcsdup() and _tcsdup()
o ftp_do_more: consider DO_MORE complete when server connects back [9]
o curl_easy_perform: gradually increase the delay time [10]
o curl: fix symbolic names for CURLUSESSL_* enum in --libcurl output
o curl: fix upload of a zip file in OpenVMS [11]
o build: fix linking on Solaris 10 [12]
o curl_formadd: CURLFORM_FILECONTENT wrongly rejected some option combos [13]
o curl_formadd: fix file upload on VMS [14]
o curl_easy_pause: on unpause, trigger mulit-socket handling [15]
o md5 & metalink: use better build macros on Apple operating systems [16]
o darwinssl: fix build error in crypto authentication under Snow Leopard [16]
o curl: make --progress-bar update the line less frequently [17]
o configure: don't error out on variable confusions (CFLAGS, LDFLAGS etc)
o mk-ca-bundle: skip more untrusted certificates
o formadd: wrong pointer for file name when CURLFORM_BUFFERPTR used [18]
o FTP: when EPSV gets a 229 but fails to connect, retry with PASV
o mk-ca-bundle.1: don't install on make install [19]
o VMS: lots of updates and fixes of the build procedure
o global dns cache: didn't work (regression)
o global dns cache: fix memory leak
o
This release includes the following known bugs:
@@ -74,43 +72,34 @@ This release includes the following known bugs:
This release would not have looked like this without help, code, reports and
advice from friends like these:
David Strauss, Kamil Dudka, Steve Holme, Nick Zitzmann, Sam Deane, Duncan,
Anders Havn, Dan Fandrich, Paul Howarth, Dave Reisner, Wouter Van Rooy,
Linus Nielsen Feltzing, Ishan SinghLevett, Alessandro Ghedini,
Ludovico Cavedon, Zdenek Pavlas, Zekun Ni, Lars Johannesen, Marc Hoersken,
Renaud Guillard, John Gardiner Myers, Jared Jennings, Eric Hu,
Yamada Yasuharu, Stefan Neis, Mike Giancola, Eric S. Raymond, Andrii Moiseiev,
Christian Weisgerber, Peter Gal, Aleksey Tulinov, Hang Su, Sergei Nikulov,
Miguel Angel, Nach M. S., Benjamin Gilbert, Erik Johansson, Timo Sirainen,
Guenter Knauf
Alex Vinnik, Alessandro Ghedini, Nick Zitzmann, Kamil Dudka,
Lluis Batlle i Rossell, Nach M. S., Kim Vandry, Ben Greear, Dan Fandrich,
Dave Reisner, Evgeny Turnaev, Guenter Knauf, John E. Malmberg, Marc Hoersken,
Patrick Monnerat, Sergei Nikulov, Yang Tse, Andreas Malzahn, Clemens Gruber,
Jean-Noel Rouvignac, Markus Moeller, Fabian Keil, Dagobert Michelsen,
Byrial Jensen, Justin Karneges, Edward Rudd, Marc Doughty, Konstantin Isakov,
Thanks! (and sorry if I forgot to mention someone)
References to bug reports and discussions on issues:
[1] = http://curl.haxx.se/mail/lib-2013-04/0142.html
[2] = http://curl.haxx.se/bug/view.cgi?id=1216
[3] = http://curl.haxx.se/mail/lib-2013-02/0102.html
[4] = http://curl.haxx.se/mail/lib-2013-04/0294.html
[5] = http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=705783
[6] = https://bugzilla.redhat.com/906031
[7] = http://curl.haxx.se/bug/view.cgi?id=1218
[8] = http://curl.haxx.se/mail/lib-2012-03/0114.html
[9] = http://curl.haxx.se/mail/lib-2013-05/0000.html
[10] = http://curl.haxx.se/bug/view.cgi?id=1196
[11] = http://curl.haxx.se/bug/view.cgi?id=1219
[12] = http://curl.haxx.se/bug/view.cgi?id=1220
[13] = http://curl.haxx.se/mail/lib-2013-05/0070.html
[14] = http://curl.haxx.se/bug/view.cgi?id=1221
[15] = http://curl.haxx.se/bug/view.cgi?id=1230
[16] = http://curl.haxx.se/bug/view.cgi?id=1233
[17] = http://curl.haxx.se/bug/view.cgi?id=1234
[18] = http://curl.haxx.se/bug/view.cgi?id=1224
[19] = http://curl.haxx.se/bug/view.cgi?id=1239
[20] = http://curl.haxx.se/bug/view.cgi?id=1236
[21] = http://curl.haxx.se/bug/view.cgi?id=1228
[22] = http://curl.haxx.se/bug/view.cgi?id=1235
[23] = http://curl.haxx.se/bug/view.cgi?id=1238
[24] = http://curl.haxx.se/bug/view.cgi?id=1215
[25] = http://curl.haxx.se/bug/view.cgi?id=1248
[26] = http://curl.haxx.se/docs/adv_20130622.html
[1] = http://curl.haxx.se/bug/view.cgi?id=1200
[2] = http://curl.haxx.se/bug/view.cgi?id=1180
[3] = http://curl.haxx.se/bug/view.cgi?id=1249
[4] = http://curl.haxx.se/bug/view.cgi?id=1191
[5] = http://curl.haxx.se/bug/view.cgi?id=1251
[6] = http://curl.haxx.se/mail/archive-2013-06/0052.html
[7] = http://curl.haxx.se/bug/view.cgi?id=1252
[8] = http://curl.haxx.se/mail/lib-2013-07/0046.html
[9] = http://curl.haxx.se/mail/lib-2013-07/0115.html
[10] = http://curl.haxx.se/mail/lib-2013-07/0103.html
[11] = http://curl.haxx.se/bug/view.cgi?id=496
[12] = http://curl.haxx.se/bug/view.cgi?id=1217
[13] = http://curl.haxx.se/mail/lib-2013-07/0258.html
[14] = http://curl.haxx.se/bug/view.cgi?id=758
[15] = http://curl.haxx.se/mail/lib-2013-07/0239.html
[16] = http://curl.haxx.se/bug/view.cgi?id=1255
[17] = http://curl.haxx.se/mail/archive-2013-07/0031.html
[18] = http://curl.haxx.se/bug/view.cgi?id=1262
[19] = http://curl.haxx.se/mail/lib-2013-08/0057.html

View File

@@ -126,7 +126,7 @@ fi
dnl figure out the libcurl version
CURLVERSION=`$SED -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' ${srcdir}/include/curl/curlver.h`
XC_CHECK_PROG_CC
AM_INIT_AUTOMAKE
XC_AUTOMAKE
AC_MSG_CHECKING([curl version])
AC_MSG_RESULT($CURLVERSION)
@@ -3531,6 +3531,8 @@ AC_OUTPUT
CURL_GENERATE_CONFIGUREHELP_PM
XC_AMEND_DISTCLEAN([lib src tests/unit tests/server tests/libtest docs/examples])
AC_MSG_NOTICE([Configured to build curl/libcurl:
curl version: ${CURLVERSION}

View File

@@ -79,9 +79,9 @@
1.3 What To Read
Source code, the man pages, the INTERNALS document, TODO, KNOWN_BUGS, the
most recent CHANGES. Just lurking on the libcurl mailing list is gonna give
you a lot of insights on what's going on right now. Asking there is a good
idea too.
most recent CHANGES. Just lurking on the curl-library mailing list is gonna
give you a lot of insights on what's going on right now. Asking there is a
good idea too.
2. cURL Coding Standards
@@ -98,12 +98,12 @@
2.2 Indenting
Please try using the same indenting levels and bracing method as all the
other code already does. It makes the source code a lot easier to follow if
all of it is written using the same style. We don't ask you to like it, we
just ask you to follow the tradition! ;-) This mainly means: 2-level indents,
using spaces only (no tabs) and having the opening brace ({) on the same line
as the if() or while().
Use the same indenting levels and bracing method as all the other code
already does. It makes the source code easier to follow if all of it is
written using the same style. We don't ask you to like it, we just ask you to
follow the tradition! ;-) This mainly means: 2-level indents, using spaces
only (no tabs) and having the opening brace ({) on the same line as the if()
or while().
Also note that we use if() and while() with no space before the parenthesis.
@@ -151,6 +151,9 @@
description exactly what they correct so that all patches can be selectively
applied by the maintainer or other interested parties.
Also, separate patches enable bisecting much better when we track problems in
the future.
2.9 Patch Against Recent Sources
Please try to get the latest available sources to make your patches
@@ -178,6 +181,10 @@
test case that verifies that it works as documented. If every submitter also
posts a few test cases, it won't end up as a heavy burden on a single person!
If you don't have test cases or perhaps you have done something that is very
hard to write tests for, do explain exactly how you have otherwise tested and
verified your changes.
3. Pushing Out Your Changes
3.1 Write Access to git Repository

View File

@@ -1045,7 +1045,7 @@ PORTS
- Alpha OpenVMS V7.1-1H2
- Alpha Tru64 v5.0 5.1
- AVR32 Linux
- ARM Android 1.5, 2.1
- ARM Android 1.5, 2.1, 2.3, 3.2, 4.x
- ARM INTEGRITY
- ARM iOS
- Cell Linux
@@ -1116,6 +1116,7 @@ GNU GSS http://www.gnu.org/software/gss/
GnuTLS http://www.gnu.org/software/gnutls/
Heimdal http://www.pdc.kth.se/heimdal/
libidn http://www.gnu.org/software/libidn/
libmetalink https://launchpad.net/libmetalink/
libssh2 http://www.libssh2.org/
MIT Kerberos http://web.mit.edu/kerberos/www/dist/
NSS http://www.mozilla.org/projects/security/pki/nss/

View File

@@ -111,6 +111,9 @@ Windows vs Unix
Library
=======
(See LIBCURL-STRUCTS for a separate document describing all major internal
structs and their purposes.)
There are plenty of entry points to the library, namely each publicly defined
function that libcurl offers to applications. All of those functions are
rather small and easy-to-follow. All the ones prefixed with 'curl_easy' are
@@ -135,16 +138,18 @@ Library
options is documented in the man page. This function mainly sets things in
the 'SessionHandle' struct.
curl_easy_perform() does a whole lot of things:
curl_easy_perform() is just a wrapper function that makes use of the multi
API. It basically curl_multi_init(), curl_multi_add_handle(),
curl_multi_wait(), and curl_multi_perform() until the transfer is done and
then returns.
It starts off in the lib/easy.c file by calling Curl_perform() and the main
work then continues in lib/url.c. The flow continues with a call to
Curl_connect() to connect to the remote site.
Some of the most important key functions in url.c are called from multi.c
when certain key steps are to be made in the transfer operation.
o Curl_connect()
... analyzes the URL, it separates the different components and connects to
the remote host. This may involve using a proxy and/or using SSL. The
Analyzes the URL, it separates the different components and connects to the
remote host. This may involve using a proxy and/or using SSL. The
Curl_resolv() function in lib/hostip.c is used for looking up host names
(it does then use the proper underlying method, which may vary between
platforms and builds).
@@ -160,10 +165,7 @@ Library
o Curl_do()
Curl_do() makes sure the proper protocol-specific function is called. The
functions are named after the protocols they handle. Curl_ftp(),
Curl_http(), Curl_dict(), etc. They all reside in their respective files
(ftp.c, http.c and dict.c). HTTPS is handled by Curl_http() and FTPS by
Curl_ftp().
functions are named after the protocols they handle.
The protocol-specific functions of course deal with protocol-specific
negotiations and setup. They have access to the Curl_sendf() (from
@@ -182,10 +184,9 @@ Library
be called with some basic info about the upcoming transfer: what socket(s)
to read/write and the expected file transfer sizes (if known).
o Transfer()
o Curl_readwrite()
Curl_perform() then calls Transfer() in lib/transfer.c that performs the
entire file transfer.
Called during the transfer of the actual protocol payload.
During transfer, the progress functions in lib/progress.c are called at a
frequent interval (or at the user's choice, a specified callback might get
@@ -207,33 +208,11 @@ Library
used. This function is only used when we are certain that no more transfers
is going to be made on the connection. It can be also closed by force, or
it can be called to make sure that libcurl doesn't keep too many
connections alive at the same time (there's a default amount of 5 but that
can be changed with the CURLOPT_MAXCONNECTS option).
connections alive at the same time.
This function cleans up all resources that are associated with a single
connection.
Curl_perform() is the function that does the main "connect - do - transfer -
done" loop. It loops if there's a Location: to follow.
When completed, the curl_easy_cleanup() should be called to free up used
resources. It runs Curl_disconnect() on all open connections.
A quick roundup on internal function sequences (many of these call
protocol-specific function-pointers):
Curl_connect - connects to a remote site and does initial connect fluff
This also checks for an existing connection to the requested site and uses
that one if it is possible.
Curl_do - starts a transfer
Curl_handler::do_it() - transfers data
Curl_done - ends a transfer
Curl_disconnect - disconnects from a remote site. This is called when the
disconnect is really requested, which doesn't necessarily have to be
exactly after curl_done in case we want to keep the connection open for
a while.
HTTP(S)
@@ -316,48 +295,38 @@ Persistent Connections
hold connection-oriented data. It is meant to hold the root data as well as
all the options etc that the library-user may choose.
o The 'SessionHandle' struct holds the "connection cache" (an array of
pointers to 'connectdata' structs). There's one connectdata struct
allocated for each connection that libcurl knows about. Note that when you
use the multi interface, the multi handle will hold the connection cache
and not the particular easy handle. This of course to allow all easy handles
in a multi stack to be able to share and re-use connections.
pointers to 'connectdata' structs).
o This enables the 'curl handle' to be reused on subsequent transfers.
o When we are about to perform a transfer with curl_easy_perform(), we first
check for an already existing connection in the cache that we can use,
otherwise we create a new one and add to the cache. If the cache is full
already when we add a new connection, we close one of the present ones. We
select which one to close dependent on the close policy that may have been
previously set.
o When the transfer operation is complete, we try to leave the connection
open. Particular options may tell us not to, and protocols may signal
closure on connections and then we don't keep it open of course.
o When libcurl is told to perform a transfer, it first checks for an already
existing connection in the cache that we can use. Otherwise it creates a
new one and adds that the cache. If the cache is full already when a new
conncetion is added added, it will first close the oldest unused one.
o When the transfer operation is complete, the connection is left
open. Particular options may tell libcurl not to, and protocols may signal
closure on connections and then they won't be kept open of course.
o When curl_easy_cleanup() is called, we close all still opened connections,
unless of course the multi interface "owns" the connections.
You do realize that the curl handle must be re-used in order for the
persistent connections to work.
The curl handle must be re-used in order for the persistent connections to
work.
multi interface/non-blocking
============================
We make an effort to provide a non-blocking interface to the library, the
multi interface. To make that interface work as good as possible, no
low-level functions within libcurl must be written to work in a blocking
manner.
The multi interface is a non-blocking interface to the library. To make that
interface work as good as possible, no low-level functions within libcurl
must be written to work in a blocking manner. (There are still a few spots
violating this rule.)
One of the primary reasons we introduced c-ares support was to allow the name
resolve phase to be perfectly non-blocking as well.
The ultimate goal is to provide the easy interface simply by wrapping the
multi interface functions and thus treat everything internally as the multi
interface is the single interface we have.
The FTP and the SFTP/SCP protocols are thus perfect examples of how we adapt
and adjust the code to allow non-blocking operations even on multi-stage
protocols. They are built around state machines that return when they could
block waiting for data. The DICT, LDAP and TELNET protocols are crappy
examples and they are subject for rewrite in the future to better fit the
libcurl protocol family.
The FTP and the SFTP/SCP protocols are examples of how we adapt and adjust
the code to allow non-blocking operations even on multi-stage command-
response protocols. They are built around state machines that return when
they would otherwise block waiting for data. The DICT, LDAP and TELNET
protocols are crappy examples and they are subject for rewrite in the future
to better fit the libcurl protocol family.
SSL libraries
=============
@@ -408,12 +377,12 @@ API/ABI
Client
======
main() resides in src/main.c together with most of the client code.
main() resides in src/tool_main.c.
src/tool_hugehelp.c is automatically generated by the mkhelp.pl perl script
to display the complete "manual" and the src/urlglob.c file holds the
functions used for the URL-"globbing" support. Globbing in the sense that
the {} and [] expansion stuff is there.
to display the complete "manual" and the src/tool_urlglob.c file holds the
functions used for the URL-"globbing" support. Globbing in the sense that the
{} and [] expansion stuff is there.
The client mostly messes around to setup its 'config' struct properly, then
it calls the curl_easy_*() functions of the library and when it gets back
@@ -425,8 +394,8 @@ Client
curl_easy_getinfo() function to extract useful information from the curl
session.
Recent versions may loop and do all this several times if many URLs were
specified on the command line or config file.
It may loop and do all this several times if many URLs were specified on the
command line or config file.
Memory Debugging
================

View File

@@ -3,6 +3,14 @@ join in and help us correct one or more of these! Also be sure to check the
changelog of the current development status, as one or more of these problems
may have been fixed since this was written!
83. curl is unable to load non-default openssl engines, because openssl isn't
initialized properly. This seems to require OpenSSL_config() or
CONF_modules_load_file() to be used by libcurl but the first seems to not
work and we've gotten not reports from tests with the latter. Possibly we
need to discuss with OpenSSL developers how this is supposed to be done. We
need users with actual external openssl engines for testing to work on this.
http://curl.haxx.se/bug/view.cgi?id=1208
82. When building with the Windows Borland compiler, it fails because the
"tlib" tool doesn't support hyphens (minus signs) in file names and we have
such in the build.
@@ -96,13 +104,6 @@ may have been fixed since this was written!
CURLOPT_FAILONERROR with FTP to detect if a file exists or not, but it is
not working: http://curl.haxx.se/mail/lib-2008-07/0295.html
57. On VMS-Alpha: When using an http-file-upload the file is not sent to the
Server with the correct content-length. Sending a file with 511 or less
bytes, content-length 512 is used. Sending a file with 513 - 1023 bytes,
content-length 1024 is used. Files with a length of a multiple of 512 Bytes
show the correct content-length. Only these files work for upload.
http://curl.haxx.se/bug/view.cgi?id=2057858
56. When libcurl sends CURLOPT_POSTQUOTE commands when connected to a SFTP
server using the multi interface, the commands are not being sent correctly
and instead the connection is "cancelled" (the operation is considered done)
@@ -180,12 +181,6 @@ may have been fixed since this was written!
We probably have even more bugs and lack of features when a SOCKS proxy is
used.
22. Sending files to a FTP server using curl on VMS, might lead to curl
complaining on "unaligned file size" on completion. The problem is related
to VMS file structures and the perceived file sizes stat() returns. A
possible fix would involve sending a "STRU VMS" command.
http://curl.haxx.se/bug/view.cgi?id=1156287
21. FTP ASCII transfers do not follow RFC959. They don't convert the data
accordingly (not for sending nor for receiving). RFC 959 section 3.1.1.1
clearly describes how this should be done:

245
docs/LIBCURL-STRUCTS Normal file
View File

@@ -0,0 +1,245 @@
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
Structs in libcurl
This document should cover 7.32.0 pretty accurately, but will make sense even
for older and later versions as things don't change drastically that often.
1. The main structs in libcurl
1.1 SessionHandle
1.2 connectdata
1.3 Curl_multi
1.4 Curl_handler
1.5 conncache
1.6 Curl_share
1.7 CookieInfo
==============================================================================
1. The main structs in libcurl
1.1 SessionHandle
The SessionHandle handle struct is the one returned to the outside in the
external API as a "CURL *". This is usually known as an easy handle in API
documentations and examples.
Information and state that is related to the actual connection is in the
'connectdata' struct. When a transfer is about to be made, libcurl will
either create a new connection or re-use an existing one. The particular
connectdata that is used by this handle is pointed out by
SessionHandle->easy_conn.
Data and information that regard this particular single transfer is put in
the SingleRequest sub-struct.
When the SessionHandle struct is added to a multi handle, as it must be in
order to do any transfer, the ->multi member will point to the Curl_multi
struct it belongs to. The ->prev and ->next members will then be used by the
multi code to keep a linked list of SessionHandle structs that are added to
that same multi handle. libcurl always uses multi so ->multi *will* point to
a Curl_multi when a transfer is in progress.
->mstate is the multi state of this particular SessionHandle. When
multi_runsingle() is called, it will act on this handle according to which
state it is in. The mstate is also what tells which sockets to return for a
speicific SessionHandle when curl_multi_fdset() is called etc.
The libcurl source code generally use the name 'data' for the variable that
points to the SessionHandle.
1.2 connectdata
A general idea in libcurl is to keep connections around in a connection
"cache" after they have been used in case they will be used again and then
re-use an existing one instead of creating a new as it creates a significant
performance boost.
Each 'connectdata' identifies a single physical conncetion to a server. If
the connection can't be kept alive, the connection will be closed after use
and then this struct can be removed from the cache and freed.
Thus, the same SessionHandle can be used multiple times and each time select
another connectdata struct to use for the connection. Keep this in mind, as
it is then important to consider if options or choices are based on the
connection or the SessionHandle.
Functions in libcurl will assume that connectdata->data points to the
SessionHandle that uses this connection.
As a special complexity, some protocols supported by libcurl require a
special disconnect procedure that is more than just shutting down the
socket. It can involve sending one or more commands to the server before
doing so. Since connections are kept in the connection cache after use, the
original SessionHandle may no longer be around when the time comes to shut
down a particular connection. For this purpose, libcurl holds a special
dummy 'closure_handle' SessionHandle in the Curl_multi struct to
FTP uses two TCP connections for a typical transfer but it keeps both in
this single struct and thus can be considered a single connection for most
internal concerns.
The libcurl source code generally use the name 'conn' for the variable that
points to the connectdata.
1.3 Curl_multi
Internally, the easy interface is implemented as a wrapper around multi
interface functions. This makes everything multi interface.
Curl_multi is the multi handle struct exposed as "CURLM *" in external APIs.
This struct holds a list of SessionHandle structs that have been added to
this handle with curl_multi_add_handle(). The start of the list is ->easyp
and ->num_easy is a counter of added SessionHandles.
->msglist is a linked list of messages to send back when
curl_multi_info_read() is called. Basically a node is added to that list
when an individual SessionHandle's transfer has completed.
->hostcache points to the name cache. It is a hash table for looking up name
to IP. The nodes have a limited life time in there and this cache is meant
to reduce the time for when the same name is wanted within a short period of
time.
->timetree points to a tree of SessionHandles, sorted by the remaining time
until it should be checked - normally some sort of timeout. Each
SessionHandle has one node in the tree.
->sockhash is a hash table to allow fast lookups of socket descriptor to
which SessionHandle that uses that descriptor. This is necessary for the
multi_socket API.
->conn_cache points to the connection cache. It keeps track of all
connections that are kept after use. The cache has a maximum size.
->closure_handle is described in the 'connectdata' section.
The libcurl source code generally use the name 'multi' for the variable that
points to the Curl_multi struct.
1.4 Curl_handler
Each unique protocol that is supported by libcurl needs to provide at least
one Curl_handler struct. It defines what the protocol is called and what
functions the main code should call to deal with protocol specific issues.
In general, there's a source file named [protocol].c in which there's a
"struct Curl_handler Curl_handler_[protocol]" declared. In url.c there's
then the main array with all individual Curl_handler structs pointed to from
a single array which is scanned through when a URL is given to libcurl to
work with.
->scheme is the URL scheme name, usually spelled out in uppercase. That's
"HTTP" or "FTP" etc. SSL versions of the protcol need its own Curl_handler
setup so HTTPS separate from HTTP.
->setup_connection is called to allow the protocol code to allocate protocol
specific data that then gets associated with that SessionHandle for the rest
of this transfer. It gets freed again at the end of the transfer. It will be
called before the 'connectdata' for the transfer has been selected/created.
Most protocols will allocate its private 'struct [PROTOCOL]' here and assign
SessionHandle->req.protop to point to it.
->connect_it allows a protocol to do some specific actions after the TCP
connect is done, that can still be considered part of the connection phase.
Some protocols will alter the connectdata->recv[] and connectdata->send[]
function pointers in this function.
->connecting is similarly a function that keeps getting called as long as the
protocol considers itself still in the connecting phase.
->do_it is the function called to issue the transfer request. What we call
the DO action internally. If the DO is not enough and things need to be kept
getting done for the entier DO sequence to complete, ->doing is then usually
also provided. Each protocol that needs to do multiple commands or similar
for do/doing need to implement their own state machines (see SCP, SFTP,
FTP). Some protocols (only FTP and only due to historical reasons) has a
separate piece of the DO state called DO_MORE.
->doing keeps getting called while issudeing the transfer request command(s)
->done gets called when the transfer is complete and DONE. That's after the
main data has been transferred.
->do_more gets called doring the DO_MORE state. The FTP protocol uses this
state when setting up the second connection.
->proto_getsock
->doing_getsock
->domore_getsock
->perform_getsock
Functions that return socket information. Which socket(s) to wait for which
action(s) during the particular multi state.
->disconnect is called immediately before the TCP connection is shutdown.
->readwrite gets called during transfer to allow the protocol to do extra
reads/writes
->defport is the default report TCP or UDP port this protocol uses
->protocol is one or more bits in the CURLPROTO_* set. The SSL versions have
their "base" protocol set and then the SSL variation. Like "HTTP|HTTPS".
->flags is a bitmask with additional information about the protocol that will
make it get treated differently by the generic engine:
PROTOPT_SSL - will make it connect and negotiate SSL
PROTOPT_DUAL - this protocol uses two connections
PROTOPT_CLOSEACTION - this protocol has actions to do before closing the
connection. This flag is no longer used by code, yet still set for a bunch
protocol handlers.
PROTOPT_DIRLOCK - "direction lock". The SSH protocols set this bit to
limit which "direction" of socket actions that the main engine will
concern itself about.
PROTOPT_NONETWORK - a protocol that doesn't use network (read file:)
PROTOPT_NEEDSPWD - this protocol needs a password and will use a default
one unless one is provided
PROTOPT_NOURLQUERY - this protocol can't handle a query part on the URL
(?foo=bar)
1.5 conncache
Is a hash table with connections for later re-use. Each SessionHandle has
a pointer to its connection cache. Each multi handle sets up a connection
cache that all added SessionHandles share by default.
1.6 Curl_share
The libcurl share API allocates a Curl_share struct, exposed to the external
API as "CURLSH *".
The idea is that the struct can have a set of own versions of caches and
pools and then by providing this struct in the CURLOPT_SHARE option, those
specific SessionHandles will use the caches/pools that this share handle
holds.
Then individual SessionHandle structs can be made to share specific things
that they otherwise wouldn't, such as cookies.
The Curl_share struct can currently hold cookies, DNS cache and the SSL
session cache.
1.7 CookieInfo
This is the main cookie struct. It holds all known cookies and related
information. Each SessionHandle has its own private CookieInfo even when
they are added to a multi handle. They can be made to share cookies by using
the share API.

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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
@@ -22,7 +22,8 @@
AUTOMAKE_OPTIONS = foreign no-dependencies
man_MANS = curl.1 curl-config.1 mk-ca-bundle.1
man_MANS = curl.1 curl-config.1
noinst_man_MANS = mk-ca-bundle.1
GENHTMLPAGES = curl.html curl-config.html mk-ca-bundle.html
PDFPAGES = curl.pdf curl-config.pdf mk-ca-bundle.pdf
@@ -36,7 +37,7 @@ EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS SSLCERTS \
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS \
KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) HISTORY INSTALL \
$(PDFPAGES) LICENSE-MIXING README.netware DISTRO-DILEMMA INSTALL.devcpp \
MAIL-ETIQUETTE HTTP-COOKIES
MAIL-ETIQUETTE HTTP-COOKIES LIBCURL-STRUCTS
MAN2HTML= roffit < $< >$@

View File

@@ -21,6 +21,7 @@ Albert Choy
Ale Vesely
Alejandro Alvarez
Aleksandar Milivojevic
Aleksey Tulinov
Alessandro Ghedini
Alessandro Vesely
Alex Bligh
@@ -47,11 +48,13 @@ Amol Pattekar
Amr Shahin
Anatoli Tubman
Anders Gustafsson
Anders Havn
Andi Jahja
Andre Guibert de Bruet
Andreas Damm
Andreas Faerber
Andreas Farber
Andreas Malzahn
Andreas Ntaflos
Andreas Olsson
Andreas Rieke
@@ -69,6 +72,7 @@ Andrew Kurushin
Andrew Moise
Andrew Wansink
Andrew de los Reyes
Andrii Moiseiev
Andrés García
Andy Cedilnik
Andy Serpa
@@ -103,6 +107,7 @@ Ben Van Hof
Ben Winslow
Benbuck Nason
Benjamin Gerard
Benjamin Gilbert
Benjamin Johnson
Bernard Leak
Bernhard Reutner-Fischer
@@ -136,6 +141,7 @@ Bruce Mitchener
Bruno de Carvalho
Bryan Henderson
Bryan Kemp
Byrial Jensen
Cameron Kaiser
Camille Moncelier
Caolan McNamara
@@ -162,6 +168,7 @@ Christian Kurz
Christian Robottom Reis
Christian Schmitz
Christian Vogt
Christian Weisgerber
Christophe Demory
Christophe Legry
Christopher Conroy
@@ -234,6 +241,7 @@ David Odin
David Phillips
David Rosenstrauch
David Shaw
David Strauss
David Tarendash
David Thiel
David Wright
@@ -266,6 +274,7 @@ Douglas R. Horner
Douglas Steinwand
Dov Murik
Duane Cathey
Duncan
Duncan Mac-Vicar Prett
Dustin Boswell
Dylan Ellicott
@@ -274,6 +283,7 @@ Early Ehlinger
Ebenezer Ikonne
Edin Kadribasic
Eduard Bloch
Edward Rudd
Edward Sheldrake
Eelco Dolstra
Eetu Ojanen
@@ -291,15 +301,18 @@ Eric Lavigne
Eric Melville
Eric Mertens
Eric Rautman
Eric S. Raymond
Eric Thelin
Eric Vergnaud
Eric Wong
Eric Young
Erick Nuwendam
Erik Johansson
Erwan Legrand
Erwin Authried
Eugene Kotlyarov
Evan Jordan
Evgeny Turnaev
Eygene Ryabinkin
Fabian Hiernaux
Fabian Keil
@@ -364,6 +377,7 @@ Gwenole Beauchesne
Götz Babin-Ebell
Hamish Mackenzie
Hang Kin Lau
Hang Su
Hanno Kranzhoff
Hans Steegers
Hans-Jurgen May
@@ -398,6 +412,7 @@ Immanuel Gregoire
Ingmar Runge
Ingo Ralf Blum
Ingo Wilken
Ishan SinghLevett
Jack Zhang
Jacky Lam
Jacob Meuser
@@ -419,6 +434,7 @@ Jan Koen Annot
Jan Kunder
Jan Schaumann
Jan Van Boghout
Jared Jennings
Jared Lundell
Jari Sundell
Jason Glasgow
@@ -433,6 +449,7 @@ Jean-Claude Chauve
Jean-Francois Bertrand
Jean-Louis Lemaire
Jean-Marc Ranger
Jean-Noel Rouvignac
Jean-Philippe Barrette-LaPierre
Jeff Connelly
Jeff Johnson
@@ -470,6 +487,7 @@ John Bradshaw
John Crow
John Dennis
John E. Malmberg
John Gardiner Myers
John Janssen
John Joseph Bachir
John Kelly
@@ -511,6 +529,7 @@ Julien Royer
Jun-ichiro itojun Hagino
Jurij Smakov
Justin Fletcher
Justin Karneges
Jörg Mueller-Tolk
Jörn Hartroth
Kai Engert
@@ -544,6 +563,7 @@ Kimmo Kinnunen
Kjell Ericson
Kjetil Jacobsen
Klevtsov Vadim
Konstantin Isakov
Kris Kennaway
Krishnendu Majumdar
Krister Johansen
@@ -556,6 +576,7 @@ Larry Fahnoe
Lars Buitinck
Lars Gustafsson
Lars J. Aas
Lars Johannesen
Lars Nilsson
Lars Torben Wilson
Lau Hang Kin
@@ -578,6 +599,7 @@ Loren Kirkby
Luca Altea
Luca Alteas
Lucas Adamski
Ludovico Cavedon
Lukasz Czekierda
Luke Amery
Luke Call
@@ -589,6 +611,7 @@ Mandy Wu
Manfred Schwarb
Manuel Massing
Marc Boucher
Marc Doughty
Marc Hoersken
Marc Kleine-Budde
Marcel Raad
@@ -668,12 +691,14 @@ Michal Gorny
Michal Kowalczyk
Michal Marek
Michele Bini
Miguel Angel
Mihai Ionescu
Mikael Johansson
Mikael Sennerholm
Mike Bytnar
Mike Crowe
Mike Dobbs
Mike Giancola
Mike Hommey
Mike Power
Mike Protts
@@ -684,6 +709,7 @@ Mohamed Lrhazi
Mohun Biswas
Moonesamy
Myk Taylor
Nach M. S.
Nathan Coulter
Nathan O'Sullivan
Nathanael Nerode
@@ -752,6 +778,7 @@ Pedro Neves
Pete Su
Peter Bray
Peter Forret
Peter Gal
Peter Heuchert
Peter Hjalmarsson
Peter Korsgaard
@@ -804,6 +831,7 @@ Reinout van Schouwen
Renato Botelho
Renaud Chaillat
Renaud Duhaut
Renaud Guillard
Rene Bernhardt
Rene Rebe
Reuven Wachtfogel
@@ -903,6 +931,7 @@ Stan van de Burgt
Stanislav Ivochkin
Stefan Esser
Stefan Krause
Stefan Neis
Stefan Teleman
Stefan Tomanek
Stefan Ulrich
@@ -950,6 +979,7 @@ Tim Harder
Tim Heckman
Tim Newsome
Tim Sneddon
Timo Sirainen
Tinus van den Berg
Tobias Rundström
Toby Peterson
@@ -1013,6 +1043,7 @@ Wez Furlong
Wilfredo Sanchez
Willem Sparreboom
Wojciech Zwiefka
Wouter Van Rooy
Wu Yongzheng
Xavier Bouchoux
Yamada Yasuharu
@@ -1024,6 +1055,7 @@ Yuriy Sosov
Yves Arrouye
Yves Lejeune
Zdenek Pavlas
Zekun Ni
Zmey Petroff
Zvi Har'El
nk

View File

@@ -16,8 +16,8 @@
1.3 struct lifreq
1.4 signal-based resolver timeouts
1.5 get rid of PATH_MAX
1.6 progress callback without doubles
1.7 Happy Eyeball dual stack connect
1.6 Happy Eyeball dual stack connect
1.7 Modified buffer size approach
2. libcurl - multi interface
2.1 More non-blocking
@@ -157,16 +157,7 @@
we need libssh2 to properly tell us when we pass in a too small buffer and
its current API (as of libssh2 1.2.7) doesn't.
1.6 progress callback without doubles
The progress callback was introduced way back in the days and the choice to
use doubles in the arguments was possibly good at the time. Today the doubles
only confuse users and make the amounts less precise. We should introduce
another progress callback option that take precedence over the old one and
have both co-exist for a forseeable time until we can remove the double-using
one.
1.7 Happy Eyeball dual stack connect
1.6 Happy Eyeball dual stack connect
In order to make alternative technologies not suffer when transitioning, like
when introducing IPv6 as an alternative to IPv4 and there are more than one
@@ -178,6 +169,28 @@
http://tools.ietf.org/html/rfc6555
1.7 Modified buffer size approach
Current libcurl allocates a fixed 16K size buffer for download and an
additional 16K for upload. They are always unconditionally part of the easy
handle. If CRLF translations are requested, an additional 32K "scratch
buffer" is allocated. A total of 64K transfer buffers in the worst case.
First, while the handles are not actually in use these buffers could be freed
so that lingering handles just kept in queues or whatever waste less memory.
Secondly, SFTP is a protocol that needs to handle many ~30K blocks at once
since each need to be individually acked and therefore libssh2 must be
allowed to send (or receive) many separate ones in parallel to achieve high
transfer speeds. A current libcurl build with a 16K buffer makes that
impossible, but one with a 512K buffer will reach MUCH faster transfers. But
allocating 512K unconditionally for all buffers just in case they would like
to do fast SFTP transfers at some point is not a good solution either.
Dynamically allocate buffer size depending on protocol in use in combination
with freeing it after each individual transfer? Other suggestions?
2. libcurl - multi interface
2.1 More non-blocking

View File

@@ -230,7 +230,9 @@ server sends an unsupported encoding, curl will report an error.
.IP "--connect-timeout <seconds>"
Maximum time in seconds that you allow the connection to the server to take.
This only limits the connection phase, once curl has connected this option is
of no more use. See also the \fI-m, --max-time\fP option.
of no more use. Since 7.32.0, this option accepts decimal values, but the
actual timeout will decrease in accuracy as the specified timeout increases in
decimal precision. See also the \fI-m, --max-time\fP option.
If this option is used several times, the last one will be used.
.IP "--create-dirs"
@@ -393,7 +395,10 @@ nickname contains ":", it needs to be preceded by "\\" so that it is not
recognized as password delimiter. If the nickname contains "\\", it needs to
be escaped as "\\\\" so that it is not recognized as an escape character.
(iOS and Mac OS X only) If curl is built against Secure Transport, then the certificate string must match the name of a certificate that's in the system or user keychain. The private key corresponding to the certificate, and certificate chain (if any), must also be present in the keychain.
(iOS and Mac OS X only) If curl is built against Secure Transport, then the
certificate string must match the name of a certificate that's in the system or
user keychain. The private key corresponding to the certificate, and
certificate chain (if any), must also be present in the keychain.
If this option is used several times, the last one will be used.
.IP "--engine <name>"
@@ -810,7 +815,10 @@ Basic authentication).
.IP "-m, --max-time <seconds>"
Maximum time in seconds that you allow the whole operation to take. This is
useful for preventing your batch jobs from hanging for hours due to slow
networks or links going down. See also the \fI--connect-timeout\fP option.
networks or links going down. Since 7.32.0, this option accepts decimal
values, but the actual timeout will decrease in accuracy as the specified
timeout increases in decimal precision. See also the \fI--connect-timeout\fP
option.
If this option is used several times, the last one will be used.
.IP "--mail-auth <address>"
@@ -1043,6 +1051,13 @@ ubiquitous in web browsers, so curl does the conversion by default to maintain
consistency. However, a server may require a POST to remain a POST after such
a redirection. This option is meaningful only when using \fI-L, --location\fP
(Added in 7.19.1)
.IP "--post303"
(HTTP) Tells curl to respect RFC 2616/10.3.2 and not convert POST requests
into GET requests when following a 303 redirection. The non-RFC behaviour is
ubiquitous in web browsers, so curl does the conversion by default to maintain
consistency. However, a server may require a POST to remain a POST after such
a redirection. This option is meaningful only when using \fI-L, --location\fP
(Added in 7.26.0)
.IP "--proto <protocols>"
Tells curl to use the listed protocols for its initial retrieval. Protocols
are evaluated left to right, are comma separated, and are each a protocol
@@ -1280,6 +1295,9 @@ If this option is used several times, the last one will be used.
Silent or quiet mode. Don't show progress meter or error messages. Makes Curl
mute. It will still output the data you ask for, potentially even to the
terminal/stdout unless you redirect it.
.IP "--sasl-ir"
Enable initial response in SASL authentication.
(Added in 7.31.0)
.IP "-S, --show-error"
When used with \fI-s\fP it makes curl show an error message if it fails.
.IP "--ssl"
@@ -1675,7 +1693,7 @@ If this option is used several times, the last one will be used.
.IP "--xattr"
When saving output to a file, this option tells curl to store certain file
metadata in extened file attributes. Currently, the URL is stored in the
metadata in extended file attributes. Currently, the URL is stored in the
xdg.origin.url attribute and, for HTTP, the content type is stored in
the mime_type attribute. If the file system does not support extended
attributes, a warning is issued.
@@ -1695,7 +1713,7 @@ speed-time seconds it gets aborted. speed-time is set with \fI-y\fP and is 30
if not set.
If this option is used several times, the last one will be used.
.IP "-z/--time-cond <date expression>|<file>"
.IP "-z, --time-cond <date expression>|<file>"
(HTTP/FTP) Request a file that has been modified later than the given time and
date, or one that has been modified before that time. The <date expression>
can be all sorts of date strings or if it doesn't match any internal ones, it

View File

@@ -5,8 +5,7 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface debug fileupload \
persistant post-callback postit2 sepheaders simple simplepost simplessl \
sendrecv httpcustomheader certinfo chkspeed ftpgetinfo ftp-wildcard \
smtp-multi simplesmtp smtp-tls rtsp externalsocket resolve \
progressfunc pop3s pop3slist imap url2file sftpget ftpsget \
usercertinmem
progressfunc pop3s pop3slist imap url2file sftpget ftpsget
# These examples require external dependencies that may not be commonly
# available on POSIX systems, so don't bother attempting to compile them here.
@@ -14,4 +13,4 @@ COMPLICATED_EXAMPLES = curlgtk.c curlx.c htmltitle.cpp cacertinmem.c \
ftpuploadresume.c ghiper.c hiperfifo.c htmltidy.c multithread.c \
opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c evhiperfifo.c \
smooth-gtk-thread.c version-check.pl href_extractor.c asiohiper.cpp \
multi-uv.c xmlstream.c
multi-uv.c xmlstream.c usercertinmem.c

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -30,9 +30,10 @@ struct myprogress {
CURL *curl;
};
static int progress(void *p,
double dltotal, double dlnow,
double ultotal, double ulnow)
/* this is how the CURLOPT_XFERINFOFUNCTION callback works */
static int xferinfo(void *p,
curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow)
{
struct myprogress *myp = (struct myprogress *)p;
CURL *curl = myp->curl;
@@ -48,7 +49,9 @@ static int progress(void *p,
fprintf(stderr, "TOTAL TIME: %f \r\n", curtime);
}
fprintf(stderr, "UP: %g of %g DOWN: %g of %g\r\n",
fprintf(stderr, "UP: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
" DOWN: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
"\r\n",
ulnow, ultotal, dlnow, dltotal);
if(dlnow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES)
@@ -56,6 +59,19 @@ static int progress(void *p,
return 0;
}
/* for libcurl older than 7.32.0 (CURLOPT_PROGRESSFUNCTION) */
static int older_progress(void *p,
double dltotal, double dlnow,
double ultotal, double ulnow)
{
return xferinfo(p,
(curl_off_t)dltotal,
(curl_off_t)dlnow,
(curl_off_t)ultotal,
(curl_off_t)ulnow);
}
int main(void)
{
CURL *curl;
@@ -68,9 +84,28 @@ int main(void)
prog.curl = curl;
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, older_progress);
/* pass the struct pointer into the progress function */
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &prog);
#if LIBCURL_VERSION_NUM >= 0x072000
/* xferinfo was introduced in 7.32.0, no earlier libcurl versions will
compile as they won't have the symbols around.
If built with a newer libcurl, but running with an older libcurl:
curl_easy_setopt() will fail in run-time trying to set the new
callback, making the older callback get used.
New libcurls will prefer the new callback and instead use that one even
if both callbacks are set. */
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo);
/* pass the struct pointer into the xferinfo function, note that this is
an alias to CURLOPT_PROGRESSDATA */
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &prog);
#endif
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
res = curl_easy_perform(curl);

View File

@@ -232,7 +232,7 @@ Pass a pointer to a char pointer to receive a pointer to a string holding the
most recent RTSP Session ID.
Applications wishing to resume an RTSP session on another connection should
retreive this info before closing the active connection.
retrieve this info before closing the active connection.
.IP CURLINFO_RTSP_CLIENT_CSEQ
Pass a pointer to a long to receive the next CSeq that will be used by the
application.
@@ -244,7 +244,7 @@ by the application.
unimplemented).\fP
Applications wishing to resume an RTSP session on another connection should
retreive this info before closing the active connection.
retrieve this info before closing the active connection.
.IP CURLINFO_RTSP_CSEQ_RECV
Pass a pointer to a long to receive the most recently received CSeq from the
server. If your application encounters a \fICURLE_RTSP_CSEQ_ERROR\fP then you

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * 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
@@ -68,6 +68,18 @@ code means something wrong occurred after the new state was set. See the
.SH AVAILABILITY
This function was added in libcurl 7.18.0. Before this version, there was no
explicit support for pausing transfers.
.SH "USAGE WITH THE MULTI-SOCKET INTERFACE"
Before libcurl 7.32.0, when a specific handle was unpaused with this function,
there was no particular forced rechecking or similar of the socket's state,
which made the continuation of the transfer get delayed until next
multi-socket call invoke or even longer. Alternatively, the user could
forcibly call for example curl_multi_socket_all(3) - with a rather hefty
performance penalty.
Starting in libcurl 7.32.0, unpausing a transfer will schedule a timeout
trigger for that handle 1 millisecond into the future, so that a
curl_multi_socket_action( ... CURL_SOCKET_TIMEOUT) can be used immediately
afterwards to get the transfer going again as desired.
.SH "MEMORY USE"
When pausing a read by returning the magic return code from a write callback,
the read data is already in libcurl's internal buffers so it'll have to keep

View File

@@ -377,10 +377,54 @@ function that performs transfers.
\fICURLOPT_NOPROGRESS\fP must be set to 0 to make this function actually
get called.
.IP CURLOPT_XFERINFOFUNCTION
Pass a pointer to a function that matches the following prototype:
.nf
\fBint function(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow);\fP
.fi
This function gets called by libcurl instead of its internal equivalent with a
frequent interval. While data is being transferred it will be called very
frequently, and during slow periods like when nothing is being transferred it
can slow down to about one call per second.
\fIclientp\fP is the pointer set with \fICURLOPT_XFERINFODATA\fP, it is only
passed along from the application to the callback.
The callback gets told how much data libcurl will transfer and has
transferred, in number of bytes. \fIdltotal\fP is the total number of bytes
libcurl expects to download in this transfer. \fIdlnow\fP is the number of
bytes downloaded so far. \fIultotal\fP is the total number of bytes libcurl
expects to upload in this transfer. \fIulnow\fP is the number of bytes
uploaded so far.
Unknown/unused argument values passed to the callback will be set to zero
(like if you only download data, the upload size will remain 0). Many times
the callback will be called one or more times first, before it knows the data
sizes so a program must be made to handle that.
Returning a non-zero value from this callback will cause libcurl to abort the
transfer and return \fICURLE_ABORTED_BY_CALLBACK\fP.
If you transfer data with the multi interface, this function will not be
called during periods of idleness unless you call the appropriate libcurl
function that performs transfers.
\fICURLOPT_NOPROGRESS\fP must be set to 0 to make this function actually
get called.
(Added in 7.32.0)
.IP CURLOPT_PROGRESSDATA
Pass a pointer that will be untouched by libcurl and passed as the first
argument in the progress callback set with \fICURLOPT_PROGRESSFUNCTION\fP.
The default value of this parameter is unspecified.
.IP CURLOPT_XFERINFODATA
Pass a pointer that will be untouched by libcurl and passed as the first
argument in the progress callback set with \fICURLOPT_XFERINFOFUNCTION\fP.
The default value of this parameter is unspecified. This option is an alias
for CURLOPT_PROGRESSDATA. (Added in 7.32.0)
.IP CURLOPT_HEADERFUNCTION
Pass a pointer to a function that matches the following prototype:
\fBsize_t function( void *ptr, size_t size, size_t nmemb, void

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * 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
@@ -29,9 +29,9 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle, CURL *easy_handle);
.ad
.SH DESCRIPTION
Adds a standard easy handle to the multi stack. This function call will make
this \fImulti_handle\fP control the specified \fIeasy_handle\fP.
Furthermore, libcurl now initiates the connection associated with the
specified \fIeasy_handle\fP.
this \fImulti_handle\fP control the specified \fIeasy_handle\fP. Furthermore,
libcurl now initiates the connection associated with the specified
\fIeasy_handle\fP.
When an easy handle has been added to a multi stack, you can not and you must
not use \fIcurl_easy_perform(3)\fP on that handle!
@@ -41,6 +41,12 @@ cache (CURLOPT_DNS_USE_GLOBAL_CACHE), it will be made to use the DNS cache
that is shared between all easy handles within the multi handle when
\fIcurl_multi_add_handle(3)\fP is called.
If you have CURLMOPT_TIMERFUNCTION set in the multi handle (and you really
should if you're working event-based with \fIcurl_multi_socket_action(3)\fP
and friends), that callback will be called from within this function to ask
for an updated timer so that your main event loop will get the activity on
this handle to get started.
The easy handle will remain added until you remove it again with
\fIcurl_multi_remove_handle(3)\fP. You should remove the easy handle from the
multi stack before you terminate first the easy handle and then the multi

View File

@@ -428,7 +428,7 @@ CURLOPT_POSTREDIR 7.19.1
CURLOPT_PREQUOTE 7.9.5
CURLOPT_PRIVATE 7.10.3
CURLOPT_PROGRESSDATA 7.1
CURLOPT_PROGRESSFUNCTION 7.1
CURLOPT_PROGRESSFUNCTION 7.1 7.32.0
CURLOPT_PROTOCOLS 7.19.4
CURLOPT_PROXY 7.1
CURLOPT_PROXYAUTH 7.10.7
@@ -525,6 +525,8 @@ CURLOPT_WRITEDATA 7.9.7
CURLOPT_WRITEFUNCTION 7.1
CURLOPT_WRITEHEADER 7.1
CURLOPT_WRITEINFO 7.1
CURLOPT_XFERINFODATA 7.32.0
CURLOPT_XFERINFOFUNCTION 7.32.0
CURLPAUSE_ALL 7.18.0
CURLPAUSE_CONT 7.18.0
CURLPAUSE_RECV 7.18.0

View File

@@ -60,11 +60,16 @@ unlink (remove) certdata.txt after processing
be verbose and print out processed CAs
.SH EXIT STATUS
Returns 0 on success. Returns 1 if it fails to download data.
.SH CERTDATA FORMAT
The file format used by Mozilla for this trust information seems to be documented here:
.nf
http://p11-glue.freedesktop.org/doc/storing-trust-policy/storing-trust-existing.html
.fi
.SH SEE ALSO
.BR curl (1)
.SH HISTORY
\fBmk-ca-bundle\fP is a command line tool that is shipped as part of every
curl and libcurl release (see http://curl.haxx.se/). It was originally based
on the parse-certs script written by Roland Krikava and was later much
improved by Guenter Knauf. This manual page was written by Jan Schaumann
\&<jschauma@netmeister.org>.
improved by Guenter Knauf. This manual page was initially written by Jan
Schaumann \&<jschauma@netmeister.org>.

View File

@@ -156,12 +156,22 @@ struct curl_httppost {
HTTPPOST_CALLBACK posts */
};
/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered
deprecated but was the only choice up until 7.31.0 */
typedef int (*curl_progress_callback)(void *clientp,
double dltotal,
double dlnow,
double ultotal,
double ulnow);
/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in
7.32.0, it avoids floating point and provides more detailed information. */
typedef int (*curl_xferinfo_callback)(void *clientp,
curl_off_t dltotal,
curl_off_t dlnow,
curl_off_t ultotal,
curl_off_t ulnow);
#ifndef CURL_MAX_WRITE_SIZE
/* Tests have proven that 20K is a very bad buffer size for uploads on
Windows, while 16K for some odd reason performed a lot better.
@@ -968,13 +978,16 @@ typedef enum {
/* 55 = OBSOLETE */
/* Function that will be called instead of the internal progress display
/* DEPRECATED
* Function that will be called instead of the internal progress display
* function. This function should be defined as the curl_progress_callback
* prototype defines. */
CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
/* Data passed to the progress callback */
/* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION
callbacks */
CINIT(PROGRESSDATA, OBJECTPOINT, 57),
#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA
/* We want the referrer field set automatically when following locations */
CINIT(AUTOREFERER, LONG, 58),
@@ -1533,6 +1546,11 @@ typedef enum {
/* Enable/disable SASL initial response */
CINIT(SASL_IR, LONG, 218),
/* Function that will be called instead of the internal progress display
* function. This function should be defined as the curl_xferinfo_callback
* prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */
CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219),
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;

View File

@@ -30,12 +30,12 @@
/* This is the version number of the libcurl package from which this header
file origins: */
#define LIBCURL_VERSION "7.31.0-DEV"
#define LIBCURL_VERSION "7.32.0-DEV"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 31
#define LIBCURL_VERSION_MINOR 32
#define LIBCURL_VERSION_PATCH 0
/* This is the numeric version of the libcurl version number, meant for easier
@@ -53,7 +53,7 @@
and it is always a greater number in a more recent release. It makes
comparisons with greater than and less than work.
*/
#define LIBCURL_VERSION_NUM 0x071f00
#define LIBCURL_VERSION_NUM 0x072000
/*
* This is the date and time when the full source package was created. The

View File

@@ -94,6 +94,10 @@ add_library(
${HHEADERS} ${CSOURCES}
)
if(MSVC AND CURL_STATICLIB)
set_target_properties(${LIB_NAME} PROPERTIES STATIC_LIBRARY_FLAGS ${CMAKE_EXE_LINKER_FLAGS})
endif()
target_link_libraries(${LIB_NAME} ${CURL_LIBS})
if(WIN32)
@@ -108,14 +112,6 @@ setup_curl_dependencies(${LIB_NAME})
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
if(MSVC)
if(NOT BUILD_RELEASE_DEBUG_DIRS)
# Ugly workaround to remove the "/debug" or "/release" in each output
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "../")
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "../")
endif()
endif()
if(WIN32)
if(NOT CURL_STATICLIB)
# Add "_imp" as a suffix before the extension to avoid conflicting with the statically linked "libcurl.lib"

View File

@@ -141,7 +141,7 @@ libcurl_la_CFLAGS_EXTRA += $(CFLAG_CURL_SYMBOL_HIDING)
endif
libcurl_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcurl_la_CPPFLAGS_EXTRA)
libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(LIBCURL_LIBS)
libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(LDFLAGS) $(LIBCURL_LIBS)
libcurl_la_CFLAGS = $(AM_CFLAGS) $(libcurl_la_CFLAGS_EXTRA)
libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_STATICLIB -DUNITTESTS

View File

@@ -52,7 +52,7 @@ LDFLAGS = -q -lq -laa -tWD
SRCDIR = .
OBJDIR = .\BCC_objs
INCDIRS = -I.;..\include
LINKLIB = $(BCCDIR)\lib\cw32mt.lib
LINKLIB = $(BCCDIR)\lib\cw32mt.lib $(BCCDIR)\lib\ws2_32.lib
DEFINES = -DNDEBUG -DWIN32 -DBUILDING_LIBCURL
# By default SSPI support is enabled for BCC
@@ -88,8 +88,24 @@ LINKLIB = $(LINKLIB) $(OPENSSL_PATH)\out32\ssleay32.lib $(OPENSSL_PATH)\out32\l
# Makefile.inc provides the CSOURCES and HHEADERS defines
!include Makefile.inc
OBJECTS = $(CSOURCES:.c=.obj)
PREPROCESSED = $(CSOURCES:.c=.int)
# Borland's command line librarian program TLIB version 4.5 is not capable
# of building a library when any of its objects contains an hypen in its
# name, due to a command line parsing bug. In order to workaround this, we
# build source files with hyphens in their name as objects with underscores
# using explicit compilation build rules instead of implicit ones.
NOHYPHEN = $(CSOURCES:-=_)
OBJECTS = $(NOHYPHEN:.c=.obj)
PREPROCESSED = $(NOHYPHEN:.c=.int)
# Borland's command line compiler (BCC32) version 5.5.1 integrated
# preprocessor has a bug which results in silently generating wrong
# definitions for libcurl macros such as CURL_OFF_T_C, on the other
# hand Borland's command line preprocessor (CPP32) version 5.5.1 does
# not have the bug and achieves proper results. In order to avoid the
# silent bug we first preprocess source files and later compile the
# preprocessed result.
.c.obj:
@-$(RM) $(@R).int
@@ -98,6 +114,21 @@ PREPROCESSED = $(CSOURCES:.c=.int)
all: $(OBJDIR) $(LIBCURL_LIB) $(LIBCURL_DLL)
asyn_ares.obj: asyn-ares.c
@-$(RM) $(@R).int
$(PP_CMD) $(CC_FLAGS) $(INCDIRS) $(DEFINES) -o$(@R).int $(?)
$(CC_CMD) $(CC_FLAGS) -o$(@) $(@R).int
asyn_thread.obj: asyn-thread.c
@-$(RM) $(@R).int
$(PP_CMD) $(CC_FLAGS) $(INCDIRS) $(DEFINES) -o$(@R).int $(?)
$(CC_CMD) $(CC_FLAGS) -o$(@) $(@R).int
non_ascii.obj: non-ascii.c
@-$(RM) $(@R).int
$(PP_CMD) $(CC_FLAGS) $(INCDIRS) $(DEFINES) -o$(@R).int $(?)
$(CC_CMD) $(CC_FLAGS) -o$(@) $(@R).int
clean:
cd $(OBJDIR)
@-$(RM) $(OBJECTS)
@@ -122,7 +153,10 @@ $(LIBCURL_LIB): $(OBJECTS)
$(LIBCURL_DLL) $(LIBCURL_IMPLIB): $(OBJECTS) $(LINKLIB)
@-$(RM) $(LIBCURL_DLL)
@-$(RM) $(LIBCURL_IMPLIB)
$(LD) $(LDFLAGS) -e$(LIBCURL_DLL) $**
$(LD) $(LDFLAGS) -e$(LIBCURL_DLL) @&&!
$(**: = ^
)
!
$(IMPLIB) $(LIBCURL_IMPLIB) $(LIBCURL_DLL)

View File

@@ -13,7 +13,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
netrc.c getinfo.c transfer.c strequal.c easy.c security.c krb4.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 curl_rand.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 gtls.c sslgen.c tftp.c splay.c strdup.c socks.c ssh.c nss.c \
@@ -25,12 +25,13 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
http_proxy.c non-ascii.c asyn-ares.c asyn-thread.c curl_gssapi.c \
curl_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_ntlm_msgs.c \
curl_sasl.c curl_schannel.c curl_multibyte.c curl_darwinssl.c \
hostcheck.c bundles.c conncache.c pipeline.c
hostcheck.c bundles.c conncache.c pipeline.c dotdot.c x509asn1.c \
gskit.c
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.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 ssluse.h escape.h telnet.h \
getinfo.h strequal.h krb4.h memdebug.h http_chunks.h curl_rand.h \
getinfo.h strequal.h krb4.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 \
@@ -44,4 +45,4 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
asyn.h curl_ntlm.h curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h \
curl_ntlm_msgs.h curl_sasl.h curl_schannel.h curl_multibyte.h \
curl_darwinssl.h hostcheck.h bundles.h conncache.h curl_setup_once.h \
multihandle.h setup-vms.h pipeline.h
multihandle.h setup-vms.h pipeline.h dotdot.h x509asn1.h gskit.h

View File

@@ -106,6 +106,7 @@ WINDOWS_SDK_PATH = "$(PROGRAMFILES)\Microsoft SDK"
CCNODBG = cl.exe /O2 /DNDEBUG
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /GZ
CFLAGSSSL = /DUSE_SSLEAY /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
@@ -114,7 +115,7 @@ LNKDLL = link.exe /DLL
LNKLIB = link.exe /lib
LFLAGS = /nologo /machine:$(MACHINE)
SSLLIBS = libeay32.lib ssleay32.lib
ZLIBLIBSDLL= zdll.lib
ZLIBLIBSDLL = zdll.lib
ZLIBLIBS = zlib.lib
WINLIBS = ws2_32.lib wldap32.lib advapi32.lib
CFLAGS = $(CFLAGS)
@@ -189,6 +190,18 @@ 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) /out:$(DIROBJ)\$(TARGET)
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
######################
# release-ssl-ssh2-zlib
@@ -515,7 +528,6 @@ X_OBJS= \
$(DIROBJ)\curl_ntlm_core.obj \
$(DIROBJ)\curl_ntlm_msgs.obj \
$(DIROBJ)\curl_ntlm_wb.obj \
$(DIROBJ)\curl_rand.obj \
$(DIROBJ)\curl_rtmp.obj \
$(DIROBJ)\curl_sasl.obj \
$(DIROBJ)\curl_schannel.obj \
@@ -523,6 +535,7 @@ X_OBJS= \
$(DIROBJ)\curl_threads.obj \
$(DIROBJ)\cyassl.obj \
$(DIROBJ)\dict.obj \
$(DIROBJ)\dotdot.obj \
$(DIROBJ)\easy.obj \
$(DIROBJ)\escape.obj \
$(DIROBJ)\file.obj \

View File

@@ -315,6 +315,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
struct SessionHandle *data = conn->data;
struct ResolverResults *res = (struct ResolverResults *)
conn->async.os_specific;
CURLcode rc = CURLE_OK;
*dns = NULL;
@@ -325,19 +326,19 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
/* temp_ai ownership is moved to the connection, so we need not free-up
them */
res->temp_ai = NULL;
destroy_async_data(&conn->async);
if(!conn->async.dns) {
failf(data, "Could not resolve %s: %s (%s)",
conn->bits.proxy?"proxy":"host",
conn->host.dispname,
ares_strerror(conn->async.status));
return conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
failf(data, "Could not resolve: %s (%s)",
conn->async.hostname, ares_strerror(conn->async.status));
rc = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
CURLE_COULDNT_RESOLVE_HOST;
}
else
*dns = conn->async.dns;
destroy_async_data(&conn->async);
}
return CURLE_OK;
return rc;
}
/*
@@ -415,37 +416,12 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
if(entry)
*entry = conn->async.dns;
if(!conn->async.dns) {
/* a name was not resolved */
if((timeout < 0) || (conn->async.status == ARES_ETIMEOUT)) {
if(conn->bits.proxy) {
failf(data, "Resolving proxy timed out: %s", conn->proxy.dispname);
rc = CURLE_COULDNT_RESOLVE_PROXY;
}
else {
failf(data, "Resolving host timed out: %s", conn->host.dispname);
rc = CURLE_COULDNT_RESOLVE_HOST;
}
}
else if(conn->async.done) {
if(conn->bits.proxy) {
failf(data, "Could not resolve proxy: %s (%s)", conn->proxy.dispname,
ares_strerror(conn->async.status));
rc = CURLE_COULDNT_RESOLVE_PROXY;
}
else {
failf(data, "Could not resolve host: %s (%s)", conn->host.dispname,
ares_strerror(conn->async.status));
rc = CURLE_COULDNT_RESOLVE_HOST;
}
}
else
rc = CURLE_OPERATION_TIMEDOUT;
if(rc)
/* close the connection, since we can't return failure here without
cleaning up this connection properly */
cleaning up this connection properly.
TODO: remove this action from here, it is not a name resolver decision.
*/
conn->bits.close = TRUE;
}
return rc;
}
@@ -614,8 +590,19 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
char *servers)
{
CURLcode result = CURLE_NOT_BUILT_IN;
int ares_result;
/* If server is NULL or empty, this would purge all DNS servers
* from ares library, which will cause any and all queries to fail.
* So, just return OK if none are configured and don't actually make
* any changes to c-ares. This lets c-ares use it's defaults, which
* it gets from the OS (for instance from /etc/resolv.conf on Linux).
*/
if(!(servers && servers[0]))
return CURLE_OK;
#if (ARES_VERSION >= 0x010704)
int ares_result = ares_set_servers_csv(data->state.resolver, servers);
ares_result = ares_set_servers_csv(data->state.resolver, servers);
switch(ares_result) {
case ARES_SUCCESS:
result = CURLE_OK;
@@ -632,7 +619,7 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
}
#else /* too old c-ares version! */
(void)data;
(void)servers;
(void)(ares_result);
#endif
return result;
}

View File

@@ -277,21 +277,27 @@
/* Define if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H
/* The following define is needed on OS400 to enable strcmpi(), stricmp() and
strdup(). */
#define __cplusplus__strings__
/* Define if you have the `strcasecmp' function. */
#undef HAVE_STRCASECMP
/* Define if you have the `strcmpi' function. */
#undef HAVE_STRCMPI
#define HAVE_STRCMPI
/* Define if you have the `stricmp' function. */
#define HAVE_STRICMP
/* Define if you have the `strdup' function. */
#undef HAVE_STRDUP
#define HAVE_STRDUP
/* Define if you have the `strftime' function. */
#define HAVE_STRFTIME
/* Define if you have the `stricmp' function. */
#undef HAVE_STRICMP
/* Define if you have the <strings.h> header file. */
#define HAVE_STRINGS_H
@@ -525,6 +531,9 @@
/* Define to use the QsoSSL package. */
#define USE_QSOSSL
/* Define to use the GSKit package. */
#undef USE_GSKIT
/* Use the system keyring as the default CA bundle. */
#define CURL_CA_BUNDLE "/QIBM/UserData/ICSS/Cert/Server/DEFAULT.KDB"

View File

@@ -1144,7 +1144,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
if(sockfd == CURL_SOCKET_BAD) {
/* no good connect was made */
failf(data, "couldn't connect to %s at %s:%d",
failf(data, "couldn't connect to %s at %s:%ld",
conn->bits.proxy?"proxy":"host",
conn->bits.proxy?conn->proxy.name:conn->host.name, conn->port);
return CURLE_COULDNT_CONNECT;

View File

@@ -89,6 +89,7 @@ Example set of cookies:
#include "strequal.h"
#include "strtok.h"
#include "sendf.h"
#include "slist.h"
#include "curl_memory.h"
#include "share.h"
#include "strtoofft.h"
@@ -1232,9 +1233,9 @@ struct curl_slist *Curl_cookie_list(struct SessionHandle *data)
curl_slist_free_all(list);
return NULL;
}
beg = curl_slist_append(list, line);
free(line);
beg = Curl_slist_append_nodup(list, line);
if(!beg) {
free(line);
curl_slist_free_all(list);
return NULL;
}

View File

@@ -38,9 +38,54 @@
#include <Security/SecureTransport.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CommonCrypto/CommonDigest.h>
/* The Security framework has changed greatly between iOS and different OS X
versions, and we will try to support as many of them as we can (back to
Leopard and iOS 5) by using macros and weak-linking.
IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then
you must build this project against the 10.8 SDK or later. */
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
#error "The darwinssl back-end requires Leopard or later."
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
#define CURL_BUILD_IOS 0
#define CURL_BUILD_MAC 1
/* This is the maximum API level we are allowed to use when building: */
#define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
#define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
#define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
#define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
/* These macros mean "the following code is present to allow runtime backward
compatibility with at least this cat or earlier":
(You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
environmental variable.) */
#define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
#define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
#define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
#define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
#elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
#define CURL_BUILD_IOS 1
#define CURL_BUILD_MAC 0
#define CURL_BUILD_MAC_10_5 0
#define CURL_BUILD_MAC_10_6 0
#define CURL_BUILD_MAC_10_7 0
#define CURL_BUILD_MAC_10_8 0
#define CURL_SUPPORT_MAC_10_5 0
#define CURL_SUPPORT_MAC_10_6 0
#define CURL_SUPPORT_MAC_10_7 0
#define CURL_SUPPORT_MAC_10_8 0
#else
#error "The darwinssl back-end requires iOS or OS X."
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#if CURL_BUILD_MAC
#include <sys/sysctl.h>
#endif
#endif /* CURL_BUILD_MAC */
#include "urldata.h"
#include "sendf.h"
@@ -61,16 +106,6 @@
#define ioErr -36
#define paramErr -50
/* In Mountain Lion and iOS 5, Apple made some changes to the API. They
added TLS 1.1 and 1.2 support, and deprecated and replaced some
functions. You need to build against the Mountain Lion or iOS 5 SDK
or later to get TLS 1.1 or 1.2 support working in cURL. We'll weak-link
to the newer functions and use them if present in the user's OS.
Builders: If you want TLS 1.1 and 1.2 but still want to retain support
for older cats, don't forget to set the MACOSX_DEPLOYMENT_TARGET
environmental variable prior to building cURL. */
/* The following two functions were ripped from Apple sample code,
* with some modifications: */
static OSStatus SocketRead(SSLConnectionRef connection,
@@ -361,7 +396,7 @@ CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
case TLS_DH_anon_WITH_AES_256_CBC_SHA:
return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
break;
#if defined(__MAC_10_6) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
/* TLS 1.0 with ECDSA (RFC 4492) */
case TLS_ECDH_ECDSA_WITH_NULL_SHA:
return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
@@ -438,8 +473,8 @@ CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
break;
#endif /* defined(__MAC_10_6) || defined(__IPHONE_5_0) */
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
/* TLS 1.2 (RFC 5246) */
case TLS_RSA_WITH_NULL_MD5:
return "TLS_RSA_WITH_NULL_MD5";
@@ -624,12 +659,12 @@ CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
break;
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
}
return "TLS_NULL_WITH_NULL_NULL";
}
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_BUILD_MAC
CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
{
int mib[2];
@@ -658,7 +693,7 @@ CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
*minor = atoi(os_version_minor);
free(os_version);
}
#endif
#endif /* CURL_BUILD_MAC */
/* Apple provides a myriad of ways of getting information about a certificate
into a string. Some aren't available under iOS or newer cats. So here's
@@ -668,37 +703,36 @@ CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
{
CFStringRef server_cert_summary = CFSTR("(null)");
#if (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
#if CURL_BUILD_IOS
/* iOS: There's only one way to do this. */
server_cert_summary = SecCertificateCopySubjectSummary(cert);
#else
#if defined(__MAC_10_7)
#if CURL_BUILD_MAC_10_7
/* Lion & later: Get the long description if we can. */
if(SecCertificateCopyLongDescription != NULL)
server_cert_summary =
SecCertificateCopyLongDescription(NULL, cert, NULL);
else
#endif /* defined(__MAC_10_7) */
#if defined(__MAC_10_6)
#endif /* CURL_BUILD_MAC_10_7 */
#if CURL_BUILD_MAC_10_6
/* Snow Leopard: Get the certificate summary. */
if(SecCertificateCopySubjectSummary != NULL)
server_cert_summary = SecCertificateCopySubjectSummary(cert);
else
#endif /* defined(__MAC_10_6) */
#endif /* CURL_BUILD_MAC_10_6 */
/* Leopard is as far back as we go... */
(void)SecCertificateCopyCommonName(cert, &server_cert_summary);
#endif /* (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) */
#endif /* CURL_BUILD_IOS */
return server_cert_summary;
}
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_SUPPORT_MAC_10_7
/* The SecKeychainSearch API was deprecated in Lion, and using it will raise
deprecation warnings, so let's not compile this unless it's necessary: */
static OSStatus CopyIdentityWithLabelOldSchool(char *label,
SecIdentityRef *out_c_a_k)
{
OSStatus status = errSecItemNotFound;
/* The SecKeychainSearch API was deprecated in Lion, and using it will raise
deprecation warnings, so let's not compile this unless it's necessary: */
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
SecKeychainAttributeList attr_list;
SecKeychainAttribute attr;
SecKeychainSearchRef search = NULL;
@@ -730,22 +764,20 @@ static OSStatus CopyIdentityWithLabelOldSchool(char *label,
if(search)
CFRelease(search);
#else
#pragma unused(label, out_c_a_k)
#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7 */
return status;
}
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#endif /* CURL_SUPPORT_MAC_10_7 */
static OSStatus CopyIdentityWithLabel(char *label,
SecIdentityRef *out_cert_and_key)
{
OSStatus status = errSecItemNotFound;
#if defined(__MAC_10_6) || defined(__IPHONE_2_0)
/* SecItemCopyMatching() was introduced in iOS and Snow Leopard. If it
exists, let's use that to find the certificate. */
if(SecItemCopyMatching != NULL) {
#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
/* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
kSecClassIdentity was introduced in Lion. If both exist, let's use them
to find the certificate. */
if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
CFTypeRef keys[4];
CFTypeRef values[4];
CFDictionaryRef query_dict;
@@ -774,15 +806,16 @@ static OSStatus CopyIdentityWithLabel(char *label,
CFRelease(query_dict);
}
else {
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
/* On Leopard, fall back to SecKeychainSearch. */
#if CURL_SUPPORT_MAC_10_7
/* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#endif /* CURL_SUPPORT_MAC_10_7 */
}
#elif (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
/* For developers building on Leopard, we have no choice but to fall back. */
#elif CURL_SUPPORT_MAC_10_7
/* For developers building on older cats, we have no choice but to fall back
to SecKeychainSearch. */
status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
#endif /* defined(__MAC_10_6) || defined(__IPHONE_2_0) */
#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
return status;
}
@@ -796,19 +829,19 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
struct in6_addr addr;
#else
struct in_addr addr;
#endif
#endif /* ENABLE_IPV6 */
size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
char *ssl_sessionid;
size_t ssl_sessionid_len;
OSStatus err = noErr;
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_BUILD_MAC
int darwinver_maj = 0, darwinver_min = 0;
GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
#endif
#endif /* CURL_BUILD_MAC */
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
if(SSLCreateContext != NULL) { /* use the newer API if avaialble */
if(connssl->ssl_ctx)
CFRelease(connssl->ssl_ctx);
@@ -820,7 +853,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
else {
/* The old ST API does not exist under iOS, so don't compile it: */
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_SUPPORT_MAC_10_8
if(connssl->ssl_ctx)
(void)SSLDisposeContext(connssl->ssl_ctx);
err = SSLNewContext(false, &(connssl->ssl_ctx));
@@ -828,7 +861,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
return CURLE_OUT_OF_MEMORY;
}
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#endif /* CURL_SUPPORT_MAC_10_8 */
}
#else
if(connssl->ssl_ctx)
@@ -838,11 +871,11 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
return CURLE_OUT_OF_MEMORY;
}
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
/* check to see if we've been told to use an explicit SSL/TLS version */
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
if(SSLSetProtocolVersionMax != NULL) {
switch(data->set.ssl.version) {
case CURL_SSLVERSION_DEFAULT: default:
@@ -858,12 +891,16 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
break;
case CURL_SSLVERSION_SSLv2:
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
if(err != noErr) {
failf(data, "Your version of the OS does not support SSLv2");
return CURLE_SSL_CONNECT_ERROR;
}
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
}
}
else {
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_SUPPORT_MAC_10_8
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
kSSLProtocolAll,
false);
@@ -899,12 +936,16 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
true);
break;
case CURL_SSLVERSION_SSLv2:
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
kSSLProtocol2,
true);
if(err != noErr) {
failf(data, "Your version of the OS does not support SSLv2");
return CURLE_SSL_CONNECT_ERROR;
}
break;
}
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#endif /* CURL_SUPPORT_MAC_10_8 */
}
#else
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
@@ -924,9 +965,13 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
true);
break;
case CURL_SSLVERSION_SSLv2:
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
kSSLProtocol2,
true);
if(err != noErr) {
failf(data, "Your version of the OS does not support SSLv2");
return CURLE_SSL_CONNECT_ERROR;
}
break;
case CURL_SSLVERSION_SSLv3:
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
@@ -934,11 +979,11 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
true);
break;
}
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
if(data->set.str[STRING_KEY]) {
infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
"Transport. The private key must be in the Keychain.");
"Transport. The private key must be in the Keychain.\n");
}
if(data->set.str[STRING_CERT]) {
@@ -992,7 +1037,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
* fail to connect if the verification fails, or if it should continue
* anyway. In the latter case the result of the verification is checked with
* SSL_get_verify_result() below. */
#if defined(__MAC_10_6) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
/* Snow Leopard introduced the SSLSetSessionOption() function, but due to
a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
works, it doesn't work as expected under Snow Leopard or Lion.
@@ -1001,11 +1046,11 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
(SecureTransport will always validate the certificate chain by
default.) */
/* (Note: Darwin 12.x.x is Mountain Lion.) */
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_BUILD_MAC
if(SSLSetSessionOption != NULL && darwinver_maj >= 12) {
#else
if(SSLSetSessionOption != NULL) {
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#endif /* CURL_BUILD_MAC */
err = SSLSetSessionOption(connssl->ssl_ctx,
kSSLSessionOptionBreakOnServerAuth,
data->set.ssl.verifypeer?false:true);
@@ -1015,14 +1060,14 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
}
else {
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_SUPPORT_MAC_10_8
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
data->set.ssl.verifypeer?true:false);
if(err != noErr) {
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
return CURLE_SSL_CONNECT_ERROR;
}
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#endif /* CURL_SUPPORT_MAC_10_8 */
}
#else
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
@@ -1031,7 +1076,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
return CURLE_SSL_CONNECT_ERROR;
}
#endif /* defined(__MAC_10_6) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
/* If this is a domain name and not an IP address, then configure SNI.
* Also: the verifyhost setting influences SNI usage */
@@ -1044,7 +1089,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
strlen(conn->host.name));
if(err != noErr) {
infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d",
infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
err);
}
}
@@ -1061,7 +1106,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
&all_ciphers_count) == noErr) {
for(i = 0UL ; i < all_ciphers_count ; i++) {
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_BUILD_MAC
/* There's a known bug in early versions of Mountain Lion where ST's ECC
ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
Work around the problem here by disabling those ciphers if we are
@@ -1070,7 +1115,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
continue;
}
#endif
#endif /* CURL_BUILD_MAC */
switch(all_ciphers[i]) {
/* Disable NULL ciphersuites: */
case SSL_NULL_WITH_NULL_NULL:
@@ -1303,7 +1348,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
infof(data, "TLS 1.0 connection using %s\n",
TLSCipherNameForNumber(cipher));
break;
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
case kTLSProtocol11:
infof(data, "TLS 1.1 connection using %s\n",
TLSCipherNameForNumber(cipher));
@@ -1330,20 +1375,22 @@ darwinssl_connect_step3(struct connectdata *conn,
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
CFStringRef server_cert_summary;
char server_cert_summary_c[128];
CFArrayRef server_certs;
CFArrayRef server_certs = NULL;
SecCertificateRef server_cert;
OSStatus err;
CFIndex i, count;
SecTrustRef trust;
SecTrustRef trust = NULL;
/* There is no step 3!
* Well, okay, if verbose mode is on, let's print the details of the
* server certificates. */
#if defined(__MAC_10_7) || defined(__IPHONE_5_0)
#if (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
#if CURL_BUILD_IOS
#pragma unused(server_certs)
err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
if(err == noErr) {
/* For some reason, SSLCopyPeerTrust() can return noErr and yet return
a null trust, so be on guard for that: */
if(err == noErr && trust) {
count = SecTrustGetCertificateCount(trust);
for(i = 0L ; i < count ; i++) {
server_cert = SecTrustGetCertificateAtIndex(trust, i);
@@ -1369,7 +1416,9 @@ darwinssl_connect_step3(struct connectdata *conn,
if(SecTrustEvaluateAsync != NULL) {
#pragma unused(server_certs)
err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
if(err == noErr) {
/* For some reason, SSLCopyPeerTrust() can return noErr and yet return
a null trust, so be on guard for that: */
if(err == noErr && trust) {
count = SecTrustGetCertificateCount(trust);
for(i = 0L ; i < count ; i++) {
server_cert = SecTrustGetCertificateAtIndex(trust, i);
@@ -1387,8 +1436,10 @@ darwinssl_connect_step3(struct connectdata *conn,
}
}
else {
#if CURL_SUPPORT_MAC_10_8
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
if(err == noErr) {
/* Just in case SSLCopyPeerCertificates() returns null too... */
if(err == noErr && server_certs) {
count = CFArrayGetCount(server_certs);
for(i = 0L ; i < count ; i++) {
server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
@@ -1406,8 +1457,9 @@ darwinssl_connect_step3(struct connectdata *conn,
}
CFRelease(server_certs);
}
#endif /* CURL_SUPPORT_MAC_10_8 */
}
#endif /* (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) */
#endif /* CURL_BUILD_IOS */
#else
#pragma unused(trust)
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
@@ -1427,7 +1479,7 @@ darwinssl_connect_step3(struct connectdata *conn,
}
CFRelease(server_certs);
}
#endif /* defined(__MAC_10_7) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
connssl->connecting_state = ssl_connect_done;
return CURLE_OK;
@@ -1579,16 +1631,16 @@ void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
if(connssl->ssl_ctx) {
(void)SSLClose(connssl->ssl_ctx);
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
if(SSLCreateContext != NULL)
CFRelease(connssl->ssl_ctx);
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_SUPPORT_MAC_10_8
else
(void)SSLDisposeContext(connssl->ssl_ctx);
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#endif /* CURL_SUPPORT_MAC_10_8 */
#else
(void)SSLDisposeContext(connssl->ssl_ctx);
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
connssl->ssl_ctx = NULL;
}
connssl->ssl_sockfd = 0;

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012, Nick Zitzmann, <nickzman@gmail.com>.
* Copyright (C) 2012 - 2013, Nick Zitzmann, <nickzman@gmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -52,6 +52,10 @@ void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
unsigned char *md5sum, /* output */
size_t md5len);
/* this backend provides these functions: */
#define have_curlssl_random 1
#define have_curlssl_md5sum 1
/* API setup for SecureTransport */
#define curlssl_init() (1)
#define curlssl_cleanup() Curl_nop_stmt

View File

@@ -87,6 +87,9 @@ extern curl_free_callback Curl_cfree;
extern curl_realloc_callback Curl_crealloc;
extern curl_strdup_callback Curl_cstrdup;
extern curl_calloc_callback Curl_ccalloc;
#if defined(WIN32) && defined(UNICODE)
extern curl_wcsdup_callback Curl_cwcsdup;
#endif
#ifndef CURLDEBUG
@@ -110,6 +113,20 @@ extern curl_calloc_callback Curl_ccalloc;
#undef free
#define free(ptr) Curl_cfree(ptr)
#ifdef WIN32
# ifdef UNICODE
# undef wcsdup
# define wcsdup(ptr) Curl_cwcsdup(ptr)
# undef _wcsdup
# define _wcsdup(ptr) Curl_cwcsdup(ptr)
# undef _tcsdup
# define _tcsdup(ptr) Curl_cwcsdup(ptr)
# else
# undef _tcsdup
# define _tcsdup(ptr) Curl_cstrdup(ptr)
# endif
#endif
#endif /* CURLDEBUG */
#else /* CURLX_NO_MEMORY_CALLBACKS */

View File

@@ -1,61 +0,0 @@
/***************************************************************************
* _ _ ____ _
* 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 http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#include <curl/curl.h>
#include "curl_rand.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
/* Private pseudo-random number seed. Unsigned integer >= 32bit. Threads
mutual exclusion is not implemented to acess it since we do not require
high quality random numbers (only used in form boudary generation). */
static unsigned int randseed;
/* Pseudo-random number support. */
unsigned int Curl_rand(void)
{
unsigned int r;
/* Return an unsigned 32-bit pseudo-random number. */
r = randseed = randseed * 1103515245 + 12345;
return (r << 16) | ((r >> 16) & 0xFFFF);
}
void Curl_srand(void)
{
/* Randomize pseudo-random number sequence. */
randseed = (unsigned int) time(NULL);
Curl_rand();
Curl_rand();
Curl_rand();
}

View File

@@ -32,7 +32,7 @@
#include "curl_base64.h"
#include "curl_md5.h"
#include "curl_rand.h"
#include "sslgen.h"
#include "curl_hmac.h"
#include "curl_ntlm_msgs.h"
#include "curl_sasl.h"
@@ -314,7 +314,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
/* Generate 64 bits of random data */
for(i = 0; i < 8; i++)
cnonce[i] = table16[Curl_rand()%16];
cnonce[i] = table16[Curl_rand(data)%16];
/* So far so good, now calculate A1 and H(A1) according to RFC 2831 */
ctxt = Curl_MD5_init(Curl_DIGEST_MD5);

View File

@@ -270,6 +270,9 @@
# endif
# endif
# include <tchar.h>
# ifdef UNICODE
typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str);
# endif
#endif
/*
@@ -617,7 +620,7 @@ int netware_init(void);
#if defined(USE_GNUTLS) || defined(USE_SSLEAY) || defined(USE_NSS) || \
defined(USE_QSOSSL) || defined(USE_POLARSSL) || defined(USE_AXTLS) || \
defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
defined(USE_DARWINSSL)
defined(USE_DARWINSSL) || defined(USE_GSKIT)
#define USE_SSL /* SSL support has been enabled */
#endif

170
lib/dotdot.c Normal file
View File

@@ -0,0 +1,170 @@
/***************************************************************************
* _ _ ____ _
* 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 http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#include "dotdot.h"
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
/*
* "Remove Dot Segments"
* http://tools.ietf.org/html/rfc3986#section-5.2.4
*/
/*
* Curl_dedotdotify()
*
* This function gets a zero-terminated path with dot and dotdot sequences
* passed in and strips them off according to the rules in RFC 3986 section
* 5.2.4.
*
* The function handles a query part ('?' + stuff) appended but it expects
* that fragments ('#' + stuff) have already been cut off.
*
* RETURNS
*
* an allocated dedotdotified output string
*/
char *Curl_dedotdotify(char *input)
{
size_t inlen = strlen(input);
char *clone;
size_t clen = inlen; /* the length of the cloned input */
char *out = malloc(inlen+1);
char *outptr;
char *orgclone;
char *queryp;
if(!out)
return NULL; /* out of memory */
/* get a cloned copy of the input */
clone = strdup(input);
if(!clone) {
free(out);
return NULL;
}
orgclone = clone;
outptr = out;
/*
* To handle query-parts properly, we must find it and remove it during the
* dotdot-operation and then append it again at the end to the output
* string.
*/
queryp = strchr(clone, '?');
if(queryp)
*queryp = 0;
do {
/* A. If the input buffer begins with a prefix of "../" or "./", then
remove that prefix from the input buffer; otherwise, */
if(!strncmp("./", clone, 2)) {
clone+=2;
clen-=2;
}
else if(!strncmp("../", clone, 3)) {
clone+=3;
clen-=3;
}
/* B. if the input buffer begins with a prefix of "/./" or "/.", where
"." is a complete path segment, then replace that prefix with "/" in
the input buffer; otherwise, */
else if(!strncmp("/./", clone, 3)) {
clone+=2;
clen-=2;
}
else if(!strcmp("/.", clone)) {
clone[1]='/';
clone++;
clen-=1;
}
/* C. if the input buffer begins with a prefix of "/../" or "/..", where
".." is a complete path segment, then replace that prefix with "/" in
the input buffer and remove the last segment and its preceding "/" (if
any) from the output buffer; otherwise, */
else if(!strncmp("/../", clone, 4)) {
clone+=3;
clen-=3;
/* remove the last segment from the output buffer */
while(outptr > out) {
outptr--;
if(*outptr == '/')
break;
}
*outptr = 0; /* zero-terminate where it stops */
}
else if(!strcmp("/..", clone)) {
clone[2]='/';
clone+=2;
clen-=2;
/* remove the last segment from the output buffer */
while(outptr > out) {
outptr--;
if(*outptr == '/')
break;
}
*outptr = 0; /* zero-terminate where it stops */
}
/* D. if the input buffer consists only of "." or "..", then remove
that from the input buffer; otherwise, */
else if(!strcmp(".", clone) || !strcmp("..", clone)) {
*clone=0;
}
else {
/* E. move the first path segment in the input buffer to the end of
the output buffer, including the initial "/" character (if any) and
any subsequent characters up to, but not including, the next "/"
character or the end of the input buffer. */
do {
*outptr++ = *clone++;
clen--;
} while(*clone && (*clone != '/'));
*outptr = 0;
}
} while(*clone);
if(queryp) {
size_t qlen;
/* There was a query part, append that to the output. The 'clone' string
may now have been altered so we copy from the original input string
from the correct index. */
size_t oindex = queryp - orgclone;
qlen = strlen(&input[oindex]);
memcpy(outptr, &input[oindex], qlen+1); /* include the ending zero byte */
}
free(orgclone);
return out;
}

View File

@@ -1,5 +1,5 @@
#ifndef HEADER_CURL_RAND_H
#define HEADER_CURL_RAND_H
#ifndef HEADER_CURL_DOTDOT_H
#define HEADER_CURL_DOTDOT_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -21,9 +21,5 @@
* KIND, either express or implied.
*
***************************************************************************/
void Curl_srand(void);
unsigned int Curl_rand(void);
#endif /* HEADER_CURL_RAND_H */
char *Curl_dedotdotify(char *input);
#endif

View File

@@ -50,6 +50,11 @@
#include <sys/param.h>
#endif
#if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGACTION) && defined(USE_OPENSSL)
#define SIGPIPE_IGNORE 1
#include <signal.h>
#endif
#include "strequal.h"
#include "urldata.h"
#include <curl/curl.h>
@@ -69,7 +74,6 @@
#include "connect.h" /* for Curl_getconnectinfo */
#include "slist.h"
#include "amigaos.h"
#include "curl_rand.h"
#include "non-ascii.h"
#include "warnless.h"
#include "conncache.h"
@@ -81,6 +85,56 @@
/* The last #include file should be: */
#include "memdebug.h"
#ifdef SIGPIPE_IGNORE
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 SessionHandle *data,
struct sigpipe_ignore *ig)
{
/* get a local copy of no_signal because the SessionHandle 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
/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
of win32_init() */
static void win32_cleanup(void)
@@ -198,6 +252,9 @@ curl_free_callback Curl_cfree = (curl_free_callback)free;
curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
#if defined(WIN32) && defined(UNICODE)
curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
#endif
#else
/*
* Symbian OS doesn't support initialization to code in writeable static data.
@@ -229,6 +286,9 @@ CURLcode curl_global_init(long flags)
Curl_crealloc = (curl_realloc_callback)realloc;
Curl_cstrdup = (curl_strdup_callback)system_strdup;
Curl_ccalloc = (curl_calloc_callback)calloc;
#if defined(WIN32) && defined(UNICODE)
Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
#endif
if(flags & CURL_GLOBAL_SSL)
if(!Curl_ssl_init()) {
@@ -276,10 +336,6 @@ CURLcode curl_global_init(long flags)
init_flags = flags;
/* Preset pseudo-random number sequence. */
Curl_srand();
return CURLE_OK;
}
@@ -423,6 +479,7 @@ CURLcode curl_easy_perform(CURL *easy)
int without_fds = 0; /* count number of consecutive returns from
curl_multi_wait() without any filedescriptors */
struct timeval before;
SIGPIPE_VARIABLE(pipe_st);
if(!easy)
return CURLE_BAD_FUNCTION_ARGUMENT;
@@ -455,6 +512,8 @@ CURLcode curl_easy_perform(CURL *easy)
return CURLE_FAILED_INIT;
}
sigpipe_ignore(data, &pipe_st);
/* assign this after curl_multi_add_handle() since that function checks for
it and rejects this handle otherwise */
data->multi = multi;
@@ -480,9 +539,7 @@ CURLcode curl_easy_perform(CURL *easy)
if(curlx_tvdiff(after, before) <= 10) {
without_fds++;
if(without_fds > 2) {
int sleep_ms = without_fds * 50;
if(sleep_ms > 1000)
sleep_ms = 1000;
int sleep_ms = without_fds < 10 ? (1 << (without_fds-1)): 1000;
Curl_wait_ms(sleep_ms);
}
}
@@ -511,6 +568,8 @@ CURLcode curl_easy_perform(CURL *easy)
a failure here, room for future improvement! */
(void)curl_multi_remove_handle(multi, easy);
sigpipe_restore(&pipe_st);
/* The multi handle is kept alive, owned by the easy handle */
return code;
}
@@ -522,11 +581,14 @@ CURLcode curl_easy_perform(CURL *easy)
void curl_easy_cleanup(CURL *curl)
{
struct SessionHandle *data = (struct SessionHandle *)curl;
SIGPIPE_VARIABLE(pipe_st);
if(!data)
return;
sigpipe_ignore(data, &pipe_st);
Curl_close(data);
sigpipe_restore(&pipe_st);
}
/*
@@ -554,12 +616,16 @@ CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
{
va_list arg;
void *paramp;
CURLcode ret;
struct SessionHandle *data = (struct SessionHandle *)curl;
va_start(arg, info);
paramp = va_arg(arg, void *);
return Curl_getinfo(data, info, paramp);
ret = Curl_getinfo(data, info, paramp);
va_end(arg);
return ret;
}
/*
@@ -746,7 +812,7 @@ CURLcode curl_easy_pause(CURL *curl, int action)
do {
chunklen = (tempsize > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:tempsize;
result = Curl_client_write(data->state.current_conn,
result = Curl_client_write(data->easy_conn,
temptype, tempwrite, chunklen);
if(result)
/* failures abort the loop at once */
@@ -788,6 +854,13 @@ CURLcode curl_easy_pause(CURL *curl, int action)
free(freewrite); /* this is unconditionally no longer used */
}
/* if there's no error and we're not pausing both directions, we want
to have this handle checked soon */
if(!result &&
((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
Curl_expire(data, 1); /* get this handle going again */
return result;
}

View File

@@ -24,9 +24,6 @@
#include <curl/curl.h>
/* Length of the random boundary string. */
#define BOUNDARY_LENGTH 40
#if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY)
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
@@ -35,7 +32,7 @@
#include "urldata.h" /* for struct SessionHandle */
#include "formdata.h"
#include "curl_rand.h"
#include "sslgen.h"
#include "strequal.h"
#include "curl_memory.h"
#include "sendf.h"
@@ -56,7 +53,7 @@ static char *Curl_basename(char *path);
#endif
static size_t readfromfile(struct Form *form, char *buffer, size_t size);
static char *formboundary(void);
static char *formboundary(struct SessionHandle *data);
/* What kind of Content-Type to use on un-specified files with unrecognized
extensions. */
@@ -171,7 +168,7 @@ static FormInfo * AddFormInfo(char *value,
* Returns some valid contenttype for filename.
*
***************************************************************************/
static const char * ContentTypeForFilename (const char *filename,
static const char *ContentTypeForFilename(const char *filename,
const char *prevtype)
{
const char *contenttype = NULL;
@@ -181,7 +178,7 @@ static const char * ContentTypeForFilename (const char *filename,
* extensions and pick the first we match!
*/
struct ContentType {
char extension[6];
const char *extension;
const char *type;
};
static const struct ContentType ctts[]={
@@ -429,7 +426,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
/* Get contents from a given file name */
case CURLFORM_FILECONTENT:
if(current_form->flags != 0)
if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE))
return_value = CURL_FORMADD_OPTION_TWICE;
else {
const char *filename = array_state?
@@ -670,9 +667,11 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
if(((form->flags & HTTPPOST_FILENAME) ||
(form->flags & HTTPPOST_BUFFER)) &&
!form->contenttype ) {
char *f = form->flags & HTTPPOST_BUFFER?
form->showfilename : form->value;
/* our contenttype is missing */
form->contenttype
= strdup(ContentTypeForFilename(form->value, prevtype));
form->contenttype = strdup(ContentTypeForFilename(f, prevtype));
if(!form->contenttype) {
return_value = CURL_FORMADD_MEMORY;
break;
@@ -777,6 +776,70 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost,
return result;
}
#ifdef __VMS
#include <fabdef.h>
/*
* get_vms_file_size does what it takes to get the real size of the file
*
* For fixed files, find out the size of the EOF block and adjust.
*
* For all others, have to read the entire file in, discarding the contents.
* Most posted text files will be small, and binary files like zlib archives
* and CD/DVD images should be either a STREAM_LF format or a fixed format.
*
*/
curl_off_t VmsRealFileSize(const char * name,
const struct_stat * stat_buf)
{
char buffer[8192];
curl_off_t count;
int ret_stat;
FILE * file;
file = fopen(name, "r");
if(file == NULL)
return 0;
count = 0;
ret_stat = 1;
while(ret_stat > 0) {
ret_stat = fread(buffer, 1, sizeof(buffer), file);
if(ret_stat != 0)
count += ret_stat;
}
fclose(file);
return count;
}
/*
*
* VmsSpecialSize checks to see if the stat st_size can be trusted and
* if not to call a routine to get the correct size.
*
*/
static curl_off_t VmsSpecialSize(const char * name,
const struct_stat * stat_buf)
{
switch(stat_buf->st_fab_rfm) {
case FAB$C_VAR:
case FAB$C_VFC:
return VmsRealFileSize(name, stat_buf);
break;
default:
return stat_buf->st_size;
}
}
#endif
#ifndef __VMS
#define filesize(name, stat_data) (stat_data.st_size)
#else
/* Getting the expected file size needs help on VMS */
#define filesize(name, stat_data) VmsSpecialSize(name, &stat_data)
#endif
/*
* AddFormData() adds a chunk of data to the FormData linked list.
*
@@ -832,7 +895,7 @@ static CURLcode AddFormData(struct FormData **formp,
if(!strequal("-", newform->line)) {
struct_stat file;
if(!stat(newform->line, &file) && !S_ISDIR(file.st_mode))
*size += file.st_size;
*size += filesize(newform->line, file);
else
return CURLE_BAD_FUNCTION_ARGUMENT;
}
@@ -1101,7 +1164,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
if(!post)
return result; /* no input => no output! */
boundary = formboundary();
boundary = formboundary(data);
if(!boundary)
return CURLE_OUT_OF_MEMORY;
@@ -1157,7 +1220,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
the magic to include several files with the same field name */
Curl_safefree(fileboundary);
fileboundary = formboundary();
fileboundary = formboundary(data);
if(!fileboundary) {
result = CURLE_OUT_OF_MEMORY;
break;
@@ -1343,6 +1406,36 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata )
return 0;
}
#ifndef __VMS
# define fopen_read fopen
#else
/*
* vmsfopenread
*
* For upload to work as expected on VMS, different optional
* parameters must be added to the fopen command based on
* record format of the file.
*
*/
# define fopen_read vmsfopenread
static FILE * vmsfopenread(const char *file, const char *mode) {
struct_stat statbuf;
int result;
result = stat(file, &statbuf);
switch (statbuf.st_fab_rfm) {
case FAB$C_VAR:
case FAB$C_VFC:
case FAB$C_STMCR:
return fopen(file, "r");
break;
default:
return fopen(file, "r", "rfm=stmlf", "ctx=stm");
}
}
#endif
/*
* readfromfile()
*
@@ -1365,7 +1458,7 @@ static size_t readfromfile(struct Form *form, char *buffer,
else {
if(!form->fp) {
/* this file hasn't yet been opened */
form->fp = fopen(form->data->line, "rb"); /* b is for binary */
form->fp = fopen_read(form->data->line, "rb"); /* b is for binary */
if(!form->fp)
return (size_t)-1; /* failure */
}
@@ -1464,28 +1557,12 @@ char *Curl_formpostheader(void *formp, size_t *len)
* formboundary() creates a suitable boundary string and returns an allocated
* one.
*/
static char *formboundary(void)
static char *formboundary(struct SessionHandle *data)
{
char *retstring;
size_t i;
static const char table16[]="0123456789abcdef";
retstring = malloc(BOUNDARY_LENGTH+1);
if(!retstring)
return NULL; /* failed */
strcpy(retstring, "----------------------------");
for(i=strlen(retstring); i<BOUNDARY_LENGTH; i++)
retstring[i] = table16[Curl_rand()%16];
/* 28 dashes and 12 hexadecimal digits makes 12^16 (184884258895036416)
/* 24 dashes and 16 hexadecimal digits makes 64 bit (18446744073709551615)
combinations */
retstring[BOUNDARY_LENGTH]=0; /* zero terminate */
return retstring;
return aprintf("------------------------%08x%08x",
Curl_rand(data), Curl_rand(data));
}
#else /* CURL_DISABLE_HTTP */

151
lib/ftp.c
View File

@@ -123,8 +123,8 @@ static void ftp_pasv_verbose(struct connectdata *conn,
char *newhost, /* ascii version */
int port);
#endif
static CURLcode ftp_state_post_rest(struct connectdata *conn);
static CURLcode ftp_state_post_cwd(struct connectdata *conn);
static CURLcode ftp_state_prepare_transfer(struct connectdata *conn);
static CURLcode ftp_state_mdtm(struct connectdata *conn);
static CURLcode ftp_state_quote(struct connectdata *conn,
bool init, ftpstate instate);
static CURLcode ftp_nb_type(struct connectdata *conn,
@@ -136,7 +136,7 @@ static CURLcode ftp_done(struct connectdata *conn,
CURLcode, bool premature);
static CURLcode ftp_connect(struct connectdata *conn, bool *done);
static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection);
static CURLcode ftp_do_more(struct connectdata *conn, bool *completed);
static CURLcode ftp_do_more(struct connectdata *conn, int *completed);
static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done);
static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks,
int numsocks);
@@ -151,8 +151,7 @@ static CURLcode wc_statemach(struct connectdata *conn);
static void wc_data_dtor(void *ptr);
static CURLcode ftp_state_post_retr_size(struct connectdata *conn,
curl_off_t filesize);
static CURLcode ftp_state_retr(struct connectdata *conn, curl_off_t filesize);
static CURLcode ftp_readresp(curl_socket_t sockfd,
struct pingpong *pp,
@@ -828,7 +827,7 @@ static void _state(struct connectdata *conn,
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
if(ftpc->state != newstate)
infof(conn->data, "FTP %p (line %d) state change from %s to %s\n",
ftpc, lineno, names[ftpc->state], names[newstate]);
(void *)ftpc, lineno, names[ftpc->state], names[newstate]);
#endif
ftpc->state = newstate;
}
@@ -851,7 +850,7 @@ static CURLcode ftp_state_pwd(struct connectdata *conn)
CURLcode result;
/* send PWD to discover our entry point */
PPSENDF(&conn->proto.ftpc.pp, "PWD", NULL);
PPSENDF(&conn->proto.ftpc.pp, "%s", "PWD");
state(conn, FTP_PWD);
return CURLE_OK;
@@ -915,7 +914,7 @@ static CURLcode ftp_state_cwd(struct connectdata *conn)
if(ftpc->cwddone)
/* already done and fine */
result = ftp_state_post_cwd(conn);
result = ftp_state_mdtm(conn);
else {
ftpc->count2 = 0; /* count2 counts failed CWDs */
@@ -943,7 +942,7 @@ static CURLcode ftp_state_cwd(struct connectdata *conn)
}
else {
/* No CWD necessary */
result = ftp_state_post_cwd(conn);
result = ftp_state_mdtm(conn);
}
}
}
@@ -1373,10 +1372,14 @@ static CURLcode ftp_state_use_pasv(struct connectdata *conn)
return result;
}
/* REST is the last command in the chain of commands when a "head"-like
request is made. Thus, if an actual transfer is to be made this is where
we take off for real. */
static CURLcode ftp_state_post_rest(struct connectdata *conn)
/*
* ftp_state_prepare_transfer() starts PORT, PASV or PRET etc.
*
* REST is the last command in the chain of commands when a "head"-like
* request is made. Thus, if an actual transfer is to be made this is where we
* take off for real.
*/
static CURLcode ftp_state_prepare_transfer(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct FTP *ftp = conn->data->state.proto.ftp;
@@ -1419,7 +1422,7 @@ static CURLcode ftp_state_post_rest(struct connectdata *conn)
return result;
}
static CURLcode ftp_state_post_size(struct connectdata *conn)
static CURLcode ftp_state_rest(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct FTP *ftp = conn->data->state.proto.ftp;
@@ -1435,12 +1438,12 @@ static CURLcode ftp_state_post_size(struct connectdata *conn)
state(conn, FTP_REST);
}
else
result = ftp_state_post_rest(conn);
result = ftp_state_prepare_transfer(conn);
return result;
}
static CURLcode ftp_state_post_type(struct connectdata *conn)
static CURLcode ftp_state_size(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct FTP *ftp = conn->data->state.proto.ftp;
@@ -1455,12 +1458,12 @@ static CURLcode ftp_state_post_type(struct connectdata *conn)
state(conn, FTP_SIZE);
}
else
result = ftp_state_post_size(conn);
result = ftp_state_rest(conn);
return result;
}
static CURLcode ftp_state_post_listtype(struct connectdata *conn)
static CURLcode ftp_state_list(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
@@ -1529,7 +1532,7 @@ static CURLcode ftp_state_post_listtype(struct connectdata *conn)
return result;
}
static CURLcode ftp_state_post_retrtype(struct connectdata *conn)
static CURLcode ftp_state_retr_prequote(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
@@ -1540,7 +1543,7 @@ static CURLcode ftp_state_post_retrtype(struct connectdata *conn)
return result;
}
static CURLcode ftp_state_post_stortype(struct connectdata *conn)
static CURLcode ftp_state_stor_prequote(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
@@ -1551,7 +1554,7 @@ static CURLcode ftp_state_post_stortype(struct connectdata *conn)
return result;
}
static CURLcode ftp_state_post_mdtm(struct connectdata *conn)
static CURLcode ftp_state_type(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct FTP *ftp = conn->data->state.proto.ftp;
@@ -1577,14 +1580,14 @@ static CURLcode ftp_state_post_mdtm(struct connectdata *conn)
return result;
}
else
result = ftp_state_post_type(conn);
result = ftp_state_size(conn);
return result;
}
/* This is called after the CWD commands have been done in the beginning of
the DO phase */
static CURLcode ftp_state_post_cwd(struct connectdata *conn)
static CURLcode ftp_state_mdtm(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
@@ -1600,7 +1603,7 @@ static CURLcode ftp_state_post_cwd(struct connectdata *conn)
state(conn, FTP_MDTM);
}
else
result = ftp_state_post_mdtm(conn);
result = ftp_state_type(conn);
return result;
}
@@ -1775,7 +1778,7 @@ static CURLcode ftp_state_quote(struct connectdata *conn,
else {
if(ftpc->known_filesize != -1) {
Curl_pgrsSetDownloadSize(data, ftpc->known_filesize);
result = ftp_state_post_retr_size(conn, ftpc->known_filesize);
result = ftp_state_retr(conn, ftpc->known_filesize);
}
else {
PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
@@ -1799,15 +1802,15 @@ static CURLcode ftp_state_quote(struct connectdata *conn,
static CURLcode ftp_epsv_disable(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
infof(conn->data, "got positive EPSV response, but can't connect. "
"Disabling EPSV\n");
infof(conn->data, "Failed EPSV attempt. Disabling EPSV\n");
/* disable it for next transfer */
conn->bits.ftp_use_epsv = FALSE;
conn->data->state.errorbuf = FALSE; /* allow error message to get
rewritten */
PPSENDF(&conn->proto.ftpc.pp, "PASV", NULL);
PPSENDF(&conn->proto.ftpc.pp, "%s", "PASV");
conn->proto.ftpc.count1++;
/* remain in the FTP_PASV state */
/* remain in/go to the FTP_PASV state */
state(conn, FTP_PASV);
return result;
}
@@ -1936,15 +1939,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
}
else if(ftpc->count1 == 0) {
/* EPSV failed, move on to PASV */
/* disable it for next transfer */
conn->bits.ftp_use_epsv = FALSE;
infof(data, "disabling EPSV usage\n");
PPSENDF(&ftpc->pp, "PASV", NULL);
ftpc->count1++;
/* remain in the FTP_PASV state */
return result;
return ftp_epsv_disable(conn);
}
else {
failf(data, "Bad PASV/EPSV response: %03d", ftpcode);
@@ -2021,14 +2016,17 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
case CURLPROXY_SOCKS5_HOSTNAME:
result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, newhost, newport,
SECONDARYSOCKET, conn);
connected = TRUE;
break;
case CURLPROXY_SOCKS4:
result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
SECONDARYSOCKET, conn, FALSE);
connected = TRUE;
break;
case CURLPROXY_SOCKS4A:
result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
SECONDARYSOCKET, conn, TRUE);
connected = TRUE;
break;
case CURLPROXY_HTTP:
case CURLPROXY_HTTP_1_0:
@@ -2080,8 +2078,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
}
}
conn->bits.tcpconnect[SECONDARYSOCKET] = TRUE;
conn->bits.tcpconnect[SECONDARYSOCKET] = connected;
conn->bits.do_more = TRUE;
state(conn, FTP_STOP); /* this phase is completed */
@@ -2221,7 +2218,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
}
if(!result)
result = ftp_state_post_mdtm(conn);
result = ftp_state_type(conn);
return result;
}
@@ -2245,18 +2242,18 @@ static CURLcode ftp_state_type_resp(struct connectdata *conn,
ftpcode);
if(instate == FTP_TYPE)
result = ftp_state_post_type(conn);
result = ftp_state_size(conn);
else if(instate == FTP_LIST_TYPE)
result = ftp_state_post_listtype(conn);
result = ftp_state_list(conn);
else if(instate == FTP_RETR_TYPE)
result = ftp_state_post_retrtype(conn);
result = ftp_state_retr_prequote(conn);
else if(instate == FTP_STOR_TYPE)
result = ftp_state_post_stortype(conn);
result = ftp_state_stor_prequote(conn);
return result;
}
static CURLcode ftp_state_post_retr_size(struct connectdata *conn,
static CURLcode ftp_state_retr(struct connectdata *conn,
curl_off_t filesize)
{
CURLcode result = CURLE_OK;
@@ -2361,11 +2358,11 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
}
#endif
Curl_pgrsSetDownloadSize(data, filesize);
result = ftp_state_post_size(conn);
result = ftp_state_rest(conn);
}
else if(instate == FTP_RETR_SIZE) {
Curl_pgrsSetDownloadSize(data, filesize);
result = ftp_state_post_retr_size(conn, filesize);
result = ftp_state_retr(conn, filesize);
}
else if(instate == FTP_STOR_SIZE) {
data->state.resume_from = filesize;
@@ -2393,7 +2390,7 @@ static CURLcode ftp_state_rest_resp(struct connectdata *conn,
return result;
}
#endif
result = ftp_state_post_rest(conn);
result = ftp_state_prepare_transfer(conn);
break;
case FTP_RETR_REST:
@@ -2834,7 +2831,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
if(data->set.ftp_ccc) {
/* CCC - Clear Command Channel
*/
PPSENDF(&ftpc->pp, "CCC", NULL);
PPSENDF(&ftpc->pp, "%s", "CCC");
state(conn, FTP_CCC);
}
else {
@@ -2921,7 +2918,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
if(!ftpc->server_os && dir[0] != '/') {
result = Curl_pp_sendf(&ftpc->pp, "SYST", NULL);
result = Curl_pp_sendf(&ftpc->pp, "%s", "SYST");
if(result != CURLE_OK) {
free(dir);
return result;
@@ -2974,7 +2971,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
if(strequal(os, "OS/400")) {
/* Force OS400 name format 1. */
result = Curl_pp_sendf(&ftpc->pp, "SITE NAMEFMT 1", NULL);
result = Curl_pp_sendf(&ftpc->pp, "%s", "SITE NAMEFMT 1");
if(result != CURLE_OK) {
free(os);
return result;
@@ -3052,7 +3049,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->count1 - 1]);
}
else {
result = ftp_state_post_cwd(conn);
result = ftp_state_mdtm(conn);
if(result)
return result;
}
@@ -3216,8 +3213,8 @@ static CURLcode ftp_init(struct connectdata *conn)
* the connection phase.
*
* The variable 'done' points to will be TRUE if the protocol-layer connect
* phase is done when this function returns, or FALSE is not. When called as
* a part of the easy interface, it will always be TRUE.
* phase is done when this function returns, or FALSE if not.
*
*/
static CURLcode ftp_connect(struct connectdata *conn,
bool *done) /* see description above */
@@ -3383,7 +3380,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) {
if(!result && ftpc->dont_check && data->req.maxdownload > 0) {
/* partial download completed */
result = Curl_pp_sendf(pp, "ABOR");
result = Curl_pp_sendf(pp, "%s", "ABOR");
if(result) {
failf(data, "Failure sending ABOR command: %s",
curl_easy_strerror(result));
@@ -3677,20 +3674,23 @@ static CURLcode ftp_range(struct connectdata *conn)
*
* This function shall be called when the second FTP (data) connection is
* connected.
*
* 'complete' can return 0 for incomplete, 1 for done and -1 for go back
* (which basically is only for when PASV is being sent to retry a failed
* EPSV).
*/
static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
{
struct SessionHandle *data=conn->data;
struct ftp_conn *ftpc = &conn->proto.ftpc;
CURLcode result = CURLE_OK;
bool connected = FALSE;
bool complete = FALSE;
/* the ftp struct is inited in ftp_connect() */
struct FTP *ftp = data->state.proto.ftp;
*complete = FALSE;
/* if the second connection isn't done yet, wait for it */
if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
if(conn->tunnel_state[SECONDARYSOCKET] == TUNNEL_CONNECT) {
@@ -3707,14 +3707,22 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
if(connected) {
DEBUGF(infof(data, "DO-MORE connected phase starts\n"));
}
else
else {
if(result && (ftpc->count1 == 0)) {
*completep = -1; /* go back to DOING please */
/* this is a EPSV connect failing, try PASV instead */
return ftp_epsv_disable(conn);
}
return result;
}
}
if(ftpc->state) {
/* already in a state so skip the intial commands.
They are only done to kickstart the do_more state */
result = ftp_multi_statemach(conn, complete);
result = ftp_multi_statemach(conn, &complete);
*completep = (int)complete;
/* if we got an error or if we don't wait for a data connection return
immediately */
@@ -3725,7 +3733,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
/* if we reach the end of the FTP state machine here, *complete will be
TRUE but so is ftpc->wait_data_conn, which says we need to wait for
the data connection and therefore we're not actually complete */
*complete = FALSE;
*completep = 0;
}
if(ftp->transfer <= FTPTRANSFER_INFO) {
@@ -3748,6 +3756,9 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
if(result)
return result;
*completep = 1; /* this state is now complete when the server has
connected back to us */
}
}
else if(data->set.upload) {
@@ -3755,7 +3766,8 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
if(result)
return result;
result = ftp_multi_statemach(conn, complete);
result = ftp_multi_statemach(conn, &complete);
*completep = (int)complete;
}
else {
/* download */
@@ -3783,7 +3795,8 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
return result;
}
result = ftp_multi_statemach(conn, complete);
result = ftp_multi_statemach(conn, &complete);
*completep = (int)complete;
}
return result;
}
@@ -3795,7 +3808,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
if(!ftpc->wait_data_conn) {
/* no waiting for the data connection so this is now complete */
*complete = TRUE;
*completep = 1;
DEBUGF(infof(data, "DO-MORE phase ends with %d\n", (int)result));
}
@@ -3838,7 +3851,9 @@ CURLcode ftp_perform(struct connectdata *conn,
/* run the state-machine */
result = ftp_multi_statemach(conn, dophase_done);
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
*connected = conn->bits.tcpconnect[SECONDARYSOCKET];
infof(conn->data, "ftp_perform ends with SECONDARY: %d\n", *connected);
if(*dophase_done)
DEBUGF(infof(conn->data, "DO phase is complete1\n"));
@@ -4189,7 +4204,7 @@ static CURLcode ftp_quit(struct connectdata *conn)
CURLcode result = CURLE_OK;
if(conn->proto.ftpc.ctl_valid) {
result = Curl_pp_sendf(&conn->proto.ftpc.pp, "QUIT", NULL);
result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "QUIT");
if(result) {
failf(conn->data, "Failure sending QUIT command: %s",
curl_easy_strerror(result));
@@ -4466,7 +4481,7 @@ static CURLcode ftp_dophase_done(struct connectdata *conn,
struct ftp_conn *ftpc = &conn->proto.ftpc;
if(connected) {
bool completed;
int completed;
CURLcode result = ftp_do_more(conn, &completed);
if(result) {

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -53,9 +53,9 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
pro->t_redirect = 0;
info->httpcode = 0;
info->httpversion=0;
info->filetime=-1; /* -1 is an illegal time and thus means unknown */
info->timecond=0;
info->httpversion = 0;
info->filetime = -1; /* -1 is an illegal time and thus means unknown */
info->timecond = FALSE;
if(info->contenttype)
free(info->contenttype);
@@ -186,7 +186,7 @@ static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
break;
case CURLINFO_CONDITION_UNMET:
/* return if the condition prevented the document to get transferred */
*param_longp = data->info.timecond;
*param_longp = data->info.timecond ? 1L : 0L;
break;
case CURLINFO_RTSP_CLIENT_CSEQ:
*param_longp = data->state.rtsp_next_client_CSeq;

906
lib/gskit.c Normal file
View File

@@ -0,0 +1,906 @@
/***************************************************************************
* _ _ ____ _
* 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 http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#ifdef USE_GSKIT
#include <gskssl.h>
#include <qsoasync.h>
/* Some symbols are undefined/unsupported on OS400 versions < V7R1. */
#ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST
#define GSK_SSL_EXTN_SERVERNAME_REQUEST 230
#endif
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
#include <curl/curl.h>
#include "urldata.h"
#include "sendf.h"
#include "gskit.h"
#include "sslgen.h"
#include "connect.h" /* for the connect timeout */
#include "select.h"
#include "strequal.h"
#include "x509asn1.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
/* Supported ciphers. */
typedef struct {
const char * name; /* Cipher name. */
const char * gsktoken; /* Corresponding token for GSKit String. */
int sslver; /* SSL version. */
} gskit_cipher;
static const gskit_cipher ciphertable[] = {
{ "null-md5", "01", CURL_SSLVERSION_SSLv3 },
{ "null-sha", "02", CURL_SSLVERSION_SSLv3 },
{ "exp-rc4-md5", "03", CURL_SSLVERSION_SSLv3 },
{ "rc4-md5", "04", CURL_SSLVERSION_SSLv3 },
{ "rc4-sha", "05", CURL_SSLVERSION_SSLv3 },
{ "exp-rc2-cbc-md5", "06", CURL_SSLVERSION_SSLv3 },
{ "exp-des-cbc-sha", "09", CURL_SSLVERSION_SSLv3 },
{ "des-cbc3-sha", "0A", CURL_SSLVERSION_SSLv3 },
{ "aes128-sha", "2F", CURL_SSLVERSION_TLSv1 },
{ "aes256-sha", "35", CURL_SSLVERSION_TLSv1 },
{ "rc4-md5", "1", CURL_SSLVERSION_SSLv2 },
{ "exp-rc4-md5", "2", CURL_SSLVERSION_SSLv2 },
{ "rc2-md5", "3", CURL_SSLVERSION_SSLv2 },
{ "exp-rc2-md5", "4", CURL_SSLVERSION_SSLv2 },
{ "des-cbc-md5", "6", CURL_SSLVERSION_SSLv2 },
{ "des-cbc3-md5", "7", CURL_SSLVERSION_SSLv2 },
{ (const char *) NULL, (const char *) NULL, 0 }
};
static bool is_separator(char c)
{
/* Return whether character is a cipher list separator. */
switch (c) {
case ' ':
case '\t':
case ':':
case ',':
case ';':
return true;
}
return false;
}
static CURLcode gskit_status(struct SessionHandle * data, int rc,
const char * procname, CURLcode defcode)
{
CURLcode cc;
/* Process GSKit status and map it to a CURLcode. */
switch (rc) {
case GSK_OK:
case GSK_OS400_ASYNCHRONOUS_SOC_INIT:
return CURLE_OK;
case GSK_KEYRING_OPEN_ERROR:
case GSK_OS400_ERROR_NO_ACCESS:
return CURLE_SSL_CACERT_BADFILE;
case GSK_INSUFFICIENT_STORAGE:
return CURLE_OUT_OF_MEMORY;
case GSK_ERROR_BAD_V2_CIPHER:
case GSK_ERROR_BAD_V3_CIPHER:
case GSK_ERROR_NO_CIPHERS:
return CURLE_SSL_CIPHER;
case GSK_OS400_ERROR_NOT_TRUSTED_ROOT:
case GSK_ERROR_CERT_VALIDATION:
return CURLE_PEER_FAILED_VERIFICATION;
case GSK_OS400_ERROR_TIMED_OUT:
return CURLE_OPERATION_TIMEDOUT;
case GSK_WOULD_BLOCK:
return CURLE_AGAIN;
case GSK_OS400_ERROR_NOT_REGISTERED:
break;
case GSK_ERROR_IO:
switch (errno) {
case ENOMEM:
return CURLE_OUT_OF_MEMORY;
default:
failf(data, "%s I/O error: %s", procname, strerror(errno));
break;
}
break;
default:
failf(data, "%s: %s", procname, gsk_strerror(rc));
break;
}
return defcode;
}
static CURLcode set_enum(struct SessionHandle * data,
gsk_handle h, GSK_ENUM_ID id, GSK_ENUM_VALUE value)
{
int rc = gsk_attribute_set_enum(h, id, value);
switch (rc) {
case GSK_OK:
return CURLE_OK;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_enum() I/O error: %s", strerror(errno));
break;
default:
failf(data, "gsk_attribute_set_enum(): %s", gsk_strerror(rc));
break;
}
return CURLE_SSL_CONNECT_ERROR;
}
static CURLcode set_buffer(struct SessionHandle * data,
gsk_handle h, GSK_BUF_ID id, const char * buffer)
{
int rc = gsk_attribute_set_buffer(h, id, buffer, 0);
switch (rc) {
case GSK_OK:
return CURLE_OK;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno));
break;
default:
failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
break;
}
return CURLE_SSL_CONNECT_ERROR;
}
static CURLcode set_numeric(struct SessionHandle * data,
gsk_handle h, GSK_NUM_ID id, int value)
{
int rc = gsk_attribute_set_numeric_value(h, id, value);
switch (rc) {
case GSK_OK:
return CURLE_OK;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_numeric_value() I/O error: %s",
strerror(errno));
break;
default:
failf(data, "gsk_attribute_set_numeric_value(): %s", gsk_strerror(rc));
break;
}
return CURLE_SSL_CONNECT_ERROR;
}
static CURLcode set_callback(struct SessionHandle * data,
gsk_handle h, GSK_CALLBACK_ID id, void * info)
{
int rc = gsk_attribute_set_callback(h, id, info);
switch (rc) {
case GSK_OK:
return CURLE_OK;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_callback() I/O error: %s", strerror(errno));
break;
default:
failf(data, "gsk_attribute_set_callback(): %s", gsk_strerror(rc));
break;
}
return CURLE_SSL_CONNECT_ERROR;
}
static CURLcode set_ciphers(struct SessionHandle * data, gsk_handle h)
{
const char * cipherlist = data->set.str[STRING_SSL_CIPHER_LIST];
char * sslv2ciphers;
char * sslv3ciphers;
const char * clp;
const gskit_cipher * ctp;
char * v2p;
char * v3p;
int i;
CURLcode cc;
/* Compile cipher list into GSKit-compatible cipher lists. */
if(!cipherlist)
return CURLE_OK;
while(is_separator(*cipherlist)) /* Skip initial separators. */
cipherlist++;
if(!*cipherlist)
return CURLE_OK;
/* We allocate GSKit buffers of the same size as the input string: since
GSKit tokens are always shorter than their cipher names, allocated buffers
will always be large enough to accomodate the result. */
i = strlen(cipherlist) + 1;
v2p = malloc(i);
if(!v2p)
return CURLE_OUT_OF_MEMORY;
v3p = malloc(i);
if(!v3p) {
free(v2p);
return CURLE_OUT_OF_MEMORY;
}
sslv2ciphers = v2p;
sslv3ciphers = v3p;
/* Process each cipher in input string. */
for(;;) {
for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);)
cipherlist++;
i = cipherlist - clp;
if(!i)
break;
/* Search the cipher in our table. */
for(ctp = ciphertable; ctp->name; ctp++)
if(strnequal(ctp->name, clp, i) && !ctp->name[i])
break;
if(!ctp->name)
failf(data, "Unknown cipher %.*s: ignored", i, clp);
else {
switch (ctp->sslver) {
case CURL_SSLVERSION_SSLv2:
strcpy(v2p, ctp->gsktoken);
v2p += strlen(v2p);
break;
default:
/* GSKit wants TLSv1 ciphers with SSLv3 ciphers. */
strcpy(v3p, ctp->gsktoken);
v3p += strlen(v3p);
break;
}
}
/* Advance to next cipher name or end of string. */
while(is_separator(*cipherlist))
cipherlist++;
}
*v2p = '\0';
*v3p = '\0';
cc = set_buffer(data, h, GSK_V2_CIPHER_SPECS, sslv2ciphers);
if(cc == CURLE_OK)
cc = set_buffer(data, h, GSK_V3_CIPHER_SPECS, sslv3ciphers);
free(sslv2ciphers);
free(sslv3ciphers);
return cc;
}
int Curl_gskit_init(void)
{
/* No initialisation needed. */
return 1;
}
void Curl_gskit_cleanup(void)
{
/* Nothing to do. */
}
static CURLcode init_environment(struct SessionHandle * data,
gsk_handle * envir, const char * appid,
const char * file, const char * label,
const char * password)
{
int rc;
CURLcode c;
gsk_handle h;
/* Creates the GSKit environment. */
rc = gsk_environment_open(&h);
switch (rc) {
case GSK_OK:
break;
case GSK_INSUFFICIENT_STORAGE:
return CURLE_OUT_OF_MEMORY;
default:
failf(data, "gsk_environment_open(): %s", gsk_strerror(rc));
return CURLE_SSL_CONNECT_ERROR;
}
c = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION);
if(c == CURLE_OK && appid)
c = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid);
if(c == CURLE_OK && file)
c = set_buffer(data, h, GSK_KEYRING_FILE, file);
if(c == CURLE_OK && label)
c = set_buffer(data, h, GSK_KEYRING_LABEL, label);
if(c == CURLE_OK && password)
c = set_buffer(data, h, GSK_KEYRING_PW, password);
if(c == CURLE_OK) {
/* Locate CAs, Client certificate and key according to our settings.
Note: this call may be blocking for some tenths of seconds. */
c = gskit_status(data, gsk_environment_init(h),
"gsk_environment_init()", CURLE_SSL_CERTPROBLEM);
if(c == CURLE_OK) {
*envir = h;
return c;
}
}
/* Error: rollback. */
gsk_environment_close(&h);
return c;
}
static void cancel_async_handshake(struct connectdata * conn, int sockindex)
{
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
Qso_OverlappedIO_t cstat;
if(QsoCancelOperation(conn->sock[sockindex], 0) > 0)
QsoWaitForIOCompletion(connssl->iocport, &cstat, (struct timeval *) NULL);
}
static void close_async_handshake(struct ssl_connect_data * connssl)
{
QsoDestroyIOCompletionPort(connssl->iocport);
connssl->iocport = -1;
}
static void close_one(struct ssl_connect_data * conn,
struct SessionHandle * data)
{
if(conn->handle) {
gskit_status(data, gsk_secure_soc_close(&conn->handle),
"gsk_secure_soc_close()", 0);
conn->handle = (gsk_handle) NULL;
}
if(conn->iocport >= 0)
close_async_handshake(conn);
}
static ssize_t gskit_send(struct connectdata * conn, int sockindex,
const void * mem, size_t len, CURLcode * curlcode)
{
struct SessionHandle * data = conn->data;
CURLcode cc;
int written;
cc = gskit_status(data,
gsk_secure_soc_write(conn->ssl[sockindex].handle,
(char *) mem, (int) len, &written),
"gsk_secure_soc_write()", CURLE_SEND_ERROR);
if(cc != CURLE_OK) {
*curlcode = cc;
written = -1;
}
return (ssize_t) written; /* number of bytes */
}
static ssize_t gskit_recv(struct connectdata * conn, int num, char * buf,
size_t buffersize, CURLcode * curlcode)
{
struct SessionHandle * data = conn->data;
int buffsize;
int nread;
CURLcode cc;
buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize;
cc = gskit_status(data, gsk_secure_soc_read(conn->ssl[num].handle,
buf, buffsize, &nread),
"gsk_secure_soc_read()", CURLE_RECV_ERROR);
if(cc != CURLE_OK) {
*curlcode = cc;
nread = -1;
}
return (ssize_t) nread;
}
static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
{
struct SessionHandle * data = conn->data;
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
gsk_handle envir;
CURLcode cc;
int rc;
char * keyringfile;
char * keyringpwd;
char * keyringlabel;
char * v2ciphers;
char * v3ciphers;
char * sni;
bool sslv2enable, sslv3enable, tlsv1enable;
long timeout;
Qso_OverlappedIO_t commarea;
/* Create SSL environment, start (preferably asynchronous) handshake. */
connssl->handle = (gsk_handle) NULL;
connssl->iocport = -1;
/* GSKit supports two ways of specifying an SSL context: either by
* application identifier (that should have been defined at the system
* level) or by keyring file, password and certificate label.
* Local certificate name (CURLOPT_SSLCERT) is used to hold either the
* application identifier of the certificate label.
* Key password (CURLOPT_KEYPASSWD) holds the keyring password.
* It is not possible to have different keyrings for the CAs and the
* local certificate. We thus use the CA file (CURLOPT_CAINFO) to identify
* the keyring file.
* If no key password is given and the keyring is the system keyring,
* application identifier mode is tried first, as recommended in IBM doc.
*/
keyringfile = data->set.str[STRING_SSL_CAFILE];
keyringpwd = data->set.str[STRING_KEY_PASSWD];
keyringlabel = data->set.str[STRING_CERT];
envir = (gsk_handle) NULL;
if(keyringlabel && *keyringlabel && !keyringpwd &&
!strcmp(keyringfile, CURL_CA_BUNDLE)) {
/* Try application identifier mode. */
init_environment(data, &envir, keyringlabel, (const char *) NULL,
(const char *) NULL, (const char *) NULL);
}
if(!envir) {
/* Use keyring mode. */
cc = init_environment(data, &envir, (const char *) NULL,
keyringfile, keyringlabel, keyringpwd);
if(cc != CURLE_OK)
return cc;
}
/* Create secure session. */
cc = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle),
"gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR);
gsk_environment_close(&envir);
if(cc != CURLE_OK)
return cc;
/* Determine which SSL/TLS version should be enabled. */
sslv2enable = sslv3enable = tlsv1enable = false;
sni = conn->host.name;
switch (data->set.ssl.version) {
case CURL_SSLVERSION_SSLv2:
sslv2enable = true;
sni = (char *) NULL;
break;
case CURL_SSLVERSION_SSLv3:
sslv3enable = true;
sni = (char *) NULL;
break;
case CURL_SSLVERSION_TLSv1:
tlsv1enable = true;
break;
default: /* CURL_SSLVERSION_DEFAULT. */
sslv3enable = true;
tlsv1enable = true;
break;
}
/* Process SNI. Ignore if not supported (on OS400 < V7R1). */
if(sni) {
rc = gsk_attribute_set_buffer(connssl->handle,
GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, 0);
switch (rc) {
case GSK_OK:
case GSK_ATTRIBUTE_INVALID_ID:
break;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno));
cc = CURLE_SSL_CONNECT_ERROR;
break;
default:
failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
cc = CURLE_SSL_CONNECT_ERROR;
break;
}
}
/* Set session parameters. */
if(cc == CURLE_OK) {
/* Compute the handshake timeout. Since GSKit granularity is 1 second,
we round up the required value. */
timeout = Curl_timeleft(data, NULL, TRUE);
if(timeout < 0)
cc = CURLE_OPERATION_TIMEDOUT;
else
cc = set_numeric(data, connssl->handle, GSK_HANDSHAKE_TIMEOUT,
(timeout + 999) / 1000);
}
if(cc == CURLE_OK)
cc = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]);
if(cc == CURLE_OK)
cc = set_ciphers(data, connssl->handle);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2,
sslv2enable? GSK_PROTOCOL_SSLV2_ON:
GSK_PROTOCOL_SSLV2_OFF);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3,
sslv3enable? GSK_PROTOCOL_SSLV3_ON:
GSK_PROTOCOL_SSLV3_OFF);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
sslv3enable? GSK_PROTOCOL_TLSV1_ON:
GSK_PROTOCOL_TLSV1_OFF);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL:
GSK_SERVER_AUTH_PASSTHRU);
if(cc == CURLE_OK) {
/* Start handshake. Try asynchronous first. */
memset(&commarea, 0, sizeof commarea);
connssl->iocport = QsoCreateIOCompletionPort();
if(connssl->iocport != -1) {
cc = gskit_status(data, gsk_secure_soc_startInit(connssl->handle,
connssl->iocport, &commarea),
"gsk_secure_soc_startInit()", CURLE_SSL_CONNECT_ERROR);
if(cc == CURLE_OK) {
connssl->connecting_state = ssl_connect_2;
return CURLE_OK;
}
else
close_async_handshake(connssl);
}
else if(errno != ENOBUFS)
cc = gskit_status(data, GSK_ERROR_IO, "QsoCreateIOCompletionPort()", 0);
else {
/* No more completion port available. Use synchronous IO. */
cc = gskit_status(data, gsk_secure_soc_init(connssl->handle),
"gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR);
if(cc == CURLE_OK) {
connssl->connecting_state = ssl_connect_3;
return CURLE_OK;
}
}
}
/* Error: rollback. */
close_one(connssl, data);
return cc;
}
static CURLcode gskit_connect_step2(struct connectdata * conn, int sockindex,
bool nonblocking)
{
struct SessionHandle * data = conn->data;
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
Qso_OverlappedIO_t cstat;
long timeout_ms;
struct timeval stmv;
CURLcode cc;
/* Poll or wait for end of SSL asynchronous handshake. */
for(;;) {
timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0)
timeout_ms = 0;
stmv.tv_sec = timeout_ms / 1000;
stmv.tv_usec = (timeout_ms - stmv.tv_sec * 1000) * 1000;
switch (QsoWaitForIOCompletion(connssl->iocport, &cstat, &stmv)) {
case 1: /* Operation complete. */
break;
case -1: /* An error occurred: handshake still in progress. */
if(errno == EINTR) {
if(nonblocking)
return CURLE_OK;
continue; /* Retry. */
}
if(errno != ETIME) {
failf(data, "QsoWaitForIOCompletion() I/O error: %s", strerror(errno));
cancel_async_handshake(conn, sockindex);
close_async_handshake(connssl);
return CURLE_SSL_CONNECT_ERROR;
}
/* FALL INTO... */
case 0: /* Handshake in progress, timeout occurred. */
if(nonblocking)
return CURLE_OK;
cancel_async_handshake(conn, sockindex);
close_async_handshake(connssl);
return CURLE_OPERATION_TIMEDOUT;
}
break;
}
cc = gskit_status(data, cstat.returnValue, "SSL handshake",
CURLE_SSL_CONNECT_ERROR);
if(cc == CURLE_OK)
connssl->connecting_state = ssl_connect_3;
close_async_handshake(connssl);
return cc;
}
static CURLcode gskit_connect_step3(struct connectdata * conn, int sockindex)
{
struct SessionHandle * data = conn->data;
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
const gsk_cert_data_elem * cdev;
int cdec;
const gsk_cert_data_elem * p;
const char * cert = (const char *) NULL;
const char * certend;
int i;
CURLcode cc;
/* SSL handshake done: gather certificate info and verify host. */
if(gskit_status(data, gsk_attribute_get_cert_info(connssl->handle,
GSK_PARTNER_CERT_INFO,
&cdev, &cdec),
"gsk_attribute_get_cert_info()", CURLE_SSL_CONNECT_ERROR) ==
CURLE_OK) {
infof(data, "Server certificate:\n");
p = cdev;
for(i = 0; i++ < cdec; p++)
switch (p->cert_data_id) {
case CERT_BODY_DER:
cert = p->cert_data_p;
certend = cert + cdev->cert_data_l;
break;
case CERT_DN_PRINTABLE:
infof(data, "\t subject: %.*s\n", p->cert_data_l, p->cert_data_p);
break;
case CERT_ISSUER_DN_PRINTABLE:
infof(data, "\t issuer: %.*s\n", p->cert_data_l, p->cert_data_p);
break;
case CERT_VALID_FROM:
infof(data, "\t start date: %.*s\n", p->cert_data_l, p->cert_data_p);
break;
case CERT_VALID_TO:
infof(data, "\t expire date: %.*s\n", p->cert_data_l, p->cert_data_p);
break;
}
}
/* Verify host. */
cc = Curl_verifyhost(conn, cert, certend);
if(cc != CURLE_OK)
return cc;
/* The only place GSKit can get the whole CA chain is a validation
callback where no user data pointer is available. Therefore it's not
possible to copy this chain into our structures for CAINFO.
However the server certificate may be available, thus we can return
info about it. */
if(data->set.ssl.certinfo) {
if(Curl_ssl_init_certinfo(data, 1))
return CURLE_OUT_OF_MEMORY;
if(cert) {
cc = Curl_extract_certinfo(conn, 0, cert, certend);
if(cc != CURLE_OK)
return cc;
}
}
connssl->connecting_state = ssl_connect_done;
return CURLE_OK;
}
static CURLcode gskit_connect_common(struct connectdata * conn, int sockindex,
bool nonblocking, bool * done)
{
struct SessionHandle * data = conn->data;
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
long timeout_ms;
Qso_OverlappedIO_t cstat;
CURLcode cc = CURLE_OK;
*done = connssl->state == ssl_connection_complete;
if(*done)
return CURLE_OK;
/* Step 1: create session, start handshake. */
if(connssl->connecting_state == ssl_connect_1) {
/* check allowed time left */
timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* no need to continue if time already is up */
failf(data, "SSL connection timeout");
cc = CURLE_OPERATION_TIMEDOUT;
}
else
cc = gskit_connect_step1(conn, sockindex);
}
/* Step 2: check if handshake is over. */
if(cc == CURLE_OK && connssl->connecting_state == ssl_connect_2) {
/* check allowed time left */
timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* no need to continue if time already is up */
failf(data, "SSL connection timeout");
cc = CURLE_OPERATION_TIMEDOUT;
}
else
cc = gskit_connect_step2(conn, sockindex, nonblocking);
}
/* Step 3: gather certificate info, verify host. */
if(cc == CURLE_OK && connssl->connecting_state == ssl_connect_3)
cc = gskit_connect_step3(conn, sockindex);
if(cc != CURLE_OK)
close_one(connssl, data);
else if(connssl->connecting_state == ssl_connect_done) {
connssl->state = ssl_connection_complete;
connssl->connecting_state = ssl_connect_1;
conn->recv[sockindex] = gskit_recv;
conn->send[sockindex] = gskit_send;
*done = TRUE;
}
return cc;
}
CURLcode Curl_gskit_connect_nonblocking(struct connectdata * conn,
int sockindex,
bool * done)
{
CURLcode cc;
cc = gskit_connect_common(conn, sockindex, TRUE, done);
if(*done || cc != CURLE_OK)
conn->ssl[sockindex].connecting_state = ssl_connect_1;
return cc;
}
CURLcode Curl_gskit_connect(struct connectdata * conn, int sockindex)
{
CURLcode retcode;
bool done;
conn->ssl[sockindex].connecting_state = ssl_connect_1;
retcode = gskit_connect_common(conn, sockindex, FALSE, &done);
if(retcode)
return retcode;
DEBUGASSERT(done);
return CURLE_OK;
}
void Curl_gskit_close(struct connectdata * conn, int sockindex)
{
struct SessionHandle * data = conn->data;
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
if(connssl->use)
close_one(connssl, data);
}
int Curl_gskit_close_all(struct SessionHandle * data)
{
/* Unimplemented. */
(void) data;
return 0;
}
int Curl_gskit_shutdown(struct connectdata * conn, int sockindex)
{
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
struct SessionHandle * data = conn->data;
ssize_t nread;
int what;
int rc;
char buf[120];
if(!connssl->handle)
return 0;
if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
return 0;
close_one(connssl, data);
rc = 0;
what = Curl_socket_ready(conn->sock[sockindex],
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
for(;;) {
if(what < 0) {
/* anything that gets here is fatally bad */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
rc = -1;
break;
}
if(!what) { /* timeout */
failf(data, "SSL shutdown timeout");
break;
}
/* Something to read, let's do it and hope that it is the close
notify alert from the server. No way to gsk_secure_soc_read() now, so
use read(). */
nread = read(conn->sock[sockindex], buf, sizeof(buf));
if(nread < 0) {
failf(data, "read: %s", strerror(errno));
rc = -1;
}
if(nread <= 0)
break;
what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
}
return rc;
}
size_t Curl_gskit_version(char * buffer, size_t size)
{
strncpy(buffer, "GSKit", size);
return strlen(buffer);
}
int Curl_gskit_check_cxn(struct connectdata * cxn)
{
int err;
int errlen;
/* The only thing that can be tested here is at the socket level. */
if(!cxn->ssl[FIRSTSOCKET].handle)
return 0; /* connection has been closed */
err = 0;
errlen = sizeof err;
if(getsockopt(cxn->sock[FIRSTSOCKET], SOL_SOCKET, SO_ERROR,
(unsigned char *) &err, &errlen) ||
errlen != sizeof err || err)
return 0; /* connection has been closed */
return -1; /* connection status unknown */
}
#endif /* USE_GSKIT */

64
lib/gskit.h Normal file
View File

@@ -0,0 +1,64 @@
#ifndef HEADER_CURL_GSKIT_H
#define HEADER_CURL_GSKIT_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 http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
/*
* This header should only be needed to get included by sslgen.c and gskit.c
*/
#include "urldata.h"
#ifdef USE_GSKIT
int Curl_gskit_init(void);
void Curl_gskit_cleanup(void);
CURLcode Curl_gskit_connect(struct connectdata * conn, int sockindex);
CURLcode Curl_gskit_connect_nonblocking(struct connectdata * conn,
int sockindex, bool * done);
void Curl_gskit_close(struct connectdata *conn, int sockindex);
int Curl_gskit_close_all(struct SessionHandle * data);
int Curl_gskit_shutdown(struct connectdata * conn, int sockindex);
size_t Curl_gskit_version(char * buffer, size_t size);
int Curl_gskit_check_cxn(struct connectdata * cxn);
/* API setup for GSKit */
#define curlssl_init Curl_gskit_init
#define curlssl_cleanup Curl_gskit_cleanup
#define curlssl_connect Curl_gskit_connect
#define curlssl_connect_nonblocking Curl_gskit_connect_nonblocking
/* No session handling for GSKit */
#define curlssl_session_free(x) Curl_nop_stmt
#define curlssl_close_all Curl_gskit_close_all
#define curlssl_close Curl_gskit_close
#define curlssl_shutdown(x,y) Curl_gskit_shutdown(x,y)
#define curlssl_set_engine(x,y) CURLE_NOT_BUILT_IN
#define curlssl_set_engine_default(x) CURLE_NOT_BUILT_IN
#define curlssl_engines_list(x) NULL
#define curlssl_version Curl_gskit_version
#define curlssl_check_cxn(x) Curl_gskit_check_cxn(x)
#define curlssl_data_pending(x,y) 0
#endif /* USE_GSKIT */
#endif /* HEADER_CURL_GSKIT_H */

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -55,6 +55,10 @@ void Curl_gtls_md5sum(unsigned char *tmp, /* input */
unsigned char *md5sum, /* output */
size_t md5len);
/* this backend provides these functions: */
#define have_curlssl_random 1
#define have_curlssl_md5sum 1
/* API setup for GnuTLS */
#define curlssl_init Curl_gtls_init
#define curlssl_cleanup Curl_gtls_cleanup

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -391,7 +391,7 @@ void Curl_hash_print(struct curl_hash *h,
if(func)
func(he->ptr);
else
fprintf(stderr, " [%p]", he->ptr);
fprintf(stderr, " [%p]", (void *)he->ptr);
he = Curl_hash_next_element(&iter);
}

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -22,8 +22,9 @@
#include "curl_setup.h"
#if defined(USE_SSLEAY) || defined(USE_AXTLS)
/* these two backends use functions from this file */
#if defined(USE_SSLEAY) || defined(USE_AXTLS) || defined(USE_QSOSSL) || \
defined(USE_GSKIT)
/* these backends use functions from this file */
#include "hostcheck.h"
#include "rawstr.h"
@@ -93,4 +94,4 @@ int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
return 0;
}
#endif /* SSLEAY or AXTLS */
#endif /* SSLEAY or AXTLS or QSOSSL or GSKIT */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -140,6 +140,10 @@ struct curl_hash *Curl_global_host_cache_init(void)
void Curl_global_host_cache_dtor(void)
{
if(host_cache_initialized) {
/* first make sure that any custom "CURLOPT_RESOLVE" names are
cleared off */
Curl_hostcache_clean(NULL, &hostname_cache);
/* then free the remaining hash completely */
Curl_hash_clean(&hostname_cache);
host_cache_initialized = 0;
}
@@ -681,12 +685,14 @@ clean_up:
* Curl_resolv_unlock() unlocks the given cached DNS entry. When this has been
* made, the struct may be destroyed due to pruning. It is important that only
* one unlock is made for each Curl_resolv() call.
*
* May be called with 'data' == NULL for global cache.
*/
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
{
DEBUGASSERT(dns && (dns->inuse>0));
if(data->share)
if(data && data->share)
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
dns->inuse--;
@@ -697,7 +703,7 @@ void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
free(dns);
}
if(data->share)
if(data && data->share)
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
}
@@ -734,22 +740,23 @@ static int hostcache_inuse(void *data, void *hc)
return 1; /* free all entries */
}
void Curl_hostcache_clean(struct SessionHandle *data)
/*
* Curl_hostcache_clean()
*
* This _can_ be called with 'data' == NULL but then of course no locking
* can be done!
*/
void Curl_hostcache_clean(struct SessionHandle *data,
struct curl_hash *hash)
{
/* Entries added to the hostcache with the CURLOPT_RESOLVE function are
* still present in the cache with the inuse counter set to 1. Detect them
* and cleanup!
*/
Curl_hash_clean_with_criterium(data->dns.hostcache, data, hostcache_inuse);
Curl_hash_clean_with_criterium(hash, data, hostcache_inuse);
}
void Curl_hostcache_destroy(struct SessionHandle *data)
{
Curl_hostcache_clean(data);
Curl_hash_destroy(data->dns.hostcache);
data->dns.hostcachetype = HCACHE_NONE;
data->dns.hostcache = NULL;
}
CURLcode Curl_loadhostpairs(struct SessionHandle *data)
{

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -203,7 +203,7 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data, char *servers);
/*
* Clean off entries from the cache
*/
void Curl_hostcache_clean(struct SessionHandle *data);
void Curl_hostcache_clean(struct SessionHandle *data, struct curl_hash *hash);
/*
* Destroy the hostcache of this handle.

View File

@@ -25,14 +25,13 @@
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
#include "urldata.h"
#include "sendf.h"
#include "rawstr.h"
#include "curl_base64.h"
#include "curl_md5.h"
#include "http_digest.h"
#include "strtok.h"
#include "url.h" /* for Curl_safefree() */
#include "curl_memory.h"
#include "sslgen.h" /* for Curl_rand() */
#include "non-ascii.h" /* included for Curl_convert_... prototypes */
#include "warnless.h"
@@ -283,7 +282,7 @@ static char *string_quoted(const char *source)
++s;
}
dest = (char *)malloc(n);
dest = malloc(n);
if(dest) {
s = source;
d = dest;
@@ -310,14 +309,12 @@ CURLcode Curl_output_digest(struct connectdata *conn,
unsigned char md5buf[16]; /* 16 bytes/128 bits */
unsigned char request_digest[33];
unsigned char *md5this;
unsigned char *ha1;
unsigned char ha1[33];/* 32 digits and 1 zero byte */
unsigned char ha2[33];/* 32 digits and 1 zero byte */
char cnoncebuf[33];
char *cnonce = NULL;
size_t cnonce_sz = 0;
char *tmp = NULL;
struct timeval now;
char **allocuserpwd;
size_t userlen;
const char *userp;
@@ -354,10 +351,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
authp = &data->state.authhost;
}
if(*allocuserpwd) {
Curl_safefree(*allocuserpwd);
*allocuserpwd = NULL;
}
/* not set means empty */
if(!userp)
@@ -376,10 +370,11 @@ CURLcode Curl_output_digest(struct connectdata *conn,
d->nc = 1;
if(!d->cnonce) {
/* Generate a cnonce */
now = Curl_tvnow();
snprintf(cnoncebuf, sizeof(cnoncebuf), "%32ld",
(long)now.tv_sec + now.tv_usec);
struct timeval now = Curl_tvnow();
snprintf(cnoncebuf, sizeof(cnoncebuf), "%08x%08x%08x%08x",
Curl_rand(data), Curl_rand(data),
(unsigned int)now.tv_sec,
(unsigned int)now.tv_usec);
rc = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf),
&cnonce, &cnonce_sz);
@@ -406,12 +401,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
Curl_md5it(md5buf, md5this);
free(md5this); /* free this again */
ha1 = malloc(33); /* 32 digits and 1 zero byte */
if(!ha1)
return CURLE_OUT_OF_MEMORY;
Curl_safefree(md5this);
md5_to_ascii(md5buf, ha1);
if(d->algo == CURLDIGESTALGO_MD5SESS) {
@@ -421,7 +411,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
return CURLE_OUT_OF_MEMORY;
CURL_OUTPUT_DIGEST_CONV(data, tmp); /* convert on non-ASCII machines */
Curl_md5it(md5buf, (unsigned char *)tmp);
free(tmp); /* free this again */
Curl_safefree(tmp);
md5_to_ascii(md5buf, ha1);
}
@@ -463,18 +453,16 @@ CURLcode Curl_output_digest(struct connectdata *conn,
TODO: replace md5 of empty string with entity-body for PUT/POST */
unsigned char *md5this2 = (unsigned char *)
aprintf("%s:%s", md5this, "d41d8cd98f00b204e9800998ecf8427e");
free(md5this);
Curl_safefree(md5this);
md5this = md5this2;
}
if(!md5this) {
free(ha1);
if(!md5this)
return CURLE_OUT_OF_MEMORY;
}
CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
Curl_md5it(md5buf, md5this);
free(md5this); /* free this again */
Curl_safefree(md5this);
md5_to_ascii(md5buf, ha2);
if(d->qop) {
@@ -492,13 +480,12 @@ CURLcode Curl_output_digest(struct connectdata *conn,
d->nonce,
ha2);
}
free(ha1);
if(!md5this)
return CURLE_OUT_OF_MEMORY;
CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
Curl_md5it(md5buf, md5this);
free(md5this); /* free this again */
Curl_safefree(md5this);
md5_to_ascii(md5buf, request_digest);
/* for test case 64 (snooped from a Mozilla 1.3a request)
@@ -515,7 +502,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
chracters.
*/
userp_quoted = string_quoted(userp);
if(!*userp_quoted)
if(!userp_quoted)
return CURLE_OUT_OF_MEMORY;
if(d->qop) {
@@ -559,7 +546,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
uripath, /* this is the PATH part of the URL */
request_digest);
}
free(userp_quoted);
Curl_safefree(userp_quoted);
if(!*allocuserpwd)
return CURLE_OUT_OF_MEMORY;
@@ -595,29 +582,12 @@ CURLcode Curl_output_digest(struct connectdata *conn,
static void digest_cleanup_one(struct digestdata *d)
{
if(d->nonce)
free(d->nonce);
d->nonce = NULL;
if(d->cnonce)
free(d->cnonce);
d->cnonce = NULL;
if(d->realm)
free(d->realm);
d->realm = NULL;
if(d->opaque)
free(d->opaque);
d->opaque = NULL;
if(d->qop)
free(d->qop);
d->qop = NULL;
if(d->algorithm)
free(d->algorithm);
d->algorithm = NULL;
Curl_safefree(d->nonce);
Curl_safefree(d->cnonce);
Curl_safefree(d->realm);
Curl_safefree(d->opaque);
Curl_safefree(d->qop);
Curl_safefree(d->algorithm);
d->nc = 0;
d->algo = CURLDIGESTALGO_MD5; /* default algorithm */

View File

@@ -77,6 +77,7 @@
#include "url.h"
#include "rawstr.h"
#include "curl_sasl.h"
#include "warnless.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -398,7 +399,7 @@ static void state(struct connectdata *conn, imapstate newstate)
if(imapc->state != newstate)
infof(conn->data, "IMAP %p state change from %s to %s\n",
imapc, names[imapc->state], names[newstate]);
(void *)imapc, names[imapc->state], names[newstate]);
#endif
imapc->state = newstate;
@@ -1152,7 +1153,7 @@ static CURLcode imap_state_auth_digest_resp_resp(struct connectdata *conn,
}
else {
/* Send an empty response */
result = Curl_pp_sendf(&conn->proto.imapc.pp, "");
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "");
if(!result)
state(conn, IMAP_AUTHENTICATE_FINAL);
@@ -1694,8 +1695,7 @@ static int imap_getsock(struct connectdata *conn, curl_socket_t *socks,
* connection phase.
*
* The variable 'done' points to will be TRUE if the protocol-layer connect
* phase is done when this function returns, or FALSE is not. When called as
* a part of the easy interface, it will always be TRUE.
* phase is done when this function returns, or FALSE if not.
*/
static CURLcode imap_connect(struct connectdata *conn, bool *done)
{
@@ -1781,7 +1781,7 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status,
state(conn, IMAP_FETCH_FINAL);
else {
/* End the APPEND command first by sending an empty line */
result = Curl_pp_sendf(&conn->proto.imapc.pp, "");
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "");
if(!result)
state(conn, IMAP_APPEND_FINAL);
}
@@ -2062,14 +2062,15 @@ static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...)
struct imap_conn *imapc = &conn->proto.imapc;
char *taggedfmt;
va_list ap;
va_start(ap, fmt);
DEBUGASSERT(fmt);
/* Calculate the next command ID wrapping at 3 digits */
imapc->cmdid = (imapc->cmdid + 1) % 1000;
/* Calculate the tag based on the connection ID and command ID */
snprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d",
'A' + (conn->connection_id % 26), imapc->cmdid);
'A' + curlx_sltosi(conn->connection_id % 26), imapc->cmdid);
/* Prefix the format with the tag */
taggedfmt = aprintf("%s %s", imapc->resptag, fmt);
@@ -2077,10 +2078,11 @@ static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...)
return CURLE_OUT_OF_MEMORY;
/* Send the data with the tag */
va_start(ap, fmt);
result = Curl_pp_vsendf(&imapc->pp, taggedfmt, ap);
va_end(ap);
Curl_safefree(taggedfmt);
va_end(ap);
return result;
}

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -260,7 +260,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
}
server = ldapssl_init(conn->host.name, (int)conn->port, 1);
if(server == NULL) {
failf(data, "LDAP local: Cannot connect to %s:%hu",
failf(data, "LDAP local: Cannot connect to %s:%ld",
conn->host.name, conn->port);
status = CURLE_COULDNT_CONNECT;
goto quit;
@@ -301,7 +301,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
}
server = ldap_init(conn->host.name, (int)conn->port);
if(server == NULL) {
failf(data, "LDAP local: Cannot connect to %s:%hu",
failf(data, "LDAP local: Cannot connect to %s:%ld",
conn->host.name, conn->port);
status = CURLE_COULDNT_CONNECT;
goto quit;
@@ -337,7 +337,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
else {
server = ldap_init(conn->host.name, (int)conn->port);
if(server == NULL) {
failf(data, "LDAP local: Cannot connect to %s:%hu",
failf(data, "LDAP local: Cannot connect to %s:%ld",
conn->host.name, conn->port);
status = CURLE_COULDNT_CONNECT;
goto quit;

View File

@@ -90,16 +90,36 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
# include <md5.h>
# endif
#elif defined(__MAC_10_4) || defined(__IPHONE_5_0)
#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.
The library's headers are even backward-compatible with OpenSSL's
headers as long as we define COMMON_DIGEST_FOR_OPENSSL first.
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.
These functions are available on Tiger and later, as well as iOS 5.0
and later. If you're building for an older cat, well, sorry. */
# define COMMON_DIGEST_FOR_OPENSSL
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
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)

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -185,8 +185,10 @@ void *curl_domalloc(size_t wantedsize, int line, const char *source)
}
if(source)
curl_memlog("MEM %s:%d malloc(%zd) = %p\n",
source, line, wantedsize, mem ? mem->mem : 0);
curl_memlog("MEM %s:%d malloc(%zu) = %p\n",
source, line, wantedsize,
mem ? (void *)mem->mem : (void *)0);
return (mem ? mem->mem : NULL);
}
@@ -212,7 +214,9 @@ void *curl_docalloc(size_t wanted_elements, size_t wanted_size,
if(source)
curl_memlog("MEM %s:%d calloc(%zu,%zu) = %p\n",
source, line, wanted_elements, wanted_size, mem?mem->mem:0);
source, line, wanted_elements, wanted_size,
mem ? (void *)mem->mem : (void *)0);
return (mem ? mem->mem : NULL);
}
@@ -234,11 +238,37 @@ char *curl_dostrdup(const char *str, int line, const char *source)
if(source)
curl_memlog("MEM %s:%d strdup(%p) (%zu) = %p\n",
source, line, str, len, mem);
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,
@@ -269,7 +299,8 @@ void *curl_dorealloc(void *ptr, size_t wantedsize,
mem = (Curl_crealloc)(mem, size);
if(source)
curl_memlog("MEM %s:%d realloc(%p, %zu) = %p\n",
source, line, ptr, wantedsize, mem?mem->mem:NULL);
source, line, (void *)ptr, wantedsize,
mem ? (void *)mem->mem : (void *)0);
if(mem) {
mem->size = wantedsize;
@@ -304,7 +335,7 @@ void curl_dofree(void *ptr, int line, const char *source)
(Curl_cfree)(mem);
if(source)
curl_memlog("MEM %s:%d free(%p)\n", source, line, ptr);
curl_memlog("MEM %s:%d free(%p)\n", source, line, (void *)ptr);
}
curl_socket_t curl_socket(int domain, int type, int protocol,
@@ -317,8 +348,10 @@ curl_socket_t curl_socket(int domain, int type, int protocol,
"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;
}
@@ -334,8 +367,10 @@ int curl_socketpair(int domain, int type, int protocol,
"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
@@ -351,9 +386,12 @@ curl_socket_t curl_accept(curl_socket_t s, void *saddr, void *saddrlen,
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;
}
@@ -382,9 +420,11 @@ 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, res);
source, line, file, mode, (void *)res);
return res;
}
@@ -393,9 +433,11 @@ 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, res);
source, line, filedes, mode, (void *)res);
return res;
}
#endif
@@ -407,9 +449,11 @@ int curl_fclose(FILE *file, int line, const char *source)
assert(file != NULL);
res=fclose(file);
if(source)
curl_memlog("FILE %s:%d fclose(%p)\n",
source, line, file);
source, line, (void *)file);
return res;
}

View File

@@ -8,7 +8,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -46,6 +46,11 @@ 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, ...);
@@ -84,6 +89,20 @@ CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
#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
#define socket(domain,type,protocol)\
curl_socket(domain,type,protocol,__LINE__,__FILE__)
#undef accept /* for those with accept as a macro */

View File

@@ -40,7 +40,7 @@ my $url = 'http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/
# If the OpenSSL commandline is not in search path you can configure it here!
my $openssl = 'openssl';
my $version = '1.18';
my $version = '1.19';
$opt_w = 76; # default base64 encoded lines length
@@ -164,7 +164,7 @@ while (<TXT>) {
if ($start_of_cert && /^CKA_LABEL UTF8 \"(.*)\"/) {
$caname = $1;
}
my $untrusted = 0;
my $untrusted = 1;
if ($start_of_cert && /^CKA_VALUE MULTILINE_OCTAL/) {
my $data;
while (<TXT>) {
@@ -184,9 +184,8 @@ while (<TXT>) {
# now scan the trust part for untrusted certs
while (<TXT>) {
last if (/^#/);
if (/^CKA_TRUST_SERVER_AUTH\s+CK_TRUST\s+CKT_NSS_NOT_TRUSTED$/
or /^CKA_TRUST_SERVER_AUTH\s+CK_TRUST\s+CKT_NSS_TRUST_UNKNOWN$/) {
$untrusted = 1;
if (/^CKA_TRUST_SERVER_AUTH\s+CK_TRUST\s+CKT_NSS_TRUSTED_DELEGATOR$/) {
$untrusted = 0;
}
}
if ($untrusted) {

View File

@@ -26,7 +26,7 @@
'* Hacked by Guenter Knauf
'***************************************************************************
Option Explicit
Const myVersion = "0.3.7"
Const myVersion = "0.3.8"
Const myUrl = "http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1"
@@ -130,9 +130,8 @@ For i = 0 To UBound(myLines)
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_NOT_TRUSTED") Or _
InstrRev(myLines(i), "CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUST_UNKNOWN")) Then
myUntrusted = TRUE
If InstrRev(myLines(i), "CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR") Then
myUntrusted = FALSE
End If
Wend
If (myUntrusted = TRUE) Then
@@ -182,7 +181,7 @@ For i = 0 To UBound(myLines)
End If
If InstrRev(myLines(i), "CKA_VALUE MULTILINE_OCTAL") Then
myInsideCert = TRUE
myUntrusted = FALSE
myUntrusted = TRUE
myData = ""
End If
If InstrRev(myLines(i), "***** BEGIN LICENSE BLOCK *****") Then

View File

@@ -380,11 +380,11 @@ static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
break;
case 'x':
vto[i].type = FORMAT_INT;
flags |= FLAGS_HEX;
flags |= FLAGS_HEX|FLAGS_UNSIGNED;
break;
case 'X':
vto[i].type = FORMAT_INT;
flags |= FLAGS_HEX|FLAGS_UPPER;
flags |= FLAGS_HEX|FLAGS_UPPER|FLAGS_UNSIGNED;
break;
case 'c':
vto[i].type = FORMAT_INT;
@@ -633,23 +633,23 @@ static int dprintf_formatf(
OUTCHAR(' ');
break;
}
if(p->flags & FLAGS_UNSIGNED) {
/* Decimal unsigned integer. */
base = 10;
goto unsigned_number;
}
if(p->flags & FLAGS_OCTAL) {
/* Octal unsigned integer. */
base = 8;
goto unsigned_number;
}
if(p->flags & FLAGS_HEX) {
else if(p->flags & FLAGS_HEX) {
/* Hexadecimal unsigned integer. */
digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
base = 16;
goto unsigned_number;
}
else if(p->flags & FLAGS_UNSIGNED) {
/* Decimal unsigned integer. */
base = 10;
goto unsigned_number;
}
/* Decimal integer. */
base = 10;

View File

@@ -68,7 +68,7 @@
((x) && (((struct SessionHandle *)(x))->magic == CURLEASY_MAGIC_NUMBER))
static void singlesocket(struct Curl_multi *multi,
struct Curl_one_easy *easy);
struct SessionHandle *easy);
static int update_timer(struct Curl_multi *multi);
static bool isHandleAtHead(struct SessionHandle *handle,
@@ -105,7 +105,7 @@ static const char * const statename[]={
static void multi_freetimeout(void *a, void *b);
/* always use this function to change state, to make debugging easier */
static void mstate(struct Curl_one_easy *easy, CURLMstate state
static void mstate(struct SessionHandle *easy, CURLMstate state
#ifdef DEBUGBUILD
, int lineno
#endif
@@ -114,29 +114,29 @@ static void mstate(struct Curl_one_easy *easy, CURLMstate state
#ifdef DEBUGBUILD
long connection_id = -5000;
#endif
CURLMstate oldstate = easy->state;
CURLMstate oldstate = easy->mstate;
if(oldstate == state)
/* don't bother when the new state is the same as the old state */
return;
easy->state = state;
easy->mstate = state;
#ifdef DEBUGBUILD
if(easy->state >= CURLM_STATE_CONNECT_PEND &&
easy->state < CURLM_STATE_COMPLETED) {
if(easy->mstate >= CURLM_STATE_CONNECT_PEND &&
easy->mstate < CURLM_STATE_COMPLETED) {
if(easy->easy_conn)
connection_id = easy->easy_conn->connection_id;
infof(easy->easy_handle,
infof(easy,
"STATE: %s => %s handle %p; line %d (connection #%ld) \n",
statename[oldstate], statename[easy->state],
(char *)easy, lineno, connection_id);
statename[oldstate], statename[easy->mstate],
(void *)easy, lineno, connection_id);
}
#endif
if(state == CURLM_STATE_COMPLETED)
/* changing to COMPLETED means there's one less easy handle 'alive' */
easy->easy_handle->multi->num_alive--;
easy->multi->num_alive--;
}
#ifndef DEBUGBUILD
@@ -307,12 +307,6 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
if(!multi->msglist)
goto error;
/* Let's make the doubly-linked list a circular list. This makes
the linked list code simpler and allows inserting at the end
with less work (we didn't keep a tail pointer before). */
multi->easy.next = &multi->easy;
multi->easy.prev = &multi->easy;
multi->max_pipeline_length = 5;
return (CURLM *) multi;
@@ -340,7 +334,6 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
CURL *easy_handle)
{
struct curl_llist *timeoutlist;
struct Curl_one_easy *easy;
struct Curl_multi *multi = (struct Curl_multi *)multi_handle;
struct SessionHandle *data = (struct SessionHandle *)easy_handle;
struct SessionHandle *new_closure = NULL;
@@ -354,8 +347,8 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
if(!GOOD_EASY_HANDLE(easy_handle))
return CURLM_BAD_EASY_HANDLE;
/* Prevent users from adding same easy handle more than
once and prevent adding to more than one multi stack */
/* Prevent users from adding same easy handle more than once and prevent
adding to more than one multi stack */
if(data->multi)
/* possibly we should create a new unique error code for this condition */
return CURLM_BAD_EASY_HANDLE;
@@ -365,19 +358,11 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
if(!timeoutlist)
return CURLM_OUT_OF_MEMORY;
/* Allocate new node for the doubly-linked circular list of
Curl_one_easy structs that holds pointers to easy handles */
easy = calloc(1, sizeof(struct Curl_one_easy));
if(!easy) {
Curl_llist_destroy(timeoutlist, NULL);
return CURLM_OUT_OF_MEMORY;
}
/* In case multi handle has no hostcache yet, allocate one */
if(!multi->hostcache) {
hostcache = Curl_mk_dnscache();
if(!hostcache) {
free(easy);
free(data);
Curl_llist_destroy(timeoutlist, NULL);
return CURLM_OUT_OF_MEMORY;
}
@@ -389,7 +374,7 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
new_closure = (struct SessionHandle *)curl_easy_init();
if(!new_closure) {
Curl_hash_destroy(hostcache);
free(easy);
free(data);
Curl_llist_destroy(timeoutlist, NULL);
return CURLM_OUT_OF_MEMORY;
}
@@ -420,44 +405,51 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
timeoutlist = NULL;
/* set the easy handle */
easy->easy_handle = data;
multistate(easy, CURLM_STATE_INIT);
/* set the back pointer to one_easy to assist in removal */
easy->easy_handle->multi_pos = easy;
multistate(data, CURLM_STATE_INIT);
if((data->set.global_dns_cache) &&
(data->dns.hostcachetype != HCACHE_GLOBAL)) {
/* global dns cache was requested but still isn't */
struct curl_hash *global = Curl_global_host_cache_init();
if(global) {
/* only do this if the global cache init works */
data->dns.hostcache = global;
data->dns.hostcachetype = HCACHE_GLOBAL;
}
}
/* for multi interface connections, we share DNS cache automatically if the
easy handle's one is currently not set. */
if(!easy->easy_handle->dns.hostcache ||
(easy->easy_handle->dns.hostcachetype == HCACHE_NONE)) {
easy->easy_handle->dns.hostcache = multi->hostcache;
easy->easy_handle->dns.hostcachetype = HCACHE_MULTI;
else if(!data->dns.hostcache ||
(data->dns.hostcachetype == HCACHE_NONE)) {
data->dns.hostcache = multi->hostcache;
data->dns.hostcachetype = HCACHE_MULTI;
}
/* Point to the multi's connection cache */
easy->easy_handle->state.conn_cache = multi->conn_cache;
data->state.conn_cache = multi->conn_cache;
/* This adds the new entry at the 'end' of the doubly-linked circular
list of Curl_one_easy structs to try and maintain a FIFO queue so
list of SessionHandle structs to try and maintain a FIFO queue so
the pipelined requests are in order. */
/* We add this new entry last in the list. We make our 'next' point to the
'first' struct and our 'prev' point to the previous 'prev' */
easy->next = &multi->easy;
easy->prev = multi->easy.prev;
/* We add this new entry last in the list. */
/* make 'easy' the last node in the chain */
multi->easy.prev = easy;
/* if there was a prev node, make sure its 'next' pointer links to
the new node */
easy->prev->next = easy;
data->next = NULL; /* end of the line */
if(multi->easyp) {
struct SessionHandle *last = multi->easylp;
last->next = data;
data->prev = last;
multi->easylp = data; /* the new last node */
}
else {
/* first node, make both prev and next be NULL! */
data->next = NULL;
data->prev = NULL;
multi->easylp = multi->easyp = data; /* both first and last */
}
/* make the SessionHandle refer back to this multi handle */
Curl_easy_addmulti(easy_handle, multi_handle);
/* make the SessionHandle struct refer back to this struct */
easy->easy_handle->set.one_easy = easy;
Curl_easy_addmulti(data, multi_handle);
/* Set the timeout for this handle to expire really soon so that it will
be taken care of even when this handle is added in the midst of operation
@@ -465,7 +457,7 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
sockets that time-out or have actions will be dealt with. Since this
handle has no action yet, we make sure it times out to get things to
happen. */
Curl_expire(easy->easy_handle, 1);
Curl_expire(data, 1);
/* increase the node-counter */
multi->num_easy++;
@@ -509,8 +501,8 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
CURL *curl_handle)
{
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
struct Curl_one_easy *easy;
struct SessionHandle *data = curl_handle;
struct SessionHandle *easy = curl_handle;
struct SessionHandle *data = easy;
/* First, make some basic checks that the CURLM handle is a good handle */
if(!GOOD_MULTI_HANDLE(multi))
@@ -520,13 +512,10 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
if(!GOOD_EASY_HANDLE(curl_handle))
return CURLM_BAD_EASY_HANDLE;
/* pick-up from the 'curl_handle' the kept position in the list */
easy = data->multi_pos;
if(easy) {
bool premature = (easy->state < CURLM_STATE_COMPLETED) ? TRUE : FALSE;
bool premature = (easy->mstate < CURLM_STATE_COMPLETED) ? TRUE : FALSE;
bool easy_owns_conn = (easy->easy_conn &&
(easy->easy_conn->data == easy->easy_handle)) ?
(easy->easy_conn->data == easy)) ?
TRUE : FALSE;
/* If the 'state' is not INIT or COMPLETED, we might need to do something
@@ -539,21 +528,21 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
if(easy->easy_conn &&
(easy->easy_conn->send_pipe->size +
easy->easy_conn->recv_pipe->size > 1) &&
easy->state > CURLM_STATE_WAITDO &&
easy->state < CURLM_STATE_COMPLETED) {
easy->mstate > CURLM_STATE_WAITDO &&
easy->mstate < CURLM_STATE_COMPLETED) {
/* If the handle is in a pipeline and has started sending off its
request but not received its response yet, we need to close
connection. */
easy->easy_conn->bits.close = TRUE;
/* Set connection owner so that Curl_done() closes it.
We can sefely do this here since connection is killed. */
easy->easy_conn->data = easy->easy_handle;
easy->easy_conn->data = easy;
}
/* The timer must be shut down before easy->multi is set to NULL,
else the timenode will remain in the splay tree after
curl_easy_cleanup is called. */
Curl_expire(easy->easy_handle, 0);
Curl_expire(easy, 0);
/* destroy the timeout list that is held in the easy handle */
if(data->state.timeoutlist) {
@@ -561,10 +550,10 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
data->state.timeoutlist = NULL;
}
if(easy->easy_handle->dns.hostcachetype == HCACHE_MULTI) {
if(easy->dns.hostcachetype == HCACHE_MULTI) {
/* stop using the multi handle's DNS cache */
easy->easy_handle->dns.hostcache = NULL;
easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
easy->dns.hostcache = NULL;
easy->dns.hostcachetype = HCACHE_NONE;
}
if(easy->easy_conn) {
@@ -582,16 +571,16 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
}
else
/* Clear connection pipelines, if Curl_done above was not called */
Curl_getoff_all_pipelines(easy->easy_handle, easy->easy_conn);
Curl_getoff_all_pipelines(easy, easy->easy_conn);
}
/* as this was using a shared connection cache we clear the pointer
to that since we're not part of that multi handle anymore */
easy->easy_handle->state.conn_cache = NULL;
easy->state.conn_cache = NULL;
/* change state without using multistate(), only to make singlesocket() do
what we want */
easy->state = CURLM_STATE_COMPLETED;
easy->mstate = CURLM_STATE_COMPLETED;
singlesocket(multi, easy); /* to let the application know what sockets
that vanish with this handle */
@@ -601,7 +590,7 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
easy->easy_conn = NULL;
}
Curl_easy_addmulti(easy->easy_handle, NULL); /* clear the association
Curl_easy_addmulti(easy, NULL); /* clear the association
to this multi handle */
{
@@ -612,7 +601,7 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
for(e = multi->msglist->head; e; e = e->next) {
struct Curl_message *msg = e->ptr;
if(msg->extmsg.easy_handle == easy->easy_handle) {
if(msg->extmsg.easy_handle == easy) {
Curl_llist_remove(multi->msglist, e, NULL);
/* there can only be one from this specific handle */
break;
@@ -623,18 +612,17 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
/* make the previous node point to our next */
if(easy->prev)
easy->prev->next = easy->next;
else
multi->easyp = easy->next; /* point to first node */
/* make our next point to our previous node */
if(easy->next)
easy->next->prev = easy->prev;
easy->easy_handle->set.one_easy = NULL; /* detached */
/* Null the position in the controlling structure */
easy->easy_handle->multi_pos = NULL;
else
multi->easylp = easy->prev; /* point to last node */
/* NOTE NOTE NOTE
We do not touch the easy handle here! */
free(easy);
multi->num_easy--; /* one less to care about now */
@@ -652,10 +640,7 @@ bool Curl_multi_pipeline_enabled(const struct Curl_multi *multi)
void Curl_multi_handlePipeBreak(struct SessionHandle *data)
{
struct Curl_one_easy *one_easy = data->set.one_easy;
if(one_easy)
one_easy->easy_conn = NULL;
data->easy_conn = NULL;
}
static int waitconnect_getsock(struct connectdata *conn,
@@ -685,7 +670,7 @@ static int domore_getsock(struct connectdata *conn,
}
/* returns bitmapped flags for this handle and its sockets */
static int multi_getsock(struct Curl_one_easy *easy,
static int multi_getsock(struct SessionHandle *easy,
curl_socket_t *socks, /* points to numsocks number
of sockets */
int numsocks)
@@ -695,16 +680,16 @@ static int multi_getsock(struct Curl_one_easy *easy,
happen when this is called from curl_multi_remove_handle() =>
singlesocket() => multi_getsock().
*/
if(easy->easy_handle->state.pipe_broke || !easy->easy_conn)
if(easy->state.pipe_broke || !easy->easy_conn)
return 0;
if(easy->state > CURLM_STATE_CONNECT &&
easy->state < CURLM_STATE_COMPLETED) {
if(easy->mstate > CURLM_STATE_CONNECT &&
easy->mstate < CURLM_STATE_COMPLETED) {
/* Set up ownership correctly */
easy->easy_conn->data = easy->easy_handle;
easy->easy_conn->data = easy;
}
switch(easy->state) {
switch(easy->mstate) {
default:
#if 0 /* switch back on these cases to get the compiler to check for all enums
to be present */
@@ -756,7 +741,7 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
Some easy handles may not have connected to the remote host yet,
and then we must make sure that is done. */
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
struct Curl_one_easy *easy;
struct SessionHandle *easy;
int this_max_fd=-1;
curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
int bitmap;
@@ -766,8 +751,8 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
if(!GOOD_MULTI_HANDLE(multi))
return CURLM_BAD_HANDLE;
easy=multi->easy.next;
while(easy != &multi->easy) {
easy=multi->easyp;
while(easy) {
bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE);
for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
@@ -805,7 +790,7 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
int *ret)
{
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
struct Curl_one_easy *easy;
struct SessionHandle *easy;
curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
int bitmap;
unsigned int i;
@@ -825,8 +810,8 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
timeout_ms = (int)timeout_internal;
/* Count up how many fds we have from the multi handle */
easy=multi->easy.next;
while(easy != &multi->easy) {
easy=multi->easyp;
while(easy) {
bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE);
for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
@@ -863,8 +848,8 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
if(curlfds) {
/* Add the curl handles to our pollfds first */
easy=multi->easy.next;
while(easy != &multi->easy) {
easy=multi->easyp;
while(easy) {
bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE);
for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
@@ -904,9 +889,30 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
++nfds;
}
if(nfds)
if(nfds) {
/* wait... */
i = Curl_poll(ufds, nfds, timeout_ms);
if(i) {
unsigned int j;
/* copy revents results from the poll to the curl_multi_wait poll
struct, the bit values of the actual underlying poll() implementation
may not be the same as the ones in the public libcurl API! */
for(j = 0; j < extra_nfds; j++) {
unsigned short mask = 0;
unsigned r = ufds[curlfds + j].revents;
if(r & POLLIN)
mask |= CURL_WAIT_POLLIN;
if(r & POLLOUT)
mask |= CURL_WAIT_POLLOUT;
if(r & POLLPRI)
mask |= CURL_WAIT_POLLPRI;
extra_fds[j].revents = mask;
}
}
}
else
i = 0;
@@ -918,7 +924,7 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
static CURLMcode multi_runsingle(struct Curl_multi *multi,
struct timeval now,
struct Curl_one_easy *easy)
struct SessionHandle *easy)
{
struct Curl_message *msg = NULL;
bool connected;
@@ -930,11 +936,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
struct SingleRequest *k;
struct SessionHandle *data;
long timeout_ms;
int control;
if(!GOOD_EASY_HANDLE(easy->easy_handle))
if(!GOOD_EASY_HANDLE(easy))
return CURLM_BAD_EASY_HANDLE;
data = easy->easy_handle;
data = easy;
do {
/* this is a single-iteration do-while loop just to allow a
@@ -945,9 +952,9 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
we're using gets cleaned up and we're left with nothing. */
if(data->state.pipe_broke) {
infof(data, "Pipe broke: handle 0x%p, url = %s\n",
easy, data->state.path);
(void *)easy, data->state.path);
if(easy->state < CURLM_STATE_COMPLETED) {
if(easy->mstate < CURLM_STATE_COMPLETED) {
/* Head back to the CONNECT state */
multistate(easy, CURLM_STATE_CONNECT);
result = CURLM_CALL_MULTI_PERFORM;
@@ -960,36 +967,36 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
}
if(!easy->easy_conn &&
easy->state > CURLM_STATE_CONNECT &&
easy->state < CURLM_STATE_DONE) {
easy->mstate > CURLM_STATE_CONNECT &&
easy->mstate < CURLM_STATE_DONE) {
/* In all these states, the code will blindly access 'easy->easy_conn'
so this is precaution that it isn't NULL. And it silences static
analyzers. */
failf(data, "In state %d with no easy_conn, bail out!\n", easy->state);
failf(data, "In state %d with no easy_conn, bail out!\n", easy->mstate);
return CURLM_INTERNAL_ERROR;
}
if(easy->easy_conn && easy->state > CURLM_STATE_CONNECT &&
easy->state < CURLM_STATE_COMPLETED)
if(easy->easy_conn && easy->mstate > CURLM_STATE_CONNECT &&
easy->mstate < CURLM_STATE_COMPLETED)
/* Make sure we set the connection's current owner */
easy->easy_conn->data = data;
if(easy->easy_conn &&
(easy->state >= CURLM_STATE_CONNECT) &&
(easy->state < CURLM_STATE_COMPLETED)) {
(easy->mstate >= CURLM_STATE_CONNECT) &&
(easy->mstate < CURLM_STATE_COMPLETED)) {
/* we need to wait for the connect state as only then is the start time
stored, but we must not check already completed handles */
timeout_ms = Curl_timeleft(data, &now,
(easy->state <= CURLM_STATE_WAITDO)?
(easy->mstate <= CURLM_STATE_WAITDO)?
TRUE:FALSE);
if(timeout_ms < 0) {
/* Handle timed out */
if(easy->state == CURLM_STATE_WAITRESOLVE)
if(easy->mstate == CURLM_STATE_WAITRESOLVE)
failf(data, "Resolving timed out after %ld milliseconds",
Curl_tvdiff(now, data->progress.t_startsingle));
else if(easy->state == CURLM_STATE_WAITCONNECT)
else if(easy->mstate == CURLM_STATE_WAITCONNECT)
failf(data, "Connection timed out after %ld milliseconds",
Curl_tvdiff(now, data->progress.t_startsingle));
else {
@@ -1010,7 +1017,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
}
}
switch(easy->state) {
switch(easy->mstate) {
case CURLM_STATE_INIT:
/* init this transfer. */
easy->result=Curl_pretransfer(data);
@@ -1210,12 +1217,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
case CURLM_STATE_WAITDO:
/* Wait for our turn to DO when we're pipelining requests */
#ifdef DEBUGBUILD
infof(data, "WAITDO: Conn %ld send pipe %zu inuse %d athead %d\n",
infof(data, "WAITDO: Conn %ld send pipe %zu inuse %s athead %s\n",
easy->easy_conn->connection_id,
easy->easy_conn->send_pipe->size,
easy->easy_conn->writechannel_inuse?1:0,
easy->easy_conn->writechannel_inuse?"TRUE":"FALSE",
isHandleAtHead(data,
easy->easy_conn->send_pipe)?1:0);
easy->easy_conn->send_pipe)?"TRUE":"FALSE");
#endif
if(!easy->easy_conn->writechannel_inuse &&
isHandleAtHead(data,
@@ -1360,13 +1367,17 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/*
* When we are connected, DO MORE and then go DO_DONE
*/
easy->result = Curl_do_more(easy->easy_conn, &dophase_done);
easy->result = Curl_do_more(easy->easy_conn, &control);
/* No need to remove this handle from the send pipeline here since that
is done in Curl_done() */
if(CURLE_OK == easy->result) {
if(dophase_done) {
multistate(easy, CURLM_STATE_DO_DONE);
if(control) {
/* if positive, advance to DO_DONE
if negative, go back to DOING */
multistate(easy, control==1?
CURLM_STATE_DO_DONE:
CURLM_STATE_DOING);
result = CURLM_CALL_MULTI_PERFORM;
}
else
@@ -1402,12 +1413,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
}
#ifdef DEBUGBUILD
else {
infof(data, "WAITPERFORM: Conn %ld recv pipe %zu inuse %d athead %d\n",
infof(data, "WAITPERFORM: Conn %ld recv pipe %zu inuse %s athead %s\n",
easy->easy_conn->connection_id,
easy->easy_conn->recv_pipe->size,
easy->easy_conn->readchannel_inuse?1:0,
easy->easy_conn->readchannel_inuse?"TRUE":"FALSE",
isHandleAtHead(data,
easy->easy_conn->recv_pipe)?1:0);
easy->easy_conn->recv_pipe)?"TRUE":"FALSE");
}
#endif
break;
@@ -1641,7 +1652,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
return CURLM_INTERNAL_ERROR;
}
if(easy->state < CURLM_STATE_COMPLETED) {
if(easy->mstate < CURLM_STATE_COMPLETED) {
if(CURLE_OK != easy->result) {
/*
* If an error was returned, and we aren't in completed state now,
@@ -1674,7 +1685,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
easy->easy_conn = NULL;
}
}
else if(easy->state == CURLM_STATE_CONNECT) {
else if(easy->mstate == CURLM_STATE_CONNECT) {
/* Curl_connect() failed */
(void)Curl_posttransfer(data);
}
@@ -1688,14 +1699,14 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
easy->easy_conn->bits.close = TRUE;
/* if not yet in DONE state, go there, otherwise COMPLETED */
multistate(easy, (easy->state < CURLM_STATE_DONE)?
multistate(easy, (easy->mstate < CURLM_STATE_DONE)?
CURLM_STATE_DONE: CURLM_STATE_COMPLETED);
result = CURLM_CALL_MULTI_PERFORM;
}
}
} WHILE_FALSE; /* just to break out from! */
if(CURLM_STATE_COMPLETED == easy->state) {
if(CURLM_STATE_COMPLETED == easy->mstate) {
/* now fill in the Curl_message with this info */
msg = &easy->msg;
@@ -1715,7 +1726,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
{
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
struct Curl_one_easy *easy;
struct SessionHandle *easy;
CURLMcode returncode=CURLM_OK;
struct Curl_tree *t;
struct timeval now = Curl_tvnow();
@@ -1723,12 +1734,12 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
if(!GOOD_MULTI_HANDLE(multi))
return CURLM_BAD_HANDLE;
easy=multi->easy.next;
while(easy != &multi->easy) {
easy=multi->easyp;
while(easy) {
CURLMcode result;
struct WildcardData *wc = &easy->easy_handle->wildcard;
struct WildcardData *wc = &easy->wildcard;
if(easy->easy_handle->set.wildcardmatch) {
if(easy->set.wildcardmatch) {
if(!wc->filelist) {
CURLcode ret = Curl_wildcard_init(wc); /* init wildcard structures */
if(ret)
@@ -1740,7 +1751,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
result = multi_runsingle(multi, now, easy);
while(CURLM_CALL_MULTI_PERFORM == result);
if(easy->easy_handle->set.wildcardmatch) {
if(easy->set.wildcardmatch) {
/* destruct wildcard structures if it is needed */
if(wc->state == CURLWC_DONE || result)
Curl_wildcard_dtor(wc);
@@ -1796,8 +1807,8 @@ static void close_all_connections(struct Curl_multi *multi)
CURLMcode curl_multi_cleanup(CURLM *multi_handle)
{
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
struct Curl_one_easy *easy;
struct Curl_one_easy *nexteasy;
struct SessionHandle *easy;
struct SessionHandle *nexteasy;
if(GOOD_MULTI_HANDLE(multi)) {
multi->type = 0; /* not good anymore */
@@ -1807,7 +1818,8 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
if(multi->closure_handle) {
multi->closure_handle->dns.hostcache = multi->hostcache;
Curl_hostcache_clean(multi->closure_handle);
Curl_hostcache_clean(multi->closure_handle,
multi->closure_handle->dns.hostcache);
Curl_close(multi->closure_handle);
multi->closure_handle = NULL;
@@ -1824,22 +1836,21 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
multi->msglist = NULL;
/* remove all easy handles */
easy = multi->easy.next;
while(easy != &multi->easy) {
easy = multi->easyp;
while(easy) {
nexteasy=easy->next;
if(easy->easy_handle->dns.hostcachetype == HCACHE_MULTI) {
if(easy->dns.hostcachetype == HCACHE_MULTI) {
/* clear out the usage of the shared DNS cache */
Curl_hostcache_clean(easy->easy_handle);
easy->easy_handle->dns.hostcache = NULL;
easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
Curl_hostcache_clean(easy, easy->dns.hostcache);
easy->dns.hostcache = NULL;
easy->dns.hostcachetype = HCACHE_NONE;
}
/* Clear the pointer to the connection cache */
easy->easy_handle->state.conn_cache = NULL;
easy->state.conn_cache = NULL;
Curl_easy_addmulti(easy->easy_handle, NULL); /* clear the association */
Curl_easy_addmulti(easy, NULL); /* clear the association */
free(easy);
easy = nexteasy;
}
@@ -1901,7 +1912,7 @@ CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue)
* call the callback accordingly.
*/
static void singlesocket(struct Curl_multi *multi,
struct Curl_one_easy *easy)
struct SessionHandle *easy)
{
curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
int i;
@@ -1909,7 +1920,6 @@ static void singlesocket(struct Curl_multi *multi,
curl_socket_t s;
int num;
unsigned int curraction;
struct Curl_one_easy *easy_by_hash;
bool remove_sock_from_hash;
for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++)
@@ -1947,7 +1957,7 @@ static void singlesocket(struct Curl_multi *multi,
}
else {
/* this is a socket we didn't have before, add it! */
entry = sh_addentry(multi->sockhash, s, easy->easy_handle);
entry = sh_addentry(multi->sockhash, s, easy);
if(!entry)
/* fatal */
return;
@@ -1955,7 +1965,7 @@ static void singlesocket(struct Curl_multi *multi,
/* we know (entry != NULL) at this point, see the logic above */
if(multi->socket_cb)
multi->socket_cb(easy->easy_handle,
multi->socket_cb(easy,
s,
action,
multi->socket_userp,
@@ -1988,10 +1998,7 @@ static void singlesocket(struct Curl_multi *multi,
/* check if the socket to be removed serves a connection which has
other easy-s in a pipeline. In this case the socket should not be
removed. */
struct connectdata *easy_conn;
easy_by_hash = entry->easy->multi_pos;
easy_conn = easy_by_hash->easy_conn;
struct connectdata *easy_conn = easy->easy_conn;
if(easy_conn) {
if(easy_conn->recv_pipe && easy_conn->recv_pipe->size > 1) {
/* the handle should not be removed from the pipe yet */
@@ -2000,8 +2007,8 @@ static void singlesocket(struct Curl_multi *multi,
/* Update the sockhash entry to instead point to the next in line
for the recv_pipe, or the first (in case this particular easy
isn't already) */
if(entry->easy == easy->easy_handle) {
if(isHandleAtHead(easy->easy_handle, easy_conn->recv_pipe))
if(entry->easy == easy) {
if(isHandleAtHead(easy, easy_conn->recv_pipe))
entry->easy = easy_conn->recv_pipe->head->next->ptr;
else
entry->easy = easy_conn->recv_pipe->head->ptr;
@@ -2014,8 +2021,8 @@ static void singlesocket(struct Curl_multi *multi,
/* Update the sockhash entry to instead point to the next in line
for the send_pipe, or the first (in case this particular easy
isn't already) */
if(entry->easy == easy->easy_handle) {
if(isHandleAtHead(easy->easy_handle, easy_conn->send_pipe))
if(entry->easy == easy) {
if(isHandleAtHead(easy, easy_conn->send_pipe))
entry->easy = easy_conn->send_pipe->head->next->ptr;
else
entry->easy = easy_conn->send_pipe->head->ptr;
@@ -2036,7 +2043,7 @@ static void singlesocket(struct Curl_multi *multi,
if(remove_sock_from_hash) {
/* in this case 'entry' is always non-NULL */
if(multi->socket_cb)
multi->socket_cb(easy->easy_handle,
multi->socket_cb(easy,
s,
CURL_POLL_REMOVE,
multi->socket_userp,
@@ -2157,16 +2164,16 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
struct timeval now = Curl_tvnow();
if(checkall) {
struct Curl_one_easy *easyp;
struct SessionHandle *easy;
/* *perform() deals with running_handles on its own */
result = curl_multi_perform(multi, running_handles);
/* walk through each easy handle and do the socket state change magic
and callbacks */
easyp=multi->easy.next;
while(easyp != &multi->easy) {
singlesocket(multi, easyp);
easyp = easyp->next;
easy=multi->easyp;
while(easy) {
singlesocket(multi, easy);
easy = easy->next;
}
/* or should we fall-through and do the timer-based stuff? */
@@ -2194,35 +2201,35 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
/* If the pipeline is enabled, take the handle which is in the head of
the pipeline. If we should write into the socket, take the send_pipe
head. If we should read from the socket, take the recv_pipe head. */
if(data->set.one_easy->easy_conn) {
if(data->easy_conn) {
if((ev_bitmask & CURL_POLL_OUT) &&
data->set.one_easy->easy_conn->send_pipe &&
data->set.one_easy->easy_conn->send_pipe->head)
data = data->set.one_easy->easy_conn->send_pipe->head->ptr;
data->easy_conn->send_pipe &&
data->easy_conn->send_pipe->head)
data = data->easy_conn->send_pipe->head->ptr;
else if((ev_bitmask & CURL_POLL_IN) &&
data->set.one_easy->easy_conn->recv_pipe &&
data->set.one_easy->easy_conn->recv_pipe->head)
data = data->set.one_easy->easy_conn->recv_pipe->head->ptr;
data->easy_conn->recv_pipe &&
data->easy_conn->recv_pipe->head)
data = data->easy_conn->recv_pipe->head->ptr;
}
if(data->set.one_easy->easy_conn &&
!(data->set.one_easy->easy_conn->handler->flags & PROTOPT_DIRLOCK))
if(data->easy_conn &&
!(data->easy_conn->handler->flags & PROTOPT_DIRLOCK))
/* set socket event bitmask if they're not locked */
data->set.one_easy->easy_conn->cselect_bits = ev_bitmask;
data->easy_conn->cselect_bits = ev_bitmask;
do
result = multi_runsingle(multi, now, data->set.one_easy);
result = multi_runsingle(multi, now, data);
while(CURLM_CALL_MULTI_PERFORM == result);
if(data->set.one_easy->easy_conn &&
!(data->set.one_easy->easy_conn->handler->flags & PROTOPT_DIRLOCK))
if(data->easy_conn &&
!(data->easy_conn->handler->flags & PROTOPT_DIRLOCK))
/* clear the bitmask only if not locked */
data->set.one_easy->easy_conn->cselect_bits = 0;
data->easy_conn->cselect_bits = 0;
if(CURLM_OK >= result)
/* get the socket(s) and check if the state has been changed since
last */
singlesocket(multi, data->set.one_easy);
singlesocket(multi, data);
/* Now we fall-through and do the timer-based stuff, since we don't want
to force the user to have to deal with timeouts as long as at least
@@ -2266,13 +2273,13 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
/* the first loop lap 'data' can be NULL */
if(data) {
do
result = multi_runsingle(multi, now, data->set.one_easy);
result = multi_runsingle(multi, now, data);
while(CURLM_CALL_MULTI_PERFORM == result);
if(CURLM_OK >= result)
/* get the socket(s) and check if the state has been changed since
last */
singlesocket(multi, data->set.one_easy);
singlesocket(multi, data);
}
/* Check if there's one (more) expired timer to deal with! This function
@@ -2472,7 +2479,7 @@ static int update_timer(struct Curl_multi *multi)
void Curl_multi_set_easy_connection(struct SessionHandle *handle,
struct connectdata *conn)
{
handle->set.one_easy->easy_conn = conn;
handle->easy_conn = conn;
}
static bool isHandleAtHead(struct SessionHandle *handle,
@@ -2560,8 +2567,8 @@ void Curl_expire(struct SessionHandle *data, long milli)
struct timeval *nowp = &data->state.expiretime;
int rc;
/* this is only interesting for multi-interface using libcurl, and only
while there is still a multi interface struct remaining! */
/* this is only interesting while there is still an associated multi struct
remaining! */
if(!multi)
return;
@@ -2691,14 +2698,14 @@ struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi)
void Curl_multi_process_pending_handles(struct Curl_multi *multi)
{
struct Curl_one_easy *easy;
struct SessionHandle *easy;
easy=multi->easy.next;
while(easy != &multi->easy) {
if(easy->state == CURLM_STATE_CONNECT_PEND) {
easy=multi->easyp;
while(easy) {
if(easy->mstate == CURLM_STATE_CONNECT_PEND) {
multistate(easy, CURLM_STATE_CONNECT);
/* Make sure that the handle will be processed soonish. */
Curl_expire(easy->easy_handle, 1);
Curl_expire(easy, 1);
}
easy = easy->next; /* operate on next handle */
}
@@ -2708,16 +2715,16 @@ void Curl_multi_process_pending_handles(struct Curl_multi *multi)
void Curl_multi_dump(const struct Curl_multi *multi_handle)
{
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
struct Curl_one_easy *easy;
struct SessionHandle *easy;
int i;
fprintf(stderr, "* Multi status: %d handles, %d alive\n",
multi->num_easy, multi->num_alive);
for(easy=multi->easy.next; easy != &multi->easy; easy = easy->next) {
if(easy->state < CURLM_STATE_COMPLETED) {
for(easy=multi->easyp; easy; easy = easy->next) {
if(easy->mstate < CURLM_STATE_COMPLETED) {
/* only display handles that are not completed */
fprintf(stderr, "handle %p, state %s, %d sockets\n",
(void *)easy->easy_handle,
statename[easy->state], easy->numsocks);
(void *)easy,
statename[easy->mstate], easy->numsocks);
for(i=0; i < easy->numsocks; i++) {
curl_socket_t s = easy->sockets[i];
struct Curl_sh_entry *entry =

View File

@@ -59,27 +59,6 @@ typedef enum {
#define GETSOCK_READABLE (0x00ff)
#define GETSOCK_WRITABLE (0xff00)
struct Curl_one_easy {
/* first, two fields for the linked list of these */
struct Curl_one_easy *next;
struct Curl_one_easy *prev;
struct SessionHandle *easy_handle; /* the easy handle for this unit */
struct connectdata *easy_conn; /* the "unit's" connection */
CURLMstate state; /* the handle's state */
CURLcode result; /* previous result */
struct Curl_message msg; /* A single posted message. */
/* Array with the plain socket numbers this handle takes care of, in no
particular order. Note that all sockets are added to the sockhash, where
the state etc are also kept. This array is mostly used to detect when a
socket is to be removed from the hash. See singlesocket(). */
curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE];
int numsocks;
};
/* 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
@@ -87,7 +66,8 @@ struct Curl_multi {
long type;
/* We have a doubly-linked circular list with easy handles */
struct Curl_one_easy easy;
struct SessionHandle *easyp;
struct SessionHandle *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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -60,6 +60,10 @@ void Curl_nss_md5sum(unsigned char *tmp, /* input */
unsigned char *md5sum, /* output */
size_t md5len);
/* this backend provides these functions: */
#define have_curlssl_random 1
#define have_curlssl_md5sum 1
/* API setup for NSS */
#define curlssl_init Curl_nss_init
#define curlssl_cleanup Curl_nss_cleanup

View File

@@ -6,6 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se>
* 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
@@ -84,9 +85,10 @@ bool Curl_pipeline_penalized(struct SessionHandle *data,
(curl_off_t)conn->chunk.datasize > chunk_penalty_size)
penalized = TRUE;
infof(data, "Conn: %d (%p) Receive pipe weight: (%d/%d), penalized: %d\n",
conn->connection_id, conn, recv_size,
conn->chunk.datasize, penalized);
infof(data, "Conn: %ld (%p) Receive pipe weight: (%" FORMAT_OFF_T
"/%zu), penalized: %s\n",
conn->connection_id, (void *)conn, recv_size,
conn->chunk.datasize, penalized?"TRUE":"FALSE");
return penalized;
}
return FALSE;
@@ -101,7 +103,7 @@ CURLcode Curl_add_handle_to_pipeline(struct SessionHandle *handle,
pipeline = conn->send_pipe;
infof(conn->data, "Adding handle: conn: %p\n", conn);
infof(conn->data, "Adding handle: conn: %p\n", (void *)conn);
infof(conn->data, "Adding handle: send: %d\n", conn->send_pipe->size);
infof(conn->data, "Adding handle: recv: %d\n", conn->recv_pipe->size);
rc = Curl_addHandleToPipeline(handle, pipeline);
@@ -111,7 +113,7 @@ CURLcode Curl_add_handle_to_pipeline(struct SessionHandle *handle,
conn->writechannel_inuse = FALSE; /* not in use yet */
#ifdef DEBUGBUILD
infof(conn->data, "%p is at send pipe head!\n",
conn->send_pipe->head->ptr);
(void *)conn->send_pipe->head->ptr);
#endif
Curl_expire(conn->send_pipe->head->ptr, 1);
}
@@ -144,7 +146,7 @@ void Curl_move_handle_from_send_to_recv_pipe(struct SessionHandle *handle,
conn->writechannel_inuse = FALSE; /* not used now */
#ifdef DEBUGBUILD
infof(conn->data, "%p is at send pipe head B!\n",
conn->send_pipe->head->ptr);
(void *)conn->send_pipe->head->ptr);
#endif
Curl_expire(conn->send_pipe->head->ptr, 1);
}
@@ -320,9 +322,9 @@ void print_pipeline(struct connectdata *conn)
curr = cb_ptr->conn_list->head;
while(curr) {
conn = curr->ptr;
infof(data, "- Conn %d (%p) send_pipe: %d, recv_pipe: %d\n",
infof(data, "- Conn %ld (%p) send_pipe: %zu, recv_pipe: %zu\n",
conn->connection_id,
conn,
(void *)conn,
conn->send_pipe->size,
conn->recv_pipe->size);
curr = curr->next;

View File

@@ -382,7 +382,7 @@ static void state(struct connectdata *conn, pop3state newstate)
if(pop3c->state != newstate)
infof(conn->data, "POP3 %p state change from %s to %s\n",
pop3c, names[pop3c->state], names[newstate]);
(void *)pop3c, names[pop3c->state], names[newstate]);
#endif
pop3c->state = newstate;
@@ -405,7 +405,7 @@ static CURLcode pop3_perform_capa(struct connectdata *conn)
pop3c->tls_supported = FALSE; /* Clear the TLS capability */
/* Send the CAPA command */
result = Curl_pp_sendf(&pop3c->pp, "CAPA");
result = Curl_pp_sendf(&pop3c->pp, "%s", "CAPA");
if(!result)
state(conn, POP3_CAPA);
@@ -424,7 +424,7 @@ static CURLcode pop3_perform_starttls(struct connectdata *conn)
CURLcode result = CURLE_OK;
/* Send the STLS command */
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "STLS");
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "STLS");
if(!result)
state(conn, POP3_STARTTLS);
@@ -693,7 +693,7 @@ static CURLcode pop3_perform_command(struct connectdata *conn)
(pop3->custom && pop3->custom[0] != '\0' ?
pop3->custom : command), pop3->id);
else
result = Curl_pp_sendf(&conn->proto.pop3c.pp,
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s",
(pop3->custom && pop3->custom[0] != '\0' ?
pop3->custom : command));
@@ -714,7 +714,7 @@ static CURLcode pop3_perform_quit(struct connectdata *conn)
CURLcode result = CURLE_OK;
/* Send the QUIT command */
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "QUIT");
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "QUIT");
if(!result)
state(conn, POP3_QUIT);
@@ -1020,7 +1020,7 @@ static CURLcode pop3_state_auth_digest_resp_resp(struct connectdata *conn,
}
else {
/* Send an empty response */
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "");
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "");
if(!result)
state(conn, POP3_AUTH_FINAL);
@@ -1421,8 +1421,7 @@ static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks,
* connection phase.
*
* The variable 'done' points to will be TRUE if the protocol-layer connect
* phase is done when this function returns, or FALSE is not. When called as
* a part of the easy interface, it will always be TRUE.
* phase is done when this function returns, or FALSE if not.
*/
static CURLcode pop3_connect(struct connectdata *conn, bool *done)
{

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -357,12 +357,21 @@ int Curl_pgrsUpdate(struct connectdata *conn)
} /* Calculations end */
if(!(data->progress.flags & PGRS_HIDE)) {
/* progress meter has not been shut off */
if(data->set.fprogress) {
/* There's a callback set, so we call that instead of writing
anything ourselves. This really is the way to go. */
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,

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -37,6 +37,7 @@
#include "sslgen.h"
#include "connect.h" /* for the connect timeout */
#include "select.h"
#include "x509asn1.h"
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
@@ -169,10 +170,7 @@ static CURLcode Curl_qsossl_handshake(struct connectdata * conn, int sockindex)
SSLHandle * h = connssl->handle;
long timeout_ms;
h->exitPgm = NULL;
if(!data->set.ssl.verifyhost)
h->exitPgm = Curl_qsossl_trap_cert;
h->exitPgm = data->set.ssl.verifypeer? NULL: Curl_qsossl_trap_cert;
/* figure out how long time we should wait at maximum */
timeout_ms = Curl_timeleft(data, NULL, TRUE);
@@ -208,6 +206,8 @@ static CURLcode Curl_qsossl_handshake(struct connectdata * conn, int sockindex)
break;
}
h->peerCert = NULL;
h->peerCertLen = 0;
rc = SSL_Handshake(h, SSL_HANDSHAKE_AS_CLIENT);
switch (rc) {
@@ -238,6 +238,23 @@ static CURLcode Curl_qsossl_handshake(struct connectdata * conn, int sockindex)
return CURLE_SSL_CONNECT_ERROR;
}
/* Verify host. */
rc = Curl_verifyhost(conn, h->peerCert, h->peerCert + h->peerCertLen);
if(rc != CURLE_OK)
return rc;
/* Gather certificate info. */
if(data->set.ssl.certinfo) {
if(Curl_ssl_init_certinfo(data, 1))
return CURLE_OUT_OF_MEMORY;
if(h->peerCert) {
rc = Curl_extract_certinfo(conn, 0, h->peerCert,
h->peerCert + h->peerCertLen);
if(rc != CURLE_OK)
return rc;
}
}
return CURLE_OK;
}
@@ -257,20 +274,23 @@ CURLcode Curl_qsossl_connect(struct connectdata * conn, int sockindex)
if(rc == CURLE_OK) {
rc = Curl_qsossl_create(conn, sockindex);
if(rc == CURLE_OK)
if(rc == CURLE_OK) {
rc = Curl_qsossl_handshake(conn, sockindex);
else {
if(rc != CURLE_OK)
SSL_Destroy(connssl->handle);
}
}
if(rc == CURLE_OK) {
conn->recv[sockindex] = qsossl_recv;
conn->send[sockindex] = qsossl_send;
connssl->state = ssl_connection_complete;
}
else {
connssl->handle = NULL;
connssl->use = FALSE;
connssl->state = ssl_connection_none;
}
}
if(rc == CURLE_OK) {
connssl->state = ssl_connection_complete;
conn->recv[sockindex] = qsossl_recv;
conn->send[sockindex] = qsossl_send;
}
return rc;
}

View File

@@ -668,7 +668,7 @@ static CURLcode rtsp_rtp_readwrite(struct SessionHandle *data,
}
if(rtp_dataleft != 0 && rtp[0] == '$') {
DEBUGF(infof(data, "RTP Rewinding %zu %s\n", rtp_dataleft,
DEBUGF(infof(data, "RTP Rewinding %zd %s\n", rtp_dataleft,
*readmore ? "(READMORE)" : ""));
/* Store the incomplete RTP packet for a "rewind" */

View File

@@ -10,7 +10,7 @@
* Copyright (c) 1998, 1999 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
*
* Copyright (C) 2001 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2001 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* All rights reserved.
*
@@ -498,7 +498,7 @@ static CURLcode choose_mech(struct connectdata *conn)
/* We have no mechanism with a NULL name but keep this check */
DEBUGASSERT(mech_name != NULL);
if(mech_name == NULL) {
infof(data, "Skipping mechanism with empty name (%p)\n", mech);
infof(data, "Skipping mechanism with empty name (%p)\n", (void *)mech);
continue;
}
tmp_allocation = realloc(conn->app_data, (*mech)->size);

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -38,6 +38,8 @@ typedef unsigned long u_int32_t;
#include <sys/socket.h>
#include <netdb.h>
#include <qsossl.h>
#include <gskssl.h>
#include <qsoasync.h>
#include <gssapi.h>
extern int Curl_getaddrinfo_a(const char * nodename, const char * servname,
@@ -68,6 +70,93 @@ extern char * Curl_SSL_Strerror_a(int sslreturnvalue, SSLErrorMsg * serrmsgp);
#define SSL_Strerror Curl_SSL_Strerror_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,
@@ -107,6 +196,7 @@ extern OM_uint32 Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
gss_buffer_t output_token);
#define gss_delete_sec_context Curl_gss_delete_sec_context_a
/* LDAP wrappers. */
#define BerValue struct berval

View File

@@ -315,6 +315,7 @@ char * unix_path;
#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

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -45,6 +45,38 @@ static struct curl_slist *slist_get_last(struct curl_slist *list)
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
@@ -55,32 +87,16 @@ static struct curl_slist *slist_get_last(struct curl_slist *list)
struct curl_slist *curl_slist_append(struct curl_slist *list,
const char *data)
{
struct curl_slist *last;
struct curl_slist *new_item;
new_item = malloc(sizeof(struct curl_slist));
if(new_item) {
char *dupdata = strdup(data);
if(dupdata) {
new_item->next = NULL;
new_item->data = dupdata;
}
else {
free(new_item);
return NULL;
}
}
else
if(!dupdata)
return NULL;
if(list) {
last = slist_get_last(list);
last->next = new_item;
list = Curl_slist_append_nodup(list, dupdata);
if(!list)
free(dupdata);
return list;
}
/* if this is the first item, then new_item *is* the list */
return new_item;
}
/*

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -29,5 +29,12 @@
*/
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 */

View File

@@ -337,7 +337,7 @@ static void state(struct connectdata *conn, smtpstate newstate)
if(smtpc->state != newstate)
infof(conn->data, "SMTP %p state change from %s to %s\n",
smtpc, names[smtpc->state], names[newstate]);
(void *)smtpc, names[smtpc->state], names[newstate]);
#endif
smtpc->state = newstate;
@@ -403,7 +403,7 @@ static CURLcode smtp_perform_starttls(struct connectdata *conn)
CURLcode result = CURLE_OK;
/* Send the STARTTLS command */
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "STARTTLS");
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "STARTTLS");
if(!result)
state(conn, SMTP_STARTTLS);
@@ -664,7 +664,7 @@ static CURLcode smtp_perform_quit(struct connectdata *conn)
CURLcode result = CURLE_OK;
/* Send the QUIT command */
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "QUIT");
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "QUIT");
if(!result)
state(conn, SMTP_QUIT);
@@ -997,7 +997,7 @@ static CURLcode smtp_state_auth_digest_resp_resp(struct connectdata *conn,
}
else {
/* Send an empty response */
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "");
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "");
if(!result)
state(conn, SMTP_AUTH_FINAL);
@@ -1159,7 +1159,7 @@ static CURLcode smtp_state_rcpt_resp(struct connectdata *conn, int smtpcode,
}
/* Send the DATA command */
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "DATA");
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "DATA");
if(!result)
state(conn, SMTP_DATA);
@@ -1387,8 +1387,7 @@ static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks,
* the connection phase.
*
* The variable pointed to by 'done' will be TRUE if the protocol-layer
* connect phase is done when this function returns, or FALSE if not. When
* called as a part of the easy interface, it will always be TRUE.
* connect phase is done when this function returns, or FALSE if not.
*/
static CURLcode smtp_connect(struct connectdata *conn, bool *done)
{

View File

@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com>
* Copyright (C) 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2012 - 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
@@ -260,8 +260,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
/* 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]);
failf(data, "User was rejected by the SOCKS5 server (%u %u).",
(unsigned int)socksreq[0], (unsigned int)socksreq[1]);
Curl_safefree(service_name);
s_pSecFn->FreeCredentialsHandle(&cred_handle);
s_pSecFn->DeleteSecurityContext(&sspi_context);
@@ -269,8 +269,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
}
if(socksreq[1] != 1) { /* status / messgae type */
failf(data, "Invalid SSPI authentication response type (%d %d).",
socksreq[0], socksreq[1]);
failf(data, "Invalid SSPI authentication response type (%u %u).",
(unsigned int)socksreq[0], (unsigned int)socksreq[1]);
Curl_safefree(service_name);
s_pSecFn->FreeCredentialsHandle(&cred_handle);
s_pSecFn->DeleteSecurityContext(&sspi_context);
@@ -494,15 +494,15 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
/* 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]);
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 (%d %d).",
socksreq[0], socksreq[1]);
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;
}
@@ -549,8 +549,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
}
if(sspi_w_token[1].cbBuffer != 1) {
failf(data, "Invalid SSPI encryption response length (%d).",
sspi_w_token[1].cbBuffer);
failf(data, "Invalid SSPI encryption response length (%lu).",
(unsigned long)sspi_w_token[1].cbBuffer);
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
s_pSecFn->DeleteSecurityContext(&sspi_context);
@@ -563,8 +563,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
}
else {
if(sspi_w_token[0].cbBuffer != 1) {
failf(data, "Invalid SSPI encryption response length (%d).",
sspi_w_token[0].cbBuffer);
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;

View File

@@ -392,7 +392,7 @@ static void state(struct connectdata *conn, sshstate nowstate)
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
if(sshc->state != nowstate) {
infof(conn->data, "SFTP %p state change from %s to %s\n",
sshc, names[sshc->state], names[nowstate]);
(void *)sshc, names[sshc->state], names[nowstate]);
}
#endif

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -31,6 +31,8 @@
Curl_ossl_ - prefix for OpenSSL ones
Curl_gtls_ - prefix for GnuTLS ones
Curl_nss_ - prefix for NSS ones
Curl_qssl_ - prefix for QsoSSL ones
Curl_gskit_ - prefix for GSKit ones
Curl_polarssl_ - prefix for PolarSSL ones
Curl_cyassl_ - prefix for CyaSSL ones
Curl_schannel_ - prefix for Schannel SSPI ones
@@ -45,6 +47,16 @@
#include "curl_setup.h"
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include "urldata.h"
#define SSLGEN_C
#include "sslgen.h" /* generic SSL protos etc */
@@ -52,17 +64,24 @@
#include "gtls.h" /* GnuTLS versions */
#include "nssg.h" /* NSS versions */
#include "qssl.h" /* QSOSSL versions */
#include "gskit.h" /* Global Secure ToolKit versions */
#include "polarssl.h" /* PolarSSL versions */
#include "axtls.h" /* axTLS versions */
#include "cyassl.h" /* CyaSSL versions */
#include "curl_schannel.h" /* Schannel SSPI version */
#include "curl_darwinssl.h" /* SecureTransport (Darwin) version */
#include "slist.h"
#include "sendf.h"
#include "rawstr.h"
#include "url.h"
#include "curl_memory.h"
#include "progress.h"
#include "share.h"
#include "timeval.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
/* The last #include file should be: */
#include "memdebug.h"
@@ -159,6 +178,62 @@ void Curl_free_ssl_config(struct ssl_config_data* sslc)
Curl_safefree(sslc->random_file);
}
/*
* Curl_rand() returns a random unsigned integer, 32bit.
*
* This non-SSL function is put here only because this file is the only one
* with knowledge of what the underlying SSL libraries provide in terms of
* randomizers.
*
* NOTE: 'data' may be passed in as NULL when coming from external API without
* easy handle!
*
*/
unsigned int Curl_rand(struct SessionHandle *data)
{
unsigned int r;
static unsigned int randseed;
static bool seeded = FALSE;
#ifndef have_curlssl_random
(void)data;
#else
if(data) {
Curl_ssl_random(data, (unsigned char *)&r, sizeof(r));
return r;
}
#endif
#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();
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;
return (r << 16) | ((r >> 16) & 0xFFFF);
}
#ifdef USE_SSL
/* "global" init done? */
@@ -518,17 +593,77 @@ void Curl_ssl_free_certinfo(struct SessionHandle *data)
}
}
#if defined(USE_SSLEAY) || defined(USE_GNUTLS) || defined(USE_NSS) || \
defined(USE_DARWINSSL)
/* these functions are only used by some SSL backends */
int Curl_ssl_init_certinfo(struct SessionHandle * data,
int num)
{
struct curl_certinfo * ci = &data->info.certs;
struct curl_slist * * table;
/* Initialize the certificate information structures. Return 0 if OK, else 1.
*/
Curl_ssl_free_certinfo(data);
ci->num_of_certs = num;
table = calloc((size_t) num, sizeof(struct curl_slist *));
if(!table)
return 1;
ci->certinfo = table;
return 0;
}
CURLcode Curl_ssl_push_certinfo_len(struct SessionHandle *data,
int certnum,
const char *label,
const char *value,
size_t valuelen)
{
struct curl_certinfo * ci = &data->info.certs;
char * output;
struct curl_slist * nl;
CURLcode res = CURLE_OK;
/* Add an information record for a particular certificate. */
output = curl_maprintf("%s:%.*s", label, valuelen, value);
if(!output)
return CURLE_OUT_OF_MEMORY;
nl = Curl_slist_append_nodup(ci->certinfo[certnum], output);
if(!nl) {
free(output);
curl_slist_free_all(ci->certinfo[certnum]);
res = CURLE_OUT_OF_MEMORY;
}
ci->certinfo[certnum] = nl;
return res;
}
/*
* This is a convenience function for push_certinfo_len that takes a zero
* terminated value.
*/
CURLcode Curl_ssl_push_certinfo(struct SessionHandle *data,
int certnum,
const char *label,
const char *value)
{
size_t valuelen = strlen(value);
return Curl_ssl_push_certinfo_len(data, certnum, label, value, valuelen);
}
/* these functions are only provided by some SSL backends */
#ifdef have_curlssl_random
void Curl_ssl_random(struct SessionHandle *data,
unsigned char *entropy,
size_t length)
{
curlssl_random(data, entropy, length);
}
#endif
#ifdef have_curlssl_md5sum
void Curl_ssl_md5sum(unsigned char *tmp, /* input */
size_t tmplen,
unsigned char *md5sum, /* output */
@@ -536,6 +671,6 @@ void Curl_ssl_md5sum(unsigned char *tmp, /* input */
{
curlssl_md5sum(tmp, tmplen, md5sum, md5len);
}
#endif /* USE_SSLEAY || USE_GNUTLS || USE_NSS || USE_DARWINSSL */
#endif
#endif /* USE_SSL */

View File

@@ -33,6 +33,8 @@ bool Curl_clone_ssl_config(struct ssl_config_data* source,
struct ssl_config_data* dest);
void Curl_free_ssl_config(struct ssl_config_data* sslc);
unsigned int Curl_rand(struct SessionHandle *);
#ifdef USE_SSL
int Curl_ssl_init(void);
void Curl_ssl_cleanup(void);
@@ -56,7 +58,16 @@ size_t Curl_ssl_version(char *buffer, size_t size);
bool Curl_ssl_data_pending(const struct connectdata *conn,
int connindex);
int Curl_ssl_check_cxn(struct connectdata *conn);
/* Certificate information list handling. */
void Curl_ssl_free_certinfo(struct SessionHandle *data);
int Curl_ssl_init_certinfo(struct SessionHandle * data, int num);
CURLcode Curl_ssl_push_certinfo_len(struct SessionHandle * data, int certnum,
const char * label, const char * value,
size_t valuelen);
CURLcode Curl_ssl_push_certinfo(struct SessionHandle * data, int certnum,
const char * label, const char * value);
/* Functions to be used by SSL library adaptation functions */
@@ -83,6 +94,13 @@ void Curl_ssl_md5sum(unsigned char *tmp, /* input */
#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */
#ifdef have_curlssl_random
#define HAVE_CURL_SSL_RANDOM
#endif
#ifdef have_curlssl_md5sum
#define HAVE_CURL_SSL_MD5SUM
#endif
#else
/* When SSL support is not present, just define away these function calls */
#define Curl_ssl_init() 1

View File

@@ -43,6 +43,7 @@
#include "inet_pton.h"
#include "ssluse.h"
#include "connect.h"
#include "slist.h"
#include "strequal.h"
#include "select.h"
#include "sslgen.h"
@@ -1790,60 +1791,6 @@ static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len)
return 0;
}
static CURLcode push_certinfo_len(struct SessionHandle *data,
int certnum,
const char *label,
const char *value,
size_t valuelen)
{
struct curl_certinfo *ci = &data->info.certs;
char *output;
struct curl_slist *nl;
CURLcode res = CURLE_OK;
size_t labellen = strlen(label);
size_t outlen = labellen + 1 + valuelen + 1; /* label:value\0 */
output = malloc(outlen);
if(!output)
return CURLE_OUT_OF_MEMORY;
/* sprintf the label and colon */
snprintf(output, outlen, "%s:", label);
/* memcpy the value (it might not be zero terminated) */
memcpy(&output[labellen+1], value, valuelen);
/* zero terminate the output */
output[labellen + 1 + valuelen] = 0;
/* TODO: we should rather introduce an internal API that can do the
equivalent of curl_slist_append but doesn't strdup() the given data as
like in this place the extra malloc/free is totally pointless */
nl = curl_slist_append(ci->certinfo[certnum], output);
free(output);
if(!nl) {
curl_slist_free_all(ci->certinfo[certnum]);
ci->certinfo[certnum] = NULL;
res = CURLE_OUT_OF_MEMORY;
}
else
ci->certinfo[certnum] = nl;
return res;
}
/* this is a convenience function for push_certinfo_len that takes a zero
terminated value */
static CURLcode push_certinfo(struct SessionHandle *data,
int certnum,
const char *label,
const char *value)
{
size_t valuelen = strlen(value);
return push_certinfo_len(data, certnum, label, value, valuelen);
}
static void pubkey_show(struct SessionHandle *data,
int num,
const char *type,
@@ -1867,7 +1814,7 @@ static void pubkey_show(struct SessionHandle *data,
left -= 3;
}
infof(data, " %s: %s\n", namebuf, buffer);
push_certinfo(data, num, namebuf, buffer);
Curl_ssl_push_certinfo(data, num, namebuf, buffer);
free(buffer);
}
}
@@ -1936,7 +1883,7 @@ static int X509V3_ext(struct SessionHandle *data,
}
infof(data, " %s\n", buf);
push_certinfo(data, certnum, namebuf, buf);
Curl_ssl_push_certinfo(data, certnum, namebuf, buf);
BIO_free(bio_out);
@@ -1956,7 +1903,7 @@ static void X509_signature(struct SessionHandle *data,
ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%02x:", sig->data[i]);
infof(data, " Signature: %s\n", buf);
push_certinfo(data, numcert, "Signature", buf);
Curl_ssl_push_certinfo(data, numcert, "Signature", buf);
}
static void dumpcert(struct SessionHandle *data, X509 *x, int numcert)
@@ -1972,30 +1919,13 @@ static void dumpcert(struct SessionHandle *data, X509 *x, int numcert)
infof(data, "%s\n", biomem->data);
push_certinfo_len(data, numcert, "Cert", biomem->data, biomem->length);
Curl_ssl_push_certinfo_len(data, numcert,
"Cert", biomem->data, biomem->length);
BIO_free(bio_out);
}
static int init_certinfo(struct SessionHandle *data,
int num)
{
struct curl_certinfo *ci = &data->info.certs;
struct curl_slist **table;
Curl_ssl_free_certinfo(data);
ci->num_of_certs = num;
table = calloc((size_t)num, sizeof(struct curl_slist *));
if(!table)
return 1;
ci->certinfo = table;
return 0;
}
/*
* This size was previously 512 which has been reported "too small" without
* any specifics, so it was enlarged to allow more data to get shown uncut.
@@ -2024,7 +1954,7 @@ static CURLcode get_cert_chain(struct connectdata *conn,
}
numcerts = sk_X509_num(sk);
if(init_certinfo(data, numcerts)) {
if(Curl_ssl_init_certinfo(data, numcerts)) {
free(bufp);
return CURLE_OUT_OF_MEMORY;
}
@@ -2049,16 +1979,16 @@ static CURLcode get_cert_chain(struct connectdata *conn,
(void)x509_name_oneline(X509_get_subject_name(x), bufp, CERTBUFFERSIZE);
infof(data, "%2d Subject: %s\n", i, bufp);
push_certinfo(data, i, "Subject", bufp);
Curl_ssl_push_certinfo(data, i, "Subject", bufp);
(void)x509_name_oneline(X509_get_issuer_name(x), bufp, CERTBUFFERSIZE);
infof(data, " Issuer: %s\n", bufp);
push_certinfo(data, i, "Issuer", bufp);
Curl_ssl_push_certinfo(data, i, "Issuer", bufp);
value = X509_get_version(x);
infof(data, " Version: %lu (0x%lx)\n", value+1, value);
snprintf(bufp, CERTBUFFERSIZE, "%lx", value);
push_certinfo(data, i, "Version", bufp); /* hex */
Curl_ssl_push_certinfo(data, i, "Version", bufp); /* hex */
num=X509_get_serialNumber(x);
if(num->length <= 4) {
@@ -2087,30 +2017,30 @@ static CURLcode get_cert_chain(struct connectdata *conn,
bufp[0]=0;
}
if(bufp[0])
push_certinfo(data, i, "Serial Number", bufp); /* hex */
Curl_ssl_push_certinfo(data, i, "Serial Number", bufp); /* hex */
cinf = x->cert_info;
j = asn1_object_dump(cinf->signature->algorithm, bufp, CERTBUFFERSIZE);
if(!j) {
infof(data, " Signature Algorithm: %s\n", bufp);
push_certinfo(data, i, "Signature Algorithm", bufp);
Curl_ssl_push_certinfo(data, i, "Signature Algorithm", bufp);
}
certdate = X509_get_notBefore(x);
asn1_output(certdate, bufp, CERTBUFFERSIZE);
infof(data, " Start date: %s\n", bufp);
push_certinfo(data, i, "Start date", bufp);
Curl_ssl_push_certinfo(data, i, "Start date", bufp);
certdate = X509_get_notAfter(x);
asn1_output(certdate, bufp, CERTBUFFERSIZE);
infof(data, " Expire date: %s\n", bufp);
push_certinfo(data, i, "Expire date", bufp);
Curl_ssl_push_certinfo(data, i, "Expire date", bufp);
j = asn1_object_dump(cinf->key->algor->algorithm, bufp, CERTBUFFERSIZE);
if(!j) {
infof(data, " Public Key Algorithm: %s\n", bufp);
push_certinfo(data, i, "Public Key Algorithm", bufp);
Curl_ssl_push_certinfo(data, i, "Public Key Algorithm", bufp);
}
pubkey = X509_get_pubkey(x);
@@ -2122,7 +2052,7 @@ static CURLcode get_cert_chain(struct connectdata *conn,
infof(data, " RSA Public Key (%d bits)\n",
BN_num_bits(pubkey->pkey.rsa->n));
snprintf(bufp, CERTBUFFERSIZE, "%d", BN_num_bits(pubkey->pkey.rsa->n));
push_certinfo(data, i, "RSA Public Key", bufp);
Curl_ssl_push_certinfo(data, i, "RSA Public Key", bufp);
print_pubkey_BN(rsa, n, i);
print_pubkey_BN(rsa, e, i);
@@ -2608,8 +2538,13 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
*curlcode = CURLE_AGAIN;
return -1;
default:
/* openssl/ssl.h says "look at error stack/return value/errno" */
/* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return
value/errno" */
/* http://www.openssl.org/docs/crypto/ERR_get_error.html */
sslerror = ERR_get_error();
if((nread < 0) || sslerror) {
/* If the return code was negative or there actually is an error in the
queue */
failf(conn->data, "SSL read: %s, errno %d",
ERR_error_string(sslerror, error_buffer),
SOCKERRNO);
@@ -2617,6 +2552,7 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
return -1;
}
}
}
return nread;
}

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -73,6 +73,10 @@ void Curl_ossl_md5sum(unsigned char *tmp, /* input */
unsigned char *md5sum /* output */,
size_t unused);
/* this backend provides these functions: */
#define have_curlssl_random 1
#define have_curlssl_md5sum 1
/* API setup for OpenSSL */
#define curlssl_init Curl_ossl_init
#define curlssl_cleanup Curl_ossl_cleanup

122
lib/url.c
View File

@@ -124,6 +124,7 @@ int curl_win32_idn_to_ascii(const char *in, char **out);
#include "conncache.h"
#include "multihandle.h"
#include "pipeline.h"
#include "dotdot.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -317,6 +318,13 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp,
if(!result) {
/* Store the username part of option if required */
if(userp) {
if(!user && option && option[0] == ':') {
/* Allocate an empty string instead of returning NULL as user name */
user = strdup("");
if(!user)
result = CURLE_OUT_OF_MEMORY;
}
Curl_safefree(*userp);
*userp = user;
}
@@ -1601,8 +1609,20 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
data->progress.callback = TRUE; /* no longer internal */
else
data->progress.callback = FALSE; /* NULL enforces internal */
break;
case CURLOPT_XFERINFOFUNCTION:
/*
* Transfer info callback function
*/
data->set.fxferinfo = va_arg(param, curl_xferinfo_callback);
if(data->set.fxferinfo)
data->progress.callback = TRUE; /* no longer internal */
else
data->progress.callback = FALSE; /* NULL enforces internal */
break;
case CURLOPT_PROGRESSDATA:
/*
* Custom client data to pass to the progress callback
@@ -1892,6 +1912,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
*/
data->set.ssl.fsslctxp = va_arg(param, void *);
break;
#endif
#if defined(USE_SSLEAY) || defined(USE_QSOSSL) || defined(USE_GSKIT)
case CURLOPT_CERTINFO:
data->set.ssl.certinfo = (0 != va_arg(param, long))?TRUE:FALSE;
break;
@@ -2552,7 +2574,7 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
conn->handler->disconnect(conn, dead_connection);
/* unlink ourselves! */
infof(data, "Closing connection %d\n", conn->connection_id);
infof(data, "Closing connection %ld\n", conn->connection_id);
Curl_conncache_remove_conn(data->state.conn_cache, conn);
#if defined(USE_LIBIDN)
@@ -2583,7 +2605,7 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
}
conn_free(conn);
data->state.current_conn = NULL;
Curl_speedinit(data);
return CURLE_OK;
@@ -2853,7 +2875,8 @@ ConnectionExists(struct SessionHandle *data,
size_t best_pipe_len = max_pipe_len;
struct curl_llist_element *curr;
infof(data, "Found bundle for host %s: %p\n", needle->host.name, bundle);
infof(data, "Found bundle for host %s: %p\n",
needle->host.name, (void *)bundle);
/* We can't pipe if we don't know anything about the server */
if(canPipeline && !bundle->server_supports_pipelining) {
@@ -2889,7 +2912,7 @@ ConnectionExists(struct SessionHandle *data,
if(dead) {
check->data = data;
infof(data, "Connection %d seems to be dead!\n",
infof(data, "Connection %ld seems to be dead!\n",
check->connection_id);
/* disconnect resources */
@@ -3674,7 +3697,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
char protobuf[16];
const char *protop;
CURLcode result;
bool fix_slash = FALSE;
bool rebuild_url = FALSE;
*prot_missing = FALSE;
@@ -3825,14 +3848,14 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
memcpy(path+1, query, hostlen);
path[0]='/'; /* prepend the missing slash */
fix_slash = TRUE;
rebuild_url = TRUE;
*query=0; /* now cut off the hostname at the ? */
}
else if(!path[0]) {
/* if there's no path set, use a single slash */
strcpy(path, "/");
fix_slash = TRUE;
rebuild_url = TRUE;
}
/* If the URL is malformatted (missing a '/' after hostname before path) we
@@ -3845,32 +3868,52 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
is bigger than the path. Use +1 to move the zero byte too. */
memmove(&path[1], path, strlen(path)+1);
path[0] = '/';
fix_slash = TRUE;
rebuild_url = TRUE;
}
else {
/* sanitise paths and remove ../ and ./ sequences according to RFC3986 */
char *newp = Curl_dedotdotify(path);
if(!newp)
return CURLE_OUT_OF_MEMORY;
if(strcmp(newp, path)) {
rebuild_url = TRUE;
free(data->state.pathbuffer);
data->state.pathbuffer = newp;
data->state.path = newp;
path = newp;
}
else
free(newp);
}
/*
* "fix_slash" means that the URL was malformatted so we need to generate an
* updated version with the new slash inserted at the right place! We need
* the corrected URL when communicating over HTTP proxy and we don't know at
* this point if we're using a proxy or not.
* "rebuild_url" means that one or more URL components have been modified so
* we need to generate an updated full version. We need the corrected URL
* when communicating over HTTP proxy and we don't know at this point if
* we're using a proxy or not.
*/
if(fix_slash) {
if(rebuild_url) {
char *reurl;
size_t plen = strlen(path); /* new path, should be 1 byte longer than
the original */
size_t urllen = strlen(data->change.url); /* original URL length */
size_t prefixlen = strlen(conn->host.name);
if(!*prot_missing)
prefixlen += strlen(protop) + strlen("://");
reurl = malloc(urllen + 2); /* 2 for zerobyte + slash */
if(!reurl)
return CURLE_OUT_OF_MEMORY;
/* copy the prefix */
memcpy(reurl, data->change.url, urllen - (plen-1));
memcpy(reurl, data->change.url, prefixlen);
/* append the trailing piece + zerobyte */
memcpy(&reurl[urllen - (plen-1)], path, plen + 1);
memcpy(&reurl[prefixlen], path, plen + 1);
/* possible free the old one */
if(data->change.url_alloc) {
@@ -3878,6 +3921,8 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
data->change.url_alloc = FALSE;
}
infof(data, "Rebuilt URL to: %s\n", reurl);
data->change.url = reurl;
data->change.url_alloc = TRUE; /* free this later */
}
@@ -4415,8 +4460,12 @@ static CURLcode parse_url_login(struct SessionHandle *data,
/* Decode the user */
newname = curl_easy_unescape(data, userp, 0, NULL);
if(!newname)
if(!newname) {
Curl_safefree(userp);
Curl_safefree(passwdp);
Curl_safefree(optionsp);
return CURLE_OUT_OF_MEMORY;
}
if(strlen(newname) < MAX_CURL_USER_LENGTH)
strcpy(user, newname);
@@ -4427,8 +4476,12 @@ static CURLcode parse_url_login(struct SessionHandle *data,
if(passwdp) {
/* We have a password in the URL so decode it */
char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL);
if(!newpasswd)
if(!newpasswd) {
Curl_safefree(userp);
Curl_safefree(passwdp);
Curl_safefree(optionsp);
return CURLE_OUT_OF_MEMORY;
}
if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH)
strcpy(passwd, newpasswd);
@@ -4439,8 +4492,12 @@ static CURLcode parse_url_login(struct SessionHandle *data,
if(optionsp) {
/* We have an options list in the URL so decode it */
char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL);
if(!newoptions)
if(!newoptions) {
Curl_safefree(userp);
Curl_safefree(passwdp);
Curl_safefree(optionsp);
return CURLE_OUT_OF_MEMORY;
}
if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH)
strcpy(options, newoptions);
@@ -4540,16 +4597,21 @@ static CURLcode parse_login_details(const char *login, const size_t len,
/* Allocate the password portion buffer */
if(!result && passwdp && plen) {
pbuf = malloc(plen + 1);
if(!pbuf)
if(!pbuf) {
Curl_safefree(ubuf);
result = CURLE_OUT_OF_MEMORY;
}
}
/* Allocate the options portion buffer */
if(!result && optionsp && olen) {
obuf = malloc(olen + 1);
if(!obuf)
if(!obuf) {
Curl_safefree(pbuf);
Curl_safefree(ubuf);
result = CURLE_OUT_OF_MEMORY;
}
}
if(!result) {
/* Store the user portion if necessary */
@@ -5274,7 +5336,7 @@ static CURLcode create_conn(struct SessionHandle *data,
if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) {
size_t pipelen = conn_temp->send_pipe->size + conn_temp->recv_pipe->size;
if(pipelen > 0) {
infof(data, "Found connection %d, with requests in the pipe (%d)\n",
infof(data, "Found connection %ld, with requests in the pipe (%zu)\n",
conn_temp->connection_id, pipelen);
if(conn_temp->bundle->num_connections < max_host_connections &&
@@ -5779,18 +5841,20 @@ CURLcode Curl_do(struct connectdata **connp, bool *done)
*
* TODO: A future libcurl should be able to work away this state.
*
* 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
* DOING state there's more work to do!
*/
CURLcode Curl_do_more(struct connectdata *conn, bool *completed)
CURLcode Curl_do_more(struct connectdata *conn, int *complete)
{
CURLcode result=CURLE_OK;
*completed = FALSE;
*complete = 0;
if(conn->handler->do_more)
result = conn->handler->do_more(conn, completed);
result = conn->handler->do_more(conn, complete);
if(!result && *completed)
if(!result && (*complete == 1))
/* do_complete must be called after the protocol-specific DO function */
do_complete(conn);
@@ -5803,9 +5867,7 @@ CURLcode Curl_do_more(struct connectdata *conn, bool *completed)
void Curl_reset_reqproto(struct connectdata *conn)
{
struct SessionHandle *data = conn->data;
if(data->state.proto.generic && data->state.current_conn != conn) {
free(data->state.proto.generic);
Curl_safefree(data->state.proto.generic);
data->state.proto.generic = NULL;
}
data->state.current_conn = conn;
}

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -37,7 +37,7 @@ CURLcode Curl_close(struct SessionHandle *data); /* opposite of curl_open() */
CURLcode Curl_connect(struct SessionHandle *, struct connectdata **,
bool *async, bool *protocol_connect);
CURLcode Curl_do(struct connectdata **, bool *done);
CURLcode Curl_do_more(struct connectdata *, bool *completed);
CURLcode Curl_do_more(struct connectdata *, int *completed);
CURLcode Curl_done(struct connectdata **, CURLcode, bool premature);
CURLcode Curl_disconnect(struct connectdata *, bool dead_connection);
CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);

View File

@@ -134,6 +134,10 @@
#include <qsossl.h>
#endif
#ifdef USE_GSKIT
#include <gskssl.h>
#endif
#ifdef USE_AXTLS
#include <axTLS/ssl.h>
#undef malloc
@@ -184,6 +188,7 @@
#include "http.h"
#include "rtsp.h"
#include "wildcard.h"
#include "multihandle.h"
#ifdef HAVE_GSSAPI
# ifdef HAVE_GSSGNU
@@ -322,6 +327,11 @@ struct ssl_connect_data {
#ifdef USE_QSOSSL
SSLHandle *handle;
#endif /* USE_QSOSSL */
#ifdef USE_GSKIT
gsk_handle handle;
int iocport;
ssl_connect_state connecting_state;
#endif
#ifdef USE_AXTLS
SSL_CTX* ssl_ctx;
SSL* ssl;
@@ -567,7 +577,7 @@ struct Curl_async {
/* These function pointer types are here only to allow easier typecasting
within the source when we need to cast between data pointers (such as NULL)
and function pointers. */
typedef CURLcode (*Curl_do_more_func)(struct connectdata *, bool *);
typedef CURLcode (*Curl_do_more_func)(struct connectdata *, int *);
typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode, bool);
@@ -1285,8 +1295,6 @@ struct UrlState {
struct POP3 *pop3;
struct SMTP *smtp;
} proto;
/* current user of this SessionHandle instance, or NULL */
struct connectdata *current_conn;
/* if true, force SSL connection retry (workaround for certain servers) */
bool ssl_connect_retry;
@@ -1319,7 +1327,7 @@ struct DynamicStatic {
* the 'DynamicStatic' struct.
* Character pointer fields point to dynamic storage, unless otherwise stated.
*/
struct Curl_one_easy; /* declared and used only in multi.c */
struct Curl_multi; /* declared and used only in multi.c */
enum dupstring {
@@ -1419,7 +1427,8 @@ struct UserDefined {
curl_read_callback fread_func; /* function that reads the input */
int is_fread_set; /* boolean, has read callback been set to non-NULL? */
int is_fwrite_set; /* boolean, has write callback been set to non-NULL? */
curl_progress_callback fprogress; /* function for progress information */
curl_progress_callback fprogress; /* OLD and deprecated progress callback */
curl_xferinfo_callback fxferinfo; /* progress callback */
curl_debug_callback fdebug; /* function that write informational data */
curl_ioctl_callback ioctl_func; /* function for I/O control */
curl_sockopt_callback fsockopt; /* function for setting socket options */
@@ -1481,12 +1490,6 @@ struct UserDefined {
long buffer_size; /* size of receive buffer to use */
void *private_data; /* application-private data */
struct Curl_one_easy *one_easy; /* When adding an easy handle to a multi
handle, an internal 'Curl_one_easy'
struct is created and this is a pointer
to the particular struct associated with
this SessionHandle */
struct curl_slist *http200aliases; /* linked list of aliases for http200 */
long ipver; /* the CURL_IPRESOLVE_* defines in the public header file
@@ -1609,6 +1612,24 @@ struct Names {
*/
struct SessionHandle {
/* first, two fields for the linked list of these */
struct SessionHandle *next;
struct SessionHandle *prev;
struct connectdata *easy_conn; /* the "unit's" connection */
CURLMstate mstate; /* the handle's state */
CURLcode result; /* previous result */
struct Curl_message msg; /* A single posted message. */
/* Array with the plain socket numbers this handle takes care of, in no
particular order. Note that all sockets are added to the sockhash, where
the state etc are also kept. This array is mostly used to detect when a
socket is to be removed from the hash. See singlesocket(). */
curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE];
int numsocks;
struct Names dns;
struct Curl_multi *multi; /* if non-NULL, points to the multi handle
struct to which this "belongs" when used by
@@ -1616,9 +1637,6 @@ struct SessionHandle {
struct Curl_multi *multi_easy; /* if non-NULL, points to the multi handle
struct to which this "belongs" when used
by the easy interface */
struct Curl_one_easy *multi_pos; /* if non-NULL, points to its position
in multi controlling structure to assist
in removal. */
struct Curl_share *share; /* Share, handles global variable mutexing */
struct SingleRequest req; /* Request-specific data */
struct UserDefined set; /* values set by the libcurl user */

1151
lib/x509asn1.c Normal file

File diff suppressed because it is too large Load Diff

129
lib/x509asn1.h Normal file
View File

@@ -0,0 +1,129 @@
#ifndef HEADER_CURL_X509ASN1_H
#define HEADER_CURL_X509ASN1_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 http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#if defined(USE_QSOSSL) || defined(USE_GSKIT)
#include "urldata.h"
/*
* Constants.
*/
/* ASN.1 classes. */
#define CURL_ASN1_UNIVERSAL 0
#define CURL_ASN1_APPLICATION 1
#define CURL_ASN1_CONTEXT_SPECIFIC 2
#define CURL_ASN1_PRIVATE 3
/* ASN.1 types. */
#define CURL_ASN1_BOOLEAN 1
#define CURL_ASN1_INTEGER 2
#define CURL_ASN1_BIT_STRING 3
#define CURL_ASN1_OCTET_STRING 4
#define CURL_ASN1_NULL 5
#define CURL_ASN1_OBJECT_IDENTIFIER 6
#define CURL_ASN1_OBJECT_DESCRIPTOR 7
#define CURL_ASN1_INSTANCE_OF 8
#define CURL_ASN1_REAL 9
#define CURL_ASN1_ENUMERATED 10
#define CURL_ASN1_EMBEDDED 11
#define CURL_ASN1_UTF8_STRING 12
#define CURL_ASN1_RELATIVE_OID 13
#define CURL_ASN1_SEQUENCE 16
#define CURL_ASN1_SET 17
#define CURL_ASN1_NUMERIC_STRING 18
#define CURL_ASN1_PRINTABLE_STRING 19
#define CURL_ASN1_TELETEX_STRING 20
#define CURL_ASN1_VIDEOTEX_STRING 21
#define CURL_ASN1_IA5_STRING 22
#define CURL_ASN1_UTC_TIME 23
#define CURL_ASN1_GENERALIZED_TIME 24
#define CURL_ASN1_GRAPHIC_STRING 25
#define CURL_ASN1_VISIBLE_STRING 26
#define CURL_ASN1_GENERAL_STRING 27
#define CURL_ASN1_UNIVERSAL_STRING 28
#define CURL_ASN1_CHARACTER_STRING 29
#define CURL_ASN1_BMP_STRING 30
/*
* Types.
*/
/* ASN.1 parsed element. */
typedef struct {
const char * beg; /* Pointer to element data. */
const char * end; /* Pointer to 1st byte after element data. */
unsigned char class; /* ASN.1 element class. */
unsigned char tag; /* ASN.1 element tag. */
bool constructed; /* Element is constructed. */
} curl_asn1Element;
/* ASN.1 OID table entry. */
typedef struct {
const char * numoid; /* Dotted-numeric OID. */
const char * textoid; /* OID name. */
} curl_OID;
/* X509 certificate: RFC 5280. */
typedef struct {
curl_asn1Element certificate;
curl_asn1Element version;
curl_asn1Element serialNumber;
curl_asn1Element signatureAlgorithm;
curl_asn1Element signature;
curl_asn1Element issuer;
curl_asn1Element notBefore;
curl_asn1Element notAfter;
curl_asn1Element subject;
curl_asn1Element subjectPublicKeyAlgorithm;
curl_asn1Element subjectPublicKey;
curl_asn1Element issuerUniqueID;
curl_asn1Element subjectUniqueID;
curl_asn1Element extensions;
} curl_X509certificate;
/*
* Prototypes.
*/
const char * Curl_getASN1Element(curl_asn1Element * elem,
const char * beg, const char * end);
const char * Curl_ASN1tostr(curl_asn1Element * elem, int type);
const char * Curl_DNtostr(curl_asn1Element * dn);
void Curl_parseX509(curl_X509certificate * cert,
const char * beg, const char * end);
CURLcode Curl_extract_certinfo(struct connectdata * conn, int certnum,
const char * beg, const char * end);
CURLcode Curl_verifyhost(struct connectdata * conn,
const char * beg, const char * end);
#endif /* USE_QSOSSL or USE_GSKIT */
#endif /* HEADER_CURL_X509ASN1_H */

253
m4/xc-am-iface.m4 Normal file
View File

@@ -0,0 +1,253 @@
#---------------------------------------------------------------------------
#
# xc-am-iface.m4
#
# Copyright (c) 2013 Daniel Stenberg <daniel@haxx.se>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
#---------------------------------------------------------------------------
# serial 1
dnl _XC_AUTOMAKE_BODY
dnl -------------------------------------------------
dnl Private macro.
dnl
dnl This macro performs embedding of automake initialization
dnl code into configure script. When automake version 1.14 or
dnl newer is used at configure script generation time, this
dnl results in 'subdir-objects' automake option being used.
dnl When using automake versions older than 1.14 this option
dnl is not used when generating configure script.
dnl
dnl Existence of automake _AM_PROG_CC_C_O m4 private macro
dnl is used to differentiate automake version 1.14 from older
dnl ones which lack this macro.
m4_define([_XC_AUTOMAKE_BODY],
[dnl
## --------------------------------------- ##
## Start of automake initialization code ##
## --------------------------------------- ##
m4_ifdef([_AM_PROG_CC_C_O],
[
AM_INIT_AUTOMAKE([subdir-objects])
],[
AM_INIT_AUTOMAKE
])dnl
## ------------------------------------- ##
## End of automake initialization code ##
## ------------------------------------- ##
dnl
m4_define([$0], [])[]dnl
])
dnl XC_AUTOMAKE
dnl -------------------------------------------------
dnl Public macro.
dnl
dnl This macro embeds automake machinery into configure
dnl script regardless of automake version used in order
dnl to generate configure script.
dnl
dnl When using automake version 1.14 or newer, automake
dnl initialization option 'subdir-objects' is used to
dnl generate the configure script, otherwise this option
dnl is not used.
AC_DEFUN([XC_AUTOMAKE],
[dnl
AC_PREREQ([2.50])dnl
dnl
AC_BEFORE([$0],[AM_INIT_AUTOMAKE])dnl
dnl
_XC_AUTOMAKE_BODY
dnl
m4_ifdef([AM_INIT_AUTOMAKE],
[m4_undefine([AM_INIT_AUTOMAKE])])dnl
dnl
m4_define([$0], [])[]dnl
])
dnl _XC_AMEND_DISTCLEAN_BODY ([LIST-OF-SUBDIRS])
dnl -------------------------------------------------
dnl Private macro.
dnl
dnl This macro performs shell code embedding into
dnl configure script in order to modify distclean
dnl and maintainer-clean targets of makefiles which
dnl are located in given list of subdirs.
dnl
dnl See XC_AMEND_DISTCLEAN comments for details.
m4_define([_XC_AMEND_DISTCLEAN_BODY],
[dnl
## ---------------------------------- ##
## Start of distclean amending code ##
## ---------------------------------- ##
for xc_subdir in [$1]
do
if test ! -f "$xc_subdir/Makefile"; then
echo "$xc_msg_err $xc_subdir/Makefile file not found. $xc_msg_abrt" >&2
exit 1
fi
# Fetch dependency tracking file list from Makefile include lines.
xc_inc_lines=`grep '^include .*(DEPDIR)' "$xc_subdir/Makefile" 2>/dev/null`
xc_cnt_words=`echo "$xc_inc_lines" | wc -w | tr -d "$xc_space$xc_tab"`
# --disable-dependency-tracking might have been used, consequently
# there is nothing to amend without a dependency tracking file list.
if test $xc_cnt_words -gt 0; then
AC_MSG_NOTICE([amending $xc_subdir/Makefile])
# Build Makefile specific patch hunk.
xc_p="$xc_subdir/xc_patch.tmp"
xc_rm_depfiles=`echo "$xc_inc_lines" \
| $SED 's%include% -rm -f%' 2>/dev/null`
xc_dep_subdirs=`echo "$xc_inc_lines" \
| $SED 's%include[[ ]][[ ]]*%%' 2>/dev/null \
| $SED 's%(DEPDIR)/.*%(DEPDIR)%' 2>/dev/null \
| sort | uniq`
echo "$xc_rm_depfiles" >$xc_p
for xc_dep_dir in $xc_dep_subdirs; do
echo "${xc_tab}@xm_dep_cnt=\`ls $xc_dep_dir | wc -l 2>/dev/null\`; \\" >>$xc_p
echo "${xc_tab}if test \$\$xm_dep_cnt -eq 0 && test -d $xc_dep_dir; then \\" >>$xc_p
echo "${xc_tab} rm -rf $xc_dep_dir; \\" >>$xc_p
echo "${xc_tab}fi" >>$xc_p
done
# Build Makefile patching sed scripts.
xc_s1="$xc_subdir/xc_script_1.tmp"
xc_s2="$xc_subdir/xc_script_2.tmp"
xc_s3="$xc_subdir/xc_script_3.tmp"
cat >$xc_s1 <<\_EOT
/^distclean[[ ]]*:/,/^[[^ ]][[^ ]]*:/{
s/^.*(DEPDIR)/___xc_depdir_line___/
}
/^maintainer-clean[[ ]]*:/,/^[[^ ]][[^ ]]*:/{
s/^.*(DEPDIR)/___xc_depdir_line___/
}
_EOT
cat >$xc_s2 <<\_EOT
/___xc_depdir_line___$/{
N
/___xc_depdir_line___$/D
}
_EOT
cat >$xc_s3 <<_EOT
/^___xc_depdir_line___/{
r $xc_p
d
}
_EOT
# Apply patch to Makefile and cleanup.
$SED -f "$xc_s1" "$xc_subdir/Makefile" >"$xc_subdir/Makefile.tmp1"
$SED -f "$xc_s2" "$xc_subdir/Makefile.tmp1" >"$xc_subdir/Makefile.tmp2"
$SED -f "$xc_s3" "$xc_subdir/Makefile.tmp2" >"$xc_subdir/Makefile.tmp3"
if test -f "$xc_subdir/Makefile.tmp3"; then
mv -f "$xc_subdir/Makefile.tmp3" "$xc_subdir/Makefile"
fi
test -f "$xc_subdir/Makefile.tmp1" && rm -f "$xc_subdir/Makefile.tmp1"
test -f "$xc_subdir/Makefile.tmp2" && rm -f "$xc_subdir/Makefile.tmp2"
test -f "$xc_subdir/Makefile.tmp3" && rm -f "$xc_subdir/Makefile.tmp3"
test -f "$xc_p" && rm -f "$xc_p"
test -f "$xc_s1" && rm -f "$xc_s1"
test -f "$xc_s2" && rm -f "$xc_s2"
test -f "$xc_s3" && rm -f "$xc_s3"
fi
done
## -------------------------------- ##
## End of distclean amending code ##
## -------------------------------- ##
dnl
m4_define([$0], [])[]dnl
])
dnl XC_AMEND_DISTCLEAN ([LIST-OF-SUBDIRS])
dnl -------------------------------------------------
dnl Public macro.
dnl
dnl This macro embeds shell code into configure script
dnl that amends, at configure runtime, the distclean
dnl and maintainer-clean targets of Makefiles located
dnl in all subdirs given in the mandatory white-space
dnl separated list argument.
dnl
dnl Embedding only takes place when using automake 1.14
dnl or newer, otherwise amending code is not included
dnl in generated configure script.
dnl
dnl distclean and maintainer-clean targets are modified
dnl to avoid unconditional removal of dependency subdirs
dnl which triggers distclean and maintainer-clean errors
dnl when using automake 'subdir-objects' option along
dnl with per-target objects and source files existing in
dnl multiple subdirs used for different build targets.
dnl
dnl New behavior first removes each dependency tracking
dnl file independently, and only removes each dependency
dnl subdir when it finds out that it no longer holds any
dnl dependency tracking file.
dnl
dnl When configure option --disable-dependency-tracking
dnl is used no amending takes place given that there are
dnl no dependency tracking files.
AC_DEFUN([XC_AMEND_DISTCLEAN],
[dnl
AC_PREREQ([2.50])dnl
dnl
m4_ifdef([_AC_OUTPUT_MAIN_LOOP],
[m4_provide_if([_AC_OUTPUT_MAIN_LOOP], [],
[m4_fatal([call to AC_OUTPUT needed before $0])])])dnl
dnl
m4_if([$#], [1], [], [m4_fatal([$0: wrong number of arguments])])dnl
m4_if([$1], [], [m4_fatal([$0: missing argument])])dnl
dnl
AC_REQUIRE([XC_CONFIGURE_PREAMBLE])dnl
dnl
m4_ifdef([_AM_PROG_CC_C_O],
[
_XC_AMEND_DISTCLEAN_BODY([$1])
])dnl
m4_define([$0], [])[]dnl
])

View File

@@ -59,7 +59,7 @@ dnl Private macro.
AC_DEFUN([_XC_PROG_CC], [
AC_REQUIRE([_XC_PROG_CC_PREAMBLE])dnl
AC_REQUIRE([XC_CHECK_USER_FLAGS])dnl
AC_REQUIRE([XC_CHECK_BUILD_FLAGS])dnl
AC_REQUIRE([AC_PROG_INSTALL])dnl
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AM_PROG_CC_C_O])dnl

View File

@@ -39,7 +39,7 @@ AC_DEFUN([_XC_CHECK_VAR_LIBS], [
done
if test $xc_bad_var_libs = yes; then
AC_MSG_NOTICE([using LIBS: $LIBS])
AC_MSG_NOTICE([LIBS error: LIBS may only be used to specify libraries (-lname).])
AC_MSG_NOTICE([LIBS note: LIBS should only be used to specify libraries (-lname).])
fi
])
@@ -68,7 +68,7 @@ AC_DEFUN([_XC_CHECK_VAR_LDFLAGS], [
done
if test $xc_bad_var_ldflags = yes; then
AC_MSG_NOTICE([using LDFLAGS: $LDFLAGS])
xc_bad_var_msg="LDFLAGS error: LDFLAGS may only be used to specify linker flags, not"
xc_bad_var_msg="LDFLAGS note: LDFLAGS should only be used to specify linker flags, not"
for xc_word in $LDFLAGS; do
case "$xc_word" in
-D*)
@@ -110,7 +110,7 @@ AC_DEFUN([_XC_CHECK_VAR_CPPFLAGS], [
done
if test $xc_bad_var_cppflags = yes; then
AC_MSG_NOTICE([using CPPFLAGS: $CPPFLAGS])
xc_bad_var_msg="CPPFLAGS error: CPPFLAGS may only be used to specify C preprocessor flags, not"
xc_bad_var_msg="CPPFLAGS note: CPPFLAGS should only be used to specify C preprocessor flags, not"
for xc_word in $CPPFLAGS; do
case "$xc_word" in
-rpath*)
@@ -158,7 +158,7 @@ AC_DEFUN([_XC_CHECK_VAR_CFLAGS], [
done
if test $xc_bad_var_cflags = yes; then
AC_MSG_NOTICE([using CFLAGS: $CFLAGS])
xc_bad_var_msg="CFLAGS error: CFLAGS may only be used to specify C compiler flags, not"
xc_bad_var_msg="CFLAGS note: CFLAGS should only be used to specify C compiler flags, not"
for xc_word in $CFLAGS; do
case "$xc_word" in
-D*)

View File

@@ -39,22 +39,24 @@ header files are thus altered during build process to use this pragma, in
order to force libcurl enums of being type int (the pragma disposition in use
before inclusion is restored before resuming the including unit compilation).
Three SSL implementations were present in libcurl. Nevertheless, none of them
is available on OS/400. To support SSL on OS/400, a fourth implementation has
been added (qssl.[ch]). There is no way to have different certificate stores
for CAs and for personal/application certificates/key. More, the SSL context
may be defined as an application identifier in the main certificate store,
or as a keyring file. As a consequence, the meaning of some fields have been
slightly altered:
_ The "certificate identifier" is taken from CURLOPT_SSLCERT if defined, else
from CURLOPT_CAINFO.
_ The certificate identifier is then used as an application identifier in the
main certificate store. If successful, this context is used.
_ If the previous step failed, the certificate identifier is used as the file
name of a keyring. CURLOPT_KEYPASSWD is used here as the keyring password.
_ The default ca-bundle (CURLOPT_CAINFO) is set to the main certificate store's
keyring file name: this allows to use the system global CAs by default. (In that
case, the keyring password is safely recovered from the system... IBM dixit!)
Two SSL implementations are available to libcurl on OS/400: QsoSSL which is
obsolescent, does not support asynchronous I/O and only allows a single SSL
context within a job, and GSKit that does not suffer from these limitations
and is able to provide some information about the server certificate.
Both implementations of SSL are working on "certificate stores" or keyrings,
rather than individual certificate/key files. Certificate stores, as weel as
"certificate labels" are managed by external IBM-defined applications.
There are two ways to specify an SSL context:
- By an application identifier.
- By a keyring file pathname and (optionally) certificate label.
To identify an SSL context by application identifier, use option
SETOPT_SSLCERT to specify the application identifier.
To address an SSL context by keyring and certificate label, use CURLOPT_CAINFO
to set-up the keyring pathname, CURLOPT_SSLCERT to define the certificate label
(omitting it will cause the default certificate in keyring to be used) and
CURLOPT_KEYPASSWD to give the keyring password. If SSL is used without
defining any of these options, the default (i.e.: system) keyring is used for
server certificate validation.
Non-standard EBCDIC wrapper prototypes are defined in an additional header
file: ccsidcurl.h. These should be self-explanatory to an OS/400-aware
@@ -154,6 +156,14 @@ use:
CURLINFO_PRIMARY_IP
CURLINFO_RTSP_SESSION_ID
CURLINFO_LOCAL_IP
Likewise, the following options are followed by a struct curl_slist * * and a
CCSID.
CURLINFO_SSL_ENGINES
CURLINFO_COOKIELIST
Lists returned should be released with curl_slist_free_all() after use.
Option CURLINFO_CERTINFO is followed by a struct curl_certinfo * * and a
CCSID. Returned structures sould be free'ed using curl_certinfo_free_all() after
use.
Other options are processed like in curl_easy_getinfo().
Standard compilation environment does support neither autotools nor make;
@@ -200,6 +210,8 @@ _ As a prerequisite, QADRT development environment must be installed.
_ Install the curl source directory in IFS.
_ Enter shell (QSH)
_ Change current directory to the curl installation directory
- If the SSL backend has to be changed, edit file lib/config-os400.h
accordingly.
_ Change current directory to ./packages/OS400
_ Edit file iniscript.sh. You may want to change tunable configuration
parameters, like debug info generation, optimisation level, listing option,

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -33,6 +33,7 @@
#include "curl.h"
#include "mprintf.h"
#include "slist.h"
#include "urldata.h"
#include "url.h"
#include "getinfo.h"
@@ -67,7 +68,7 @@ makeOS400IconvCode(char buf[ICONV_ID_SIZE], unsigned int ccsid)
ccsid &= 0xFFFF;
if (ccsid == NOCONV_CCSID)
if(ccsid == NOCONV_CCSID)
ccsid = ASCII_CCSID;
memset(buf, 0, ICONV_ID_SIZE);
@@ -93,7 +94,7 @@ iconv_open_CCSID(unsigned int ccsidout, unsigned int ccsidin, unsigned int cstr)
makeOS400IconvCode(tocode, ccsidout);
memset(tocode + 13, 0, sizeof tocode - 13); /* Dest. code id format. */
if (cstr)
if(cstr)
fromcode[18] = '1'; /* Set null-terminator flag. */
return iconv_open(tocode, fromcode);
@@ -117,23 +118,23 @@ convert(char * d, size_t dlen, int dccsid,
*** Return the converted destination byte count, or -1 if error.
**/
if (sccsid == 65535)
if(sccsid == 65535)
sccsid = ASCII_CCSID;
if (dccsid == 65535)
if(dccsid == 65535)
dccsid = ASCII_CCSID;
if (sccsid == dccsid) {
if(sccsid == dccsid) {
lslen = slen >= 0? slen: strlen(s) + 1;
i = lslen < dlen? lslen: dlen;
if (s != d && i > 0)
if(s != d && i > 0)
memcpy(d, s, i);
return i;
}
if (slen < 0) {
if(slen < 0) {
lslen = 0;
cd = iconv_open_CCSID(dccsid, sccsid, 1);
}
@@ -142,12 +143,12 @@ convert(char * d, size_t dlen, int dccsid,
cd = iconv_open_CCSID(dccsid, sccsid, 0);
}
if (ICONV_OPEN_ERROR(cd))
if(ICONV_OPEN_ERROR(cd))
return -1;
i = dlen;
if ((int) iconv(cd, (char * *) &s, &lslen, &d, &dlen) < 0)
if((int) iconv(cd, (char * *) &s, &lslen, &d, &dlen) < 0)
i = -1;
else
i -= dlen;
@@ -174,24 +175,24 @@ dynconvert(int dccsid, const char * s, int slen, int sccsid)
dlen *= MAX_CONV_EXPANSION; /* Allow some expansion. */
d = malloc(dlen);
if (!d)
if(!d)
return (char *) NULL;
l = convert(d, dlen, dccsid, s, slen, sccsid);
if (l < 0) {
if(l < 0) {
free(d);
return (char *) NULL;
}
if (slen < 0) {
if(slen < 0) {
/* Need to null-terminate even when source length is given.
Since destination code size is unknown, use a conversion to generate
terminator. */
l2 = convert(d + l, dlen - l, dccsid, &nullbyte, -1, ASCII_CCSID);
if (l2 < 0) {
if(l2 < 0) {
free(d);
return (char *) NULL;
}
@@ -199,10 +200,10 @@ dynconvert(int dccsid, const char * s, int slen, int sccsid)
l += l2;
}
if ((size_t) l < dlen) {
if((size_t) l < dlen) {
cp = realloc(d, l); /* Shorten to minimum needed. */
if (cp)
if(cp)
d = cp;
}
@@ -210,6 +211,24 @@ dynconvert(int dccsid, const char * s, int slen, int sccsid)
}
static struct curl_slist *
slist_convert(int dccsid, struct curl_slist * from, int sccsid)
{
struct curl_slist * to = (struct curl_slist *) NULL;
char * cp;
for (; from; from = from->next) {
if(!(cp = dynconvert(dccsid, from->data, -1, sccsid))) {
curl_slist_free_all(to);
return (struct curl_slist *) NULL;
}
to = Curl_slist_append_nodup(to, cp);
}
return to;
}
char *
curl_version_ccsid(unsigned int ccsid)
@@ -220,16 +239,16 @@ curl_version_ccsid(unsigned int ccsid)
aversion = curl_version();
if (!aversion)
if(!aversion)
return aversion;
i = strlen(aversion) + 1;
i *= MAX_CONV_EXPANSION;
if (!(eversion = Curl_thread_buffer(LK_CURL_VERSION, i)))
if(!(eversion = Curl_thread_buffer(LK_CURL_VERSION, i)))
return (char *) NULL;
if (convert(eversion, i, ccsid, aversion, -1, ASCII_CCSID) < 0)
if(convert(eversion, i, ccsid, aversion, -1, ASCII_CCSID) < 0)
return (char *) NULL;
return eversion;
@@ -244,20 +263,20 @@ curl_easy_escape_ccsid(CURL * handle, const char * string, int length,
char * s;
char * d;
if (!string) {
if(!string) {
errno = EINVAL;
return (char *) NULL;
}
s = dynconvert(ASCII_CCSID, s, length? length: -1, sccsid);
if (!s)
if(!s)
return (char *) NULL;
d = curl_easy_escape(handle, s, 0);
free(s);
if (!d)
if(!d)
return (char *) NULL;
s = dynconvert(dccsid, d, -1, ASCII_CCSID);
@@ -275,26 +294,26 @@ curl_easy_unescape_ccsid(CURL * handle, const char * string, int length,
char * s;
char * d;
if (!string) {
if(!string) {
errno = EINVAL;
return (char *) NULL;
}
s = dynconvert(ASCII_CCSID, s, length? length: -1, sccsid);
if (!s)
if(!s)
return (char *) NULL;
d = curl_easy_unescape(handle, s, 0, outlength);
free(s);
if (!d)
if(!d)
return (char *) NULL;
s = dynconvert(dccsid, d, -1, ASCII_CCSID);
free(d);
if (s && outlength)
if(s && outlength)
*outlength = strlen(s);
return s;
@@ -310,12 +329,12 @@ curl_slist_append_ccsid(struct curl_slist * list,
s = (char *) NULL;
if (!data)
if(!data)
return curl_slist_append(list, data);
s = dynconvert(ASCII_CCSID, data, -1, ccsid);
if (!s)
if(!s)
return (struct curl_slist *) NULL;
list = curl_slist_append(list, s);
@@ -331,12 +350,12 @@ curl_getdate_ccsid(const char * p, const time_t * unused, unsigned int ccsid)
char * s;
time_t t;
if (!p)
if(!p)
return curl_getdate(p, unused);
s = dynconvert(ASCII_CCSID, p, -1, ccsid);
if (!s)
if(!s)
return (time_t) -1;
t = curl_getdate(s, unused);
@@ -357,10 +376,10 @@ convert_version_info_string(const char * * stringp,
`*bufp' and `*left' are updated accordingly.
Return 0 if ok, else -1. */
if (*stringp) {
if(*stringp) {
l = convert(*bufp, *left, ccsid, *stringp, -1, ASCII_CCSID);
if (l <= 0)
if(l <= 0)
return -1;
*stringp = *bufp;
@@ -393,12 +412,12 @@ curl_version_info_ccsid(CURLversion stamp, unsigned int ccsid)
/* If caller has been compiled with a new version, error. */
if (stamp > CURLVERSION_NOW)
if(stamp > CURLVERSION_NOW)
return (curl_version_info_data *) NULL;
p = curl_version_info(stamp);
if (!p)
if(!p)
return p;
/* Measure thread space needed. */
@@ -406,53 +425,53 @@ curl_version_info_ccsid(CURLversion stamp, unsigned int ccsid)
n = 0;
nproto = 0;
if (p->protocols) {
if(p->protocols) {
while (p->protocols[nproto])
n += strlen(p->protocols[nproto++]);
n += nproto++;
}
if (p->version)
if(p->version)
n += strlen(p->version) + 1;
if (p->host)
if(p->host)
n += strlen(p->host) + 1;
if (p->ssl_version)
if(p->ssl_version)
n += strlen(p->ssl_version) + 1;
if (p->libz_version)
if(p->libz_version)
n += strlen(p->libz_version) + 1;
if (p->ares)
if(p->ares)
n += strlen(p->ares) + 1;
if (p->libidn)
if(p->libidn)
n += strlen(p->libidn) + 1;
if (p->libssh_version)
if(p->libssh_version)
n += strlen(p->libssh_version) + 1;
/* Allocate thread space. */
n *= MAX_CONV_EXPANSION;
if (nproto)
if(nproto)
n += nproto * sizeof(const char *);
cp = Curl_thread_buffer(LK_VERSION_INFO_DATA, n);
id = (curl_version_info_data *) Curl_thread_buffer(LK_VERSION_INFO,
sizeof *id);
if (!id || !cp)
if(!id || !cp)
return (curl_version_info_data *) NULL;
/* Copy data and convert strings. */
memcpy((char *) id, (char *) p, sizeof *p);
if (id->protocols) {
if(id->protocols) {
id->protocols = (const char * const *) cp;
i = nproto * sizeof id->protocols[0];
memcpy(cp, (char *) p->protocols, i);
@@ -460,30 +479,30 @@ curl_version_info_ccsid(CURLversion stamp, unsigned int ccsid)
n -= i;
for (i = 0; id->protocols[i]; i++)
if (convert_version_info_string(((const char * *) id->protocols) + i,
if(convert_version_info_string(((const char * *) id->protocols) + i,
&cp, &n, ccsid))
return (curl_version_info_data *) NULL;
}
if (convert_version_info_string(&id->version, &cp, &n, ccsid))
if(convert_version_info_string(&id->version, &cp, &n, ccsid))
return (curl_version_info_data *) NULL;
if (convert_version_info_string(&id->host, &cp, &n, ccsid))
if(convert_version_info_string(&id->host, &cp, &n, ccsid))
return (curl_version_info_data *) NULL;
if (convert_version_info_string(&id->ssl_version, &cp, &n, ccsid))
if(convert_version_info_string(&id->ssl_version, &cp, &n, ccsid))
return (curl_version_info_data *) NULL;
if (convert_version_info_string(&id->libz_version, &cp, &n, ccsid))
if(convert_version_info_string(&id->libz_version, &cp, &n, ccsid))
return (curl_version_info_data *) NULL;
if (convert_version_info_string(&id->ares, &cp, &n, ccsid))
if(convert_version_info_string(&id->ares, &cp, &n, ccsid))
return (curl_version_info_data *) NULL;
if (convert_version_info_string(&id->libidn, &cp, &n, ccsid))
if(convert_version_info_string(&id->libidn, &cp, &n, ccsid))
return (curl_version_info_data *) NULL;
if (convert_version_info_string(&id->libssh_version, &cp, &n, ccsid))
if(convert_version_info_string(&id->libssh_version, &cp, &n, ccsid))
return (curl_version_info_data *) NULL;
return id;
@@ -500,15 +519,15 @@ curl_easy_strerror_ccsid(CURLcode error, unsigned int ccsid)
s = curl_easy_strerror(error);
if (!s)
if(!s)
return s;
i = MAX_CONV_EXPANSION * (strlen(s) + 1);
if (!(buf = Curl_thread_buffer(LK_EASY_STRERROR, i)))
if(!(buf = Curl_thread_buffer(LK_EASY_STRERROR, i)))
return (const char *) NULL;
if (convert(buf, i, ccsid, s, -1, ASCII_CCSID) < 0)
if(convert(buf, i, ccsid, s, -1, ASCII_CCSID) < 0)
return (const char *) NULL;
return (const char *) buf;
@@ -525,15 +544,15 @@ curl_share_strerror_ccsid(CURLSHcode error, unsigned int ccsid)
s = curl_share_strerror(error);
if (!s)
if(!s)
return s;
i = MAX_CONV_EXPANSION * (strlen(s) + 1);
if (!(buf = Curl_thread_buffer(LK_SHARE_STRERROR, i)))
if(!(buf = Curl_thread_buffer(LK_SHARE_STRERROR, i)))
return (const char *) NULL;
if (convert(buf, i, ccsid, s, -1, ASCII_CCSID) < 0)
if(convert(buf, i, ccsid, s, -1, ASCII_CCSID) < 0)
return (const char *) NULL;
return (const char *) buf;
@@ -550,21 +569,39 @@ curl_multi_strerror_ccsid(CURLMcode error, unsigned int ccsid)
s = curl_multi_strerror(error);
if (!s)
if(!s)
return s;
i = MAX_CONV_EXPANSION * (strlen(s) + 1);
if (!(buf = Curl_thread_buffer(LK_MULTI_STRERROR, i)))
if(!(buf = Curl_thread_buffer(LK_MULTI_STRERROR, i)))
return (const char *) NULL;
if (convert(buf, i, ccsid, s, -1, ASCII_CCSID) < 0)
if(convert(buf, i, ccsid, s, -1, ASCII_CCSID) < 0)
return (const char *) NULL;
return (const char *) buf;
}
void
curl_certinfo_free_all(struct curl_certinfo *info)
{
int i;
/* Free all memory used by certificate info. */
if(info) {
if(info->certinfo) {
for (i = 0; i < info->num_of_certs; i++)
curl_slist_free_all(info->certinfo[i]);
free((char *) info->certinfo);
}
free((char *) info);
}
}
CURLcode
curl_easy_getinfo_ccsid(CURL * curl, CURLINFO info, ...)
@@ -577,6 +614,10 @@ curl_easy_getinfo_ccsid(CURL * curl, CURLINFO info, ...)
char * s;
char * d;
struct SessionHandle * data;
struct curl_slist * * slp;
struct curl_certinfo * cipf;
struct curl_certinfo * cipt;
int i;
/* WARNING: unlike curl_easy_get_info(), the strings returned by this
procedure have to be free'ed. */
@@ -586,25 +627,66 @@ curl_easy_getinfo_ccsid(CURL * curl, CURLINFO info, ...)
paramp = va_arg(arg, void *);
ret = Curl_getinfo(data, info, paramp);
if (ret != CURLE_OK || ((int) info & CURLINFO_TYPEMASK) != CURLINFO_STRING) {
va_end(arg);
return ret;
}
if(ret == CURLE_OK)
switch ((int) info & CURLINFO_TYPEMASK) {
case CURLINFO_STRING:
ccsid = va_arg(arg, unsigned int);
va_end(arg);
cpp = (char * *) paramp;
s = *cpp;
if (!s)
return ret;
if(s) {
d = dynconvert(ccsid, s, -1, ASCII_CCSID);
*cpp = d;
if (!d)
return CURLE_OUT_OF_MEMORY;
if(!d)
ret = CURLE_OUT_OF_MEMORY;
}
break;
case CURLINFO_SLIST:
ccsid = va_arg(arg, unsigned int);
if(info == CURLINFO_CERTINFO) {
cipf = *(struct curl_certinfo * *) paramp;
if(cipf) {
if(!(cipt = (struct curl_certinfo *) malloc(sizeof *cipt)))
ret = CURLE_OUT_OF_MEMORY;
else {
cipt->certinfo = (struct curl_slist * *) calloc(cipf->num_of_certs +
1, sizeof(struct curl_slist *));
if(!cipt->certinfo)
ret = CURLE_OUT_OF_MEMORY;
else {
cipt->num_of_certs = cipf->num_of_certs;
for (i = 0; i < cipf->num_of_certs; i++)
if(cipf->certinfo[i])
if(!(cipt->certinfo[i] = slist_convert(ccsid,
cipf->certinfo[i],
ASCII_CCSID))) {
ret = CURLE_OUT_OF_MEMORY;
break;
}
}
}
if(ret != CURLE_OK) {
curl_certinfo_free_all(cipt);
cipt = (struct curl_certinfo *) NULL;
}
*(struct curl_certinfo * *) paramp = cipt;
}
}
else {
slp = (struct curl_slist * *) paramp;
if(*slp)
if(!(*slp = slist_convert(ccsid, *slp, ASCII_CCSID)))
ret = CURLE_OUT_OF_MEMORY;
}
}
va_end(arg);
return ret;
}
@@ -634,9 +716,9 @@ Curl_formadd_release_local(struct curl_forms * forms, int nargs, int skip)
{
while (nargs--)
if (nargs != skip)
if (Curl_is_formadd_string(forms[nargs].option))
if (forms[nargs].value)
if(nargs != skip)
if(Curl_is_formadd_string(forms[nargs].option))
if(forms[nargs].value)
free((char *) forms[nargs].value);
free((char *) forms);
@@ -652,35 +734,35 @@ Curl_formadd_convert(struct curl_forms * forms,
char * cp;
char * cp2;
if (formx < 0 || !forms[formx].value)
if(formx < 0 || !forms[formx].value)
return 0;
if (lengthx >= 0)
if(lengthx >= 0)
l = (int) forms[lengthx].value;
else
l = strlen(forms[formx].value) + 1;
cp = malloc(MAX_CONV_EXPANSION * l);
if (!cp)
if(!cp)
return -1;
l = convert(cp, MAX_CONV_EXPANSION * l, ASCII_CCSID,
forms[formx].value, l, ccsid);
if (l < 0) {
if(l < 0) {
free(cp);
return -1;
}
cp2 = realloc(cp, l); /* Shorten buffer to the string size. */
if (cp2)
if(cp2)
cp = cp2;
forms[formx].value = cp;
if (lengthx >= 0)
if(lengthx >= 0)
forms[lengthx].value = (char *) l; /* Update to length after conversion. */
return l;
@@ -729,7 +811,7 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
lformlen = ALLOC_GRANULE;
lforms = malloc(lformlen * sizeof *lforms);
if (!lforms)
if(!lforms)
return CURL_FORMADD_MEMORY;
/* Process the arguments, copying them into local array, latching conversion
@@ -747,11 +829,11 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
for (;;) {
/* Make sure there is still room for an item in local array. */
if (nargs >= lformlen) {
if(nargs >= lformlen) {
lformlen += ALLOC_GRANULE;
tforms = realloc(lforms, lformlen * sizeof *lforms);
if (!tforms) {
if(!tforms) {
result = CURL_FORMADD_MEMORY;
break;
}
@@ -761,7 +843,7 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
/* Get next option. */
if (forms) {
if(forms) {
/* Get option from array. */
option = forms->option;
@@ -773,7 +855,7 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
option = va_arg(arg, CURLformoption);
if (option == CURLFORM_END)
if(option == CURLFORM_END)
break;
}
@@ -786,7 +868,7 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
continue;
case CURLFORM_ARRAY:
if (!forms) {
if(!forms) {
forms = va_arg(arg, struct curl_forms *);
continue;
}
@@ -798,12 +880,12 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
option = CURLFORM_PTRNAME; /* Static for now. */
case CURLFORM_PTRNAME:
if (namex >= 0)
if(namex >= 0)
result = CURL_FORMADD_OPTION_TWICE;
namex = nargs;
if (!forms) {
if(!forms) {
value = va_arg(arg, char *);
nameccsid = (unsigned int) va_arg(arg, long);
}
@@ -815,12 +897,12 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
break;
case CURLFORM_COPYCONTENTS:
if (contentx >= 0)
if(contentx >= 0)
result = CURL_FORMADD_OPTION_TWICE;
contentx = nargs;
if (!forms) {
if(!forms) {
value = va_arg(arg, char *);
contentccsid = (unsigned int) va_arg(arg, long);
}
@@ -833,7 +915,7 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
case CURLFORM_PTRCONTENTS:
case CURLFORM_BUFFERPTR:
if (!forms)
if(!forms)
value = va_arg(arg, char *); /* No conversion. */
break;
@@ -841,7 +923,7 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
case CURLFORM_CONTENTSLENGTH:
lengthx = nargs;
if (!forms)
if(!forms)
value = (char *) va_arg(arg, long);
break;
@@ -849,25 +931,25 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
case CURLFORM_NAMELENGTH:
namelengthx = nargs;
if (!forms)
if(!forms)
value = (char *) va_arg(arg, long);
break;
case CURLFORM_BUFFERLENGTH:
if (!forms)
if(!forms)
value = (char *) va_arg(arg, long);
break;
case CURLFORM_CONTENTHEADER:
if (!forms)
if(!forms)
value = (char *) va_arg(arg, struct curl_slist *);
break;
case CURLFORM_STREAM:
if (!forms)
if(!forms)
value = (char *) va_arg(arg, void *);
break;
@@ -875,7 +957,7 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
case CURLFORM_CONTENTTYPE:
/* If a previous content has been encountered, convert it now. */
if (Curl_formadd_convert(lforms, contentx, lengthx, contentccsid) < 0) {
if(Curl_formadd_convert(lforms, contentx, lengthx, contentccsid) < 0) {
result = CURL_FORMADD_MEMORY;
break;
}
@@ -887,12 +969,12 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
default:
/* Must be a convertible string. */
if (!Curl_is_formadd_string(option)) {
if(!Curl_is_formadd_string(option)) {
result = CURL_FORMADD_UNKNOWN_OPTION;
break;
}
if (!forms) {
if(!forms) {
value = va_arg(arg, char *);
ccsid = (unsigned int) va_arg(arg, long);
}
@@ -905,7 +987,7 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
lforms[nargs].value = value;
if (Curl_formadd_convert(lforms, nargs, -1, ccsid) < 0) {
if(Curl_formadd_convert(lforms, nargs, -1, ccsid) < 0) {
result = CURL_FORMADD_MEMORY;
break;
}
@@ -913,7 +995,7 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
value = lforms[nargs].value;
}
if (result != CURL_FORMADD_OK)
if(result != CURL_FORMADD_OK)
break;
lforms[nargs].value = value;
@@ -924,15 +1006,15 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
/* Convert the name and the last content, now that we know their lengths. */
if (result == CURL_FORMADD_OK && namex >= 0) {
if (Curl_formadd_convert(lforms, namex, namelengthx, nameccsid) < 0)
if(result == CURL_FORMADD_OK && namex >= 0) {
if(Curl_formadd_convert(lforms, namex, namelengthx, nameccsid) < 0)
result = CURL_FORMADD_MEMORY;
else
lforms[namex].option = CURLFORM_COPYNAME; /* Force copy. */
}
if (result == CURL_FORMADD_OK) {
if (Curl_formadd_convert(lforms, contentx, lengthx, contentccsid) < 0)
if(result == CURL_FORMADD_OK) {
if(Curl_formadd_convert(lforms, contentx, lengthx, contentccsid) < 0)
result = CURL_FORMADD_MEMORY;
else
contentx = -1;
@@ -940,7 +1022,7 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
/* Do the formadd with our converted parameters. */
if (result == CURL_FORMADD_OK) {
if(result == CURL_FORMADD_OK) {
lforms[nargs].option = CURLFORM_END;
result = curl_formadd(httppost, last_post,
CURLFORM_ARRAY, lforms, CURLFORM_END);
@@ -971,17 +1053,17 @@ Curl_formget_callback_ccsid(void * arg, const char * buf, size_t len)
p = (cfcdata *) arg;
if ((long) len <= 0)
if((long) len <= 0)
return (*p->append)(p->arg, buf, len);
b = malloc(MAX_CONV_EXPANSION * len);
if (!b)
if(!b)
return (size_t) -1;
l = convert(b, MAX_CONV_EXPANSION * len, p->ccsid, buf, len, ASCII_CCSID);
if (l < 0) {
if(l < 0) {
free(b);
return (size_t) -1;
}
@@ -1026,13 +1108,13 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
the same message; but since threadsafeness is not handled here,
this may occur (and we don't care!). */
if (testwarn) {
if(testwarn) {
testwarn = 0;
#ifdef USE_TLS_SRP
if ((int) STRING_LAST != (int) STRING_TLSAUTH_PASSWORD + 1)
if((int) STRING_LAST != (int) STRING_TLSAUTH_PASSWORD + 1)
#else
if ((int) STRING_LAST != (int) STRING_MAIL_AUTH + 1)
if((int) STRING_LAST != (int) STRING_MAIL_AUTH + 1)
#endif
curl_mfprintf(stderr,
"*** WARNING: curl_easy_setopt_ccsid() should be reworked ***\n");
@@ -1097,10 +1179,10 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
s = va_arg(arg, char *);
ccsid = va_arg(arg, unsigned int);
if (s) {
if(s) {
s = dynconvert(ASCII_CCSID, s, -1, ccsid);
if (!s) {
if(!s) {
result = CURLE_OUT_OF_MEMORY;
break;
}
@@ -1108,7 +1190,7 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
result = curl_easy_setopt(curl, tag, s);
if (s)
if(s)
free(s);
break;
@@ -1122,16 +1204,16 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
pfsize = data->set.postfieldsize;
if (!s || !pfsize || ccsid == NOCONV_CCSID || ccsid == ASCII_CCSID) {
if(!s || !pfsize || ccsid == NOCONV_CCSID || ccsid == ASCII_CCSID) {
result = curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, s);
break;
}
if (pfsize == -1) {
if(pfsize == -1) {
/* Data is null-terminated. */
s = dynconvert(ASCII_CCSID, s, -1, ccsid);
if (!s) {
if(!s) {
result = CURLE_OUT_OF_MEMORY;
break;
}
@@ -1139,7 +1221,7 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
else {
/* Data length specified. */
if (pfsize < 0 || pfsize > SIZE_MAX) {
if(pfsize < 0 || pfsize > SIZE_MAX) {
result = CURLE_OUT_OF_MEMORY;
break;
}
@@ -1147,19 +1229,19 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
len = pfsize;
pfsize = len * MAX_CONV_EXPANSION;
if (pfsize > SIZE_MAX)
if(pfsize > SIZE_MAX)
pfsize = SIZE_MAX;
cp = malloc(pfsize);
if (!cp) {
if(!cp) {
result = CURLE_OUT_OF_MEMORY;
break;
}
pfsize = convert(cp, pfsize, ASCII_CCSID, s, len, ccsid);
if (pfsize < 0) {
if(pfsize < 0) {
free(cp);
result = CURLE_OUT_OF_MEMORY;
break;

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -60,5 +60,6 @@ CURL_EXTERN int curl_formget_ccsid(struct curl_httppost * form, void * arg,
curl_formget_callback append,
unsigned int ccsid);
CURL_EXTERN CURLcode curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...);
CURL_EXTERN void curl_certinfo_free_all(struct curl_certinfo *info);
#endif

View File

@@ -498,6 +498,8 @@
d c 87
d CURLE_CHUNK_FAILED...
d c 88
d CURLE_NO_CONNECTION_AVAILABLE...
d c 89
*
/if not defined(CURL_NO_OLDIES)
d CURLE_URL_MALFORMAT_USER...
@@ -859,6 +861,8 @@
d c 20056
d CURLOPT_PROGRESSDATA...
d c 10057
d CURLOPT_XFERINFODATA...
d c 10057 PROGRESSDATA alias
d CURLOPT_AUTOREFERER...
d c 00058
d CURLOPT_PROXYPORT...
@@ -1154,6 +1158,10 @@
d c 00216
d CURLOPT_MAIL_AUTH...
d c 10217
d CURLOPT_SASL_IR...
d c 00218
d CURLOPT_XFERINFOFUNCTION...
d c 20219
*
/if not defined(CURL_NO_OLDIES)
d CURLOPT_SSLKEYPASSWD...
@@ -1462,6 +1470,20 @@
d c 10005
d CURLMOPT_MAXCONNECTS...
d c 00006
d CURLMOPT_MAX_HOST_CONNECTIONS...
d c 00007
d CURLMOPT_MAX_PIPELINE_LENGTH...
d c 00008
d CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE...
d c 30009
d CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE...
d c 30010
d CURLMOPT_PIPELINING_SITE_BL...
d c 10011
d CURLMOPT_PIPELINING_SERVER_BL...
d c 10012
d CURLMOPT_MAX_TOTAL_CONNECTIONS...
d c 00013
*
* Public API enums for RTSP requests.
*
@@ -1641,6 +1663,9 @@
d s * based(######ptr######) procptr
*
d curl_progress_callback...
d s * based(######ptr######) procptr
*
d curl_xferinfo_callback...
d s * based(######ptr######) procptr
*
d curl_read_callback...
@@ -2109,14 +2134,19 @@
d code value like(CURLMcode)
d ccsid 10u 0 value
*
* May be used for strings and structures.
d curl_easy_getinfo_ccsid...
d pr extproc('curl_easy_getinfo_ccsid')
d like(CURLcode)
d curl * value CURL *
d info value like(CURLINFO)
d stringarg * options(*nopass) char *
d ptrarg * options(*nopass) char *
d ccsid 10u 0 value options(*nopass)
*
d curl_certinfo_free_all...
d pr extproc('curl_certinfo_free_all')
d info * value
*
d curl_formadd_ccsid...
d pr extproc('curl_formadd_ccsid')
d like(CURLFORMcode)

View File

@@ -47,6 +47,7 @@ done
# Build in each directory.
for SUBDIR in include lib src tests
# for SUBDIR in include lib src tests
for SUBDIR in include lib src
do "${SCRIPTDIR}/make-${SUBDIR}.sh"
done

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -42,6 +42,11 @@
#include <qsossl.h>
#endif
#ifdef USE_GSKIT
#include <gskssl.h>
#include <qsoasync.h>
#endif
#ifdef HAVE_GSSAPI
#include <gssapi.h>
#endif
@@ -451,6 +456,412 @@ Curl_SSL_Strerror_a(int sslreturnvalue, SSLErrorMsg * serrmsgp)
#endif /* USE_QSOSSL */
#ifdef USE_GSKIT
/* ASCII wrappers for the GSKit procedures. */
/*
* EBCDIC --> ASCII string mapping table.
* Some strings returned by GSKit are dynamically allocated and automatically
* released when closing the handle.
* To provide the same functionality, we use a "private" handle that
* holds the GSKit handle and a list of string mappings. This will allow
* avoid conversion of already converted strings and releasing them upon
* close time.
*/
struct gskstrlist {
struct gskstrlist * next;
const char * ebcdicstr;
const char * asciistr;
};
struct Curl_gsk_descriptor {
gsk_handle h;
struct gskstrlist * strlist;
};
int
Curl_gsk_environment_open(gsk_handle * my_env_handle)
{
struct Curl_gsk_descriptor * p;
gsk_handle h;
int rc;
if(!my_env_handle)
return GSK_OS400_ERROR_INVALID_POINTER;
if(!(p = (struct Curl_gsk_descriptor *) malloc(sizeof *p)))
return GSK_INSUFFICIENT_STORAGE;
p->strlist = (struct gskstrlist *) NULL;
if((rc = gsk_environment_open(&p->h)) != GSK_OK)
free(p);
else
*my_env_handle = (gsk_handle) p;
return rc;
}
int
Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
gsk_handle * my_session_handle)
{
struct Curl_gsk_descriptor * p;
gsk_handle h;
int rc;
if(!my_env_handle)
return GSK_INVALID_HANDLE;
if(!my_session_handle)
return GSK_OS400_ERROR_INVALID_POINTER;
h = ((struct Curl_gsk_descriptor *) my_env_handle)->h;
if(!(p = (struct Curl_gsk_descriptor *) malloc(sizeof *p)))
return GSK_INSUFFICIENT_STORAGE;
p->strlist = (struct gskstrlist *) NULL;
if((rc = gsk_secure_soc_open(h, &p->h)) != GSK_OK)
free(p);
else
*my_session_handle = (gsk_handle) p;
return rc;
}
static void
gsk_free_handle(struct Curl_gsk_descriptor * p)
{
struct gskstrlist * q;
while ((q = p->strlist)) {
p->strlist = q;
free((void *) q->asciistr);
free(q);
}
free(p);
}
int
Curl_gsk_environment_close(gsk_handle * my_env_handle)
{
struct Curl_gsk_descriptor * p;
int rc;
if(!my_env_handle)
return GSK_OS400_ERROR_INVALID_POINTER;
if(!*my_env_handle)
return GSK_INVALID_HANDLE;
p = (struct Curl_gsk_descriptor *) *my_env_handle;
if ((rc = gsk_environment_close(&p->h)) == GSK_OK) {
gsk_free_handle(p);
*my_env_handle = (gsk_handle) NULL;
}
return rc;
}
int
Curl_gsk_secure_soc_close(gsk_handle * my_session_handle)
{
struct Curl_gsk_descriptor * p;
int rc;
if(!my_session_handle)
return GSK_OS400_ERROR_INVALID_POINTER;
if(!*my_session_handle)
return GSK_INVALID_HANDLE;
p = (struct Curl_gsk_descriptor *) *my_session_handle;
if ((rc = gsk_secure_soc_close(&p->h)) == GSK_OK) {
gsk_free_handle(p);
*my_session_handle = (gsk_handle) NULL;
}
return rc;
}
int
Curl_gsk_environment_init(gsk_handle my_env_handle)
{
struct Curl_gsk_descriptor * p;
if(!my_env_handle)
return GSK_INVALID_HANDLE;
p = (struct Curl_gsk_descriptor *) my_env_handle;
return gsk_environment_init(p->h);
}
int
Curl_gsk_secure_soc_init(gsk_handle my_session_handle)
{
struct Curl_gsk_descriptor * p;
if(!my_session_handle)
return GSK_INVALID_HANDLE;
p = (struct Curl_gsk_descriptor *) my_session_handle;
return gsk_secure_soc_init(p->h);
}
int
Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
const char * buffer, int bufSize)
{
struct Curl_gsk_descriptor * p;
char * ebcdicbuf;
int rc;
if(!my_gsk_handle)
return GSK_INVALID_HANDLE;
if(!buffer)
return GSK_OS400_ERROR_INVALID_POINTER;
if(bufSize < 0)
return GSK_ATTRIBUTE_INVALID_LENGTH;
p = (struct Curl_gsk_descriptor *) my_gsk_handle;
if(!bufSize)
bufSize = strlen(buffer);
if (!(ebcdicbuf = malloc(bufSize + 1)))
return GSK_INSUFFICIENT_STORAGE;
QadrtConvertA2E(ebcdicbuf, buffer, bufSize, bufSize);
ebcdicbuf[bufSize] = '\0';
rc = gsk_attribute_set_buffer(p->h, bufID, ebcdicbuf, bufSize);
free(ebcdicbuf);
return rc;
}
int
Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
GSK_ENUM_VALUE enumValue)
{
struct Curl_gsk_descriptor * p;
if(!my_gsk_handle)
return GSK_INVALID_HANDLE;
p = (struct Curl_gsk_descriptor *) my_gsk_handle;
return gsk_attribute_set_enum(p->h, enumID, enumValue);
}
int
Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
GSK_NUM_ID numID, int numValue)
{
struct Curl_gsk_descriptor * p;
if(!my_gsk_handle)
return GSK_INVALID_HANDLE;
p = (struct Curl_gsk_descriptor *) my_gsk_handle;
return gsk_attribute_set_numeric_value(p->h, numID, numValue);
}
int
Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
GSK_CALLBACK_ID callBackID,
void * callBackAreaPtr)
{
struct Curl_gsk_descriptor * p;
if(!my_gsk_handle)
return GSK_INVALID_HANDLE;
p = (struct Curl_gsk_descriptor *) my_gsk_handle;
return gsk_attribute_set_callback(p->h, callBackID, callBackAreaPtr);
}
static int
cachestring(struct Curl_gsk_descriptor * p,
const char * ebcdicbuf, int bufsize, const char * * buffer)
{
int rc;
char * asciibuf;
struct gskstrlist * sp;
for (sp = p->strlist; sp; sp = sp->next)
if(sp->ebcdicstr == ebcdicbuf)
break;
if(!sp) {
if(!(sp = (struct gskstrlist *) malloc(sizeof *sp)))
return GSK_INSUFFICIENT_STORAGE;
if(!(asciibuf = malloc(bufsize + 1))) {
free(sp);
return GSK_INSUFFICIENT_STORAGE;
}
QadrtConvertE2A(asciibuf, ebcdicbuf, bufsize, bufsize);
asciibuf[bufsize] = '\0';
sp->ebcdicstr = ebcdicbuf;
sp->asciistr = asciibuf;
sp->next = p->strlist;
p->strlist = sp;
}
*buffer = sp->asciistr;
return GSK_OK;
}
int
Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
const char * * buffer, int * bufSize)
{
struct Curl_gsk_descriptor * p;
int rc;
const char * mybuf;
int mylen;
if(!my_gsk_handle)
return GSK_INVALID_HANDLE;
if(!buffer || !bufSize)
return GSK_OS400_ERROR_INVALID_POINTER;
p = (struct Curl_gsk_descriptor *) my_gsk_handle;
if ((rc = gsk_attribute_get_buffer(p->h, bufID, &mybuf, &mylen)) != GSK_OK)
return rc;
if((rc = cachestring(p, mybuf, mylen, buffer)) == GSK_OK)
*bufSize = mylen;
return rc;
}
int
Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
GSK_ENUM_VALUE * enumValue)
{
struct Curl_gsk_descriptor * p;
if(!my_gsk_handle)
return GSK_INVALID_HANDLE;
p = (struct Curl_gsk_descriptor *) my_gsk_handle;
return gsk_attribute_get_enum(p->h, enumID, enumValue);
}
int
Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
GSK_NUM_ID numID, int * numValue)
{
struct Curl_gsk_descriptor * p;
if(!my_gsk_handle)
return GSK_INVALID_HANDLE;
p = (struct Curl_gsk_descriptor *) my_gsk_handle;
return gsk_attribute_get_numeric_value(p->h, numID, numValue);
}
int
Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
GSK_CERT_ID certID,
const gsk_cert_data_elem * * certDataElem,
int * certDataElementCount)
{
struct Curl_gsk_descriptor * p;
if(!my_gsk_handle)
return GSK_INVALID_HANDLE;
p = (struct Curl_gsk_descriptor *) my_gsk_handle;
/* No need to convert code: text results are already in ASCII. */
return gsk_attribute_get_cert_info(p->h, certID,
certDataElem, certDataElementCount);
}
int
Curl_gsk_secure_soc_misc(gsk_handle my_session_handle, GSK_MISC_ID miscID)
{
struct Curl_gsk_descriptor * p;
if(!my_session_handle)
return GSK_INVALID_HANDLE;
p = (struct Curl_gsk_descriptor *) my_session_handle;
return gsk_secure_soc_misc(p->h, miscID);
}
int
Curl_gsk_secure_soc_read(gsk_handle my_session_handle, char * readBuffer,
int readBufSize, int * amtRead)
{
struct Curl_gsk_descriptor * p;
if(!my_session_handle)
return GSK_INVALID_HANDLE;
p = (struct Curl_gsk_descriptor *) my_session_handle;
return gsk_secure_soc_read(p->h, readBuffer, readBufSize, amtRead);
}
int
Curl_gsk_secure_soc_write(gsk_handle my_session_handle, char * writeBuffer,
int writeBufSize, int * amtWritten)
{
struct Curl_gsk_descriptor * p;
if(!my_session_handle)
return GSK_INVALID_HANDLE;
p = (struct Curl_gsk_descriptor *) my_session_handle;
return gsk_secure_soc_write(p->h, writeBuffer, writeBufSize, amtWritten);
}
const char *
Curl_gsk_strerror_a(int gsk_return_value)
{
int i;
const char * cp;
char * cp2;
cp = gsk_strerror(gsk_return_value);
if (!cp)
return cp;
i = strlen(cp);
if (!(cp2 = Curl_thread_buffer(LK_GSK_ERROR, MAX_CONV_EXPANSION * i + 1)))
return cp2;
i = QadrtConvertE2A(cp2, cp, MAX_CONV_EXPANSION * i, i);
cp2[i] = '\0';
return cp2;
}
int
Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
int IOCompletionPort,
Qso_OverlappedIO_t * communicationsArea)
{
struct Curl_gsk_descriptor * p;
if(!my_session_handle)
return GSK_INVALID_HANDLE;
p = (struct Curl_gsk_descriptor *) my_session_handle;
return gsk_secure_soc_startInit(p->h, IOCompletionPort, communicationsArea);
}
#endif /* USE_GSKIT */
#ifdef HAVE_GSSAPI
/* ASCII wrappers for the GSSAPI procedures. */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -31,6 +31,7 @@
typedef enum {
LK_SSL_ERROR,
LK_GSK_ERROR,
LK_LDAP_ERROR,
LK_CURL_VERSION,
LK_VERSION_INFO,

View File

@@ -1,9 +1,36 @@
EXTRA_DIST = \
backup_gnv_curl_src.com \
build_curl-config_script.com \
build_gnv_curl.com \
build_gnv_curl_pcsi_desc.com \
build_gnv_curl_pcsi_text.com \
build_gnv_curl_release_notes.com \
build_libcurl_pc.com \
build_vms.com \
clean_gnv_curl.com \
compare_curl_source.com \
config_h.com \
curl_crtl_init.c \
curl_gnv_build_steps.txt \
curl_release_note_start.txt \
curl_startup.com \
curlmsg.h \
curlmsg.msg \
curlmsg.sdl \
curlmsg_vms.h \
generate_config_vms_h_curl.com \
readme
generate_vax_transfer.com \
gnv_conftest.c_first \
gnv_curl_configure.sh \
gnv_libcurl_symbols.opt \
gnv_link_curl.com \
macro32_exactcase.patch \
make_gnv_curl_install.sh \
make_pcsi_curl_kit_name.com \
pcsi_gnv_curl_file_list.txt \
pcsi_product_gnv_curl.com \
readme \
report_openssl_version.c \
setup_gnv_curl_build.com \
stage_curl_install.com \
vms_eco_level.h

View File

@@ -0,0 +1,132 @@
$! File: Backup_gnv_curl_src.com
$!
$! $Id$
$!
$! Procedure to create backup save sets for installing in a PCSI kit.
$!
$! To comply with most Open Source licenses, the source used for building
$! a kit will be packaged with the distribution kit for the binary.
$!
$! Backup save sets are the only storage format that I can expect a
$! VMS system to be able to extract ODS-5 filenames and directories.
$!
$! The make_pcsi_kit_name.com needs to be run before this procedure to
$! properly name the files that will be created.
$!
$! This file is created from a template file for the purpose of making it
$! easier to port Unix code, particularly open source code to VMS.
$! Therefore permission is freely granted for any use.
$!
$! Copyright 2009, John Malmberg
$!
$! Permission to use, copy, modify, and/or distribute this software for any
$! purpose with or without fee is hereby granted, provided that the above
$! copyright notice and this permission notice appear in all copies.
$!
$! THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
$! WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
$! MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
$! ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
$! WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
$! ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
$! OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
$!
$! 13-Jun-2009 J. Malmberg
$!
$!===========================================================================
$!
$! Save default
$ default_dir = f$environment("DEFAULT")
$!
$ arch_type = f$getsyi("ARCH_NAME")
$ arch_code = f$extract(0, 1, arch_type)
$!
$ if arch_code .nes. "V"
$ then
$ set proc/parse=extended
$ endif
$!
$ ss_abort = 44
$ status = ss_abort
$!
$ kit_name = f$trnlnm("GNV_PCSI_KITNAME")
$ if kit_name .eqs. ""
$ then
$ write sys$output "@MAKE_PCSI_BASH_KIT_NAME.COM has not been run."
$ goto all_exit
$ endif
$ producer = f$trnlnm("GNV_PCSI_PRODUCER")
$ if producer .eqs. ""
$ then
$ write sys$output "@MAKE_PCSI_BASH_KIT_NAME.COM has not been run."
$ goto all_exit
$ endif
$ filename_base = f$trnlnm("GNV_PCSI_FILENAME_BASE")
$ if filename_base .eqs. ""
$ then
$ write sys$output "@MAKE_PCSI_BASH_KIT_NAME.COM has not been run."
$ goto all_exit
$ endif
$!
$ node_swvers = f$getsyi("NODE_SWVERS")
$ node_swvers_type = f$extract(0, 1, node_swvers)
$ node_swvers_vers = f$extract(1, f$length(node_swvers), node_swvers)
$ swvers_maj = f$element(0, ".", node_swvers_vers)
$ node_swvers_min_update = f$element(1, ".", node_swvers_vers)
$ swvers_min = f$element(0, "-", node_swvers_min_update)
$ swvers_update = f$element(1, "-", node_swvers_min_update)
$!
$ if swvers_update .eqs. "-" then swvers_update = ""
$!
$ vms_vers = f$fao("!2ZB!2ZB!AS", 'swvers_maj', 'swvers_min', swvers_update)
$!
$!
$!
$! If available make an interchange save set
$!-------------------------------------------
$ interchange = ""
$ if arch_code .eqs. "V"
$ then
$ interchange = "/interchange"
$ endif
$ if (swvers_maj .ges. "8") .and. (swvers_min .ges. 4)
$ then
$ interchange = "/interchange/noconvert"
$ endif
$!
$!
$! Move to the base directories
$ set def [--]
$!
$! Put things back on error.
$ on warning then goto all_exit
$!
$ current_default = f$environment("DEFAULT")
$ my_dir = f$parse(current_default,,,"DIRECTORY") - "[" - "<" - ">" - "]"
$!
$ src_root = "src_root:"
$ if f$trnlnm("src_root1") .nes. "" then src_root = "src_root1:"
$ backup'interchange' 'src_root'[curl...]*.*;0 -
'filename_base'_original_src.bck/sav
$ status = $status
$!
$! There may be a VMS specific source kit
$!-----------------------------------------
$ vms_root = "vms_root:"
$ if f$trnlnm("vms_root1") .nes. "" then vms_root = "vms_root1:"
$ files_found = 0
$ define/user sys$error nl:
$ define/user sys$output nl:
$ directory 'vms_root'[...]*.*;*/exc=*.dir
$ if '$severity' .eq. 1 then files_found = 1
$!
$ if files_found .eq. 1
$ then
$ backup'interchange' 'vms_root'[curl...]*.*;0 -
'filename_base'_vms_src.bck/sav
$ status = $status
$ endif
$!
$all_exit:
$ set def 'default_dir'
$ exit

View File

@@ -0,0 +1,288 @@
$! File: build_libcurl_pc.com
$!
$! $Id:$
$!
$! Build the curl-config file from the config_curl.in file
$!
$! Copyright 2013, John Malmberg
$!
$! Permission to use, copy, modify, and/or distribute this software for any
$! purpose with or without fee is hereby granted, provided that the above
$! copyright notice and this permission notice appear in all copies.
$!
$! THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
$! WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
$! MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
$! ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
$! WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
$! ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
$! OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
$!
$!
$! 15-Jun-2013 J. Malmberg
$!
$!===========================================================================
$!
$! Skip this if the curl-config. already exists.
$ if f$search("[--]curl-config.") .nes. "" then goto all_exit
$!
$! Need to know the kit type.
$ kit_name = f$trnlnm("GNV_PCSI_KITNAME")
$ if kit_name .eqs. ""
$ then
$ write sys$output "@MAKE_PCSI_CURL_KIT_NAME.COM has not been run."
$ goto all_exit
$ endif
$!
$!
$! Parse the kit name into components.
$!---------------------------------------
$ producer = f$element(0, "-", kit_name)
$ base = f$element(1, "-", kit_name)
$ product = f$element(2, "-", kit_name)
$ mmversion = f$element(3, "-", kit_name)
$ majorver = f$extract(0, 3, mmversion)
$ minorver = f$extract(3, 2, mmversion)
$ updatepatch = f$element(4, "-", kit_name)
$ if updatepatch .eqs. "-" then updatepatch = ""
$!
$! kit type of "D" means a daily build
$ kit_type = f$edit(f$extract(0, 1, majorver), "upcase")
$!
$ cfg_file_in = "[--]curl-config.in"
$!
$ if f$search(cfg_file_in) .eqs. ""
$ then
$ write sys$output "Can not find curl-config.in."
$ goto all_exit
$ endif
$!
$ if (f$getsyi("HW_MODEL") .lt. 1024)
$ then
$ arch_name = "VAX"
$ else
$ arch_name = ""
$ arch_name = arch_name + f$edit(f$getsyi("ARCH_NAME"), "UPCASE")
$ if (arch_name .eqs. "") then arch_name = "UNK"
$ endif
$!
$!
$ curl_version = "0.0.0"
$ open/read vf [--.include.curl]curlver.h
$version_loop:
$ read vf/end=version_loop_end line_in
$ if line_in .eqs. "" then goto version_loop
$ key = f$element(0, " ", line_in)
$ if key .nes. "#define" then goto version_loop
$ name = f$element(1, " ", line_in)
$ if name .eqs. "LIBCURL_VERSION"
$ then
$ curl_version = f$element(2, " ", line_in) - """" - """"
$ goto version_loop
$ endif
$ if name .eqs. "LIBCURL_VERSION_NUM"
$ then
$ version_num_hex = f$element(2, " ", line_in)
$ version_num = version_num_hex - "0x"
$ goto version_loop
$ endif
$version_loop_end:
$ close vf
$!
$!
$ create [--]curl-config.
$ open/append pco [--]curl-config.
$ open/read pci 'cfg_file_in'
$cfg_file_loop:
$ read pci/end=cfg_file_loop_end line_in
$!
$! blank lines
$ if line_in .eqs. ""
$ then
$ write pco ""
$ goto cfg_file_loop
$ endif
$!
$! comment lines
$ key = f$extract(0, 1, line_in)
$ if key .eqs. "#"
$ then
$ write pco line_in
$ goto cfg_file_loop
$ endif
$!
$! No substitution line
$ line_in_len = f$length(line_in)
$ if f$locate("@", line_in) .ge. line_in_len
$ then
$ write pco line_in
$ goto cfg_file_loop
$ endif
$!
$ if f$locate("@prefix@", line_in) .lt line_in_len
$ then
$ if kit_type .nes. "D"
$ then
$ write pco "prefix=/usr"
$ else
$ write pco "prefix=/beta"
$ endif
$ goto cfg_file_loop
$ endif
$ if f$locate("@exec_prefix@", line_in) .lt line_in_len
$ then
$ if kit_type .nes. "D"
$ then
$ write pco "exec_prefix=/usr"
$ else
$ write pco "exec_prefix=/beta"
$ endif
$ goto cfg_file_loop
$ endif
$ if f$locate("=@includedir@", line_in) .lt line_in_len
$ then
$ write pco "includedir=$(prefix}/include"
$ goto cfg_file_loop
$ endif
$ if f$locate("X@includedir@", line_in) .lt line_in_len
$ then
$ write pco " if test ""X$(prefix}/include""; then"
$ goto cfg_file_loop
$ endif
$ if f$locate("I@includedir@", line_in) .lt line_in_len
$ then
$ write pco " echo "${CPPFLAG_CURL_STATICLIB}-I$(prefix}/include"
$ goto cfg_file_loop
$ endif
$ if f$locate("@CPPFLAG_CURL_STATICLIB@", line_in) .lt line_in_len
$ then
$ write pco "cppflag_curl_staticlib=-DCURL_STATICLIB"
$ goto cfg_file_loop
$ endif
$ if f$locate("@ENABLE_SHARED@", line_in) .lt line_in_len
$ then
$ write pco " echo no"
$ goto cfg_file_loop
$ endif
$ if f$locate("@CURL_CA_BUNDLE@", line_in) .lt line_in_len
$ then
$ write pco " echo """""
$ goto cfg_file_loop
$ endif
$ if f$locate("@CC@", line_in) .lt line_in_len
$ then
$ write pco " echo ""cc"""
$ goto cfg_file_loop
$ endif
$ if f$locate("@SUPPORT_FEATURES@", line_in) .lt line_in_len
$ then
$ if arch_name .eqs. "VAX"
$ then
$ write pco " for feature in SSL libz NTLM ""; do"
$ else
$ write pco " for feature in SSL IPv6 libz NTLM ""; do"
$ endif
$ goto cfg_file_loop
$ endif
$ if f$locate("@SUPPORT_PROTOCOLS@", line_in) .lt line_in_len
$ then
$ proto1 = "DICT FILE FTP FTPS GOPHER HTTP HTTPS IMAP IMAPS"
$ proto2 = " LDAP LDAPS POP3 POP3S RTSP SMTP SMTPS TELNET TFTP"
$ proto = proto1 + proto2
$ write pco " for protocol in " + proto + "; do"
$ goto cfg_file_loop
$ endif
$ if f$locate("libcurl @CURLVERSION@", line_in) .lt line_in_len
$ then
$ write pco " echo libcurl ''curl_version'"
$ goto cfg_file_loop
$ endif
$ if f$locate("existing @CURLVERSION@", line_in) .lt line_in_len
$ then
$ line_start = -
" echo ""requested version $checkfor is newer than existing"
$ write pco "''line_start' ''curl_version'"""
$ goto cfg_file_loop
$ endif
$ if f$locate("`echo @versionnum@", line_in) .lt line_in_len
$ then
$ write pco " numuppercase=`echo ''version_num' | tr 'a-f' 'A-F'`"
$ goto cfg_file_loop
$ endif
$ if f$locate(" echo @versionnum@", line_in) .lt line_in_len
$ then
$ write pco " echo ''version_num'"
$ goto cfg_file_loop
$ endif
$ if f$locate("X@libdir@", line_in) .lt line_in_len
$ then
$ part1 = " if test ""$(exec_prefix}/lib"" != ""X/usr/lib"""
$ part2 = "-a ""X$(exec_prefix}/lib"" != ""X/usr/lib64""; then"
$ write pco part1,part2
$ goto cfg_file_loop
$ endif
$ if f$locate("L@libdir@", line_in) .lt line_in_len
$ then
$ write pco " CURLLIBDIR=""$(exec_prefix}/lib """
$ goto cfg_file_loop
$ endif
$ if f$locate("@REQUIRE_LIB_DEPS@", line_in) .lt line_in_len
$ then
$ write pco " if test "Xyes" = "Xyes"; then"
$ goto cfg_file_loop
$ endif
$ if f$locate("@LIBCURL_LIBS@", line_in) .lt line_in_len
$ then
$ if arch_name .eqs. "VAX"
$ then
$ write pco " echo ${CURLLIBDIR}-lssl -lcrypto -lz"
$ else
$ write pco " echo ${CURLLIBDIR}-lssl -lcrypto -lgssapi -lz"
$ endif
$ goto cfg_file_loop
$ endif
$ if f$locate("@ENABLE_STATIC@", line_in) .lt line_in_len
$ then
$ write pco " if test "Xyes" != "Xno" ; then"
$ goto cfg_file_loop
$ endif
$ if f$locate("@LIBCURL_LIBS@", line_in) .lt line_in_len
$ then
$ part1 = " echo ${exec_prefix}/lib/libcurl.a"
$ part2 = "-L/usr/lib -L/SSL_LIB"
$ if arch_name .eqs. "VAX"
$ then
$ write pco "''part1' ''part2' -lssl -lcrypto -lz"
$ else
$ write pco "''part1' ''part2' -lssl -lcrypto -lgssapi -lz"
$ endif
$ goto cfg_file_loop
$ endif
$ if f$locate("@CONFIGURE_OPTIONS@", line_in) .lt line_in_len
$ then
$ if kit_type .nes. "D"
$ then
$ part1 = " echo "" '--prefix=/usr' '--exec-prefix=/usr' "
$ else
$ part1 = " echo "" '--prefix=/beta' '--exec_prefix=/beta' "
$ endif
$ if arch_name .eqs. "VAX"
$ then
$ part3 = ""
$ else
$ part3 = "'--with-gssapi' "
$ endif
$ part2 = "'--disable-dependency-tracking' '--disable-libtool-lock' "
$ part4 = "'--disable-ntlm-wb' '--with-ca-path=gnv$curl_ca_path'"""
$!
$ write pco part1,part2,part3,part4
$!
$ goto cfg_file_loop
$ endif
$!
$pc_file_loop_end:
$ close pco
$ close pci
$!
$all_exit:
$ exit

View File

@@ -0,0 +1,38 @@
$! File: build_gnv_curl.com
$!
$! $Id$
$!
$! All in one build procedure
$!
$! Copyright 2009, John Malmberg
$!
$! Permission to use, copy, modify, and/or distribute this software for any
$! purpose with or without fee is hereby granted, provided that the above
$! copyright notice and this permission notice appear in all copies.
$!
$! THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
$! WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
$! MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
$! ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
$! WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
$! ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
$! OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
$!
$!
$! 11-Jun-2009 J. Malmberg
$!-----------------------------------------------------------------------
$!
$ @setup_gnv_curl_build.com
$!
$ bash gnv_curl_configure.sh
$!
$ @clean_gnv_curl.com
$!
$ bash make_gnv_curl_install.sh
$!
$ @gnv_link_curl.com
$!
$ purge new_gnu:[*...]/log
$!
$!
$exit

View File

@@ -0,0 +1,488 @@
$! File: Build_GNV_CURL_PCSI_DESC.COM
$!
$! $Id$
$!
$! Build the *.pcsi$text file in the following sections:
$! Required software dependencies.
$! install/upgrade/postinstall steps.
$! 1. Duplicate filenames need an alias procedure. (N/A for curl)
$! 2. ODS-5 filenames need an alias procedure. (N/A for curl)
$! 3. Special alias links for executables (curl. -> curl.exe)
$! if a lot, then an alias procedure is needed.
$! 4. Rename the files to lowercase.
$! Move Release Notes to destination
$! Source kit option
$! Create directory lines
$! Add file lines for curl.
$! Add Link alias procedure file (N/A for curl)
$! Add [.SYS$STARTUP]curl_startup file
$! Add Release notes file.
$!
$! The file PCSI_GNV_CURL_FILE_LIST.TXT is read in to get the files other
$! than the release notes file and the source backup file.
$!
$! The PCSI system can really only handle ODS-2 format filenames and
$! assumes that there is only one source directory. It also assumes that
$! all destination files with the same name come from the same source file.
$! Fortunately CURL does not trip most of these issues, so those steps
$! above are marked N/A.
$!
$! A rename action section is needed to make sure that the files are
$! created in the GNV$GNU: in the correct case, and to create the alias
$! link [usr.bin]curl. for [usr.bin]curl.exe.
$!
$! Copyright 2009, John Malmberg
$!
$! Permission to use, copy, modify, and/or distribute this software for any
$! purpose with or without fee is hereby granted, provided that the above
$! copyright notice and this permission notice appear in all copies.
$!
$! THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
$! WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
$! MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
$! ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
$! WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
$! ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
$! OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
$!
$!
$! 15-Jun-2009 J. Malmberg
$!
$!===========================================================================
$!
$ kit_name = f$trnlnm("GNV_PCSI_KITNAME")
$ if kit_name .eqs. ""
$ then
$ write sys$output "@MAKE_PCSI_CURL_KIT_NAME.COM has not been run."
$ goto all_exit
$ endif
$ producer = f$trnlnm("GNV_PCSI_PRODUCER")
$ if producer .eqs. ""
$ then
$ write sys$output "@MAKE_PCSI_CURL_KIT_NAME.COM has not been run."
$ goto all_exit
$ endif
$ filename_base = f$trnlnm("GNV_PCSI_FILENAME_BASE")
$ if filename_base .eqs. ""
$ then
$ write sys$output "@MAKE_PCSI_CURL_KIT_NAME.COM has not been run."
$ goto all_exit
$ endif
$!
$!
$! Parse the kit name into components.
$!---------------------------------------
$ producer = f$element(0, "-", kit_name)
$ base = f$element(1, "-", kit_name)
$ product = f$element(2, "-", kit_name)
$ mmversion = f$element(3, "-", kit_name)
$ majorver = f$extract(0, 3, mmversion)
$ minorver = f$extract(3, 2, mmversion)
$ updatepatch = f$element(4, "-", kit_name)
$ if updatepatch .eqs. "-" then updatepatch = ""
$!
$! kit type of "D" means a daily build
$ kit_type = f$edit(f$extract(0, 1, majorver), "upcase")
$!
$!
$ product_line = "product ''producer' ''base' ''product'"
$ if updatepatch .eqs. ""
$ then
$ product_name = " ''majorver'.''minorver'"
$ else
$ product_name = " ''majorver'.''minorver'-''updatepatch'"
$ endif
$ product_line = product_line + " ''product_name' full;"
$!write sys$output product_line
$!
$!
$!
$! Create the file as a VMS text file.
$!----------------------------------------
$ base_file = kit_name
$ create 'base_file'.pcsi$desc
$!
$!
$! Start building file.
$!----------------------
$ open/append pdsc 'base_file'.pcsi$desc
$!
$ write pdsc product_line
$!
$! Required product dependencies.
$!----------------------------------
$ vmsprd = "DEC"
$ if base .eqs. "I64VMS" then vmsprd = "HP"
$!
$ write pdsc " software ''vmsprd' ''base' VMS ;"
$ arch_type = f$getsyi("ARCH_NAME")
$ node_swvers = f$getsyi("node_swvers")
$ vernum = f$extract(1, f$length(node_swvers), node_swvers)
$ majver = f$element(0, ".", vernum)
$ minverdash = f$element(1, ".", vernum)
$ minver = f$element(0, "-", minverdash)
$ dashver = f$element(1, "-", minverdash)
$ if dashver .eqs. "-" then dashver = ""
$ vmstag = majver + minver + dashver
$ code = f$extract(0, 1, arch_type)
$ arch_code = f$extract(0, 1, arch_type)
$ write pdsc -
" if (not <software ''vmsprd' ''base' VMS version minimum ''node_swvers'>) ;"
$ write pdsc " error NEED_VMS''vmstag';"
$ write pdsc " end if;"
$!
$write pdsc " software VMSPORTS ''base' ZLIB ;"
$write pdsc -
" if (not <software VMSPORTS ''base' ZLIB version minimum V1.2-8>) ;"
$write pdsc " error NEED_ZLIB;"
$write pdsc " end if;"
$!
$!
$!
$! install/upgrade/postinstall steps.
$!-----------------------------------
$! 1. Duplicate filenames need an alias procedure. (N/A for curl)
$! 2. ODS-5 filenames need an alias procedure. (N/A for curl)
$! 3. Special alias links for executables (curl. -> curl.exe)
$! if a lot, then an alias procedure is needed.
$! 4. Rename the files to lowercase.
$!
$!
$! Alias links needed.
$!-------------------------
$ add_alias_lines = ""
$ rem_alias_lines = ""
$ line_out = ""
$!
$! Read through the file list to set up aliases and rename commands.
$!---------------------------------------------------------------------
$ open/read flst pcsi_gnv_curl_file_list.txt
$!
$inst_alias_loop:
$ read/end=inst_alias_loop_end flst line_in
$ line_in = f$edit(line_in,"compress,trim,uncomment")
$ if line_in .eqs. "" then goto inst_alias_loop
$ pathname = f$element(0, " ", line_in)
$ linkflag = f$element(1, " ", line_in)
$ if linkflag .nes. "->" then goto inst_alias_write
$!
$ linktarget = f$element(2, " ", line_in)
$ if kit_type .eqs. "D"
$ then
$ old_start = f$locate("[gnv.usr", pathname)
$ if old_start .lt. f$length(pathname)
$ then
$ pathname = "[gnv.beta" + pathname - "[gnv.usr"
$ linktarget = "[gnv.beta" + linktarget - "[gnv.usr"
$ endif
$ endif
$ nlink = "pcsi$destination:" + pathname
$ ntarg = "pcsi$destination:" + linktarget
$ new_add_alias_line = -
"""if f$search(""""''nlink'"""") .eqs. """""""" then" + -
" set file/enter=''nlink' ''ntarg'"""
$ if add_alias_lines .nes. ""
$ then
$ add_alias_lines = add_alias_lines + "," + new_add_alias_line
$ else
$ add_alias_lines = new_add_alias_line
$ endif
$!
$ new_rem_alias_line = -
"""if f$search(""""''nlink'"""") .nes. """""""" then" + -
" set file/remove ''nlink';"""
$ if rem_alias_lines .nes. ""
$ then
$ rem_alias_lines = rem_alias_lines + "," + new_rem_alias_line
$ else
$ rem_alias_lines = new_rem_alias_line
$ endif
$!
$ goto inst_alias_loop
$!
$inst_alias_write:
$!
$! execute install / remove
$ write pdsc " execute install ("
$! add aliases
$ i = 0
$ex_ins_loop:
$ line = f$element(i, ",", add_alias_lines)
$ i = i + 1
$ if line .eqs. "" then goto ex_ins_loop
$ if line .eqs. "," then goto ex_ins_loop_end
$ if line_out .nes. "" then write pdsc line_out,","
$ line_out = line
$ goto ex_ins_loop
$ex_ins_loop_end:
$ write pdsc line_out
$ line_out = ""
$ write pdsc " )"
$ write pdsc " remove ("
$! remove aliases
$ i = 0
$ex_rem_loop:
$ line = f$element(i, ",", rem_alias_lines)
$ i = i + 1
$ if line .eqs. "" then goto ex_rem_loop
$ if line .eqs. "," then goto ex_rem_loop_end
$ if line_out .nes. "" then write pdsc line_out,","
$ line_out = line
$ goto ex_rem_loop
$ex_rem_loop_end:
$ write pdsc line_out
$ line_out = ""
$ write pdsc " ) ;"
$!
$! execute upgrade
$ write pdsc " execute upgrade ("
$ i = 0
$ex_upg_loop:
$ line = f$element(i, ",", rem_alias_lines)
$ i = i + 1
$ if line .eqs. "" then goto ex_upg_loop
$ if line .eqs. "," then goto ex_upg_loop_end
$ if line_out .nes. "" then write pdsc line_out,","
$ line_out = line
$ goto ex_upg_loop
$ex_upg_loop_end:
$ write pdsc line_out
$ line_out = ""
$! remove aliases
$ write pdsc " ) ;"
$!
$! execute postinstall
$ write pdsc " execute postinstall ("
$ if arch_code .nes. "V"
$ then
$ line_out = " ""set process/parse=extended"""
$ endif
$ i = 0
$ex_pins_loop:
$ line = f$element(i, ",", add_alias_lines)
$ i = i + 1
$ if line .eqs. "" then goto ex_pins_loop
$ if line .eqs. "," then goto ex_pins_loop_end
$ if line_out .nes. "" then write pdsc line_out,","
$ line_out = line
$ goto ex_pins_loop
$ex_pins_loop_end:
$ if line_out .eqs. "" then line_out = " ""continue"""
$! write pdsc line_out
$! line_out = ""
$! add aliases and follow with renames.
$!
$goto inst_dir
$!
$inst_dir_loop:
$ read/end=inst_alias_loop_end flst line_in
$ line_in = f$edit(line_in,"compress,trim,uncomment")
$ if line_in .eqs. "" then goto inst_dir_loop
$inst_dir:
$ pathname = f$element(0, " ", line_in)
$ if kit_type .eqs. "D"
$ then
$ if pathname .eqs. "[gnv]usr.dir"
$ then
$ pathname = "[gnv]beta.dir"
$ else
$ old_start = f$locate("[gnv.usr", pathname)
$ if old_start .lt. f$length(pathname)
$ then
$ pathname = "[gnv.beta" + pathname - "[gnv.usr"
$ endif
$ endif
$ endif
$!
$! Ignore the directory entries for now.
$!-----------------------------------------
$ filedir = f$parse(pathname,,,"DIRECTORY")
$ if pathname .eqs. filedir then goto inst_dir_loop
$!
$! process .dir extensions for rename
$! If this is not a directory then start processing files.
$!-------------------------
$ filetype = f$parse(pathname,,,"TYPE")
$ filetype_u = f$edit(filetype, "upcase")
$ filename = f$parse(pathname,,,"NAME")
$ if filetype_u .nes. ".DIR" then goto inst_file
$!
$! process directory lines for rename.
$!--------------------------------------
$ if line_out .nes. ""
$ then
$ write pdsc line_out,","
$ line_out = ""
$ endif
$ if arch_code .nes. "V"
$ then
$ if line_out .nes. "" then write pdsc line_out,","
$ line_out = " ""rename pcsi$destination:''pathname' ''filename'.DIR"""
$ else
$ if line_out .nes. "" then write pdsc line_out
$ line_out = ""
$ endif
$ goto inst_dir_loop
$!
$!
$! process file lines for rename
$!---------------------------------
$inst_file_loop:
$ read/end=inst_alias_loop_end flst line_in
$ line_in = f$edit(line_in,"compress,trim,uncomment")
$ if line_in .eqs. "" then goto inst_dir_loop
$ pathname = f$element(0, " ", line_in)
$ if kit_type .eqs. "D"
$ then
$ if pathname .eqs. "[gnv]usr.dir"
$ then
$ pathname = "[gnv]beta.dir"
$ else
$ old_start = f$locate("[gnv.usr", pathname)
$ if old_start .lt. f$length(pathname)
$ then
$ pathname = "[gnv.beta" + pathname - "[gnv.usr"
$ endif
$ endif
$ endif
$!
$! Filenames with $ in them are VMS special and do not need to be lowercased.
$! --------------------------------------------------------------------------
$ if f$locate("$", pathname) .lt. f$length(pathname) then goto inst_file_loop
$!
$ filetype = f$parse(pathname,,,"TYPE")
$ filename = f$parse(pathname,,,"NAME") + filetype
$inst_file:
$ if arch_code .nes. "V"
$ then
$ if line_out .nes. "" then write pdsc line_out,","
$ filetype = f$parse(pathname,,,"TYPE")
$ filename = f$parse(pathname,,,"NAME") + filetype
$ line_out = " ""rename pcsi$destination:''pathname' ''filename'"""
$ else
$ if line_out .nes. "" then write pdsc line_out
$ line_out = ""
$ endif
$ goto inst_file_loop
$!
$inst_alias_loop_end:
$!
$write pdsc line_out
$write pdsc " ) ;"
$close flst
$!
$! Move Release Notes to destination
$!-------------------------------------
$write pdsc " information RELEASE_NOTES phase after ;"
$!
$! Source kit option
$!---------------------
$write pdsc " option SOURCE default 0;"
$write pdsc " directory ""[gnv.common_src]"" PROTECTION PUBLIC ;"
$write pdsc -
" file ""[gnv.common_src]''filename_base'_original_src.bck"""
$write pdsc -
" source [common_src]''filename_base'_original_src.bck ;"
$if f$search("gnv$gnu:[vms_src]''filename_base'_vms_src.bck") .nes. ""
$then
$ write pdsc " directory ""[gnv.vms_src]"" PROTECTION PUBLIC ;"
$ write pdsc " file ""[gnv.vms_src]''filename_base'_vms_src.bck"""
$ write pdsc " source [vms_src]''filename_base'_vms_src.bck ;"
$endif
$write pdsc " end option;"
$!
$!
$! Read through the file list again.
$!----------------------------------
$open/read flst pcsi_gnv_curl_file_list.txt
$!
$!
$! Create directory lines
$!-------------------------
$flst_dir_loop:
$ read/end=flst_loop_end flst line_in
$ line_in = f$edit(line_in,"compress,trim,uncomment")
$ if line_in .eqs. "" then goto flst_dir_loop
$!
$ filename = f$element(0, " ", line_in)
$ linkflag = f$element(1, " ", line_in)
$ if linkflag .eqs. "->" then goto flst_dir_loop
$!
$! Ignore .dir extensions
$!-------------------------
$ filetype = f$edit(f$parse(filename,,,"TYPE"), "upcase")
$ if filetype .eqs. ".DIR" then goto flst_dir_loop
$!
$ destname = filename
$ if kit_type .eqs. "D"
$ then
$ old_start = f$locate("[gnv.usr", destname)
$ if old_start .lt. f$length(destname)
$ then
$ destname = "[gnv.beta" + destname - "[gnv.usr"
$ endif
$ endif
$!
$! It should be just a directory then.
$!-------------------------------------
$ filedir = f$edit(f$parse(filename,,,"DIRECTORY"), "lowercase")
$! If this is not a directory then start processing files.
$!---------------------------------------------------------
$ if filename .nes. filedir then goto flst_file
$!
$ write pdsc " directory ""''destname'"" PROTECTION PUBLIC ;"
$ goto flst_dir_loop
$!
$!
$! Add file lines for curl.
$!---------------------------
$flst_file_loop:
$ read/end=flst_loop_end flst line_in
$ line_in = f$edit(line_in,"compress,trim,uncomment")
$ if line_in .eqs. "" then goto inst_file_loop
$ filename = f$element(0, " ", line_in)
$ destname = filename
$ if kit_type .eqs. "D"
$ then
$ old_start = f$locate("[gnv.usr", destname)
$ if old_start .lt. f$length(destname)
$ then
$ destname = "[gnv.beta" + destname - "[gnv.usr"
$ endif
$ endif
$flst_file:
$ srcfile = filename - "gnv."
$ write pdsc " file ""''destname'"" "
$ write pdsc " source ""''srcfile'"" ;"
$ goto flst_file_loop
$!
$flst_loop_end:
$ close flst
$!
$! Add Link alias procedure file (N/A for curl)
$!------------------------------------------------
$!
$! Add [.SYS$STARTUP]curl_startup file
$!---------------------------------------
$ if kit_type .eqs. "D"
$ then
$ write pdsc " file ""[sys$startup]curl_daily_startup.com"""
$ else
$ write pdsc " file ""[sys$startup]curl_startup.com"""
$ endif
$ write pdsc " source [usr.lib]curl_startup.com ;"
$!
$! Add Release notes file.
$!------------------------------
$ write pdsc -
" file ""[SYSHLP]''filename_base'.release_notes"" release notes ;"
$!
$! Close the product file
$!------------------------
$ write pdsc "end product;"
$!
$close pdsc
$!
$all_exit:
$ exit

View File

@@ -0,0 +1,198 @@
$! File: Build_GNV_curl_pcsi_text.com
$!
$! $Id$
$!
$! Build the *.pcsi$text file from the four components:
$! 1. Generated =product header section
$! 2. [--]readme. file from the Curl distribution, modified to fit
$! a pcsi$text file format.
$! 3. [--]copying file from the Curl distribution, modified to fit
$! a pcsi$text file format.
$! 4. Generated Producer section.
$!
$! Set the name of the release notes from the GNV_PCSI_FILENAME_BASE
$!
$! Copyright 2009, John Malmberg
$!
$! Permission to use, copy, modify, and/or distribute this software for any
$! purpose with or without fee is hereby granted, provided that the above
$! copyright notice and this permission notice appear in all copies.
$!
$! THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
$! WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
$! MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
$! ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
$! WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
$! ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
$! OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
$!
$!
$! 15-Jun-2009 J. Malmberg
$!
$!===========================================================================
$!
$ kit_name = f$trnlnm("GNV_PCSI_KITNAME")
$ if kit_name .eqs. ""
$ then
$ write sys$output "@MAKE_PCSI_CURL_KIT_NAME.COM has not been run."
$ goto all_exit
$ endif
$ producer = f$trnlnm("GNV_PCSI_PRODUCER")
$ if producer .eqs. ""
$ then
$ write sys$output "@MAKE_PCSI_CURL_KIT_NAME.COM has not been run."
$ goto all_exit
$ endif
$ producer_full_name = f$trnlnm("GNV_PCSI_PRODUCER_FULL_NAME")
$ if producer_full_name .eqs. ""
$ then
$ write sys$output "@MAKE_PCSI_CURL_KIT_NAME.COM has not been run."
$ goto all_exit
$ endif
$!
$!
$! Parse the kit name into components.
$!---------------------------------------
$ producer = f$element(0, "-", kit_name)
$ base = f$element(1, "-", kit_name)
$ product = f$element(2, "-", kit_name)
$ mmversion = f$element(3, "-", kit_name)
$ majorver = f$extract(0, 3, mmversion)
$ minorver = f$extract(3, 2, mmversion)
$ updatepatch = f$element(4, "-", kit_name)
$ if updatepatch .eqs. "-" then updatepatch = ""
$!
$!
$ product_line = "=product ''producer' ''base' ''product'"
$ if updatepatch .eqs. ""
$ then
$ product_name = " ''majorver'.''minorver'"
$ else
$ product_name = " ''majorver'.''minorver'-''updatepatch'"
$ endif
$ product_line = product_line + " ''product_name' full"
$!
$!
$! If this is VAX and the file is on NFS, the names may be mangled.
$!-----------------------------------------------------------------
$ readme_file = ""
$ if f$search("[--]readme.") .nes. ""
$ then
$ readme_file = "[--]readme."
$ else
$ if f$search("[--]$README.") .nes. ""
$ then
$ readme_file = "[--]$README."
$ else
$ write sys$output "Can not find readme file."
$ goto all_exit
$ endif
$ endif
$ copying_file = ""
$ if f$search("[--]copying.") .nes. ""
$ then
$ copying_file = "[--]copying."
$ else
$ if f$search("[--]$COPYING.") .nes. ""
$ then
$ copying_file = "[--]$COPYING."
$ else
$ write sys$output "Can not find copying file."
$ goto all_exit
$ endif
$ endif
$!
$! Create the file as a VMS text file.
$!----------------------------------------
$ base_file = kit_name
$ create 'base_file'.pcsi$text
$!
$!
$! Start building file.
$!----------------------
$ open/append ptxt 'base_file'.pcsi$text
$ write ptxt product_line
$!
$!
$! First insert the Readme file.
$!
$ open/read rf 'readme_file'
$!
$ write ptxt "1 'PRODUCT"
$ write ptxt "=prompt ''producter' ''product' for OpenVMS"
$!
$rf_loop:
$ read/end=rf_loop_end rf line_in
$ if line_in .nes. ""
$ then
$! PCSI files use the first character in for their purposes.
$!--------------------------------------------------------------
$ first_char = f$extract(0, 1, line_in)
$ if first_char .nes. " " then line_in = " " + line_in
$ endif
$ write ptxt line_in
$ goto rf_loop
$rf_loop_end:
$ close rf
$!
$!
$! Now add in the copying file
$!--------------------------------
$ write ptxt ""
$ write ptxt "1 'NOTICE"
$ write ptxt ""
$!
$ open/read cf 'copying_file'
$!
$cf_loop:
$ read/end=cf_loop_end cf line_in
$ if line_in .nes. ""
$ then
$! PCSI files use the first character in for their purposes.
$!--------------------------------------------------------------
$ first_char = f$extract(0, 1, line_in)
$ if first_char .nes. " " then line_in = " " + line_in
$ endif
$ write ptxt line_in
$ goto cf_loop
$cf_loop_end:
$ close cf
$!
$! Now we need the rest of the boiler plate.
$!--------------------------------------------
$ write ptxt ""
$ write ptxt "1 'PRODUCER"
$ write ptxt "=prompt ''producer_full_name'"
$ write ptxt -
"This software product is provided by ''producer_full_name' with no warranty."
$!
$ arch_type = f$getsyi("ARCH_NAME")
$ node_swvers = f$getsyi("node_swvers")
$ vernum = f$extract(1, f$length(node_swvers), node_swvers)
$ majver = f$element(0, ".", vernum)
$ minverdash = f$element(1, ".", vernum)
$ minver = f$element(0, "-", minverdash)
$ dashver = f$element(1, "-", minverdash)
$ if dashver .eqs. "-" then dashver = ""
$ vmstag = majver + minver + dashver
$ code = f$extract(0, 1, arch_type)
$!
$ write ptxt "1 NEED_VMS''vmstag'"
$ write ptxt -
"=prompt OpenVMS ''vernum' or later is not installed on your system."
$ write ptxt "This product requires OpenVMS ''vernum' or later to function."
$ write ptxt "1 NEED_ZLIB"
$ write ptxt "=prompt ZLIB 1.2-8 or later is not installed on your system."
$ write ptxt "This product requires ZLIB 1.2-8 or later to function."
$ write ptxt "1 SOURCE"
$ write ptxt "=prompt Source modules for ''product'"
$ write ptxt "The Source modules for ''product' will be installed."
$ write ptxt "1 RELEASE_NOTES"
$ write ptxt "=prompt Release notes are available in the [SYSHLP] directory."
$!
$ close ptxt
$!
$!
$!
$all_exit:
$ exit

Some files were not shown because too many files have changed in this diff Show More