Compare commits

...

133 Commits

Author SHA1 Message Date
Daniel Stenberg
818aed35e2 static functions are better not Curl_ prefixed to make their static
status more obvious
2004-06-23 09:08:03 +00:00
Daniel Stenberg
2ed524f07e When adding the return -1 to prevent warnings on some compilers, others
started complaining since it won't be reached... So I removed the call to
abort() and just return -1 instead. abort() was wrong to call anyway since
this is a library!
2004-06-23 06:17:17 +00:00
Daniel Stenberg
5f1eefd03f prevent a warning 2004-06-23 06:14:23 +00:00
Gunter Knauf
522b4d7576 one copy&paste too much, removed the define again. 2004-06-22 23:56:19 +00:00
Gunter Knauf
d6dcb08407 argh - copy&paste error. 2004-06-22 23:22:37 +00:00
Gunter Knauf
806c756a2d syncronized with recent getdate.y updates. 2004-06-22 23:04:57 +00:00
Daniel Stenberg
2494701347 the hostname variable wasn't assigned and we no longer use it 2004-06-22 21:25:53 +00:00
Daniel Stenberg
1c10272e15 cookie size 2004-06-22 21:22:42 +00:00
Daniel Stenberg
0badcf381a extended to include a cookie with 4998 bytes of content 2004-06-22 21:21:54 +00:00
Daniel Stenberg
35558e6bd7 David Cohen pointed out that RFC2109 says clients should allow cookies to
contain least 4096 bytes while libcurl only allowed 2047. I raised the limit
to 4999 now and made the used buffer get malloc()ed instead of simply
allocated on stack as before.
2004-06-22 21:15:51 +00:00
Daniel Stenberg
7659747e6f Gnter Knauf fixed getdate.y to remove a few warnings. I removed the
ifdef'ed test we never ever use anyway.
2004-06-22 21:12:34 +00:00
Gunter Knauf
53189fb2d7 added new --target option for autobuilding other targets than GNU-like. 2004-06-22 20:02:49 +00:00
Gunter Knauf
450c178d77 added 'clean' targets for mingw32 and netware. 2004-06-22 18:26:23 +00:00
Daniel Stenberg
a20eb6df1b reset CURLOPT_HTTPHEADER with NULL 2004-06-22 17:22:30 +00:00
Daniel Stenberg
d73425061a Moved the "About to connect() to" text to the place where the host name is
actually known, as before this text lied when used in i.e FTP.
2004-06-22 15:23:01 +00:00
Daniel Stenberg
0051d5ac88 Gisle Vanem improved the certificate wildcard checks 2004-06-22 08:54:42 +00:00
Daniel Stenberg
76920413d9 Gisle fixed the wildcard checks for certificates. 2004-06-22 08:51:22 +00:00
Daniel Stenberg
44d9a8ba4e Gunter's fix to avoid the notorious YYSTACK_USE_ALLOCA warning we get on
several platforms/compilers/yacc versions.
2004-06-22 07:27:43 +00:00
Daniel Stenberg
38dc548a87 retry to read the sent request a few times if it doesn't exist the first time 2004-06-22 07:09:47 +00:00
Daniel Stenberg
dca6386234 pass an int pointer when it expects an int pointer... 2004-06-22 06:50:41 +00:00
Daniel Stenberg
2a701a1aac modified some logging output 2004-06-22 06:44:14 +00:00
Daniel Stenberg
0cb297abc9 testcurl.sh is dead, long live tests/testcurl.pl! 2004-06-21 14:58:03 +00:00
Daniel Stenberg
821a23535b This is the old script for testing curl, now use tests/testcurl.pl instead.
It is more portable.
2004-06-21 14:56:48 +00:00
Daniel Stenberg
bc80599178 read callback return code and fixed the pycurl url 2004-06-21 14:20:34 +00:00
Daniel Stenberg
941374b573 CURL_READFUNC_ABORT stuff 2004-06-21 14:10:39 +00:00
Daniel Stenberg
1886893d66 Added blurb for the READFUNCTION, including the new CURL_READFUNC_ABORT
return code.
2004-06-21 14:09:23 +00:00
Daniel Stenberg
7291772b1f added test case 513 2004-06-21 14:08:48 +00:00
Daniel Stenberg
8e28721057 The read callback can now return CURL_READFUNC_ABORT to stop a transfer. 2004-06-21 14:07:38 +00:00
Daniel Stenberg
8d2120566e added CURL_READFUNC_ABORT 2004-06-21 14:04:36 +00:00
Daniel Stenberg
67341c4cbe when the client disconnects prematurely, dump the request as received thus
far
2004-06-21 14:00:11 +00:00
Daniel Stenberg
f8188ddfee recent events 2004-06-21 10:56:33 +00:00
Daniel Stenberg
29c546b426 typecasts to prevent compiler warnings 2004-06-21 08:37:53 +00:00
Daniel Stenberg
0d259b898b updates 2004-06-21 08:28:18 +00:00
Daniel Stenberg
c136b80af5 refer to the new tutorial man page 2004-06-21 08:28:10 +00:00
Daniel Stenberg
83b87d53c1 removed libcurl-the-guide from the dist 2004-06-21 08:27:45 +00:00
Daniel Stenberg
1e99f1ee41 libcurl-tutorial.3 is the former libcurl-the-guide converted to man page format 2004-06-21 08:17:08 +00:00
Daniel Stenberg
d7fe136d54 test 177 HTTP POST with --digest that gets a 302 response 2004-06-19 10:10:50 +00:00
Daniel Stenberg
cd7a0f829f When doing auth negotiations or authprobing, we only consider HTTP code
<300 to be good.
2004-06-19 10:10:24 +00:00
Daniel Stenberg
cf3f1ef284 prevent compiler warning 2004-06-19 09:38:08 +00:00
Daniel Stenberg
a737864a1c ispell-buffer 2004-06-18 13:11:49 +00:00
Daniel Stenberg
c68a6805b3 two issues to remember to fix before next release 2004-06-18 11:47:08 +00:00
Daniel Stenberg
bd3d5a17b4 Gisle's "SSL patch" from June 16th 2004, modified by me as discussed on the
mailing list.
2004-06-18 06:20:43 +00:00
Daniel Stenberg
d4b577114b With David Byron's test server I could repeat his problem and make sure that
POSTing over HTTPS:// with NTLM works fine now. There was a general problem
with multi-pass authentication with non-GET operations with CONNECT.
2004-06-18 06:15:26 +00:00
Daniel Stenberg
713effb6e4 large file FTP upload bug 2004-06-17 08:07:24 +00:00
Daniel Stenberg
b92e2ab6b1 new daring features, not used by any current test 2004-06-17 08:06:03 +00:00
Daniel Stenberg
05baf94b43 Keep the upload byte counter in an curl_off_t, not an int. 32bits is not
enough. This is most likely the bug Jean-Louis Lemaire reported that makes
2GB FTP uploads to report error when completed.
Also padded comments to get them aligned again, only for visibility.
2004-06-16 09:28:47 +00:00
Daniel Stenberg
a76288b99a Alexander Krasnostavsky fixed a flaw in the 3rd party transfer code that
didn't properly check return code.
2004-06-16 09:05:22 +00:00
Daniel Stenberg
557e95c0a3 post with auth problems fixed 2004-06-15 11:04:21 +00:00
Daniel Stenberg
0a83fa90bb skip the pid from the logging 2004-06-15 10:28:56 +00:00
Daniel Stenberg
daeb143177 test 176, use --ntlm and POST when the server doesn't require any auth 2004-06-15 09:20:04 +00:00
Daniel Stenberg
9f752120c0 added test case 175, use HTTP POST and DIGEST set but the server requires no
auth
2004-06-15 08:50:15 +00:00
Daniel Stenberg
80a1e972fc Fix the auth code to enable us to i.e set DIGEST and then find out that the
server doesn't require any auth at all and then we just continue nicely. We
now have an extra bit in the connection struct named 'authprobe' that is TRUE
when doing pure "HTTP authentication probing".
2004-06-15 08:45:22 +00:00
Daniel Stenberg
5e65d48ffa we actually build and run fine with libidn 0.4.1 too, so let's not require
anything newer than that
2004-06-14 21:40:11 +00:00
Daniel Stenberg
752ef08141 lots of multi interface description but also some general updates and additions 2004-06-14 14:44:28 +00:00
Daniel Stenberg
070e0e8b0a prevent compiler warnings on non-win32 platforms 2004-06-14 10:45:30 +00:00
Daniel Stenberg
2ed0728cef added test 174, HTTP POST --anyauth to server without auth requirements.
An attempt to repeat a reported auth problem. Works for me!
2004-06-14 09:16:39 +00:00
Daniel Stenberg
a79b9e9d4a recent action 2004-06-14 08:54:59 +00:00
Daniel Stenberg
24572daccc Allow formposting of files larger than what fits in memory by not reading the
file until it is actually being uploaded.
Make sure we build and still work with HTTP disabled - the SSL code might use
the boundary string for some random seeding.
2004-06-14 08:51:43 +00:00
Daniel Stenberg
1770563fff refuse running the torture tests without a debug build 2004-06-14 08:25:54 +00:00
Daniel Stenberg
4cd96483f6 moved default: in a switch case to prevent compiler warning that 'request'
might be used uninitialized
2004-06-13 09:08:38 +00:00
Daniel Stenberg
8f1783b8a7 provide curl_formfree() even when http is disabled, it does nothing then 2004-06-13 08:59:37 +00:00
Daniel Stenberg
be72eaa327 use Curl_strcasestr() when checking wildcard cert names 2004-06-13 08:33:26 +00:00
Daniel Stenberg
61bded1d82 added Curl_strcasestr() for case insensitive strstr() searching 2004-06-13 08:32:57 +00:00
Gunter Knauf
4b3937373a removed unused include path. 2004-06-11 17:27:03 +00:00
Gunter Knauf
08bf0907d4 fixed xdc generation, added lib target, load curl.nlm into ring3 by default. 2004-06-11 15:33:07 +00:00
Daniel Stenberg
eb044f8787 Tim Sneddon made it build fine on VMS again. 2004-06-11 12:29:30 +00:00
Gunter Knauf
8d0c77403c some more makefile changes. 2004-06-11 02:29:16 +00:00
Gunter Knauf
601062455c respect CVS builds in version string. 2004-06-11 01:36:27 +00:00
Gunter Knauf
5be788ba36 some more makefile changes. 2004-06-11 01:04:06 +00:00
Gunter Knauf
281559b31b cosmetic correction. 2004-06-10 22:24:37 +00:00
Gunter Knauf
ef1aa4e5e9 converted to UNIX format. 2004-06-10 21:20:15 +00:00
Gunter Knauf
7b7ac04895 added timeval.c to the sources for curlx_ functions. 2004-06-10 20:46:24 +00:00
Gunter Knauf
60f5b2b275 minor output fix. 2004-06-10 20:43:46 +00:00
Gunter Knauf
c0f9d7fdb7 ups! no copy command defined. 2004-06-10 20:29:19 +00:00
Gunter Knauf
fc4d6f73a6 added generation of missing files. 2004-06-10 20:25:02 +00:00
Gunter Knauf
295169f9d9 added generation of missing files. 2004-06-10 20:12:49 +00:00
Gunter Knauf
1a3797a699 make include path overridable. 2004-06-10 17:11:39 +00:00
Daniel Stenberg
977e106924 Gisle Vanem's init patch for Windows 2004-06-10 13:11:32 +00:00
Daniel Stenberg
8d76d4016d removed trailing whitespace 2004-06-10 11:56:02 +00:00
Daniel Stenberg
9f92657f76 Gisle corrected two comments 2004-06-10 11:55:37 +00:00
Daniel Stenberg
9f341f9ce5 Gisle Vanem's improved verbose output and timeout handling when connecting to
a host name that resolves to multiple IP addresses.
2004-06-10 11:06:21 +00:00
Daniel Stenberg
2098871509 build again with disabled http 2004-06-10 07:46:24 +00:00
Daniel Stenberg
3d00c86f4c Steven Bazyl and Seshubabu Pasam pointed out a bug on win32 when freeing the
path after a transfer.
2004-06-10 07:17:28 +00:00
Daniel Stenberg
90037b85d1 Alexander Krasnostavsky's fix to make libcurl build fine with configure
--disable-http, which thus builds a libcurl without HTTP support.
2004-06-09 08:23:55 +00:00
Daniel Stenberg
6ec145d4b4 when built with HTTP disabled, provide a curl_formadd() function anyway to
keep the API complete at all times
2004-06-09 08:22:02 +00:00
Daniel Stenberg
40a58c392f Added CURL_FORMADD_DISABLED when libcurl is built with HTTP disabled 2004-06-09 08:21:11 +00:00
Daniel Stenberg
9733cd59bb removed reference to the removed curl_formparse 2004-06-09 08:18:17 +00:00
Daniel Stenberg
b3caf7bfa8 Setting CURLOPT_RANGE to NULL disables it.
Setting CURLOPT_RESUME_FROM to 0 prevents a resumed transfer.
2004-06-09 08:05:23 +00:00
Daniel Stenberg
23fbb89805 recent changes 2004-06-09 07:01:48 +00:00
Daniel Stenberg
bd1adaf7ea when producing curllib.dsp, include libcurl.def as a source file.
An Alexander Krasnostavsky fix.
2004-06-09 06:54:12 +00:00
Gunter Knauf
0c9e23fc0c added the new source files. 2004-06-09 01:27:48 +00:00
Gunter Knauf
f091ce64ac corrected copyright. 2004-06-09 01:15:03 +00:00
Daniel Stenberg
55a69ebea6 Gisle's patch that'll allow curl to continue with the following URLs even
if one transfer fails.
2004-06-08 21:56:30 +00:00
Daniel Stenberg
d6b3850562 fix 2004-06-08 21:26:03 +00:00
Daniel Stenberg
80197cf493 James Bursa fixed a RISC OS init issue, removed trailing whitespace 2004-06-08 21:25:11 +00:00
Daniel Stenberg
8ee564c216 Marty Kuhrt's VMS fixes 2004-06-08 21:21:53 +00:00
Gunter Knauf
5bfeb60a83 corrected defines. 2004-06-08 15:05:45 +00:00
Daniel Stenberg
1ab4a2f870 delete trailing whitespace 2004-06-08 15:05:20 +00:00
Gunter Knauf
2a627059ac convert to UNIX format. 2004-06-08 14:57:37 +00:00
Gunter Knauf
3f739acf24 converted to UNIX format. 2004-06-08 14:52:32 +00:00
Daniel Stenberg
d3454ceb94 Kjetil Jacobsen pointed out that the CURLOPT_FILETIME option was wrongly
marked as accepting an objectpoint argument while it actually assumes a long.
The comment was also grossly misleading. The man page was and is correct
though.
2004-06-08 14:13:50 +00:00
Daniel Stenberg
59695c05b1 time schedule for this year 2004-06-08 12:23:48 +00:00
Daniel Stenberg
f0969c9692 prevent compiler warning with picky compilers 2004-06-07 10:28:14 +00:00
Daniel Stenberg
18dd8154e2 Reverted the previous change and redid it differently as it seemed to not
work. This is supposed to detect cross-compiling and alert the user, and not
do the POSIX-check for strerror_r() if it already detected a glibc-compatible
strerror_r().
2004-06-07 08:30:36 +00:00
Daniel Stenberg
4c58797607 When sending info about which host that sends what, include proper direction
to/from, based on a suggestion from Alexander Krasnostavsky
2004-06-07 07:01:29 +00:00
Daniel Stenberg
d620f1e529 configure fix 2004-06-04 20:57:59 +00:00
Daniel Stenberg
e0b436f8e1 1 - do better when cross-compiling when checking for strerror_r() - alert
the user.
2 - don't check for POSIX-style if glibc-style is found first
2004-06-04 19:01:58 +00:00
Daniel Stenberg
e99d1e97de test 173 added: HTTP RFC1867-formpost a file from stdin with "faked" filename 2004-06-04 12:24:47 +00:00
Daniel Stenberg
1fb74b4fa2 fixed spell, removed reference to a 'tools' subdir in the curl dir, as we
don't have one
2004-06-04 07:21:12 +00:00
Daniel Stenberg
473f6ea9f0 Gnter Knauf's netware fix 2004-06-04 07:04:32 +00:00
Daniel Stenberg
0b04c52119 Gnter Knauf's netware build fixes 2004-06-04 07:02:30 +00:00
Daniel Stenberg
8383945acc 3rd party transfers are in CVS now 2004-06-04 06:48:58 +00:00
Daniel Stenberg
fce9d51122 updated a comment 2004-06-03 14:42:08 +00:00
Daniel Stenberg
7c3ee84295 updates 2004-06-03 14:41:44 +00:00
Daniel Stenberg
a8db25f48b the test targets won't invoke the test suite if curl is built cross-compiled.
Pointed out by Chris Gaukroger.
2004-06-03 14:38:07 +00:00
Daniel Stenberg
20705ca311 set an automake conditional for if this is a cross-compile or not 2004-06-03 14:37:14 +00:00
Daniel Stenberg
af33c6b549 deleted trailing whitespace 2004-06-03 13:03:57 +00:00
Daniel Stenberg
2b8775dff7 7.12.0 introduced IDN support 2004-06-03 11:43:21 +00:00
Daniel Stenberg
ea81dd9e2e Alexander Krasnostavsky's FTP third party transfer (proxy) support 2004-06-03 11:41:05 +00:00
Daniel Stenberg
7dcb102733 Mention the python-isque mailing list, don't mention the commit mailing lists
as they are probably very rarely intresting to the "common people" anyway.
2004-06-03 11:30:30 +00:00
Daniel Stenberg
aa0e32060e CURLE_FAILED_INIT is returend when an unknown option is set 2004-06-03 11:19:35 +00:00
Daniel Stenberg
2e8f37aca5 Added example of how to use the upcoming support for FTP 3rd party transfers 2004-06-03 11:15:27 +00:00
Daniel Stenberg
195d769c4b corrected to use the proxy user name for proxy auth, as was just bugfixed! 2004-06-03 10:42:53 +00:00
Daniel Stenberg
70f08b5baa Vincent Bronner made the code use the correct user name + password when
doing proxy authentication.
2004-06-03 10:42:20 +00:00
Daniel Stenberg
9e987ac6a2 getinfo.c is a new tiny example that uses curl_easy_getinfo() to get the
content-type after a transfer.
2004-06-03 09:20:48 +00:00
Daniel Stenberg
de03f172ad very minor format edit 2004-06-02 14:39:34 +00:00
Daniel Stenberg
0078944486 CURLOPT_PUT is deprecated 2004-06-02 14:06:49 +00:00
Daniel Stenberg
d3f796ac59 Made CURLOPT_UPLOAD and CURLOPT_PUT mean the same thing internally (the
previous difference was not clear nor documented properly). They can now both
be used interchangeably, but we prefer UPLOAD to PUT since it is a more
generic term.
2004-06-02 13:57:38 +00:00
Daniel Stenberg
3d38080d54 *seven* new options to support 3rd party FTP transfers 2004-06-02 13:51:36 +00:00
Daniel Stenberg
fe07962f9c 7.12.1-CVS in progress 2004-06-02 11:39:06 +00:00
Daniel Stenberg
938a72b2db Gisle's adjustments to allow building with lcc-win32 2004-06-02 11:36:07 +00:00
Daniel Stenberg
a8827b1ed6 Gisle made ftp_mkd static 2004-06-02 11:34:53 +00:00
Daniel Stenberg
ff40cd71ac and we start all over again 2004-06-02 11:31:36 +00:00
88 changed files with 5669 additions and 2913 deletions

145
CHANGES
View File

@@ -6,6 +6,151 @@
Changelog
Daniel (22 June 2004)
- David Cohen pointed out that RFC2109 says clients should allow cookies to
contain least 4096 bytes while libcurl only allowed 2047. I raised the limit
to 4999 now and made the used buffer get malloc()ed instead of simply
allocated on stack as before. Extended test case 46 to include a cookie with
very huge content to verify the fix.
- G<>nter Knauf fixed getdate.y to remove a few warnings. I removed the
ifdef'ed test we never ever use anyway.
- Gisle Vanem fixed the certificate wildcard checks to support a '*'-letter
anywhere in the wildcard string, support multiple '*'-letters in the
wildcard and to allow the '*'-letter to match a string that includes a dot.
Daniel (21 June 2004)
- testcurl.sh is now removed completely, tests/testcurl.pl is the script to
use when autobuilding curl!
- Kjetil Jacobsen brought my attention to the fact that you cannot properly
abort an upload with the readfunction callback, since returning 0 or -1 only
stops the upload and libcurl will continue waiting for downloaded data and
the server often waits for the rest of the upload data to arrive.
Thus, I've now added the ability for read callbacks to return
CURL_READFUNC_ABORT to abort an upload from a read callback. This will stop
the transfer immediately with a CURLE_ABORTED_BY_CALLBACK return code.
Test case 513 was added to verify that it works. I had to improve the test
HTTP server too to dump the request to a file even when the client
disconnects prematurely.
Daniel (19 June 2004)
- Luca Alteas provided a test case with a failing curl operation: when we POST
to a site with --digest (or similar) set, and the server responded with a 302
Location: to the "authprobe" request, it was not treated correctly. We still
will behave badly if FOLLOWLOCATION is enabled for this case, but I'm not
in the mood to dive into this right now and will leave it as-is for now.
Verified my fix with test case 177.
Daniel (18 June 2004)
- Gisle Vanem's patch that provides more details from the SSL layers (if you
use an OpenSSL version that supports it). It also introduces two new types
of data that can be sent to the debug callback: CURLINFO_SSL_DATA_IN and
CURLINFO_SSL_DATA_OUT.
- With David Byron's test server I could repeat his problem and make sure that
POSTing over HTTPS:// with NTLM works fine now. There was a general problem
with multi-pass authentication with non-GET operations with CONNECT.
Daniel (16 June 2004)
- Modified to keep the upload byte counter in an curl_off_t, not an int as
before. 32bits is not enough. This is most likely the bug Jean-Louis Lemaire
reported that makes 2GB FTP uploads to report error ("unaligned file sizes")
when completed.
Daniel (15 June 2004)
- Luca Alteas reported a problem that I fixed: if you did a POST with
CURLAUTH_DIGEST set but the server didn't require any authentication,
libcurl would repeatedly send HEAD lots of times until it gives up. This was
actually the case for all multi-pass authentications. Added test case 174,
175 and 176 to verify this.
Daniel (14 June 2004)
- Multipart formposts uploading files no longer inserts the files themselves
into the huge prebuilt chunk. This enables libcurl to formpost files that is
larger than the amount of system memory. When the file given is passed on
stdin, libcurl still uses the old method of reading the full fill before the
upload takes place. This approach was selected in order to not alter the
behavior for existing applications, as when using stdin libcurl can't know
the size of the upload and chunked transfer-encoding can only be used on
HTTP 1.1 servers.
Daniel (13 June 2004)
- Gisle found out that we did wildcard cert name checks wrong, so that parts
of the check wrongly was case sensitive.
Daniel (11 June 2004)
- Tim Sneddon brought a minor VMS fix to make curl build properly on his VMS
machine. He also had some interesting libcurl patches... they might be able
to do in a slightly nicer way. Discussions are in progress.
Daniel (10 June 2004)
- Gisle Vanem brought code cleanupsm better verbose output and better connect
timeout handling when attempting to connect to a host that resolves to
multiple IP addresses.
- Steven Bazyl and Seshubabu Pasam pointed out a bug on win32 when freeing the
path after a file:// transfer.
Daniel (9 June 2004)
- Alexander Krasnostavsky made 'configure --disable-http' work to build libcurl
without HTTP support. I added a new return code for curl_formadd() in case
libcurl is built with HTTP disable: CURL_FORMADD_DISABLED.
- Alexander Krasnostavsky pointed out a missing file in the generated
curllib.dsp file, and now people building with this should get a libcurl.lib
file generated as it used to do before we generated this file.
Daniel (8 June 2004)
- Marty Kuhrt fixed a minor build problem for VMS.
Daniel (7 June 2004)
- Reverted the configure check from the 4th since it obviously didn't work.
Remade it in a different manner that hopefully works better.
Daniel (4 June 2004)
- G<>nter Knauf brought patches to make curl build fine on NetWare again.
- Made the configure checks for strerror_r() not exit the configure script
when built for cross-compiling.
Daniel (3 June 2004)
- Chris Gaukroger pointed out that 'make test' attempts to run the tests even
if curl is built cross-compiled. I've now made it output a short message
instead, saying it isn't possible to do.
- Alexander Krasnostavsky brought FTP 3rd party transfer support to libcurl.
You can now use libcurl to transfer files between two remote hosts using
FTP. There are a bunch of new options to control this with:
CURLOPT_SOURCE_HOST
CURLOPT_SOURCE_USERPWD
CURLOPT_SOURCE_PATH
CURLOPT_SOURCE_PORT
CURLOPT_PASV_HOST
CURLOPT_SOURCE_PREQUOTE
CURLOPT_SOURCE_POSTQUOTE
(They still remain to be documented properly in the curl_easy_setopt man
page.)
When using this, the ordinary CURLOPT_URL specifies the target URL, and you
specify the source data with these additional options. ftp3rdparty.c is a
new example source code showing how to use this.
- Vincent Bronner fixed the HTTP Digest code to use the proxy user name and
password when doing proxy authentication, it previously always used the host
user name and password!
Daniel (2 June 2004)
- CURLOPT_UPLOAD and CURLOPT_PUT now do the exact same thing internally, which
fixes some old confusions on when which of these should be used and what the
differences are.
- Applied Gisle's fixes to make curl build fine with lcc-win32
Version 7.12.0 (2 June 2004)
Daniel (1 June 2004)

View File

@@ -24,7 +24,7 @@
AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = CHANGES COPYING maketgz reconf Makefile.dist \
curl-config.in curl-style.el sample.emacs testcurl.sh RELEASE-NOTES
curl-config.in curl-style.el sample.emacs RELEASE-NOTES
bin_SCRIPTS = curl-config

View File

@@ -41,6 +41,10 @@ mingw32-ssl:
cd lib & make -f Makefile.m32 SSL=1 ZLIB=1
cd src & make -f Makefile.m32 SSL=1 ZLIB=1
mingw32-clean:
cd lib & make -f Makefile.m32 clean
cd src & make -f Makefile.m32 clean
vc:
cd lib
nmake /f Makefile.vc6 cfg=release
@@ -82,8 +86,16 @@ amiga:
cd ./src && make -f makefile.amiga
netware:
cd lib && make -f Makefile.netware
cd src && make -f Makefile.netware
$(MAKE) -C lib -f Makefile.netware
$(MAKE) -C src -f Makefile.netware
netware-ssl:
$(MAKE) -C lib -f Makefile.netware SSL=1
$(MAKE) -C src -f Makefile.netware SSL=1
netware-clean:
$(MAKE) -C lib -f Makefile.netware clean
$(MAKE) -C src -f Makefile.netware clean
unix: all

View File

@@ -1,62 +1,51 @@
Curl and libcurl 7.12.0.
Curl and libcurl 7.12.1
Public curl release number: 81
Releases counted from the very beginning: 108
Public curl release number: 82
Releases counted from the very beginning: 109
Available command line options: 96
Available curl_easy_setopt() options: 113
Available curl_easy_setopt() options: 120
Number of public functions in libcurl: 36
A special thanks to:
archivas.com and Alan Pinstein, for paying me to focus on their requests
This release includes the following changes:
o added ability to "upload" to file:// URLs
o added curl_global_init_mem()
o removed curl_formparse()
o the MSVC project file in the release archive is automatically built
o curl --proxy-digest is a new command line option
o the Windows version of libcurl can use wldap32.dll for LDAP
o added curl_easy_strerror(), curl_multi_strerror() and curl_share_strerror()
o IPv6-enabled Windows hosts now resolves names threaded/asynch as well
o configure --with-libidn can be used to point out the root dir of a libidn
installation (version 0.4.5 or later) for curl to use, then libcurl can
resolve and use IDNA names (domain names with "international" letters)
o read callbacks can stop the transfer by returning CURL_READFUNC_ABORT
o libcurl-tutorial.3 is the new man page formerly known as libcurl-the-guide
o additional SSL trace data might be sent to the debug callback using two new
types: CURLINFO_SSL_DATA_IN and CURLINFO_SSL_DATA_OUT
o multipart formposts can upload files larger than system memory
o the curl tool continues with the next URL even if one transfer fails
o FTP 3rd party transfer support - seven new setopt() options
This release includes the following bugfixes:
o incoming cookies with domains set with a prefixed dot now works better
o CURLOPT_COOKIEFILE and CURLOPT_COOKIE can be used in the same request
o improved peer certificate name verification
o allocation failures cause no leaks nor crashes
o the progress meter display now handles file sizes up to full 8 exabytes
(which is as high a signed 64 bit number can reach)
o general HTTP authentication improvements
o HTTP Digest authentication with the proxy works
o mulipart formposting with -F and file names with spaces work again
o curl_easy_duphandle() now works when ares-enabled
o HTTP Digest authentication works a lot more like the RFC says
o curl works with telnet and stdin properly on Windows
o configure --without-ssl works even when pkg-config has OpenSSL details
o src/hugehelp.c builds correct again in non-configure build environments
o cookies can now hold 4999 bytes of content
o HTTP POST/PUT with NTLM/Digest/Negotiate to a URL returning 3XX
o HTTPS POST/PUT over a proxy requiring NTLM/Digest/Negotiate works now
o less restrictive libidn requirements, 0.4.1 or later is fine
o fixed HTTP POST or PUT with Digest/Negotiate/NTLM selected but the server
didn't require any authentication
o win32 file:// transfer free memory bug
o configure --disable-http builds a libcurl without HTTP support
o CURLOPT_FILETIME had wrong type, it expects a long argument
o builds fine with Borland on Windows again
o the msvc curllib.dsp now builds the libcurl.lib file again
o builds fine on VMS again
o builds fine on NetWare again
o HTTP Digest authentication with proxies uses correct user name + password
o now builds fine with lcc-win32
Other curl-related news since the previous public release:
o The CVS repository was moved to cool.haxx.se
o AdacURL 7.11.2 was released: http://www.almroth.com/adacurl/
o PycURL 7.11.3 was released: http://pycurl.sourceforge.net
o A new German download mirror: http://www.mirrorspace.org/curl/
o Two new mailing lists are available:
curl-and-python - for python programmers using pycurl or curl
curl-perl-commmits - receives commits done to the curl-perl CVS module
o James Hu took over after Kevin Roth as maintainer of the curl package on
cygwin. Many saludos to Kevin for a work well done during many years.
o Gambas binding for libcurl: http://gambas.sf.net/
o pycurl 7.12.0 was released http://pycurl.sf.net/
This release would not have looked like this without help, code, reports and
advice from friends like these:
Gisle Vanem, Tommy Tam, Luca Altea, James Bursa, Mihai Ionescu, Michael
Benedict, Andr<64>s Garc<72>a, Joe Halpin, Seshubabu Pasam, Peter Sylvester, Robert
D. Young, Jesse Noller, David Byron, Massimiliano Ziccardi, Mohun Biswas,
Renaud Duhaut
Gisle Vanem, Vincent Bronner, Alexander Krasnostavsky, Chris Gaukroger,
G<EFBFBD>nter Knauf, Marty Kuhrt, Kjetil Jacobsen, Steven Bazyl, Seshubabu Pasam,
Luca Alteas, Jean-Louis Lemaire, David Byron, David Cohen
Thanks! (and sorry if I forgot to mention someone)

View File

@@ -1,13 +1,17 @@
Issues not sorted in any particular order.
#[num] refers to bug report numbers.
UNASSIGNED means that no person has publicly stated to work on the issue.
DELETE means the issue is subject for dismissal
To get fixed in 7.12.0 (planned release: June 2004)
======================
To get fixed in 7.12.1 (planned release: August 2004)
======================
* FTP 3rd party transfers
35 - Fix multi interface when connecting to host with multiple IP addresses:
http://curl.haxx.se/mail/lib-2004-06/0163.html and
http://curl.haxx.se/mail/lib-2004-06/0167.html
UNASSIGNED
* Bugfixes reported until late July
To get fixed in 7.12.2 (planned release: December 2004)
======================
Bugfixes reported until late November

View File

@@ -423,13 +423,18 @@ main () {
return 0;
}
],
GLIBC_STRERROR_R="1"
AC_DEFINE(HAVE_GLIBC_STRERROR_R, 1, [we have a glibc-style strerror_r()])
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no])
AC_MSG_RESULT([no]),
dnl cross-compiling!
AC_MSG_NOTICE([cannot determine strerror_r() style: edit lib/config.h manually!])
)
AC_MSG_CHECKING([for a POSIX strerror_r API])
AC_TRY_RUN([
if test -z "$GLIBC_STRERROR_R"; then
AC_MSG_CHECKING([for a POSIX strerror_r API])
AC_TRY_RUN([
#include <string.h>
#include <errno.h>
int
@@ -444,12 +449,16 @@ main () {
return 0;
}
],
AC_DEFINE(HAVE_POSIX_STRERROR_R, 1, [we have a POSIX-style strerror_r()])
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no])
AC_DEFINE(HAVE_POSIX_STRERROR_R, 1, [we have a POSIX-style strerror_r()])
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no]) ,
dnl cross-compiling!
AC_MSG_NOTICE([cannot determine strerror_r() style: edit lib/config.h manually!])
)
fi
fi dnl if not using glibc API
fi dnl we have a strerror_r
])

View File

@@ -1,5 +1,26 @@
Changelog for the c-ares project
* June 10
- Gisle Vanem's init patch for Windows:
The init_by_resolv_conf() function fetches the DNS-server(s)
from a series of registry branches.
This can be wrong in the case where DHCP has assigned nameservers, but the
user has overridden these servers with other prefered settings. Then it's
wrong to use the DHCPNAMESERVER setting in registry.
In the case of no global DHCP-assigned or fixed servers, but DNS server(s)
per adapter, one has to query the adapter branches. But how can c-ares know
which adapter is valid for use? AFAICS it can't. There could be one adapter
that is down (e.g. a VPN adapter).
So it's better to leave this to the IP Helper API (iphlapi) available in
Win-98/2000 and later. My patch falls-back to the old way if not available.
* June 8
- James Bursa fixed an init issue for RISC OS.
* May 11
- Nico Stappenbelt reported that when processing domain and search lines in
the resolv.conf file, the first entry encountered is processed and used as

View File

@@ -17,6 +17,8 @@
#ifdef WIN32
#include "nameser.h"
#include <iphlpapi.h>
#include <malloc.h>
#else
#include <sys/param.h>
#include <sys/time.h>
@@ -231,24 +233,24 @@ static int init_by_environment(ares_channel channel)
return ARES_SUCCESS;
}
#ifdef WIN32
static int get_res_size_nt(HKEY hKey, char *subkey, int *size)
{
return RegQueryValueEx(hKey, subkey, 0, NULL, NULL, size);
}
/* Warning: returns a dynamically allocated buffer, the user MUST
#ifdef WIN32
/*
* Warning: returns a dynamically allocated buffer, the user MUST
* use free() if the function returns 1
*/
static int get_res_nt(HKEY hKey, char *subkey, char **obuf)
static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
{
/* Test for the size we need */
int size = 0;
DWORD size = 0;
int result;
result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
return 0;
*obuf = malloc(size+1);
if (!*obuf)
return 0;
if (RegQueryValueEx(hKey, subkey, 0, NULL, *obuf, &size) != ERROR_SUCCESS)
{
@@ -263,29 +265,99 @@ static int get_res_nt(HKEY hKey, char *subkey, char **obuf)
return 1;
}
static int get_res_interfaces_nt(HKEY hKey, char *subkey, char **obuf)
static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
{
char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
int enum_size = 39;
DWORD enum_size = 39;
int idx = 0;
HKEY hVal;
while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
{
int rc;
enum_size = 39;
if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
ERROR_SUCCESS)
continue;
if (!get_res_nt(hVal, subkey, obuf))
RegCloseKey(hVal);
else
{
rc = get_res_nt(hVal, subkey, obuf);
RegCloseKey(hVal);
if (rc)
return 1;
}
}
return 0;
}
static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
{
FIXED_INFO *fi = alloca (sizeof(*fi));
DWORD size = sizeof (*fi);
DWORD WINAPI (*GetNetworkParams) (FIXED_INFO*, DWORD*); /* available only on Win-98/2000+ */
HMODULE handle;
IP_ADDR_STRING *ipAddr;
int i, count = 0;
int debug = 0;
size_t ip_size = sizeof("255.255.255.255,")-1;
size_t left = ret_size;
char *ret = ret_buf;
if (!fi)
return (0);
handle = LoadLibrary ("iphlpapi.dll");
if (!handle)
return (0);
(void*)GetNetworkParams = GetProcAddress (handle, "GetNetworkParams");
if (!GetNetworkParams)
goto quit;
if ((*GetNetworkParams) (fi, &size) != ERROR_BUFFER_OVERFLOW)
goto quit;
fi = alloca (size);
if (!fi || (*GetNetworkParams) (fi, &size) != ERROR_SUCCESS)
goto quit;
if (debug)
{
printf ("Host Name: %s\n", fi->HostName);
printf ("Domain Name: %s\n", fi->DomainName);
printf ("DNS Servers:\n"
" %s (primary)\n", fi->DnsServerList.IpAddress.String);
}
if (inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
left > ip_size)
{
ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
left -= ret - ret_buf;
count++;
}
for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
ipAddr = ipAddr->Next, i++)
{
if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
{
ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
left -= ret - ret_buf;
count++;
}
if (debug)
printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
}
quit:
if (handle)
FreeLibrary (handle);
if (debug && left <= ip_size)
printf ("Too many nameservers. Truncating to %d addressess", count);
if (ret > ret_buf)
ret[-1] = '\0';
return (count);
}
#endif
static int init_by_resolv_conf(ares_channel channel)
@@ -298,6 +370,11 @@ static int init_by_resolv_conf(ares_channel channel)
#ifdef WIN32
/*
NameServer info via IPHLPAPI (IP helper API):
GetNetworkParams() should be the trusted source for this.
Available in Win-98/2000 and later. If that fail, fall-back to
registry information.
NameServer Registry:
On Windows 9X, the DNS server can be found in:
@@ -320,9 +397,17 @@ DhcpNameServer
DWORD data_type;
DWORD bytes;
DWORD result;
DWORD keysize = MAX_PATH;
char buf[256];
status = ARES_EFILE;
if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
return ARES_SUCCESS;
if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
{
status = config_nameserver(&servers, &nservers, buf);
if (status == ARES_SUCCESS)
goto okay;
}
if (IsNT)
{
@@ -388,15 +473,8 @@ DhcpNameServer
RegCloseKey(mykey);
}
if (status != ARES_EFILE)
{
/*
if (!channel->lookups) {
status = config_lookup(channel, "file bind");
}
*/
if (status == ARES_SUCCESS)
status = ARES_EOF;
}
#elif defined(riscos)
@@ -404,7 +482,7 @@ DhcpNameServer
system variable Inet$Resolvers, space separated. */
line = getenv("Inet$Resolvers");
status = ARES_EFILE;
status = ARES_EOF;
if (line) {
char *resolvers = strdup(line), *pos, *space;
@@ -474,6 +552,9 @@ DhcpNameServer
}
/* If we got any name server entries, fill them in. */
#ifdef WIN32
okay:
#endif
if (servers)
{
channel->servers = servers;

View File

@@ -1365,6 +1365,8 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]),
AC_MSG_RESULT(no)
)
AM_CONDITIONAL(CROSSCOMPILING, test x$cross_compiling = xyes)
AC_CONFIG_FILES([Makefile \
docs/Makefile \
docs/examples/Makefile \

View File

@@ -126,3 +126,5 @@ visitors to the curl.haxx.se site. Five official web mirrors.
December 2003, full-fledged SSL for FTP is supported.
January 2004: curl 7.11.0 introduced large file support.
June 2004: curl 7.12.0 introduced IDN support. 10 official web mirrors.

View File

@@ -851,7 +851,7 @@ MAILING LISTS
For your convenience, we have several open mailing lists to discuss curl,
its development and things relevant to this. Get all info at
http://curl.haxx.se/mail/. The lists available are:
http://curl.haxx.se/mail/. Some of the lists available are:
curl-users
@@ -865,24 +865,18 @@ MAILING LISTS
curl-announce
Low-traffic. Only announcements of new public versions.
Low-traffic. Only receives announcements of new public versions. At worst,
that makes something like one or two mails per month, but usually only one
mail every second month.
curl-and-PHP
curl-and-php
Using the curl functions in PHP. Everything curl with a PHP angle. Or PHP
with a curl angle.
curl-commits
curl-and-python
Receives notifications on all CVS commits done to the curl source module.
This can become quite a large amount of mails during intense development,
be aware. This is for us who like email...
curl-www-commits
Receives notifications on all CVS commits done to the curl www module
(basicly the web site). This can become quite a large amount of mails
during intense changing, be aware. This is for us who like email...
Python hackers using curl with or without the python binding pycurl.
Please direct curl questions, feature requests and trouble reports to one of
these mailing lists instead of mailing any individual.

View File

@@ -17,7 +17,7 @@ CLEANFILES = $(GENHTMLPAGES) $(PDFPAGES)
EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS SSLCERTS \
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS \
KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) HISTORY INSTALL \
libcurl-the-guide $(PDFPAGES) LICENSE-MIXING
$(PDFPAGES) LICENSE-MIXING
MAN2HTML= roffit < $< >$@

View File

@@ -9,7 +9,7 @@ EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit2.c \
ftpupload.c httpput.c simplessl.c ftpgetresp.c http-post.c \
post-callback.c multi-app.c multi-double.c multi-single.c \
multi-post.c fopen.c simplepost.c makefile.dj curlx.c https.c \
multi-debugcallback.c fileupload.c
multi-debugcallback.c fileupload.c getinfo.c ftp3rdparty.c
all:
@echo "done"

104
docs/examples/ftp3rdparty.c Normal file
View File

@@ -0,0 +1,104 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*/
#include <stdio.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
/*
* This is an example showing how to transfer a file between two remote hosts.
*/
int main(void)
{
CURL *curl;
CURLcode res;
char sourceFileName[] = "/tmp/file";
char targetFileName[] = "/tmp/curlTargetTest.dat";
char sourceHost[] = "source";
char targetHost[] = "target";
char sourceUserPass[] = "user:pass";
char targetUserPass[] = "user:pass";
char url[100];
struct curl_slist *source_pre_cmd = NULL;
struct curl_slist *target_pre_cmd = NULL;
struct curl_slist *source_post_cmd = NULL;
struct curl_slist *target_post_cmd = NULL;
char cmd[] = "PWD"; /* just to test */
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (curl) {
sprintf(url, "ftp://%s@%s/%s", targetUserPass, targetHost, targetFileName);
printf("%s\n", url);
curl_easy_setopt(curl, CURLOPT_URL, url);
/* Set a proxy host */
curl_easy_setopt(curl, CURLOPT_SOURCE_HOST, sourceHost);
/* Set a proxy user and password */
curl_easy_setopt(curl, CURLOPT_SOURCE_USERPWD, sourceUserPass);
/* Set a proxy full file name */
curl_easy_setopt(curl, CURLOPT_SOURCE_PATH, sourceFileName);
/* Set a proxy passive host */
curl_easy_setopt(curl, CURLOPT_PASV_HOST, 0); /* optional */
/* build a list of commands to pass to libcurl */
source_pre_cmd = curl_slist_append(source_pre_cmd, cmd);
/* Set a proxy pre-quote command */
curl_easy_setopt(curl, CURLOPT_SOURCE_PREQUOTE, source_pre_cmd);
/* build a list of commands to pass to libcurl */
target_pre_cmd = curl_slist_append(target_pre_cmd, cmd);
/* Set a pre-quote command */
curl_easy_setopt(curl, CURLOPT_PREQUOTE, target_pre_cmd);
/* build a list of commands to pass to libcurl */
source_post_cmd = curl_slist_append(source_post_cmd, cmd);
/* Set a proxy post-quote command */
curl_easy_setopt(curl, CURLOPT_SOURCE_POSTQUOTE, source_post_cmd);
/* build a list of commands to pass to libcurl */
target_post_cmd = curl_slist_append(target_post_cmd, cmd);
/* Set a post-quote command */
curl_easy_setopt(curl, CURLOPT_POSTQUOTE, target_post_cmd);
/* Switch on full protocol/debug output */
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
res = curl_easy_perform(curl);
/* clean up the FTP commands list */
curl_slist_free_all(source_pre_cmd);
curl_slist_free_all(target_pre_cmd);
curl_slist_free_all(source_post_cmd);
curl_slist_free_all(target_post_cmd);
/* always cleanup */
curl_easy_cleanup(curl);
if(CURLE_OK != res) {
/* we failed */
fprintf(stderr, "curl told us %d\n", res);
}
}
curl_global_cleanup();
return 0;
}

37
docs/examples/getinfo.c Normal file
View File

@@ -0,0 +1,37 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*/
#include <stdio.h>
#include <curl/curl.h>
int main(void)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se");
res = curl_easy_perform(curl);
if(CURLE_OK == res) {
char *ct;
/* ask for the content-type */
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);
if((CURLE_OK == res) && ct)
printf("We received Content-Type: %s\n", ct);
}
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}

View File

@@ -16,7 +16,7 @@ About this Document
This document will refer to 'the user' as the person writing the source code
that uses libcurl. That would probably be you or someone in your position.
What will be generally refered to as 'the program' will be the collected
What will be generally referred to as 'the program' will be the collected
source code that you write that is using libcurl for transfers. The program
is outside libcurl and libcurl is outside of the program.
@@ -44,7 +44,7 @@ Building
When having compiled the program, you need to link your object files to
create a single executable. For that to succeed, you need to link with
libcurl and possibly also with other libraries that libcurl itself depends
on. Like OpenSSL librararies, but even some standard OS libraries may be
on. Like OpenSSL libraries, but even some standard OS libraries may be
needed on the command line. To figure out which flags to use, once again
the 'curl-config' tool comes to the rescue:
@@ -65,6 +65,8 @@ Building
possibly together with a few other features that can be on and off on
different libcurls.
See also the "Features libcurl Provides" further down.
Portable Code in a Portable World
@@ -86,22 +88,22 @@ Global Preparation
curl_global_init()
and it takes one parameter which is a bit pattern that tells libcurl what to
intialize. Using CURL_GLOBAL_ALL will make it initialize all known internal
initialize. Using CURL_GLOBAL_ALL will make it initialize all known internal
sub modules, and might be a good default option. The current two bits that
are specified are:
CURL_GLOBAL_WIN32 which only does anything on Windows machines. When used on
a Windows machine, it'll make libcurl intialize the win32 socket
a Windows machine, it'll make libcurl initialize the win32 socket
stuff. Without having that initialized properly, your program cannot use
sockets properly. You should only do this once for each application, so if
your program already does this or of another library in use does it, you
should not tell libcurl to do this as well.
CURL_GLOBAL_SSL which only does anything on libcurls compiled and built
SSL-enabled. On these systems, this will make libcurl init OpenSSL properly
for this application. This is only needed to do once for each application so
if your program or another library already does this, this bit should not be
needed.
SSL-enabled. On these systems, this will make libcurl initialize OpenSSL
properly for this application. This is only needed to do once for each
application so if your program or another library already does this, this
bit should not be needed.
libcurl has a default protection mechanism that detects if curl_global_init()
hasn't been called by the time curl_easy_perform() is called and if that is
@@ -117,18 +119,26 @@ Global Preparation
avoided. They should only be called once each.
Features libcurl Provides
It is considered best-practice to determine libcurl features run-time rather
than build-time (if possible of course). By calling curl_version_info() and
checking tout he details of the returned struct, your program can figure out
exactly what the currently running libcurl supports.
Handle the Easy libcurl
libcurl version 7 is oriented around the so called easy interface. All
operations in the easy interface are prefixed with 'curl_easy'.
libcurl first introduced the so called easy interface. All operations in the
easy interface are prefixed with 'curl_easy'.
Future libcurls will also offer the multi interface. More about that
interface, what it is targeted for and how to use it is still only debated on
the libcurl mailing list and developer web pages. Join up to discuss and
figure out!
Recent libcurl versions also offer the multi interface. More about that
interface, what it is targeted for and how to use it is detailed in a
separate chapter further down. You still need to understand the easy
interface first, so please continue reading for better understanding.
To use the easy interface, you must first create yourself an easy handle. You
need one handle for each easy session you want to perform. Basicly, you
need one handle for each easy session you want to perform. Basically, you
should use one handle for every thread you plan to use for transferring. You
must never share the same handle in multiple threads.
@@ -145,7 +155,7 @@ Handle the Easy libcurl
set in the handle until set again to something different. Alas, multiple
requests using the same handle will use the same options.
Many of the informationals you set in libcurl are "strings", pointers to data
Many of the options you set in libcurl are "strings", pointers to data
terminated with a zero byte. Keep in mind that when you set strings with
curl_easy_setopt(), libcurl will not copy the data. It will merely point to
the data. You MUST make sure that the data remains available for libcurl to
@@ -157,7 +167,7 @@ Handle the Easy libcurl
curl_easy_setopt(easyhandle, CURLOPT_URL, "http://curl.haxx.se/");
Let's assume for a while that you want to receive data as the URL indentifies
Let's assume for a while that you want to receive data as the URL identifies
a remote resource you want to get here. Since you write a sort of application
that needs this transfer, I assume that you would like to get the data passed
to you directly instead of simply getting it passed to stdout. So, you write
@@ -219,26 +229,21 @@ Handle the Easy libcurl
Multi-threading issues
libcurl is completely thread safe, except for two issues: signals and alarm
handlers. Signals are needed for a SIGPIPE handler, and the alarm() syscall
is used to catch timeouts (mostly during DNS lookup).
handlers. Signals are needed for a SIGPIPE handler, and the alarm() Bacall
is used to catch timeouts (mostly during ENS lookup).
If you are accessing HTTPS or FTPS URLs in a multi-threaded manner, you are
then of course using OpenSSL multi-threaded and it has itself a few
requirements on this. Basicly, you need to provide one or two functions to
requirements on this. Basilio, you need to provide one or two functions to
allow it to function properly. For all details, see this:
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
When using multiple threads you should first ignore SIGPIPE in your main
thread and set the CURLOPT_NOSIGNAL option to TRUE for all handles.
Everything will work fine except that timeouts are not honored during the DNS
lookup - which you can work around by building libcurl with ares-support.
Ares is a library that provides asynchronous name resolves. Unfortunately,
ares does not yet support IPv6.
For SIGPIPE info see the UNIX Socket FAQ at
http://www.unixguide.net/network/socketfaq/2.22.shtml
When using multiple threads you should set the CURLOPT_NOSIGNAL option to
TRUE for all handles. Everything will work fine except that timeouts are not
honored during the DNS lookup - which you can work around by building libcurl
with c-ares support. c-ares is a library that provides asynchronous name
resolves. Unfortunately, c-ares does not yet support IPv6.
Also, note that CURLOPT_DNS_USE_GLOBAL_CACHE is not thread-safe.
@@ -251,10 +256,10 @@ When It Doesn't Work
There's one golden rule when these things occur: set the CURLOPT_VERBOSE
option to TRUE. It'll cause the library to spew out the entire protocol
details it sends, some internal info and some received protcol data as well
details it sends, some internal info and some received protocol data as well
(especially when using FTP). If you're using HTTP, adding the headers in the
received output to study is also a clever way to get a better understanding
wht the server behaves the way it does. Include headers in the normal body
why the server behaves the way it does. Include headers in the normal body
output with CURLOPT_HEADER set TRUE.
Of course there are bugs left. We need to get to know about them to be able
@@ -342,7 +347,7 @@ Passwords
curl_easy_setopt(easyhandle, CURLOPT_USERPWD, "myname:thesecret");
Another case where name and password might be needed at times, is for those
users who need to athenticate themselves to a proxy they use. libcurl offers
users who need to authenticate themselves to a proxy they use. libcurl offers
another option for this, the CURLOPT_PROXYUSERPWD. It is used quite similar
to the CURLOPT_USERPWD option like this:
@@ -382,7 +387,7 @@ HTTP Authentication
many different ways a client can provide those credentials to the server and
you can control what way libcurl will (attempt to) use. The default HTTP
authentication method is called 'Basic', which is sending the name and
password in clear-text in the HTTP request, base64-encoded. This is unsecure.
password in clear-text in the HTTP request, base64-encoded. This is insecure.
At the time of this writing libcurl can be built to use: Basic, Digest, NTLM,
Negotiate, GSS-Negotiate and SPNEGO. You can tell libcurl which one to use
@@ -427,7 +432,7 @@ HTTP POSTing
curl_easy_perform(easyhandle); /* post away! */
Simple enough, huh? Since you set the POST options with the
CURLOPT_POSTFIELDS, this automaticly switches the handle to use POST in the
CURLOPT_POSTFIELDS, this automatically switches the handle to use POST in the
upcoming request.
Ok, so what if you want to post binary data that also requires you to set the
@@ -454,12 +459,12 @@ HTTP POSTing
curl_slist_free_all(headers); /* free the header list */
While the simple examples above cover the majority of all cases where HTTP
POST operations are required, they don't do multipart formposts. Multipart
POST operations are required, they don't do multi-part formposts. Multi-part
formposts were introduced as a better way to post (possibly large) binary
data and was first documented in the RFC1867. They're called multipart
data and was first documented in the RFC1867. They're called multi-part
because they're built by a chain of parts, each being a single unit. Each
part has its own name and contents. You can in fact create and post a
multipart formpost with the regular libcurl POST support described above, but
multi-part formpost with the regular libcurl POST support described above, but
that would require that you build a formpost yourself and provide to
libcurl. To make that easier, libcurl provides curl_formadd(). Using this
function, you add parts to the form. When you're done adding parts, you post
@@ -553,7 +558,7 @@ Showing Progress
libcurl with C++
There's basicly only one thing to keep in mind when using C++ instead of C
There's basically only one thing to keep in mind when using C++ instead of C
when interfacing libcurl:
"The Callbacks Must Be Plain C"
@@ -580,8 +585,8 @@ Proxies
as a substitute for another".
Proxies are exceedingly common these days. Companies often only offer
internet access to employees through their HTTP proxies. Network clients or
user-agents ask the proxy for docuements, the proxy does the actual request
Internet access to employees through their HTTP proxies. Network clients or
user-agents ask the proxy for documents, the proxy does the actual request
and then it returns them.
libcurl has full support for HTTP proxies, so when a given URL is wanted,
@@ -591,7 +596,7 @@ Proxies
The fact that the proxy is a HTTP proxy puts certain restrictions on what can
actually happen. A requested URL that might not be a HTTP URL will be still
be passed to the HTTP proxy to deliver back to libcurl. This happens
transparantly, and an application may not need to know. I say "may", because
transparently, and an application may not need to know. I say "may", because
at times it is very important to understand that all operations over a HTTP
proxy is using the HTTP protocol. For example, you can't invoke your own
custom FTP commands or even proper FTP directory listings.
@@ -612,9 +617,9 @@ Proxies
Environment Variables
libcurl automaticly checks and uses a set of environment variables to know
what proxies to use for certain protocols. The names of the variables are
following an ancient de facto standard and are built up as
libcurl automatically checks and uses a set of environment variables to
know what proxies to use for certain protocols. The names of the variables
are following an ancient de facto standard and are built up as
"[protocol]_proxy" (note the lower casing). Which makes the variable
'http_proxy' checked for a name of a proxy to use when the input URL is
HTTP. Following the same rule, the variable named 'ftp_proxy' is checked
@@ -622,11 +627,12 @@ Proxies
names of the variables simply allows different HTTP proxies to be used.
The proxy environment variable contents should be in the format
"[protocol://]machine[:port]". Where the protocol:// part is simply
ignored if present (so http://proxy and bluerk://proxy will do the same)
and the optional port number specifies on which port the proxy operates on
the host. If not specified, the internal default port number will be used
and that is most likely *not* the one you would like it to be.
"[protocol://][user:password]machine[:port]". Where the protocol:// part
is simply ignored if present (so http://proxy and bluerk://proxy will do
the same) and the optional port number specifies on which port the proxy
operates on the host. If not specified, the internal default port number
will be used and that is most likely *not* the one you would like it to
be.
There are two special environment variables. 'all_proxy' is what sets
proxy for any URL in case the protocol specific variable wasn't set, and
@@ -637,7 +643,7 @@ Proxies
SSL and Proxies
SSL is for secure point-to-point connections. This involves strong
encryption and similar things, which effectivly makes it impossible for a
encryption and similar things, which effectively makes it impossible for a
proxy to operate as a "man in between" which the proxy's task is, as
previously discussed. Instead, the only way to have SSL work over a HTTP
proxy is to ask the proxy to tunnel trough everything without being able
@@ -668,7 +674,7 @@ Proxies
operations over a HTTP proxy. You can in fact use things such as FTP
upload or FTP custom commands this way.
Again, this is often prevented by the adminstrators of proxies and is
Again, this is often prevented by the administrators of proxies and is
rarely allowed.
Tell libcurl to use proxy tunneling like this:
@@ -682,13 +688,13 @@ Proxies
Proxy Auto-Config
Netscape first came up with this. It is basicly a web page (usually using
a .pac extension) with a javascript that when executed by the browser with
the requested URL as input, returns information to the browser on how to
connect to the URL. The returned information might be "DIRECT" (which
means no proxy should be used), "PROXY host:port" (to tell the browser
where the proxy for this particular URL is) or "SOCKS host:port" (to
direct the brower to a SOCKS proxy).
Netscape first came up with this. It is basically a web page (usually
using a .pac extension) with a javascript that when executed by the
browser with the requested URL as input, returns information to the
browser on how to connect to the URL. The returned information might be
"DIRECT" (which means no proxy should be used), "PROXY host:port" (to tell
the browser where the proxy for this particular URL is) or "SOCKS
host:port" (to direct the browser to a SOCKS proxy).
libcurl has no means to interpret or evaluate javascript and thus it
doesn't support this. If you get yourself in a position where you face
@@ -706,7 +712,7 @@ Proxies
- Ask your admins to stop this, for a static proxy setup or similar.
Persistancy Is The Way to Happiness
Persistence Is The Way to Happiness
Re-cycling the same easy handle several times when doing multiple requests is
the way to go.
@@ -717,11 +723,11 @@ Persistancy Is The Way to Happiness
reduces network impact a lot.
Even if the connection is dropped, all connections involving SSL to the same
host again, will benefit from libcurl's session ID cache that drasticly
host again, will benefit from libcurl's session ID cache that drastically
reduces re-connection time.
FTP connections that are kept alive saves a lot of time, as the command-
response roundtrips are skipped, and also you don't risk getting blocked
response round-trips are skipped, and also you don't risk getting blocked
without permission to login again like on many FTP servers only allowing N
persons to be logged in at the same time.
@@ -747,13 +753,13 @@ Persistancy Is The Way to Happiness
used for the longest time. This is the default behavior.
CURLCLOSEPOLICY_OLDEST closes the oldest connection, the one that was
createst the longest time ago.
created the longest time ago.
There are, or at least were, plans to support a close policy that would call
a user-specified callback to let the user be able to decide which connection
to dump when this is necessary and therefor is the CURLOPT_CLOSEFUNCTION an
existing option still today. Nothing ever uses this though and this will not
be used within the forseeable future either.
be used within the foreseeable future either.
To force your upcoming request to not use an already existing connection (it
will even close one first if there happens to be one alive to the same host
@@ -765,8 +771,8 @@ Persistancy Is The Way to Happiness
HTTP Headers Used by libcurl
When you use libcurl to do HTTP requeests, it'll pass along a series of
headers automaticly. It might be good for you to know and understand these
When you use libcurl to do HTTP requests, it'll pass along a series of
headers automatically. It might be good for you to know and understand these
ones.
Host
@@ -777,7 +783,7 @@ HTTP Headers Used by libcurl
Pragma
"no-cache". Tells a possible proxy to not grap a copy from the cache but
"no-cache". Tells a possible proxy to not grab a copy from the cache but
to fetch a fresh one.
Accept:
@@ -851,7 +857,7 @@ Customizing Operations
headers = curl_slist_append(headers, "Accept:");
Both replacing and cancelling internal headers should be done with careful
Both replacing and canceling internal headers should be done with careful
consideration and you should be aware that you may violate the HTTP
protocol when doing so.
@@ -861,7 +867,7 @@ Customizing Operations
chunked" when doing a non-GET HTTP operation, libcurl will switch over to
"chunked" upload, even though the size of the data to upload might be
known. By default, libcurl usually switches over to chunked upload
automaticly if the upload data size is unknown.
automatically if the upload data size is unknown.
HTTP Version
@@ -881,10 +887,10 @@ Customizing Operations
you want to make for example your FTP transfers to behave differently.
Sending custom commands to a FTP server means that you need to send the
comands exactly as the FTP server expects them (RFC959 is a good guide
commands exactly as the FTP server expects them (RFC959 is a good guide
here), and you can only use commands that work on the control-connection
alone. All kinds of commands that requires data interchange and thus needs
a data-connection must be left to libcurl's own judgement. Also be aware
a data-connection must be left to libcurl's own judgment. Also be aware
that libcurl will do its very best to change directory to the target
directory before doing any transfer, so if you change directory (with CWD
or similar) you might confuse libcurl and then it might not attempt to
@@ -948,16 +954,16 @@ Cookies Without Chocolate Chips
curl_easy_setopt(easyhandle, CURLOPT_COOKIE, "name1=var1; name2=var2;");
In many cases, that is not enough. You might want to dynamicly save whatever
cookies the remote server passes to you, and make sure those cookies are then
use accordingly on later requests.
In many cases, that is not enough. You might want to dynamically save
whatever cookies the remote server passes to you, and make sure those cookies
are then use accordingly on later requests.
One way to do this, is to save all headers you receive in a plain file and
when you make a request, you tell libcurl to read the previous headers to
figure out which cookies to use. Set header file to read cookies from with
CURLOPT_COOKIEFILE.
The CURLOPT_COOKIEFILE option also automaticly enables the cookie parser in
The CURLOPT_COOKIEFILE option also automatically enables the cookie parser in
libcurl. Until the cookie parser is enabled, libcurl will not parse or
understand incoming cookies and they will just be ignored. However, when the
parser is enabled the cookies will be understood and the cookies will be kept
@@ -970,7 +976,7 @@ Cookies Without Chocolate Chips
If you rather use existing cookies that you've previously received with your
Netscape or Mozilla browsers, you can make libcurl use that cookie file as
input. The CURLOPT_COOKIEFILE is used for that too, as libcurl will
automaticly find out what kind of file it is and act accordingly.
automatically find out what kind of file it is and act accordingly.
The perhaps most advanced cookie operation libcurl offers, is saving the
entire internal cookie state back into a Netscape/Mozilla formatted cookie
@@ -990,7 +996,7 @@ FTP Peculiarities We Need
libcurl can either connect to the server a second time or tell the server to
connect back to it. The first option is the default and it is also what works
best for all the people behind firewalls, NATs or IP-masquarading setups.
best for all the people behind firewalls, NATs or IP-masquerading setups.
libcurl then tells the server to open up a new port and wait for a second
connection. This is by default attempted with EPSV first, and if that doesn't
work it tries PASV instead. (EPSV is an extension to the original FTP spec
@@ -1063,7 +1069,7 @@ Security Considerations
.netrc
.netrc is a pretty handy file/feature that allows you to login quickly and
automaticly to frequently visited sites. The file contains passwords in
automatically to frequently visited sites. The file contains passwords in
clear text and is a real security risk. In some cases, your .netrc is also
stored in a home directory that is NFS mounted or used on another network
based file system, so the clear text password will fly through your
@@ -1077,8 +1083,8 @@ Security Considerations
Many of the protocols libcurl supports send name and password unencrypted
as clear text (HTTP Basic authentication, FTP, TELNET etc). It is very
easy for anyone on your network or a network nearby yours, to just fire up
a network analyzer tool and evesdrop on your passwords. Don't let the fact
that HTTP uses base64 encoded passwords fool you. They may not look
a network analyzer tool and eavesdrop on your passwords. Don't let the
fact that HTTP uses base64 encoded passwords fool you. They may not look
readable at a first glance, but they very easily "deciphered" by anyone
within seconds.
@@ -1090,21 +1096,17 @@ Security Considerations
Showing What You Do
On a related issue, be aware that even in situations like when you have
problems with libcurl and ask somone for help, everything you reveal in
problems with libcurl and ask someone for help, everything you reveal in
order to get best possible help might also impose certain security related
risks. Host names, user names, paths, operating system specifics etc (not
to mention passwords of course) may in fact be used by intruders to gain
additional information of a potential target.
To avoid this problem, you must of course use your common sense. Often,
you can just edit out the senstive data or just rearch/replace your true
you can just edit out the sensitive data or just search/replace your true
information with faked data.
SSL, Certificates and Other Tricks
[ seeding, passwords, keys, certificates, ENGINE, ca certs ]
Multiple Transfers Using the multi Interface
The easy interface as described in detail in this document is a synchronous
@@ -1115,18 +1117,69 @@ Multiple Transfers Using the multi Interface
multiple files in both directions at the same time, without forcing you to
use multiple threads.
[fill in lots of more multi stuff here]
To use this interface, you are better off if you first understand the basics
of how to use the easy interface. The multi interface is simply a way to make
multiple transfers at the same time, by adding up multiple easy handles in to
a "multi stack".
Future
You create the easy handles you want and you set all the options just like
you have been told above, and then you create a multi handle with
curl_multi_init() and add all those easy handles to that multi handle with
curl_multi_add_handle().
[ sharing between handles, mutexes, pipelining ]
When you've added the handles you have for the moment (you can still add new
ones at any time), you start the transfers by call curl_multi_perform().
curl_multi_perform() is asynchronous. It will only execute as little as
possible and then return back control to your program. It is designed to
never block. If it returns CURLM_CALL_MULTI_PERFORM you better call it again
soon, as that is a signal that it still has local data to send or remote data
to receive.
The best usage of this interface is when you do a select() on all possible
file descriptors or sockets to know when to call libcurl again. This also
makes it easy for you to wait and respond to actions on your own
application's sockets/handles. You figure out what to select() for by using
curl_multi_fdset(), that fills in a set of fd_set variables for you with the
particular file descriptors libcurl uses for the moment.
When you then call select(), it'll return when one of the file handles signal
action and you then call curl_multi_perform() to allow libcurl to do what it
wants to do. Take note that libcurl does also feature some time-out code so
we advice you to never use very long timeouts on select() before you call
curl_multi_perform(), which thus should be called unconditionally every now
and then even if none of its file descriptors have signaled ready. Another
precaution you should use: always call curl_multi_fdset() immediately before
the select() call since the current set of file descriptors may change when
calling a curl function.
If you want to stop the transfer of one of the easy handles in the stack, you
can use curl_multi_remove_handle() to remove individual easy
handles. Remember that easy handles should be curl_easy_cleanup()ed.
When a transfer within the multi stack has finished, the counter of running
transfers (as filled in by curl_multi_perform()) will decrease. When the
number reaches zero, all transfers are done.
curl_multi_info_read() can be used to get information about completed
transfers. It then returns the CURLcode for each easy transfer, to allow you
to figure out success on each individual transfer.
SSL, Certificates and Other Tricks
[ seeding, passwords, keys, certificates, ENGINE, ca certs ]
Sharing Data Between Easy Handles
[ fill in ]
-----
Footnotes:
[1] = libcurl 7.10.3 and later have the ability to switch over to chunked
Tranfer-Encoding in cases were HTTP uploads are done with data of an
Transfer-Encoding in cases were HTTP uploads are done with data of an
unknown size.
[2] = This happens on Windows machines when libcurl is built and used as a

View File

@@ -15,7 +15,8 @@ man_MANS = curl_easy_cleanup.3 curl_easy_getinfo.3 curl_easy_init.3 \
curl_multi_perform.3 curl_multi_remove_handle.3 curl_share_cleanup.3 \
curl_share_init.3 curl_share_setopt.3 libcurl.3 libcurl-easy.3 \
libcurl-multi.3 libcurl-share.3 libcurl-errors.3 curl_easy_strerror.3 \
curl_multi_strerror.3 curl_share_strerror.3 curl_global_init_mem.3
curl_multi_strerror.3 curl_share_strerror.3 curl_global_init_mem.3 \
libcurl-tutorial.3
HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
curl_easy_init.html curl_easy_perform.html curl_easy_setopt.html \
@@ -30,7 +31,8 @@ HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
curl_share_cleanup.html curl_share_init.html curl_share_setopt.html \
libcurl.html libcurl-multi.html libcurl-easy.html libcurl-share.html \
libcurl-errors.html curl_easy_strerror.html curl_multi_strerror.html \
curl_share_strerror.html curl_global_init_mem.html
curl_share_strerror.html curl_global_init_mem.html \
libcurl-tutorial.html
PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \
curl_easy_init.pdf curl_easy_perform.pdf curl_easy_setopt.pdf \
@@ -45,7 +47,7 @@ PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \
curl_share_init.pdf curl_share_setopt.pdf libcurl.pdf \
libcurl-multi.pdf libcurl-easy.pdf libcurl-share.pdf \
libcurl-errors.pdf curl_easy_strerror.pdf curl_multi_strerror.pdf \
curl_share_strerror.pdf curl_global_init_mem.pdf
curl_share_strerror.pdf curl_global_init_mem.pdf libcurl-tutorial.pdf
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)

View File

@@ -119,6 +119,15 @@ filled with at most \fIsize\fP multiplied with \fInmemb\fP number of
bytes. Your function must return the actual number of bytes that you stored in
that memory area. Returning 0 will signal end-of-file to the library and cause
it to stop the current transfer.
If you stop the current transfer by returning 0 "pre-maturely" (i.e before the
server expected it, like when you've told you will upload N bytes and you
upload less than N bytes), you may experience that the server "hangs" waiting
for the rest of the data that won't come.
In libcurl 7.12.1 and later, the read callback may return
\fICURL_READFUNC_ABORT\fP to stop the current operation at once, with a
\fICURLE_ABORTED_BY_CALLBACK\fP error code from the transfer.
.IP CURLOPT_READDATA
Data pointer to pass to the file read function. Note that if you specify the
\fICURLOPT_READFUNCTION\fP, this is the pointer you'll get as input. If you
@@ -456,6 +465,9 @@ redirections have been followed, the next redirect will cause an error
.IP CURLOPT_PUT
A non-zero parameter tells the library to use HTTP PUT to transfer data. The
data should be set with \fICURLOPT_READDATA\fP and \fICURLOPT_INFILESIZE\fP.
This option is deprecated and starting with version 7.12.1 you should instead
use \fICURLOPT_UPLOAD\fP.
.IP CURLOPT_POST
A non-zero parameter tells the library to do a regular HTTP post. This is a
normal application/x-www-form-urlencoded kind, which is the most commonly used
@@ -522,6 +534,8 @@ The first line in a request (usually containing a GET or POST) is not a header
and cannot be replaced using this option. Only the lines following the
request-line are headers.
Pass a NULL to this to reset back to no custom headers.
\fBNOTE:\fP The most commonly replaced headers have "shortcuts" in the options
\fICURLOPT_COOKIE\fP, \fICURLOPT_USERAGENT\fP and \fICURLOPT_REFERER\fP.
.IP CURLOPT_HTTP200ALIASES
@@ -692,10 +706,11 @@ want. It should be in the format "X-Y", where X or Y may be left out. HTTP
transfers also support several intervals, separated with commas as in
\fI"X-Y,N-M"\fP. Using this kind of multiple intervals will cause the HTTP
server to send the response document in pieces (using standard MIME separation
techniques).
techniques). Pass a NULL to this option to disable the use of ranges.
.IP CURLOPT_RESUME_FROM
Pass a long as parameter. It contains the offset in number of bytes that you
want the transfer to start from.
want the transfer to start from. Set this option to 0 to make the transfer
start from the beginning (effectively disabling resume).
.IP CURLOPT_RESUME_FROM_LARGE
Pass an curl_off_t as parameter. It contains the offset in number of bytes
that you want the transfer to start from. (Added in 7.11.0)
@@ -734,7 +749,8 @@ as a curl_off_t. (Added in 7.11.0)
.IP CURLOPT_UPLOAD
A non-zero parameter tells the library to prepare for an upload. The
\fICURLOPT_READDATA\fP and \fICURLOPT_INFILESIZE_LARGE\fP are also interesting
for uploads.
for uploads. If the protocol is HTTP, uploading means using the PUT request
unless you tell libcurl otherwise.
.IP CURLOPT_MAXFILESIZE
Pass a long as parameter. This allows you to specify the maximum size (in
bytes) of a file to download. If the file requested is larger than this value,
@@ -960,5 +976,9 @@ standard for details.
CURLE_OK (zero) means that the option was set properly, non-zero means an
error occurred as \fI<curl/curl.h>\fP defines. See the \fIlibcurl-errors(3)\fP
man page for the full list with descriptions.
If you try to set an option that libcurl doesn't know about, perhaps because
the library is too old to support it or the option was removed in a recent
version, this function will return \fICURLE_FAILED_INIT\fP.
.SH "SEE ALSO"
.BR curl_easy_init "(3), " curl_easy_cleanup "(3), "

View File

@@ -205,5 +205,4 @@ defines.
.SH "SEE ALSO"
.BR curl_easy_setopt "(3), "
.BR curl_formparse "(3) [deprecated], "
.BR curl_formfree "(3)"

View File

@@ -16,7 +16,7 @@
<br><a href="libcurl-multi.html">libcurl-multi</a>
<br><a href="libcurl-share.html">libcurl-share</a>
<br><a href="libcurl-errors.html">libcurl-errors</a>
<br><a href="../libcurl-the-guide">libcurl-the-guide</a> (plain text)
<br><a href="libcurl-tutorial.html">libcurl-tutorial</a>
<H2>Library Functions (A-Z)</H2>
<a href="curl_easy_cleanup.html">curl_easy_cleanup</A>
@@ -34,6 +34,7 @@
<br><a href="curl_getenv.html">curl_getenv</A>
<br><a href="curl_global_cleanup.html">curl_global_cleanup</A>
<br><a href="curl_global_init.html">curl_global_init</A>
<br><a href="curl_global_init_mem.html">curl_global_init_mem</A>
<br><a href="curl_mprintf.html">curl_mprintf</A>
<br><a href="curl_multi_add_handle.html">curl_multi_add_handle</a>
<br><a href="curl_multi_cleanup.html">curl_multi_cleanup</a>

View File

@@ -8,9 +8,9 @@ libcurl-multi \- how to use the multi interface
.SH DESCRIPTION
This is an overview on how to use the libcurl multi interface in your C
programs. There are specific man pages for each function mentioned in
here. There's also the libcurl-the-guide document for a complete tutorial to
programming with libcurl and the \fIlibcurl(3)\fP man page for an overview of
the libcurl easy interface.
here. There's also the \fIlibcurl-tutorial(3)f\P man page for a complete
tutorial to programming with libcurl and the \fIlibcurl-easy(3)\fP man page
for an overview of the libcurl easy interface.
All functions in the multi interface are prefixed with curl_multi.
.SH "PLEASE NOTICE"

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +1,17 @@
.\" You can view this file with:
.\" nroff -man [file]
.\" $Id$
.\"
.TH libcurl 3 "19 March 2002" "libcurl 7.9.6" "libcurl overview"
.SH NAME
libcurl \- client-side URL transfers
.SH DESCRIPTION
This is an overview on how to use libcurl in your C programs. There are
This is an short overview on how to use libcurl in your C programs. There are
specific man pages for each function mentioned in here. There are also the
\fIlibcurl-easy(3)\fP man page, the \fIlibcurl-multi(3)\fP man page, the
\fIlibcurl-share(3)\fP man page and the \fIlibcurl-the-guide\fP document for
further reading on how to do programming with libcurl.
\fIlibcurl-share(3)\fP man page and the \fIlibcurl-tutorial(3)\fP man page for
in-depth understanding on how to program with libcurl.
There exist more than a dozen custom bindings that bring libcurl access to
your favourite language. Look elsewhere for documentation on those.
There are more than a twenty custom bindings available that bring libcurl
access to your favourite language. Look elsewhere for documentation on those.
All applications that use libcurl should call \fIcurl_global_init(3)\fP
exactly once before any libcurl function can be used. After all usage of

View File

@@ -52,11 +52,11 @@ extern "C" {
* platforms. We also provide a CURL_FORMAT_OFF_T define to use in *printf
* format strings when outputting a variable of type curl_off_t.
*/
#if defined(_MSC_VER)
#if defined(_MSC_VER) || defined(__LCC__)
/* MSVC */
typedef signed __int64 curl_off_t;
#define CURL_FORMAT_OFF_T "%I64d"
#else /* MSC_VER */
#else /* _MSC_VER || __LCC__ */
#if (defined(__GNUC__) && defined(WIN32)) || defined(__WATCOMC__)
/* gcc on windows or Watcom */
typedef long long curl_off_t;
@@ -88,7 +88,7 @@ extern "C" {
#define CURL_FORMAT_OFF_T "%ld"
#endif
#endif /* GCC or Watcom on Windows */
#endif /* MSC_VER */
#endif /* _MSC_VER || __LCC__ */
#ifdef UNDEF_FILE_OFFSET_BITS
/* this was defined above for our checks, undefine it again */
@@ -143,6 +143,9 @@ typedef size_t (*curl_write_callback)(char *buffer,
size_t nitems,
void *outstream);
/* This is a brand new return code for the read callback that will signal
the caller to immediately abort the current transfer. */
#define CURL_READFUNC_ABORT 0x10000000
typedef size_t (*curl_read_callback)(char *buffer,
size_t size,
size_t nitems,
@@ -173,6 +176,8 @@ typedef enum {
CURLINFO_HEADER_OUT, /* 2 */
CURLINFO_DATA_IN, /* 3 */
CURLINFO_DATA_OUT, /* 4 */
CURLINFO_SSL_DATA_IN, /* 5 */
CURLINFO_SSL_DATA_OUT, /* 6 */
CURLINFO_END
} curl_infotype;
@@ -327,7 +332,7 @@ typedef enum {
* platforms.
*/
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
defined(__HP_aCC) || defined(__BORLANDC__)
defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__)
/* This compiler is believed to have an ISO compatible preprocessor */
#define CURL_ISOCPP
#else
@@ -518,7 +523,7 @@ typedef enum {
CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */
CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */
CINIT(PUT, LONG, 54), /* PUT the input file */
CINIT(PUT, LONG, 54), /* HTTP PUT */
/* 55 = OBSOLETE */
@@ -564,9 +569,9 @@ typedef enum {
/* Maximum number of http redirects to follow */
CINIT(MAXREDIRS, LONG, 68),
/* Pass a pointer to a time_t to get a possible date of the requested
document! Pass a NULL to shut it off. */
CINIT(FILETIME, OBJECTPOINT, 69),
/* Pass a long set to 1 to get the date of the requested document (if
possible)! Pass a zero to shut it off. */
CINIT(FILETIME, LONG, 69),
/* This points to a linked list of telnet options */
CINIT(TELNETOPTIONS, OBJECTPOINT, 70),
@@ -780,6 +785,34 @@ typedef enum {
/* Enable/disable the TCP Nagle algorithm */
CINIT(TCP_NODELAY, LONG, 121),
/* When doing 3rd party transfer, set the source host name with this */
CINIT(SOURCE_HOST, OBJECTPOINT, 122),
/* When doing 3rd party transfer, set the source user and password with
this */
CINIT(SOURCE_USERPWD, OBJECTPOINT, 123),
/* When doing 3rd party transfer, set the source file path with this */
CINIT(SOURCE_PATH, OBJECTPOINT, 124),
/* When doing 3rd party transfer, set the source server's port number
with this */
CINIT(SOURCE_PORT, LONG, 125),
/* When doing 3rd party transfer, decide which server that should get the
PASV command (and the other gets the PORT).
0 (default) - The target host issues PASV.
1 - The source host issues PASV */
CINIT(PASV_HOST, LONG, 126),
/* When doing 3rd party transfer, set the source pre-quote linked list
of commands with this */
CINIT(SOURCE_PREQUOTE, OBJECTPOINT, 127),
/* When doing 3rd party transfer, set the source post-quote linked list
of commands with this */
CINIT(SOURCE_POSTQUOTE, OBJECTPOINT, 128),
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
@@ -937,6 +970,7 @@ typedef enum {
CURL_FORMADD_UNKNOWN_OPTION,
CURL_FORMADD_INCOMPLETE,
CURL_FORMADD_ILLEGAL_ARRAY,
CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */
CURL_FORMADD_LAST /* last */
} CURLFORMcode;

View File

@@ -28,7 +28,7 @@
/* This is the version number of the libcurl package from which this header
file origins: */
#define LIBCURL_VERSION "7.12.0-CVS"
#define LIBCURL_VERSION "7.12.1-CVS"
/* This is the numeric version of the libcurl version number, meant for easier
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
@@ -44,12 +44,12 @@
always a greater number in a more recent release. It makes comparisons with
greater than and less than work.
*/
#define LIBCURL_VERSION_NUM 0x070c00
#define LIBCURL_VERSION_NUM 0x070c01
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 12
#define LIBCURL_VERSION_PATCH 0
#define LIBCURL_VERSION_PATCH 1
#endif /* __CURL_CURLVER_H */

View File

@@ -106,7 +106,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
libcurl_la_SOURCES = $(CSOURCES) $(HHEADERS)
WIN32SOURCES = $(CSOURCES)
WIN32SOURCES = $(CSOURCES) libcurl.def
WIN32HEADERS = $(HHEADERS) config-win32.h
BUILT_SOURCES = $(srcdir)/getdate.c $(top_builddir)/lib/ca-bundle.h

View File

@@ -47,7 +47,8 @@ libcurl_a_SOURCES = arpa_telnet.h file.c netrc.h timeval.c base64.c \
strtok.c connect.c hash.c llist.c multi.c share.c share.h \
content_encoding.h content_encoding.c http_digest.h http_digest.c \
http_negotiate.c http_negotiate.h http_ntlm.c http_ntlm.h md5.h \
md5.c strtoofft.c inet_pton.c
md5.c strtoofft.c inet_pton.c strerror.c hostares.c hostasyn.c \
hostip4.c hostip6.c hostsyn.c hostthre.c inet_ntop.c
libcurl_a_OBJECTS = file.o timeval.o base64.o hostip.o progress.o \
formdata.o cookie.o http.o sendf.o ftp.o url.o dict.o if2ip.o \
@@ -56,7 +57,8 @@ libcurl_a_OBJECTS = file.o timeval.o base64.o hostip.o progress.o \
strequal.o easy.o security.o krb4.o memdebug.o http_chunks.o \
strtok.o connect.o hash.o llist.o multi.o share.o \
content_encoding.o http_digest.o http_negotiate.o http_ntlm.o md5.o \
strtoofft.o inet_pton.o
strtoofft.o inet_pton.o strerror.o hostares.o hostasyn.o hostip4.o \
hostip6.o hostsyn.o hostthre.o inet_ntop.o
LIBRARIES = $(libcurl_a_LIBRARIES)
SOURCES = $(libcurl_a_SOURCES)

View File

@@ -8,11 +8,13 @@
#################################################################
# Edit the path below to point to the base of your Novell NDK.
BASE = c:/novell
INSTDIR = s:/libcurl
ifndef NDKBASE
NDKBASE = c:/novell
endif
INSTDIR = ..\curl-$(LIBCURL_VERSION_STR)-bin-nw
# Edit the path below to point to the base of your Zlib sources.
ZLIB_PATH = ../../../cw/zlib-src-1.1.4
#ZLIB_PATH = ../../zlib-1.2.1
# Edit the vars below to change NLM target settings.
TARGET = libcurl
@@ -22,7 +24,6 @@ DESCR = cURL libcurl $(LIBCURL_VERSION_STR) - http://curl.haxx.se
MTSAFE = YES
STACK = 64000
SCREEN = none
#MODULES = libz.nlm
EXPORTS = @libcurl.imp
# Edit the var below to point to your lib architecture.
@@ -33,6 +34,7 @@ endif
# must be equal to DEBUG or NDEBUG
DB = NDEBUG
# DB = DEBUG
# DB = CURLDEBUG
# Optimization: -O<n> or debugging: -g
ifeq ($(DB),NDEBUG)
OPT = -O2
@@ -42,7 +44,7 @@ else
OBJDIR = debug
endif
# Include the version info retrieved from jk_version.h
# Include the version info retrieved from curlver.h
-include $(OBJDIR)/version.inc
# The following line defines your compiler.
@@ -51,36 +53,39 @@ ifdef METROWERKS
else
CC = gcc
endif
CP = cp -afv
# RM = rm -f
# CP = cp -fv
# if you want to mark the target as MTSAFE you will need a tool for
# generating the xdc data for the linker; here's a minimal tool:
# http://www.gknw.de/development/prgtools/mkxdc.zip
# http://www.gknw.com/development/prgtools/mkxdc.zip
MPKXDC = mkxdc
# Global flags for all compilers
CFLAGS = $(OPT) -D$(DB) -DNETWARE -nostdinc
#CFLAGS += -DHAVE_LIBZ
ifeq ($(CC),mwccnlm)
LD = mwldnlm
LDFLAGS = -nostdlib $(PRELUDE) $(OBJDIR)/*.o -o $(OBJDIR)/$(TARGET).nlm -commandfile
CFLAGS += -gccinc -inline off -opt nointrinsics
AR = mwldnlm
ARFLAGS = -type library -w nocmdline $(OBJDIR)/*.o -o
CFLAGS += -msgstyle gcc -gccinc -inline off -opt nointrinsics -proc 586
CFLAGS += -relax_pointers
#CFLAGS += -w on
ifeq ($(LIBARCH),LIBC)
PRELUDE = $(SDK_LIBC)/imports/libcpre.o
CFLAGS += -align 4 -inst mmx -proc 686
CFLAGS += -align 4
CFLAGS += -D_POSIX_SOURCE
# CFLAGS += -D__ANSIC__
else
PRELUDE = "$(METROWERKS)/Novell Support/libraries/runtime/prelude.obj"
# CFLAGS += -include "$(METROWERKS)/Novell Support/headers/nlm_prefix.h"
CFLAGS += -align 1 -proc 586
CFLAGS += -align 1
endif
else
LD = nlmconv
LDFLAGS = -T
AR = ar
ARFLAGS = -cq
CFLAGS += -fno-builtin -fpack-struct -fpcc-struct-return
CFLAGS += -Wall # -pedantic
ifeq ($(LIBARCH),LIBC)
@@ -89,40 +94,51 @@ ifeq ($(LIBARCH),LIBC)
# CFLAGS += -D__ANSIC__
else
PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o
CFLAGS += -include $(BASE)/nlmconv/genlm.h
CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h
endif
endif
LDLIBS =
NDK_ROOT = $(BASE)/ndk
NDK_ROOT = $(NDKBASE)/ndk
SDK_CLIB = $(NDK_ROOT)/nwsdk
SDK_LIBC = $(NDK_ROOT)/libc
SDK_LDAP = $(NDK_ROOT)/cldapsdk/netware
CURL_INC = ../include
INCLUDES = -I$(CURL_INC)
INCLUDES += -I$(ZLIB_PATH)
INCLUDES = -I. -I../include
ifdef ZLIB_PATH
INCLUDES += -I$(ZLIB_PATH)
CFLAGS += -DHAVE_ZLIB_H -DHAVE_LIBZ
IMPORTS = @$(ZLIB_PATH)/nw/zlib.imp
MODULES = libz.nlm
endif
ifeq ($(LIBARCH),LIBC)
INCLUDES += -I$(SDK_LIBC)/include -I$(SDK_LIBC)/include/nks
INCLUDES += -I$(SDK_LIBC)/include/winsock
INCLUDES += -I$(SDK_LDAP)/libc/inc
# INCLUDES += -I$(SDK_LDAP)/libc/inc
else
INCLUDES += -I$(SDK_CLIB)/include/nlm -I$(SDK_CLIB)/include
# INCLUDES += -I$(SDK_CLIB)/include/nlm/obsolete
INCLUDES += -I$(SDK_LDAP)/clib/inc
# INCLUDES += -I$(SDK_LDAP)/clib/inc
CFLAGS += -DNETDB_USE_INTERNET
endif
CFLAGS += $(INCLUDES)
ifeq ($(MTSAFE),YES)
XDCOPT = -n
endif
ifeq ($(MTSAFE),NO)
XDCOPT = -u
endif
ifdef XDCOPT
XDCDATA = $(OBJDIR)/$(TARGET).xdc
endif
ifeq ($(OSTYPE),linux)
DL = '
-include $(BASE)/nlmconv/ncpfs.inc
#-include $(NDKBASE)/nlmconv/ncpfs.inc
endif
OBJS = \
@@ -169,35 +185,57 @@ OBJS = \
$(OBJDIR)/http_ntlm.o \
$(OBJDIR)/md5.o \
$(OBJDIR)/strtoofft.o \
$(OBJDIR)/nwlib.o
$(OBJDIR)/strerror.o \
$(OBJDIR)/hostares.o \
$(OBJDIR)/hostasyn.o \
$(OBJDIR)/hostip4.o \
$(OBJDIR)/hostip6.o \
$(OBJDIR)/hostsyn.o \
$(OBJDIR)/hostthre.o \
$(OBJDIR)/inet_ntop.o \
OBJL = $(OBJS) $(OBJDIR)/nwlib.o
all: $(OBJDIR) $(OBJDIR)/version.inc $(OBJDIR)/$(TARGET).nlm
nlm: $(OBJDIR) $(OBJDIR)/version.inc $(OBJDIR)/$(TARGET).nlm
lib: $(OBJDIR) $(OBJDIR)/$(TARGET).lib
all: lib nlm
$(OBJDIR)/%.o: %.c
@echo Compiling $<
@$(CC) $(CFLAGS) -c $< -o $@
# @echo Compiling $<
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR)/version.inc: $(CURL_INC)/curl/curl.h $(OBJDIR)
$(OBJDIR)/version.inc: ../include/curl/curlver.h $(OBJDIR)
@echo Creating $@
@awk -f ../packages/netware/get_ver.awk $< > $@
@awk -f ../packages/NetWare/get_ver.awk $< > $@
dist: all
-$(RM) $(OBJDIR)/*.o $(OBJDIR)/$(TARGET).map $(OBJDIR)/$(TARGET).ncv
-$(RM) $(OBJDIR)/$(TARGET).def $(OBJDIR)/version.inc $(XDCDATA)
# -$(CP) ../changes.txt $(OBJDIR)/
install: all
@[ -d $(INSTDIR) ] || mkdir $(INSTDIR)
install: $(INSTDIR) all
@$(CP) $(TARGET).nlm $(INSTDIR)
@$(CP) ../CHANGES $(INSTDIR)
@$(CP) ../COPYING $(INSTDIR)
@$(CP) ../README $(INSTDIR)
@$(CP) ../RELEASE-NOTES $(INSTDIR)
clean:
-$(RM) -r $(OBJDIR)
$(INSTDIR):
@mkdir $(INSTDIR)
$(OBJDIR):
@mkdir $(OBJDIR)
$(OBJDIR)/$(TARGET).nlm: $(OBJS) $(OBJDIR)/$(TARGET).def $(XDCDATA)
$(OBJDIR)/$(TARGET).lib: $(OBJS)
@echo Creating $@
@-$(RM) $@
@$(AR) $(ARFLAGS) $@ $^
$(OBJDIR)/$(TARGET).nlm: $(OBJL) $(OBJDIR)/$(TARGET).def $(XDCDATA)
@echo Linking $@
@-$(RM) $@
@$(LD) $(LDFLAGS) $(OBJDIR)/$(TARGET).def
@@ -239,25 +277,21 @@ ifeq ($(LIBARCH),CLIB)
@echo $(DL)import @$(SDK_CLIB)/imports/threads.imp$(DL) >> $@
@echo $(DL)import @$(SDK_CLIB)/imports/nlmlib.imp$(DL) >> $@
@echo $(DL)import @$(SDK_CLIB)/imports/socklib.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapsdk.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapssl.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapx.imp$(DL) >> $@
# @echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapsdk.imp$(DL) >> $@
# @echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapssl.imp$(DL) >> $@
# @echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapx.imp$(DL) >> $@
@echo $(DL)module clib$(DL) >> $@
else
ifeq ($(LD),nlmconv)
@echo $(DL)flag_on 64$(DL) >> $@
else
@echo $(DL)autounload$(DL) >> $@
endif
@echo $(DL)pseudopreemption$(DL) >> $@
@echo $(DL)start _LibCPrelude$(DL) >> $@
@echo $(DL)exit _LibCPostlude$(DL) >> $@
@echo $(DL)check _LibCCheckUnload$(DL) >> $@
@echo $(DL)import @$(SDK_LIBC)/imports/libc.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LIBC)/imports/netware.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapsdk.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapssl.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapx.imp$(DL) >> $@
# @echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapsdk.imp$(DL) >> $@
# @echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapssl.imp$(DL) >> $@
# @echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapx.imp$(DL) >> $@
@echo $(DL)module libc$(DL) >> $@
endif
ifdef MODULES
@@ -275,3 +309,18 @@ ifeq ($(LD),nlmconv)
@echo $(DL)output $(TARGET).nlm$(DL) >> $@
endif
ca-bundle.h: Makefile.netware
@echo Creating $@
@echo $(DL)/* Do not edit this file - it is created by make!$(DL) > $@
@echo $(DL)** All your changes will be lost!!$(DL) >> $@
@echo $(DL)*/$(DL) >> $@
@echo $(DL)#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")$(DL) >> $@
getdate.c: getdate.c.cvs
@echo Creating $@
@-$(RM) getdate.y
@$(CP) $< $@
url.c: ca-bundle.h

View File

@@ -182,10 +182,6 @@
/* Define to 1 if you have the `ssl' library (-lssl). */
#undef HAVE_LIBSSL
/* If zlib is available */
#undef HAVE_LIBZ
//#define HAVE_LIBZ 1
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
@@ -396,14 +392,17 @@
/* Define to 1 if you have the <x509.h> header file. */
#undef HAVE_X509_H
/* if you have the zlib.h header file */
#define HAVE_ZLIB_H 1
/* if you have the zlib.h header file - set from Makefile */
/* #undef HAVE_ZLIB_H */
/* If zlib is available - set from Makefile */
/* #undef HAVE_LIBZ */
/* need REENTRANT defined */
#undef NEED_REENTRANT
/* cpu-machine-OS */
#define OS "i386-pc-NetWare"
#define OS "i586-pc-NetWare"
/* Name of package */
#undef PACKAGE

View File

@@ -1,6 +1,9 @@
/* config.h. Generated automatically by configure. */
/* config.h.in. Generated automatically from configure.in by autoheader. */
#ifndef __CONFIG_WIN32_H
#define __CONFIG_WIN32_H
/* Define if on AIX 3.
System headers sometimes define this.
We just want to avoid a redefinition error message. */
@@ -223,9 +226,12 @@
/*************************************************
* This section is for compiler specific defines.*
*************************************************/
#if defined(MINGW32) || defined(__WATCOMC__) /* Borland and MS don't have this */
/* Borland and MS don't have this */
#if defined(MINGW32) || defined(__WATCOMC__) || defined(__LCC__)
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
#endif
#endif

View File

@@ -490,8 +490,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
/* check for connect without timeout as we want to return immediately */
rc = waitconnect(sockfd, 0);
if(0 == rc) {
if (verifyconnect(sockfd,NULL)) {
if(WAITCONN_CONNECTED == rc) {
if (verifyconnect(sockfd, NULL)) {
/* we are connected, awesome! */
*connected = TRUE;
return CURLE_OK;
@@ -500,25 +500,22 @@ CURLcode Curl_is_connected(struct connectdata *conn,
failf(data, "Connection failed");
return CURLE_COULDNT_CONNECT;
}
else if(1 != rc) {
else if(WAITCONN_TIMEOUT != rc) {
int error = Curl_ourerrno();
failf(data, "Failed connect to %s:%d; %s",
conn->host.name, conn->port, Curl_strerror(conn,error));
return CURLE_COULDNT_CONNECT;
}
/*
* If the connection phase is "done" here, we should attempt to connect
* to the "next address" in the Curl_hostaddr structure that we resolved
* before. But we don't have that struct around anymore and we can't just
* keep a pointer since the cache might in fact have gotten pruned by the
* time we want to read this... Alas, we don't do this yet.
* If the connection failed here, we should attempt to connect to the "next
* address" for the given host.
*/
return CURLE_OK;
}
static void Curl_setNoDelay(struct connectdata *conn,
curl_socket_t sockfd)
static void tcpnodelay(struct connectdata *conn,
curl_socket_t sockfd)
{
#ifdef TCP_NODELAY
struct SessionHandle *data= conn->data;
@@ -549,22 +546,22 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
bool *connected) /* really connected? */
{
struct SessionHandle *data = conn->data;
curl_socket_t sockfd = CURL_SOCKET_BAD;
int rc, error;
curl_socket_t sockfd= CURL_SOCKET_BAD;
int aliasindex=0;
char *hostname;
int aliasindex;
int num_addr;
bool conected;
char addr_buf[256];
Curl_ipconnect *curr_addr;
struct timeval after;
struct timeval before = Curl_tvnow();
#ifdef ENABLE_IPV6
struct addrinfo *ai;
#endif
/*************************************************************
* Figure out what maximum time we have left
*************************************************************/
long timeout_ms=300000; /* milliseconds, default to five minutes */
long timeout_ms=300000; /* milliseconds, default to five minutes total */
long timeout_per_addr;
*connected = FALSE; /* default to not connected */
@@ -600,31 +597,35 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
}
}
hostname = data->change.proxy?conn->proxy.name:conn->host.name;
infof(data, "About to connect() to %s port %d\n",
hostname, port);
/* Max time for each address */
num_addr = Curl_num_addresses(remotehost->addr);
timeout_per_addr = timeout_ms / num_addr;
/* Below is the loop that attempts to connect to all IP-addresses we
* know for the given host. One by one until one IP succeedes.
*/
#ifdef ENABLE_IPV6
/*
* Connecting with a getaddrinfo chain
*/
for (ai = remotehost->addr; ai; ai = ai->ai_next, aliasindex++) {
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sockfd == CURL_SOCKET_BAD)
(void)port; /* the port number is already included in the getaddrinfo
struct */
for (curr_addr = remotehost->addr, aliasindex=0; curr_addr;
curr_addr = curr_addr->ai_next, aliasindex++) {
sockfd = socket(curr_addr->ai_family, curr_addr->ai_socktype,
curr_addr->ai_protocol);
if (sockfd == CURL_SOCKET_BAD) {
timeout_per_addr += timeout_per_addr / (num_addr - aliasindex);
continue;
}
else if(data->set.tcp_nodelay)
Curl_setNoDelay(conn, sockfd);
#else
/*
* Connecting with old style IPv4-only support
*/
/* This is the loop that attempts to connect to all IP-addresses we
know for the given host. One by one. */
for(rc=-1, aliasindex=0;
rc && (struct in_addr *)remotehost->addr->h_addr_list[aliasindex];
aliasindex++) {
curr_addr = (Curl_ipconnect*)remotehost->addr->h_addr_list[0];
for(aliasindex=0; curr_addr;
curr_addr=(Curl_ipconnect*)remotehost->addr->h_addr_list[++aliasindex]) {
struct sockaddr_in serv_addr;
/* create an IPv4 TCP socket */
@@ -634,18 +635,21 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
return CURLE_COULDNT_CONNECT; /* big time error */
}
else if(data->set.tcp_nodelay)
Curl_setNoDelay(conn, sockfd);
/* nasty address work before connect can be made */
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
memcpy((char *)&(serv_addr.sin_addr),
(struct in_addr *)remotehost->addr->h_addr_list[aliasindex],
memcpy((char *)&(serv_addr.sin_addr), curr_addr,
sizeof(struct in_addr));
serv_addr.sin_family = remotehost->addr->h_addrtype;
serv_addr.sin_port = htons((unsigned short)port);
#endif
Curl_printable_address(curr_addr, addr_buf, sizeof(addr_buf));
infof(data, " Trying %s... ", addr_buf);
if(data->set.tcp_nodelay)
tcpnodelay(conn, sockfd);
if(conn->data->set.device) {
/* user selected to bind the outgoing socket to a specified "device"
before doing connect */
@@ -661,7 +665,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
a defined macro on some platforms and some compilers don't like to mix
#ifdefs with macro usage! (AmigaOS is one such platform) */
#ifdef ENABLE_IPV6
rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen);
rc = connect(sockfd, curr_addr->ai_addr, curr_addr->ai_addrlen);
#else
rc = connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
#endif
@@ -682,38 +686,39 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
/* asynchronous connect, wait for connect or timeout */
if(data->state.used_interface == Curl_if_multi)
/* don't hang when doing multi */
timeout_ms = 0;
timeout_per_addr = timeout_ms = 0;
rc = waitconnect(sockfd, timeout_ms);
rc = waitconnect(sockfd, timeout_per_addr);
break;
default:
/* unknown error, fallthrough and try another address! */
failf(data, "Failed to connect to %s IP number %d: %s",
hostname, aliasindex+1, Curl_strerror(conn,error));
failf(data, "Failed to connect to %s (IP number %d): %s",
addr_buf, aliasindex+1, Curl_strerror(conn,error));
break;
}
}
/* The '1 == rc' comes from the waitconnect(), and not from connect().
We can be sure of this since connect() cannot return 1. */
if((1 == rc) && (data->state.used_interface == Curl_if_multi)) {
/* The 'WAITCONN_TIMEOUT == rc' comes from the waitconnect(), and not from
connect(). We can be sure of this since connect() cannot return 1. */
if((WAITCONN_TIMEOUT == rc) &&
(data->state.used_interface == Curl_if_multi)) {
/* Timeout when running the multi interface, we return here with a
CURLE_OK return code. */
rc = 0;
break;
}
if(0 == rc) {
if (verifyconnect(sockfd,NULL)) {
/* we are connected, awesome! */
*connected = TRUE; /* this is a true connect */
break;
}
/* nope, not connected for real */
rc = -1;
conected = verifyconnect(sockfd, &error);
if(!rc && conected) {
/* we are connected, awesome! */
*connected = TRUE; /* this is a true connect */
break;
}
if(WAITCONN_TIMEOUT == rc)
infof(data, "Timeout\n");
else
verifyconnect(sockfd,&error); /* get non-blocking error */
infof(data, "%s\n", Curl_strerror(conn, error));
/* connect failed or timed out */
sclose(sockfd);
@@ -727,24 +732,19 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
return CURLE_OPERATION_TIMEOUTED;
}
before = after;
}
} /* end of connect-to-each-address loop */
if (sockfd == CURL_SOCKET_BAD) {
/* no good connect was made */
*sockconn = -1;
failf(data, "Connect failed; %s", Curl_strerror(conn,error));
*sockconn = CURL_SOCKET_BAD;
return CURLE_COULDNT_CONNECT;
}
/* leave the socket in non-blocking mode */
/* store the address we use */
if(addr) {
#ifdef ENABLE_IPV6
*addr = ai;
#else
*addr = (struct in_addr *)remotehost->addr->h_addr_list[aliasindex];
#endif
}
if(addr)
*addr = curr_addr;
/* allow NULL-pointers to get passed in */
if(sockconn)

View File

@@ -149,7 +149,7 @@ Curl_cookie_add(struct SessionHandle *data,
unless set */
{
struct Cookie *clist;
char what[MAX_COOKIE_LINE];
char *what;
char name[MAX_NAME];
char *ptr;
char *semiptr;
@@ -167,6 +167,13 @@ Curl_cookie_add(struct SessionHandle *data,
if(httpheader) {
/* This line was read off a HTTP-header */
char *sep;
what = malloc(MAX_COOKIE_LINE);
if(!what) {
free(co);
return NULL;
}
semiptr=strchr(lineptr, ';'); /* first, find a semicolon */
while(*lineptr && isspace((int)*lineptr))
@@ -387,6 +394,8 @@ Curl_cookie_add(struct SessionHandle *data,
}
}
free(what);
if(badcookie || !co->name) {
/* we didn't get a cookie name or a bad one,
this is an illegal line, bail out */

View File

@@ -60,13 +60,20 @@ struct CookieInfo {
bool newsession; /* new session, discard session cookies on load */
};
/* This is the maximum line length we accept for a cookie line */
#define MAX_COOKIE_LINE 2048
#define MAX_COOKIE_LINE_TXT "2047"
/* This is the maximum line length we accept for a cookie line. RFC 2109
section 6.3 says:
"at least 4096 bytes per cookie (as measured by the size of the characters
that comprise the cookie non-terminal in the syntax description of the
Set-Cookie header)"
*/
#define MAX_COOKIE_LINE 5000
#define MAX_COOKIE_LINE_TXT "4999"
/* This is the maximum length of a cookie name we deal with: */
#define MAX_NAME 256
#define MAX_NAME_TXT "255"
#define MAX_NAME 1024
#define MAX_NAME_TXT "1023"
struct SessionHandle;
/*

View File

@@ -333,7 +333,8 @@ CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
/* This is a function pointer type */
param_func = va_arg(arg, func_T );
ret = Curl_setopt(data, tag, param_func);
} else {
}
else {
/* This is a curl_off_t type */
param_offset = va_arg(arg, curl_off_t);
ret = Curl_setopt(data, tag, param_offset);
@@ -458,6 +459,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
outcurl->progress.flags = data->progress.flags;
outcurl->progress.callback = data->progress.callback;
#ifndef CURL_DISABLE_HTTP
if(data->cookies) {
/* If cookies are enabled in the parent handle, we enable them
in the clone as well! */
@@ -469,6 +471,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
break;
}
}
#endif /* CURL_DISABLE_HTTP */
/* duplicate all values in 'change' */
if(data->change.url) {

View File

@@ -175,7 +175,7 @@ CURLcode Curl_file_done(struct connectdata *conn,
{
struct FILEPROTO *file = conn->proto.file;
(void)status; /* not used */
Curl_safefree(file->path);
Curl_safefree(file->freepath);
return CURLE_OK;
}
@@ -218,7 +218,12 @@ static CURLcode file_upload(struct connectdata *conn)
Curl_pgrsSetUploadSize(data, data->set.infilesize);
while (res == CURLE_OK) {
nread = Curl_fillreadbuffer(conn, BUFSIZE);
int readcount;
res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount);
if(res)
return res;
nread = (size_t)readcount;
if (nread <= 0)
break;

View File

@@ -100,6 +100,10 @@ Content-Disposition: form-data; name="FILECONTENT"
*/
#include "setup.h"
#include <curl/curl.h>
/* Length of the random boundary string. */
#define BOUNDARY_LENGTH 40
#ifndef CURL_DISABLE_HTTP
@@ -108,7 +112,7 @@ Content-Disposition: form-data; name="FILECONTENT"
#include <string.h>
#include <stdarg.h>
#include <time.h>
#include <curl/curl.h>
#include <sys/stat.h>
#include "formdata.h"
#include "strequal.h"
#include "memory.h"
@@ -119,9 +123,6 @@ Content-Disposition: form-data; name="FILECONTENT"
/* The last #include file should be: */
#include "memdebug.h"
/* Length of the random boundary string. */
#define BOUNDARY_LENGTH 40
/* What kind of Content-Type to use on un-specified files with unrecognized
extensions. */
#define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream"
@@ -785,9 +786,10 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost,
* size is incremented by the chunk length, unless it is NULL
*/
static CURLcode AddFormData(struct FormData **formp,
enum formtype type,
const void *line,
size_t length,
size_t *size)
curl_off_t *size)
{
struct FormData *newform = (struct FormData *)
malloc(sizeof(struct FormData));
@@ -807,6 +809,7 @@ static CURLcode AddFormData(struct FormData **formp,
memcpy(newform->line, line, length);
newform->length = length;
newform->line[length]=0; /* zero terminate for easier debugging */
newform->type = type;
if(*formp) {
(*formp)->next = newform;
@@ -815,8 +818,20 @@ static CURLcode AddFormData(struct FormData **formp,
else
*formp = newform;
if (size)
*size += length;
if (size) {
if(type == FORM_DATA)
*size += length;
else {
/* Since this is a file to be uploaded here, add the size of the actual
file */
if(!strequal("-", newform->line)) {
struct stat file;
if(!stat(newform->line, &file)) {
*size += file.st_size;
}
}
}
}
return CURLE_OK;
}
@@ -825,7 +840,7 @@ static CURLcode AddFormData(struct FormData **formp,
*/
static CURLcode AddFormDataf(struct FormData **formp,
size_t *size,
curl_off_t *size,
const char *fmt, ...)
{
char s[4096];
@@ -834,39 +849,7 @@ static CURLcode AddFormDataf(struct FormData **formp,
vsprintf(s, fmt, ap);
va_end(ap);
return AddFormData(formp, s, 0, size);
}
/*
* Curl_FormBoundary() creates a suitable boundary string and returns an
* allocated one.
*/
char *Curl_FormBoundary(void)
{
char *retstring;
static int randomizer=0; /* this is just so that two boundaries within
the same form won't be identical */
size_t i;
static char table16[]="abcdef0123456789";
retstring = (char *)malloc(BOUNDARY_LENGTH+1);
if(!retstring)
return NULL; /* failed */
srand(time(NULL)+randomizer++); /* seed */
strcpy(retstring, "----------------------------");
for(i=strlen(retstring); i<BOUNDARY_LENGTH; i++)
retstring[i] = table16[rand()%16];
/* 28 dashes and 12 hexadecimal digits makes 12^16 (184884258895036416)
combinations */
retstring[BOUNDARY_LENGTH]=0; /* zero terminate */
return retstring;
return AddFormData(formp, FORM_DATA, s, 0, size);
}
/*
@@ -936,7 +919,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
struct curl_httppost *file;
CURLcode result = CURLE_OK;
size_t size =0;
curl_off_t size=0; /* support potentially ENORMOUS formposts */
char *boundary;
char *fileboundary=NULL;
struct curl_slist* curList;
@@ -977,16 +960,17 @@ CURLcode Curl_getFormData(struct FormData **finalform,
if (result)
break;
result = AddFormData(&form,
"Content-Disposition: form-data; name=\"", 0, &size);
result = AddFormDataf(&form, &size,
"Content-Disposition: form-data; name=\"");
if (result)
break;
result = AddFormData(&form, post->name, post->namelength, &size);
result = AddFormData(&form, FORM_DATA, post->name, post->namelength,
&size);
if (result)
break;
result = AddFormData(&form, "\"", 0, &size);
result = AddFormDataf(&form, &size, "\"");
if (result)
break;
@@ -1071,7 +1055,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
}
#endif
result = AddFormData(&form, "\r\n\r\n", 0, &size);
result = AddFormDataf(&form, &size, "\r\n\r\n");
if (result)
break;
@@ -1079,11 +1063,10 @@ CURLcode Curl_getFormData(struct FormData **finalform,
(post->flags & HTTPPOST_READFILE)) {
/* we should include the contents from the specified file */
FILE *fileread;
char buffer[1024];
size_t nread;
fileread = strequal("-", file->contents)?
stdin:fopen(file->contents, "rb"); /* binary read for win32 */
/*
* VMS: This only allows for stream files on VMS. Stream files are
* OK, as are FIXED & VAR files WITHOUT implied CC For implied CC,
@@ -1091,13 +1074,27 @@ CURLcode Curl_getFormData(struct FormData **finalform,
*/
if(fileread) {
while((nread = fread(buffer, 1, 1024, fileread))) {
result = AddFormData(&form, buffer, nread, &size);
if (result)
break;
}
if(fileread != stdin)
if(fileread != stdin) {
/* close the file again */
fclose(fileread);
/* add the file name only - for later reading from this */
result = AddFormData(&form, FORM_FILE, file->contents, 0, &size);
}
else {
/* When uploading from stdin, we can't know the size of the file,
* thus must read the full file as before. We *could* use chunked
* transfer-encoding, but that only works for HTTP 1.1 and we
* can't be sure we work with such a server.
*/
size_t nread;
char buffer[512];
while((nread = fread(buffer, 1, sizeof(buffer), fileread))) {
result = AddFormData(&form, FORM_DATA, buffer, nread, &size);
if (result)
break;
}
}
if (result) {
Curl_formclean(firstform);
free(boundary);
@@ -1115,16 +1112,16 @@ CURLcode Curl_getFormData(struct FormData **finalform,
}
else if (post->flags & HTTPPOST_BUFFER) {
/* include contents of buffer */
result = AddFormData(&form, post->buffer, post->bufferlength,
&size);
result = AddFormData(&form, FORM_DATA, post->buffer,
post->bufferlength, &size);
if (result)
break;
}
else {
/* include the contents we got */
result = AddFormData(&form, post->contents, post->contentslength,
&size);
result = AddFormData(&form, FORM_DATA, post->contents,
post->contentslength, &size);
if (result)
break;
}
@@ -1183,10 +1180,32 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata )
form->data = formdata;
form->sent = 0;
form->fp = NULL;
return 0;
}
static size_t readfromfile(struct Form *form, char *buffer, size_t size)
{
size_t nread;
if(!form->fp) {
/* this file hasn't yet been opened */
form->fp = fopen(form->data->line, "rb"); /* b is for binary */
if(!form->fp)
return -1; /* failure */
}
nread = fread(buffer, 1, size, form->fp);
if(nread != size) {
/* this is the last chunk form the file, move on */
fclose(form->fp);
form->fp = NULL;
form->data = form->data->next;
}
return nread;
}
/*
* Curl_FormReader() is the fread() emulation function that will be used to
* deliver the formdata to the transfer loop and then sent away to the peer.
@@ -1207,6 +1226,9 @@ size_t Curl_FormReader(char *buffer,
if(!form->data)
return 0; /* nothing, error, empty */
if(form->data->type == FORM_FILE)
return readfromfile(form, buffer, wantedsize);
do {
if( (form->data->length - form->sent ) > wantedsize - gotsize) {
@@ -1228,7 +1250,7 @@ size_t Curl_FormReader(char *buffer,
form->data = form->data->next; /* advance */
} while(form->data);
} while(form->data && (form->data->type == FORM_DATA));
/* If we got an empty line and we have more data, we proceed to the next
line immediately to avoid returning zero before we've reached the end.
This is the bug reported November 22 1999 on curl 6.3. (Daniel) */
@@ -1458,4 +1480,53 @@ int main(int argc, char **argv)
#endif
#endif /* CURL_DISABLE_HTTP */
#else /* CURL_DISABLE_HTTP */
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
struct curl_httppost **last_post,
...)
{
(void)httppost;
(void)last_post;
return CURL_FORMADD_DISABLED;
}
void curl_formfree(struct curl_httppost *form)
{
(void)form;
/* does nothing HTTP is disabled */
}
#endif /* CURL_DISABLE_HTTP */
/*
* Curl_FormBoundary() creates a suitable boundary string and returns an
* allocated one. This is also used by SSL-code so it must be present even
* if HTTP is disabled!
*/
char *Curl_FormBoundary(void)
{
char *retstring;
static int randomizer=0; /* this is just so that two boundaries within
the same form won't be identical */
size_t i;
static char table16[]="abcdef0123456789";
retstring = (char *)malloc(BOUNDARY_LENGTH+1);
if(!retstring)
return NULL; /* failed */
srand(time(NULL)+randomizer++); /* seed */
strcpy(retstring, "----------------------------");
for(i=strlen(retstring); i<BOUNDARY_LENGTH; i++)
retstring[i] = table16[rand()%16];
/* 28 dashes and 12 hexadecimal digits makes 12^16 (184884258895036416)
combinations */
retstring[BOUNDARY_LENGTH]=0; /* zero terminate */
return retstring;
}

View File

@@ -23,17 +23,25 @@
*
* $Id$
***************************************************************************/
enum formtype {
FORM_DATA, /* regular data */
FORM_FILE /* 'line' points to a file name we should read from */
};
/* plain and simple linked list with lines to send */
struct FormData {
struct FormData *next;
enum formtype type;
char *line;
size_t length;
};
struct Form {
struct FormData *data; /* current form line to send */
unsigned int sent; /* number of bytes of the current line that has already
been sent in a previous invoke */
size_t sent; /* number of bytes of the current line that has
already been sent in a previous invoke */
FILE *fp; /* file to read from */
};
/* used by FormAdd for temporary storage */

603
lib/ftp.c
View File

@@ -119,6 +119,10 @@ static CURLcode ftp_cwd(struct connectdata *conn, char *path);
static CURLcode ftp_mkd(struct connectdata *conn, char *path);
static CURLcode ftp_cwd_and_mkd(struct connectdata *conn, char *path);
static CURLcode ftp_quit(struct connectdata *conn);
static CURLcode ftp_3rdparty_pretransfer(struct connectdata *conn);
static CURLcode ftp_3rdparty_transfer(struct connectdata *conn);
static CURLcode ftp_regular_transfer(struct connectdata *conn);
static CURLcode ftp_3rdparty(struct connectdata *conn);
/* easy-to-use macro: */
#define FTPSENDF(x,y,z) if((result = Curl_ftpsendf(x,y,z))) return result
@@ -369,7 +373,7 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
/* output debug output if that is requested */
if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN, line_start, perline);
Curl_debug(data, CURLINFO_HEADER_IN, line_start, perline, conn->host.dispname);
/*
* We pass all response-lines to the callback function registered
@@ -487,6 +491,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
ftp->passwd = conn->passwd;
ftp->response_time = 3600; /* set default response time-out */
#ifndef CURL_DISABLE_HTTP
if (conn->bits.tunnel_proxy) {
/* We want "seamless" FTP operations through HTTP proxy tunnel */
result = Curl_ConnectHTTPProxyTunnel(conn, FIRSTSOCKET,
@@ -494,6 +499,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
if(CURLE_OK != result)
return result;
}
#endif /* CURL_DISABLE_HTTP */
if(conn->protocol & PROT_FTPS) {
/* FTPS is simply ftp with SSL for the control channel */
@@ -844,8 +850,13 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
ftp->no_transfer = FALSE;
ftp->dont_check = FALSE;
if (!result && conn->sec_conn) { /* 3rd party transfer */
/* "done" with the secondary connection */
result = Curl_ftp_done(conn->sec_conn, status);
}
/* Send any post-transfer QUOTE strings? */
if(!result && data->set.postquote)
if(!status && !result && data->set.postquote)
result = ftp_sendquote(conn, data->set.postquote);
return result;
@@ -1702,6 +1713,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn,
/* this just dumps information about this second connection */
ftp_pasv_verbose(conn, conninfo, newhostp, connectport);
#ifndef CURL_DISABLE_HTTP
if(conn->bits.tunnel_proxy) {
/* We want "seamless" FTP operations through HTTP proxy tunnel */
result = Curl_ConnectHTTPProxyTunnel(conn, SECONDARYSOCKET,
@@ -1709,6 +1721,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn,
if(CURLE_OK != result)
return result;
}
#endif /* CURL_DISABLE_HTTP */
return CURLE_OK;
}
@@ -2334,11 +2347,393 @@ CURLcode ftp_perform(struct connectdata *conn,
* parts etc as a wrapper to the actual DO function (ftp_perform).
*
* The input argument is already checked for validity.
*/
CURLcode Curl_ftp(struct connectdata *conn)
{
CURLcode retcode = CURLE_OK;
if (conn->sec_conn) /* 3rd party transfer */
retcode = ftp_3rdparty(conn);
else
retcode = ftp_regular_transfer(conn);
return retcode;
}
/***********************************************************************
*
* Curl_ftpsendf()
*
* Sends the formated string as a ftp command to a ftp server
*
* NOTE: we build the command in a fixed-length buffer, which sets length
* restrictions on the command!
*/
CURLcode Curl_ftpsendf(struct connectdata *conn,
const char *fmt, ...)
{
ssize_t bytes_written;
char s[256];
size_t write_len;
char *sptr=s;
CURLcode res = CURLE_OK;
va_list ap;
va_start(ap, fmt);
vsnprintf(s, 250, fmt, ap);
va_end(ap);
strcat(s, "\r\n"); /* append a trailing CRLF */
bytes_written=0;
write_len = strlen(s);
while(1) {
res = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
&bytes_written);
if(CURLE_OK != res)
break;
if(conn->data->set.verbose)
Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, bytes_written, conn->host.dispname);
if(bytes_written != (ssize_t)write_len) {
write_len -= bytes_written;
sptr += bytes_written;
}
else
break;
}
return res;
}
/***********************************************************************
*
* ftp_quit()
*
* This should be called before calling sclose() on an ftp control connection
* (not data connections). We should then wait for the response from the
* server before returning. The calling code should then try to close the
* connection.
*
*/
static CURLcode ftp_quit(struct connectdata *conn)
{
ssize_t nread;
int ftpcode;
CURLcode ret = CURLE_OK;
if(conn->proto.ftp->ctl_valid) {
ret = Curl_ftpsendf(conn, "%s", "QUIT");
if(CURLE_OK == ret)
ret = Curl_GetFTPResponse(&nread, conn, &ftpcode);
}
return ret;
}
/***********************************************************************
*
* Curl_ftp_disconnect()
*
* Disconnect from an FTP server. Cleanup protocol-specific per-connection
* resources
*/
CURLcode Curl_ftp_disconnect(struct connectdata *conn)
{
struct FTP *ftp= conn->proto.ftp;
/* We cannot send quit unconditionally. If this connection is stale or
bad in any way, sending quit and waiting around here will make the
disconnect wait in vain and cause more problems than we need to.
ftp_quit() will check the state of ftp->ctl_valid. If it's ok it
will try to send the QUIT command, otherwise it will just return.
*/
/* The FTP session may or may not have been allocated/setup at this point! */
if(ftp) {
(void)ftp_quit(conn); /* ignore errors on the QUIT */
if(ftp->entrypath)
free(ftp->entrypath);
if(ftp->cache) {
free(ftp->cache);
ftp->cache = NULL;
}
freedirs(ftp);
}
return CURLE_OK;
}
/***********************************************************************
*
* ftp_mkd()
*
* Makes a directory on the FTP server.
*
* Calls failf()
*/
static CURLcode ftp_mkd(struct connectdata *conn, char *path)
{
CURLcode result=CURLE_OK;
int ftpcode; /* for ftp status */
ssize_t nread;
/* Create a directory on the remote server */
FTPSENDF(conn, "MKD %s", path);
result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
if(result)
return result;
switch(ftpcode) {
case 257:
/* success! */
infof( conn->data , "Created remote directory %s\n" , path );
break;
case 550:
failf(conn->data, "Permission denied to make directory %s", path);
result = CURLE_FTP_ACCESS_DENIED;
break;
default:
failf(conn->data, "unrecognized MKD response: %d", ftpcode );
result = CURLE_FTP_ACCESS_DENIED;
break;
}
return result;
}
/***********************************************************************
*
* ftp_cwd()
*
* Send 'CWD' to the remote server to Change Working Directory. It is the ftp
* version of the unix 'cd' command. This function is only called from the
* ftp_cwd_and_mkd() function these days.
*
* This function does NOT call failf().
*/
static
CURLcode ftp_cwd(struct connectdata *conn, char *path)
{
ssize_t nread;
int ftpcode;
CURLcode result;
FTPSENDF(conn, "CWD %s", path);
result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
if (!result) {
/* According to RFC959, CWD is supposed to return 250 on success, but
there seem to be non-compliant FTP servers out there that return 200,
so we accept any '2xy' code here. */
if (ftpcode/100 != 2)
result = CURLE_FTP_ACCESS_DENIED;
}
return result;
}
/***********************************************************************
*
* ftp_cwd_and_mkd()
*
* Change to the given directory. If the directory is not present, and we
* have been told to allow it, then create the directory and cd to it.
*
*/
static CURLcode ftp_cwd_and_mkd(struct connectdata *conn, char *path)
{
CURLcode result;
result = ftp_cwd(conn, path);
if (result) {
if(conn->data->set.ftp_create_missing_dirs) {
result = ftp_mkd(conn, path);
if (result)
/* ftp_mkd() calls failf() itself */
return result;
result = ftp_cwd(conn, path);
}
if(result)
failf(conn->data, "Couldn't cd to %s", path);
}
return result;
}
/***********************************************************************
*
* ftp_3rdparty_pretransfer()
*
* Preparation for 3rd party transfer.
*
*/
static CURLcode ftp_3rdparty_pretransfer(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct connectdata *sec_conn = conn->sec_conn;
/* sets transfer type */
result = ftp_transfertype(conn, data->set.ftp_ascii);
if (result)
return result;
result = ftp_transfertype(sec_conn, data->set.ftp_ascii);
if (result)
return result;
/* Send any PREQUOTE strings after transfer type is set? */
if (data->set.source_prequote) {
/* sends command(s) to source server before file transfer */
result = ftp_sendquote(sec_conn, data->set.source_prequote);
}
if (!result && data->set.prequote)
result = ftp_sendquote(conn, data->set.prequote);
return result;
}
/***********************************************************************
*
* ftp_3rdparty_transfer()
*
* Performs 3rd party transfer.
*
*/
static CURLcode ftp_3rdparty_transfer(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
ssize_t nread;
int ftpcode, ip[4], port[2];
struct SessionHandle *data = conn->data;
struct connectdata *sec_conn = conn->sec_conn;
char *buf = data->state.buffer; /* this is our buffer */
char *str = buf;
char pasv_port[50];
const char *stor_cmd;
struct connectdata *pasv_conn;
struct connectdata *port_conn;
if (data->set.pasvHost == CURL_TARGET_PASV) {
pasv_conn = conn;
port_conn = sec_conn;
}
else {
pasv_conn = sec_conn;
port_conn = conn;
}
/* sets the passive mode */
FTPSENDF(pasv_conn, "%s", "PASV");
result = Curl_GetFTPResponse(&nread, pasv_conn, &ftpcode);
if (result) return result;
if (ftpcode != 227) {
failf(data, "Odd return code after PASV:%s", buf + 3);
return CURLE_FTP_WEIRD_PASV_REPLY;
}
while (*str) {
if (6 == sscanf(str, "%d,%d,%d,%d,%d,%d",
&ip[0], &ip[1], &ip[2], &ip[3], &port[0], &port[1]))
break;
str++;
}
if (!*str) {
failf(pasv_conn->data, "Couldn't interpret this 227-reply: %s", buf);
return CURLE_FTP_WEIRD_227_FORMAT;
}
snprintf(pasv_port, sizeof(pasv_port), "%d,%d,%d,%d,%d,%d", ip[0], ip[1],
ip[2], ip[3], port[0], port[1]);
/* sets data connection between remote hosts */
FTPSENDF(port_conn, "PORT %s", pasv_port);
result = Curl_GetFTPResponse(&nread, port_conn, &ftpcode);
if (result)
return result;
if (ftpcode != 200) {
failf(data, "PORT command attempts failed:%s", buf + 3);
return CURLE_FTP_PORT_FAILED;
}
/* we might append onto the file instead of overwriting it */
stor_cmd = data->set.ftp_append?"APPE":"STOR";
/* transfers file between remote hosts */
FTPSENDF(sec_conn, "RETR %s", data->set.source_path);
if(data->set.pasvHost == CURL_TARGET_PASV) {
result = Curl_GetFTPResponse(&nread, sec_conn, &ftpcode);
if (result)
return result;
if (ftpcode != 150) {
failf(data, "Failed RETR: %s", buf + 4);
return CURLE_FTP_COULDNT_RETR_FILE;
}
result = Curl_ftpsendf(conn, "%s %s", stor_cmd, conn->path);
if(CURLE_OK == result)
result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
if (result)
return result;
if (ftpcode != 150) {
failf(data, "Failed FTP upload: %s", buf + 4);
return CURLE_FTP_COULDNT_STOR_FILE;
}
}
else {
result = Curl_ftpsendf(conn, "%s %s", stor_cmd, conn->path);
if(CURLE_OK == result)
result = Curl_GetFTPResponse(&nread, sec_conn, &ftpcode);
if (result)
return result;
if (ftpcode != 150) {
failf(data, "Failed FTP upload: %s", buf + 4);
return CURLE_FTP_COULDNT_STOR_FILE;
}
result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
if (result)
return result;
if (ftpcode != 150) {
failf(data, "Failed FTP upload: %s", buf + 4);
return CURLE_FTP_COULDNT_STOR_FILE;
}
}
return CURLE_OK;
}
/***********************************************************************
*
* ftp_regular_transfer()
*
* The input argument is already checked for validity.
* Performs a regular transfer between local and remote hosts.
*
* ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the
* Curl_ftp_done() function without finding any major problem.
*/
CURLcode Curl_ftp(struct connectdata *conn)
static
CURLcode ftp_regular_transfer(struct connectdata *conn)
{
CURLcode retcode=CURLE_OK;
bool connected=0;
@@ -2448,207 +2843,27 @@ CURLcode Curl_ftp(struct connectdata *conn)
return retcode;
}
/***********************************************************************
*
* Curl_ftpsendf()
*
* Sends the formated string as a ftp command to a ftp server
*
* NOTE: we build the command in a fixed-length buffer, which sets length
* restrictions on the command!
*/
CURLcode Curl_ftpsendf(struct connectdata *conn,
const char *fmt, ...)
{
ssize_t bytes_written;
char s[256];
size_t write_len;
char *sptr=s;
CURLcode res = CURLE_OK;
va_list ap;
va_start(ap, fmt);
vsnprintf(s, 250, fmt, ap);
va_end(ap);
strcat(s, "\r\n"); /* append a trailing CRLF */
bytes_written=0;
write_len = strlen(s);
while(1) {
res = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
&bytes_written);
if(CURLE_OK != res)
break;
if(conn->data->set.verbose)
Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, bytes_written);
if(bytes_written != (ssize_t)write_len) {
write_len -= bytes_written;
sptr += bytes_written;
}
else
break;
}
return res;
}
/***********************************************************************
*
* ftp_quit()
*
* This should be called before calling sclose() on an ftp control connection
* (not data connections). We should then wait for the response from the
* server before returning. The calling code should then try to close the
* connection.
* ftp_3rdparty()
*
* The input argument is already checked for validity.
* Performs a 3rd party transfer between two remote hosts.
*/
static CURLcode ftp_quit(struct connectdata *conn)
static CURLcode ftp_3rdparty(struct connectdata *conn)
{
ssize_t nread;
int ftpcode;
CURLcode ret = CURLE_OK;
CURLcode retcode = CURLE_OK;
if(conn->proto.ftp->ctl_valid) {
ret = Curl_ftpsendf(conn, "%s", "QUIT");
if(CURLE_OK == ret)
ret = Curl_GetFTPResponse(&nread, conn, &ftpcode);
}
conn->proto.ftp->ctl_valid = conn->sec_conn->proto.ftp->ctl_valid = TRUE;
conn->size = conn->sec_conn->size = -1;
return ret;
}
retcode = ftp_3rdparty_pretransfer(conn);
if (!retcode)
retcode = ftp_3rdparty_transfer(conn);
/***********************************************************************
*
* Curl_ftp_disconnect()
*
* Disconnect from an FTP server. Cleanup protocol-specific per-connection
* resources
*/
CURLcode Curl_ftp_disconnect(struct connectdata *conn)
{
struct FTP *ftp= conn->proto.ftp;
/* We cannot send quit unconditionally. If this connection is stale or
bad in any way, sending quit and waiting around here will make the
disconnect wait in vain and cause more problems than we need to.
ftp_quit() will check the state of ftp->ctl_valid. If it's ok it
will try to send the QUIT command, otherwise it will just return.
*/
/* The FTP session may or may not have been allocated/setup at this point! */
if(ftp) {
(void)ftp_quit(conn); /* ignore errors on the QUIT */
if(ftp->entrypath)
free(ftp->entrypath);
if(ftp->cache) {
free(ftp->cache);
ftp->cache = NULL;
}
freedirs(ftp);
}
return CURLE_OK;
}
/***********************************************************************
*
* ftp_mkd()
*
* Makes a directory on the FTP server.
*
* Calls failf()
*/
CURLcode ftp_mkd(struct connectdata *conn, char *path)
{
CURLcode result=CURLE_OK;
int ftpcode; /* for ftp status */
ssize_t nread;
/* Create a directory on the remote server */
FTPSENDF(conn, "MKD %s", path);
result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
if(result)
return result;
switch(ftpcode) {
case 257:
/* success! */
infof( conn->data , "Created remote directory %s\n" , path );
break;
case 550:
failf(conn->data, "Permission denied to make directory %s", path);
result = CURLE_FTP_ACCESS_DENIED;
break;
default:
failf(conn->data, "unrecognized MKD response: %d", ftpcode );
result = CURLE_FTP_ACCESS_DENIED;
break;
}
return result;
}
/***********************************************************************
*
* ftp_cwd()
*
* Send 'CWD' to the remote server to Change Working Directory. It is the ftp
* version of the unix 'cd' command. This function is only called from the
* ftp_cwd_and_mkd() function these days.
*
* This function does NOT call failf().
*/
static
CURLcode ftp_cwd(struct connectdata *conn, char *path)
{
ssize_t nread;
int ftpcode;
CURLcode result;
FTPSENDF(conn, "CWD %s", path);
result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
if (!result) {
/* According to RFC959, CWD is supposed to return 250 on success, but
there seem to be non-compliant FTP servers out there that return 200,
so we accept any '2xy' code here. */
if (ftpcode/100 != 2)
result = CURLE_FTP_ACCESS_DENIED;
}
return result;
}
/***********************************************************************
*
* ftp_cwd_and_mkd()
*
* Change to the given directory. If the directory is not present, and we
* have been told to allow it, then create the directory and cd to it.
*
*/
static CURLcode ftp_cwd_and_mkd(struct connectdata *conn, char *path)
{
CURLcode result;
result = ftp_cwd(conn, path);
if (result) {
if(conn->data->set.ftp_create_missing_dirs) {
result = ftp_mkd(conn, path);
if (result)
/* ftp_mkd() calls failf() itself */
return result;
result = ftp_cwd(conn, path);
}
if(result)
failf(conn->data, "Couldn't cd to %s", path);
}
return result;
return retcode;
}
#endif /* CURL_DISABLE_FTP */

View File

@@ -1758,7 +1758,8 @@ ToHour (Hours, Meridian)
default:
abort ();
}
/* NOTREACHED */
/* NOTREACHED - but make gcc happy! */
return -1;
}
static int

View File

@@ -26,6 +26,11 @@
#define YYDEBUG 0
#endif
#ifndef YYSTACK_USE_ALLOCA
/* to satisfy gcc -Wundef, we set this to 0 */
#define YYSTACK_USE_ALLOCA 0
#endif
/* Since the code of getdate.y is not included in the Emacs executable
itself, there is no need to #define static in this file. Even if
the code were included in the Emacs executable, it probably
@@ -717,9 +722,10 @@ ToHour (int Hours, MERIDIAN Meridian)
Hours = 0;
return Hours + 12;
default:
abort ();
break; /* used to do abort() here */
}
/* NOTREACHED */
/* NOTREACHED - but make gcc happy! */
return -1;
}
static int
@@ -1073,31 +1079,3 @@ curl_getdate (const char *p, const time_t *now)
return Start;
}
#if defined (TEST)
/* ARGSUSED */
int
main (int ac, char *av[])
{
char buff[MAX_BUFF_LEN + 1];
time_t d;
(void) printf ("Enter date, or blank line to exit.\n\t> ");
(void) fflush (stdout);
buff[MAX_BUFF_LEN] = 0;
while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
{
d = curl_getdate (buff, (time_t *) NULL);
if (d == -1)
(void) printf ("Bad format - couldn't convert.\n");
else
(void) printf ("%s", ctime (&d));
(void) printf ("\t> ");
(void) fflush (stdout);
}
exit (0);
/* NOTREACHED */
}
#endif /* defined (TEST) */

View File

@@ -79,6 +79,7 @@
#include "share.h"
#include "strerror.h"
#include "url.h"
#include "inet_ntop.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -167,6 +168,43 @@ void Curl_global_host_cache_dtor(void)
}
}
/*
* Return # of adresses in a Curl_addrinfo struct
*/
int Curl_num_addresses(const Curl_addrinfo *addr)
{
int i;
#ifdef ENABLE_IPV6
for (i = 0; addr; addr = addr->ai_next, i++)
#else
for (i = 0; addr->h_addr_list[i]; i++)
#endif
;
return (i);
}
/*
* Curl_printable_address() returns a printable version of the 1st address
* given in the 'ip' argument. The result will be stored in the buf that is
* bufsize bytes big.
*
* If the conversion fails, it returns NULL.
*/
const char *Curl_printable_address(const Curl_ipconnect *ip,
char *buf, size_t bufsize)
{
#ifdef CURLRES_IPV6
const void *ip4 = &((const struct sockaddr_in*)ip->ai_addr)->sin_addr;
const void *ip6 = &((const struct sockaddr_in6*)ip->ai_addr)->sin6_addr;
int af = ip->ai_family;
return Curl_inet_ntop(af, af == AF_INET6 ? ip6 : ip4, buf, bufsize);
#else
return Curl_inet_ntop(AF_INET, ip, buf, bufsize);
#endif
}
/*
* Count the number of characters that an integer would use in a string
* (base 10).

View File

@@ -102,6 +102,9 @@ curl_hash *Curl_mk_dnscache(void);
/* prune old entries from the DNS cache */
void Curl_hostcache_prune(struct SessionHandle *data);
/* Return # of adresses in a Curl_addrinfo struct */
int Curl_num_addresses (const Curl_addrinfo *addr);
#ifdef CURLDEBUG
void curl_dofreeaddrinfo(struct addrinfo *freethis,
int line, const char *source);
@@ -133,12 +136,11 @@ void Curl_hostent_relocate(struct hostent *h, long offset);
Curl_addrinfo *Curl_addrinfo_copy(Curl_addrinfo *orig);
/*
* (IPv6) Curl_printable_address() returns a printable version of the
* ai->ai_addr address given in the 2nd argument. The first should be the
* ai->ai_family and the result will be stored in the buf that is bufsize
* bytes big.
* Curl_printable_address() returns a printable version of the 1st address
* given in the 'ip' argument. The result will be stored in the buf that is
* bufsize bytes big.
*/
const char *Curl_printable_address(int af, void *addr,
const char *Curl_printable_address(const Curl_ipconnect *ip,
char *buf, size_t bufsize);
/*

View File

@@ -79,7 +79,6 @@
#include "share.h"
#include "strerror.h"
#include "url.h"
#include "inet_ntop.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -106,26 +105,6 @@ void Curl_freeaddrinfo(Curl_addrinfo *p)
freeaddrinfo(p);
}
/*
* Curl_printable_address() returns a printable version of the ai->ai_addr
* address given in the 2nd argument. The first should be the ai->ai_family
* and the result will be stored in the buf that is bufsize bytes big.
*
* If the conversion fails, it returns NULL.
*/
const char *Curl_printable_address(int af, void *addr,
char *buf, size_t bufsize)
{
const struct in_addr *addr4 =
&((const struct sockaddr_in*)addr)->sin_addr;
const struct in6_addr *addr6 =
&((const struct sockaddr_in6*)addr)->sin6_addr;
return Curl_inet_ntop(af, af == AF_INET6 ?
(const void *)addr6 :
(const void *)addr4, buf, bufsize);
}
#ifdef CURLRES_ASYNCH
/*
* Curl_addrinfo_copy() is used by the asynch callback to copy a given

View File

@@ -142,7 +142,7 @@ static void dump_addrinfo (struct connectdata *conn, const struct addrinfo *ai)
trace_it(" fam %2d, CNAME %s, ",
ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
if (Curl_printable_address(ai->ai_family, ai->ai_addr, buf, sizeof(buf)))
if (Curl_printable_address(ai, buf, sizeof(buf)))
trace_it("%s\n", buf);
else
trace_it("failed; %s\n", Curl_strerror(conn,WSAGetLastError()));

View File

@@ -168,29 +168,25 @@ static CURLcode Curl_output_basic(struct connectdata *conn, bool proxy)
static bool pickoneauth(struct auth *pick)
{
bool picked;
if(pick->avail) {
/* only deal with authentication we want */
long avail = pick->avail & pick->want;
picked = TRUE;
/* only deal with authentication we want */
long avail = pick->avail & pick->want;
picked = TRUE;
/* The order of these checks is highly relevant, as this will be the order
of preference in case of the existance of multiple accepted types. */
if(avail & CURLAUTH_GSSNEGOTIATE)
pick->picked = CURLAUTH_GSSNEGOTIATE;
else if(avail & CURLAUTH_DIGEST)
pick->picked = CURLAUTH_DIGEST;
else if(avail & CURLAUTH_NTLM)
pick->picked = CURLAUTH_NTLM;
else if(avail & CURLAUTH_BASIC)
pick->picked = CURLAUTH_BASIC;
else {
pick->picked = CURLAUTH_NONE; /* none was picked clear it */
picked = FALSE;
}
pick->avail = CURLAUTH_NONE; /* clear it here */
/* The order of these checks is highly relevant, as this will be the order
of preference in case of the existance of multiple accepted types. */
if(avail & CURLAUTH_GSSNEGOTIATE)
pick->picked = CURLAUTH_GSSNEGOTIATE;
else if(avail & CURLAUTH_DIGEST)
pick->picked = CURLAUTH_DIGEST;
else if(avail & CURLAUTH_NTLM)
pick->picked = CURLAUTH_NTLM;
else if(avail & CURLAUTH_BASIC)
pick->picked = CURLAUTH_BASIC;
else {
pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
picked = FALSE;
}
else
return FALSE;
pick->avail = CURLAUTH_NONE; /* clear it here */
return picked;
}
@@ -212,22 +208,27 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
if(data->state.authproblem)
return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
if(conn->bits.user_passwd) {
if(conn->bits.user_passwd &&
((conn->keep.httpcode == 401) ||
(conn->bits.authprobe && conn->keep.httpcode < 300))) {
pickhost = pickoneauth(&data->state.authhost);
if(!pickhost && (conn->keep.httpcode == 401))
if(!pickhost)
data->state.authproblem = TRUE;
}
if(conn->bits.proxy_user_passwd) {
if(conn->bits.proxy_user_passwd &&
((conn->keep.httpcode == 407) ||
(conn->bits.authprobe && conn->keep.httpcode < 300))) {
pickproxy = pickoneauth(&data->state.authproxy);
if(!pickproxy && (conn->keep.httpcode == 407))
if(!pickproxy)
data->state.authproblem = TRUE;
}
if(pickhost || pickproxy)
conn->newurl = strdup(data->change.url); /* clone URL */
else if((data->info.httpcode < 400) &&
(!data->state.authhost.done)) {
else if((conn->keep.httpcode < 300) &&
(!data->state.authhost.done) &&
conn->bits.authprobe) {
/* no (known) authentication available,
authentication is not "done" yet and
no authentication seems to be required and
@@ -283,21 +284,17 @@ Curl_http_output_auth(struct connectdata *conn,
return CURLE_OK; /* no authentication with no user or password */
}
if(data->state.authhost.want &&
!data->state.authhost.picked) {
if(data->state.authhost.want && !data->state.authhost.picked)
/* The app has selected one or more methods, but none has been picked
so far by a server round-trip. Then we set the picked one to the
want one, and if this is one single bit it'll be used instantly. */
data->state.authhost.picked = data->state.authhost.want;
}
if(data->state.authproxy.want &&
!data->state.authproxy.picked) {
/* The app has selected one or more methods, but none has been picked
so far by a server round-trip. Then we set the picked one to the
want one, and if this is one single bit it'll be used instantly. */
if(data->state.authproxy.want && !data->state.authproxy.picked)
/* The app has selected one or more methods, but none has been picked so
far by a proxy round-trip. Then we set the picked one to the want one,
and if this is one single bit it'll be used instantly. */
data->state.authproxy.picked = data->state.authproxy.want;
}
/* To prevent the user+password to get sent to other than the original
host due to a location-follow, we do some weirdo checks here */
@@ -740,7 +737,8 @@ CURLcode add_buffer_send(send_buffer *in,
if(conn->data->set.verbose)
/* this data _may_ contain binary stuff */
Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, amount);
Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, amount,
conn->host.dispname);
*bytes_written += amount;
@@ -1044,7 +1042,8 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
/* output debug output if that is requested */
if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN, line_start, perline);
Curl_debug(data, CURLINFO_HEADER_IN, line_start, perline,
conn->host.dispname);
/* send the header to the callback */
writetype = CLIENTWRITE_HEADER;
@@ -1080,7 +1079,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
else if(2 == sscanf(line_start, "HTTP/1.%d %d",
&subversion,
&k->httpcode)) {
/* store the HTTP code */
/* store the HTTP code from the proxy */
data->info.httpproxycode = k->httpcode;
}
/* put back the letter we blanked out before */
@@ -1098,9 +1097,10 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
if(error)
return CURLE_RECV_ERROR;
/* Deal with the possibly already received authenticate headers. 'newurl'
is set to a new URL if we must loop. */
Curl_http_auth_act(conn);
if(data->info.httpproxycode != 200)
/* Deal with the possibly already received authenticate
headers. 'newurl' is set to a new URL if we must loop. */
Curl_http_auth_act(conn);
} while(conn->newurl);
@@ -1277,14 +1277,13 @@ CURLcode Curl_http(struct connectdata *conn)
case HTTPREQ_PUT:
request = (char *)"PUT";
break;
default: /* this should never happen */
case HTTPREQ_GET:
request = (char *)"GET";
break;
case HTTPREQ_HEAD:
request = (char *)"HEAD";
break;
default: /* this should never happen */
break;
}
}
}
@@ -1312,7 +1311,11 @@ CURLcode Curl_http(struct connectdata *conn)
httpreq = HTTPREQ_HEAD;
request = (char *)"HEAD";
conn->bits.no_body = TRUE;
conn->bits.authprobe = TRUE; /* this is a request done to probe for
authentication methods */
}
else
conn->bits.authprobe = FALSE;
Curl_safefree(conn->allocptr.ref);
if(data->change.referer && !checkheaders(data, "Referer:"))
@@ -1764,13 +1767,11 @@ CURLcode Curl_http(struct connectdata *conn)
}
if(!checkheaders(data, "Content-Type:")) {
/* Get Content-Type: line from Curl_formpostheader, which happens
to always be the first line. We can know this for sure since
we always build the formpost linked list the same way!
/* Get Content-Type: line from Curl_formpostheader.
The Content-Type header line also contains the MIME boundary
string etc why disabling this header is likely to not make things
work, but we support it anyway.
work, but we support disabling it anyway.
*/
char *contentType;
size_t linelength=0;

View File

@@ -50,5 +50,12 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
CURLcode Curl_http_auth_act(struct connectdata *conn);
int Curl_http_should_fail(struct connectdata *conn);
/* If only the PICKNONE bit is set, there has been a round-trip and we
selected to use no auth at all. Ie, we actively select no auth, as opposed
to not having one selected. The other CURLAUTH_* defines are present in the
public curl/curl.h header. */
#define CURLAUTH_PICKNONE (1<<30) /* don't use auth */
#endif
#endif

View File

@@ -221,23 +221,37 @@ CURLcode Curl_output_digest(struct connectdata *conn,
char *cnonce;
char *tmp = NULL;
struct timeval now;
char **allocuserpwd;
char *userp;
char *passwdp;
struct auth *authp;
char **userp;
struct SessionHandle *data = conn->data;
struct digestdata *d;
if(proxy) {
d = &data->state.proxydigest;
allocuserpwd = &conn->allocptr.proxyuserpwd;
userp = conn->proxyuser;
passwdp = conn->proxypasswd;
authp = &data->state.authproxy;
userp = &conn->allocptr.proxyuserpwd;
}
else {
d = &data->state.digest;
allocuserpwd = &conn->allocptr.userpwd;
userp = conn->user;
passwdp = conn->passwd;
authp = &data->state.authhost;
userp = &conn->allocptr.userpwd;
}
/* not set means empty */
if(!userp)
userp=(char *)"";
if(!passwdp)
passwdp=(char *)"";
if(!d->nonce) {
authp->done = FALSE;
return CURLE_OK;
@@ -269,7 +283,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
*/
md5this = (unsigned char *)
aprintf("%s:%s:%s", conn->user, d->realm, conn->passwd);
aprintf("%s:%s:%s", userp, d->realm, passwdp);
if(!md5this)
return CURLE_OUT_OF_MEMORY;
Curl_md5it(md5buf, md5this);
@@ -347,10 +361,10 @@ CURLcode Curl_output_digest(struct connectdata *conn,
nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
*/
Curl_safefree(conn->allocptr.userpwd);
Curl_safefree(*allocuserpwd);
if (d->qop) {
*userp =
*allocuserpwd =
aprintf( "%sAuthorization: Digest "
"username=\"%s\", "
"realm=\"%s\", "
@@ -361,7 +375,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
"qop=\"%s\", "
"response=\"%s\"",
proxy?"Proxy-":"",
conn->user,
userp,
d->realm,
d->nonce,
uripath, /* this is the PATH part of the URL */
@@ -376,7 +390,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
same nonce in the qop=auth mode. */
}
else {
*userp =
*allocuserpwd =
aprintf( "%sAuthorization: Digest "
"username=\"%s\", "
"realm=\"%s\", "
@@ -384,40 +398,40 @@ CURLcode Curl_output_digest(struct connectdata *conn,
"uri=\"%s\", "
"response=\"%s\"",
proxy?"Proxy-":"",
conn->user,
userp,
d->realm,
d->nonce,
uripath, /* this is the PATH part of the URL */
request_digest);
}
if(!*userp)
if(!*allocuserpwd)
return CURLE_OUT_OF_MEMORY;
/* Add optional fields */
if(d->opaque) {
/* append opaque */
tmp = aprintf("%s, opaque=\"%s\"", *userp, d->opaque);
tmp = aprintf("%s, opaque=\"%s\"", *allocuserpwd, d->opaque);
if(!tmp)
return CURLE_OUT_OF_MEMORY;
free(*userp);
*userp = tmp;
free(*allocuserpwd);
*allocuserpwd = tmp;
}
if(d->algorithm) {
/* append algorithm */
tmp = aprintf("%s, algorithm=\"%s\"", *userp, d->algorithm);
tmp = aprintf("%s, algorithm=\"%s\"", *allocuserpwd, d->algorithm);
if(!tmp)
return CURLE_OUT_OF_MEMORY;
free(*userp);
*userp = tmp;
free(*allocuserpwd);
*allocuserpwd = tmp;
}
/* append CRLF to the userpwd header */
tmp = (char*) realloc(*userp, strlen(*userp) + 3 + 1);
tmp = (char*) realloc(*allocuserpwd, strlen(*allocuserpwd) + 3 + 1);
if(!tmp)
return CURLE_OUT_OF_MEMORY;
strcat(tmp, "\r\n");
*userp = tmp;
*allocuserpwd = tmp;
return CURLE_OK;
}

View File

@@ -427,12 +427,12 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
if (user) {
domain = userp;
domlen = user - domain;
domlen = (int)(user - domain);
user++;
}
else
user = userp;
userlen = strlen(user);
userlen = (int)strlen(user);
mkhash(passwdp, &ntlm->nonce[0], lmresp
#ifdef USE_NTRESPONSES

View File

@@ -9,7 +9,6 @@
curl_easy_setopt,
curl_escape,
curl_unescape,
curl_formparse,
curl_formfree,
curl_getdate,
curl_getenv,
@@ -39,6 +38,8 @@
curl_version_info,
curl_share_init,
curl_share_setopt,
curl_share_cleanup
curl_share_cleanup,
curl_global_init_mem,
curl_easy_strerror,
curl_multi_strerror,
curl_share_strerror

View File

@@ -30,7 +30,7 @@ BEGIN
VALUE "OriginalFilename", "libcurl.dll\0"
VALUE "ProductName", "The cURL library\0"
VALUE "ProductVersion", LIBCURL_VERSION "\0"
VALUE "LegalCopyright", "Copyright 1996-2003 by Daniel Stenberg. http://curl.haxx.se/docs/copyright.html\0"
VALUE "LegalCopyright", "Copyright 1996-2004 by Daniel Stenberg. http://curl.haxx.se/docs/copyright.html\0"
END
END

View File

@@ -142,7 +142,7 @@ void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
va_start(ap, fmt);
vsnprintf(print_buffer, 1024, fmt, ap);
va_end(ap);
Curl_debug(data, CURLINFO_TEXT, print_buffer, strlen(print_buffer));
Curl_debug(data, CURLINFO_TEXT, print_buffer, strlen(print_buffer), NULL);
}
}
@@ -166,7 +166,7 @@ void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
data->set.errorbuffer[len] = '\n';
data->set.errorbuffer[++len] = '\0';
}
Curl_debug(data, CURLINFO_TEXT, data->set.errorbuffer, len);
Curl_debug(data, CURLINFO_TEXT, data->set.errorbuffer, len, NULL);
if(doneit)
/* cut off the newline again */
data->set.errorbuffer[--len]=0;
@@ -204,7 +204,8 @@ CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
break;
if(data->set.verbose)
Curl_debug(data, CURLINFO_DATA_OUT, sptr, bytes_written);
Curl_debug(data, CURLINFO_DATA_OUT, sptr, bytes_written,
conn->host.dispname);
if((size_t)bytes_written != write_len) {
/* if not all was written at once, we must advance the pointer, decrease
@@ -440,11 +441,11 @@ int Curl_read(struct connectdata *conn, /* connection data */
}
/* return 0 on success */
int Curl_debug(struct SessionHandle *data, curl_infotype type,
char *ptr, size_t size)
static int showit(struct SessionHandle *data, curl_infotype type,
char *ptr, size_t size)
{
static const char * const s_infotype[CURLINFO_END] = {
"* ", "< ", "> ", "{ ", "} " };
"* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
if(data->set.fdebug)
return (*data->set.fdebug)(data, type, ptr, size,
@@ -462,3 +463,34 @@ int Curl_debug(struct SessionHandle *data, curl_infotype type,
}
return 0;
}
int Curl_debug(struct SessionHandle *data, curl_infotype type,
char *ptr, size_t size, char *host)
{
int rc;
if(data->set.printhost && host) {
char buffer[160];
const char *t=NULL;
switch (type) {
case CURLINFO_HEADER_IN:
case CURLINFO_DATA_IN:
t = "from";
break;
case CURLINFO_HEADER_OUT:
case CURLINFO_DATA_OUT:
t = "to";
break;
default:
break;
}
if(t) {
snprintf(buffer, sizeof(buffer), "[Data %s %s]", t, host);
rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
if(rc)
return rc;
}
}
rc = showit(data, type, ptr, size);
return rc;
}

View File

@@ -50,7 +50,7 @@ CURLcode Curl_write(struct connectdata *conn,
/* the function used to output verbose information */
int Curl_debug(struct SessionHandle *handle, curl_infotype type,
char *data, size_t size);
char *data, size_t size, char *host);
#endif

View File

@@ -261,7 +261,8 @@ typedef int curl_socket_t;
#error "ares does not yet support IPv6. Disable IPv6 or ares and rebuild"
#endif
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(USE_ARES)
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(USE_ARES) && \
!defined(__LCC__) /* lcc-win32 doesn't have _beginthreadex() */
#ifdef ENABLE_IPV6
#define USE_THREADING_GETADDRINFO
#else
@@ -304,7 +305,7 @@ typedef struct in_addr Curl_ipconnect;
/* This could benefit from additional checks that some of the used/important
header files are present as well before we define the USE_* define. */
#define USE_LIBIDN
#define LIBIDN_REQUIRED_VERSION "0.4.5"
#define LIBIDN_REQUIRED_VERSION "0.4.1"
#endif
#endif /* __CONFIG_H */

View File

@@ -77,6 +77,7 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
}
break;
#ifndef CURL_DISABLE_HTTP
case CURL_LOCK_DATA_COOKIE:
if (!share->cookies) {
share->cookies = Curl_cookie_init(NULL, NULL, NULL, TRUE );
@@ -84,6 +85,7 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
return CURLSHE_NOMEM;
}
break;
#endif /* CURL_DISABLE_HTTP */
case CURL_LOCK_DATA_SSL_SESSION: /* not supported (yet) */
case CURL_LOCK_DATA_CONNECT: /* not supported (yet) */
@@ -106,12 +108,14 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
}
break;
#ifndef CURL_DISABLE_HTTP
case CURL_LOCK_DATA_COOKIE:
if (share->cookies) {
Curl_cookie_cleanup(share->cookies);
share->cookies = NULL;
}
break;
#endif /* CURL_DISABLE_HTTP */
case CURL_LOCK_DATA_SSL_SESSION:
break;
@@ -165,8 +169,10 @@ curl_share_cleanup(CURLSH *sh)
if(share->hostcache)
Curl_hash_destroy(share->hostcache);
#ifndef CURL_DISABLE_HTTP
if(share->cookies)
Curl_cookie_cleanup(share->cookies);
#endif /* CURL_DISABLE_HTTP */
share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
free (share);

View File

@@ -45,6 +45,10 @@
#include "inet_pton.h"
#include "ssluse.h"
#include "connect.h" /* Curl_ourerrno() proto */
#include "strequal.h"
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
#include <curl/mprintf.h>
#ifdef USE_SSLEAY
#include <openssl/rand.h>
@@ -55,6 +59,10 @@
/* The last #include file should be: */
#include "memdebug.h"
#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#endif
#if OPENSSL_VERSION_NUMBER >= 0x0090581fL
#define HAVE_SSL_GET1_SESSION 1
#else
@@ -731,40 +739,59 @@ static int Curl_ASN1_UTCTIME_output(struct connectdata *conn,
/* ====================================================== */
#ifdef USE_SSLEAY
static int
cert_hostcheck(const char *certname, const char *hostname)
{
char *tmp;
const char *certdomain;
if(!certname ||
strlen(certname)<3 ||
!hostname ||
!strlen(hostname)) /* sanity check */
/*
* Match a hostname against a wildcard pattern.
* E.g.
* "foo.host.com" matches "*.host.com".
*
* We are a bit more liberal than RFC2818 describes in that we
* accept multiple "*" in pattern (similar to what some other browsers do).
* E.g.
* "abc.def.domain.com" should strickly not match "*.domain.com", but we
* don't consider "." to be important in CERT checking.
*/
#define HOST_NOMATCH 0
#define HOST_MATCH 1
static int hostmatch(const char *hostname, const char *pattern)
{
while (1) {
int c = *pattern++;
if (c == '\0')
return (*hostname ? HOST_NOMATCH : HOST_MATCH);
if (c == '*') {
c = *pattern;
if (c == '\0') /* "*\0" matches anything remaining */
return HOST_MATCH;
while (*hostname) {
/* The only recursive function in libcurl! */
if (hostmatch(hostname++,pattern) == HOST_MATCH)
return HOST_MATCH;
}
return HOST_NOMATCH;
}
if (toupper(c) != toupper(*hostname++))
return HOST_NOMATCH;
}
}
static int
cert_hostcheck(const char *match_pattern, const char *hostname)
{
if (!match_pattern || !*match_pattern ||
!hostname || !*hostname) /* sanity check */
return 0;
if(curl_strequal(certname, hostname)) /* trivial case */
if(curl_strequal(hostname,match_pattern)) /* trivial case */
return 1;
certdomain = certname + 1;
if((certname[0] != '*') || (certdomain[0] != '.'))
return 0; /* not a wildcard certificate, check failed */
if(!strchr(certdomain+1, '.'))
return 0; /* the certificate must have at least another dot in its name */
/* find 'certdomain' within 'hostname' */
tmp = strstr(hostname, certdomain);
if(tmp) {
/* ok the certname's domain matches the hostname, let's check that it's a
tail-match */
if(curl_strequal(tmp, certdomain))
/* looks like a match. Just check we havent swallowed a '.' */
return tmp == strchr(hostname, '.');
else
return 0;
}
if (hostmatch(hostname,match_pattern) == HOST_MATCH)
return 1;
return 0;
}
@@ -820,19 +847,9 @@ static CURLcode verifyhost(struct connectdata *conn,
altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL);
if(altnames) {
int hostlen = 0;
int domainlen = 0;
char *domain = NULL;
int numalts;
int i;
if(GEN_DNS == target) {
hostlen = (int)strlen(conn->host.name);
domain = strchr(conn->host.name, '.');
if(domain)
domainlen = (int)strlen(domain);
}
/* get amount of alternatives, RFC2459 claims there MUST be at least
one, but we don't depend on it... */
numalts = sk_GENERAL_NAME_num(altnames);
@@ -846,25 +863,28 @@ static CURLcode verifyhost(struct connectdata *conn,
if(check->type == target) {
/* get data and length */
const char *altptr = (char *)ASN1_STRING_data(check->d.ia5);
const int altlen = ASN1_STRING_length(check->d.ia5);
int altlen;
switch(target) {
case GEN_DNS: /* name comparison */
/* Is this an exact match? */
if((hostlen == altlen) &&
curl_strnequal(conn->host.name, altptr, hostlen))
matched = TRUE;
case GEN_DNS: /* name/pattern comparison */
/* The OpenSSL man page explicitly says: "In general it cannot be
assumed that the data returned by ASN1_STRING_data() is null
terminated or does not contain embedded nulls." But also that
"The actual format of the data will depend on the actual string
type itself: for example for and IA5String the data will be ASCII"
/* Is this a wildcard match? */
else if((altptr[0] == '*') &&
(domainlen == altlen-1) &&
curl_strnequal(domain, altptr+1, domainlen))
Gisle researched the OpenSSL sources:
"I checked the 0.9.6 and 0.9.8 sources before my patch and
it always 0-terminates an IA5String."
*/
if (cert_hostcheck(altptr, conn->host.name))
matched = TRUE;
break;
case GEN_IPADD: /* IP address comparison */
/* compare alternative IP address if the data chunk is the same size
our server IP address is */
altlen = ASN1_STRING_length(check->d.ia5);
if((altlen == addrlen) && !memcmp(altptr, &addr, altlen))
matched = TRUE;
break;
@@ -937,6 +957,115 @@ static CURLcode verifyhost(struct connectdata *conn,
}
#endif
/* The SSL_CTRL_SET_MSG_CALLBACK doesn't exist in ancient OpenSSL versions
and thus this cannot be done there. */
#ifdef SSL_CTRL_SET_MSG_CALLBACK
static const char *ssl_msg_type(int ssl_ver, int msg)
{
if (ssl_ver == SSL2_VERSION_MAJOR) {
switch (msg) {
case SSL2_MT_ERROR:
return "Error";
case SSL2_MT_CLIENT_HELLO:
return "Client hello";
case SSL2_MT_CLIENT_MASTER_KEY:
return "Client key";
case SSL2_MT_CLIENT_FINISHED:
return "Client finished";
case SSL2_MT_SERVER_HELLO:
return "Server hello";
case SSL2_MT_SERVER_VERIFY:
return "Server verify";
case SSL2_MT_SERVER_FINISHED:
return "Server finished";
case SSL2_MT_REQUEST_CERTIFICATE:
return "Request CERT";
case SSL2_MT_CLIENT_CERTIFICATE:
return "Client CERT";
}
}
else if (ssl_ver == SSL3_VERSION_MAJOR) {
switch (msg) {
case SSL3_MT_HELLO_REQUEST:
return "Hello request";
case SSL3_MT_CLIENT_HELLO:
return "Client hello";
case SSL3_MT_SERVER_HELLO:
return "Server hello";
case SSL3_MT_CERTIFICATE:
return "CERT";
case SSL3_MT_SERVER_KEY_EXCHANGE:
return "Server key exchange";
case SSL3_MT_CLIENT_KEY_EXCHANGE:
return "Client key exchange";
case SSL3_MT_CERTIFICATE_REQUEST:
return "Request CERT";
case SSL3_MT_SERVER_DONE:
return "Server finished";
case SSL3_MT_CERTIFICATE_VERIFY:
return "CERT verify";
case SSL3_MT_FINISHED:
return "Finished";
}
}
return "Unknown";
}
static const char *tls_rt_type(int type)
{
return (
type == SSL3_RT_CHANGE_CIPHER_SPEC ? "TLS change cipher, " :
type == SSL3_RT_ALERT ? "TLS alert, " :
type == SSL3_RT_HANDSHAKE ? "TLS handshake, " :
type == SSL3_RT_APPLICATION_DATA ? "TLS app data, " :
"TLS Unknown, ");
}
/*
* Our callback from the SSL/TLS layers.
*/
static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
const void *buf, size_t len, const SSL *ssl,
struct connectdata *conn)
{
struct SessionHandle *data = conn->data;
const char *msg_name, *tls_rt_name;
char ssl_buf[1024];
int ver, msg_type, txt_len;
if (!conn || !conn->data || !conn->data->set.fdebug ||
(direction != 0 && direction != 1))
return;
data = conn->data;
ssl_ver >>= 8;
ver = (ssl_ver == SSL2_VERSION_MAJOR ? '2' :
ssl_ver == SSL3_VERSION_MAJOR ? '3' : '?');
/* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL
* always pass-up content-type as 0. But the interesting message-type
* is at 'buf[0]'.
*/
if (ssl_ver == SSL3_VERSION_MAJOR && content_type != 0)
tls_rt_name = tls_rt_type(content_type);
else
tls_rt_name = "";
msg_type = *(char*)buf;
msg_name = ssl_msg_type(ssl_ver, msg_type);
txt_len = 1 + sprintf(ssl_buf, "SSLv%c, %s%s (%d):\n",
ver, tls_rt_name, msg_name, msg_type);
Curl_debug(data, CURLINFO_TEXT, ssl_buf, txt_len, NULL);
Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT :
CURLINFO_SSL_DATA_IN, (char *)buf, len, NULL);
(void) ssl;
}
#endif
/* ====================================================== */
CURLcode
Curl_SSLConnect(struct connectdata *conn,
@@ -990,6 +1119,14 @@ Curl_SSLConnect(struct connectdata *conn,
return CURLE_OUT_OF_MEMORY;
}
#ifdef SSL_CTRL_SET_MSG_CALLBACK
if (data->set.fdebug) {
SSL_CTX_callback_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK,
ssl_tls_trace);
SSL_CTX_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, conn);
}
#endif
/* OpenSSL contains code to work-around lots of bugs and flaws in various
SSL-implementations. SSL_CTX_set_options() is used to enabled those
work-arounds. The man page for this option states that SSL_OP_ALL enables
@@ -1000,6 +1137,16 @@ Curl_SSLConnect(struct connectdata *conn,
*/
SSL_CTX_set_options(connssl->ctx, SSL_OP_ALL);
#if 0
/*
* Not sure it's needed to tell SSL_connect() that socket is
* non-blocking. It doesn't seem to care, but just return with
* SSL_ERROR_WANT_x.
*/
if (data->state.used_interface == Curl_if_multi)
SSL_CTX_ctrl(connssl->ctx, BIO_C_SET_NBIO, 1, NULL);
#endif
if(data->set.cert) {
if(!cert_stuff(conn,
connssl->ctx,
@@ -1104,10 +1251,6 @@ Curl_SSLConnect(struct connectdata *conn,
/* Evaluate in milliseconds how much time that has passed */
has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start);
#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#endif
/* get the most strict timeout of the ones converted to milliseconds */
if(data->set.timeout &&
(data->set.timeout>data->set.connecttimeout))
@@ -1149,6 +1292,8 @@ Curl_SSLConnect(struct connectdata *conn,
unsigned long errdetail;
char error_buffer[120]; /* OpenSSL documents that this must be at least
120 bytes long. */
CURLcode rc;
const char *cert_problem = NULL;
errdetail = ERR_get_error(); /* Gets the earliest error code from the
thread's error queue and removes the
@@ -1160,16 +1305,34 @@ Curl_SSLConnect(struct connectdata *conn,
SSL routines:
SSL2_SET_CERTIFICATE:
certificate verify failed */
/* fall-through */
case 0x14090086:
/* 14090086:
SSL routines:
SSL3_GET_SERVER_CERTIFICATE:
certificate verify failed */
failf(data,
"SSL certificate problem, verify that the CA cert is OK");
return CURLE_SSL_CACERT;
cert_problem = "SSL certificate problem, verify that the CA cert is"
" OK. Details:\n";
rc = CURLE_SSL_CACERT;
break;
default:
rc = CURLE_SSL_CONNECT_ERROR;
break;
}
/* detail is already set to the SSL error above */
/* If we e.g. use SSLv2 request-method and the server doesn't like us
* (RST connection etc.), OpenSSL gives no explanation whatsoever and
* the SO_ERROR is also lost.
*/
if (CURLE_SSL_CONNECT_ERROR == rc && errdetail == 0) {
failf(data, "Unknown SSL protocol error in connection to %s:%d ",
conn->host.name, conn->port);
return rc;
}
/* Could be a CERT problem */
#ifdef HAVE_ERR_ERROR_STRING_N
/* OpenSSL 0.9.6 and later has a function named
ERRO_error_string_n() that takes the size of the buffer as a
@@ -1178,10 +1341,8 @@ Curl_SSLConnect(struct connectdata *conn,
#else
ERR_error_string(errdetail, error_buffer);
#endif
failf(data, "SSL: %s", error_buffer);
return CURLE_SSL_CONNECT_ERROR;
}
failf(data, "%s%s", cert_problem ? cert_problem : "", error_buffer);
return rc;
}
}
else
@@ -1277,18 +1438,18 @@ Curl_SSLConnect(struct connectdata *conn,
/* We could do all sorts of certificate verification stuff here before
deallocating the certificate. */
data->set.ssl.certverifyresult=SSL_get_verify_result(connssl->handle);
err = data->set.ssl.certverifyresult=SSL_get_verify_result(connssl->handle);
if(data->set.ssl.certverifyresult != X509_V_OK) {
if(data->set.ssl.verifypeer) {
/* We probably never reach this, because SSL_connect() will fail
and we return earlyer if verifypeer is set? */
failf(data, "SSL certificate verify result: %d",
data->set.ssl.certverifyresult);
failf(data, "SSL certificate verify result: %s (%d)",
X509_verify_cert_error_string(err), err);
retcode = CURLE_SSL_PEER_CERTIFICATE;
}
else
infof(data, "SSL certificate verify result: %d, continuing anyway.\n",
data->set.ssl.certverifyresult);
infof(data, "SSL certificate verify result: %s (%d), continuing anyway.\n",
X509_verify_cert_error_string(err), err);
}
else
infof(data, "SSL certificate verify ok.\n");

View File

@@ -78,6 +78,25 @@ int curl_strnequal(const char *first, const char *second, size_t max)
#endif
}
/*
* Curl_strcasestr() finds the first occurrence of the substring needle in the
* string haystack. The terminating `\0' characters are not compared. The
* matching is done CASE INSENSITIVE, which thus is the difference between
* this and strstr().
*/
char *Curl_strcasestr(const char *haystack, const char *needle)
{
size_t nlen = strlen(needle);
size_t hlen = strlen(haystack);
while(hlen-- >= nlen) {
if(curl_strnequal(haystack, needle, nlen))
return (char *)haystack;
haystack++;
}
return NULL;
}
#ifndef HAVE_STRLCAT
/*
* The strlcat() function appends the NUL-terminated string src to the end

View File

@@ -36,6 +36,9 @@ int curl_strnequal(const char *first, const char *second, size_t max);
argument is zero-byte terminated */
#define checkprefix(a,b) strnequal(a,b,strlen(a))
/* case insensitive strstr() */
char *Curl_strcasestr(const char *haystack, const char *needle);
#ifndef HAVE_STRLCAT
#define strlcat(x,y,z) Curl_strlcat(x,y,z)
size_t Curl_strlcat(char *dst, const char *src, size_t siz);

View File

@@ -37,7 +37,8 @@
#endif
#ifndef HAVE_GETTIMEOFDAY
#if !defined(_WINSOCKAPI_) && !defined(__MINGW32__) && !defined(_AMIGASF)
#if !defined(_WINSOCKAPI_) && !defined(__MINGW32__) && !defined(_AMIGASF) && \
!defined(__LCC__)
struct timeval {
long tv_sec;
long tv_usec;

View File

@@ -125,8 +125,9 @@ static struct timeval notimeout={0,0};
* This function will call the read callback to fill our buffer with data
* to upload.
*/
int Curl_fillreadbuffer(struct connectdata *conn, int bytes)
CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
{
struct SessionHandle *data = conn->data;
int buffersize = bytes;
int nread;
@@ -139,6 +140,11 @@ int Curl_fillreadbuffer(struct connectdata *conn, int bytes)
nread = conn->fread(conn->upload_fromhere, 1,
buffersize, conn->fread_in);
if(nread == CURL_READFUNC_ABORT) {
failf(data, "operation aborted by callback\n");
return CURLE_ABORTED_BY_CALLBACK;
}
if(!conn->bits.forbidchunk && conn->bits.upload_chunky) {
/* if chunked Transfer-Encoding */
char hexbuffer[11];
@@ -161,7 +167,10 @@ int Curl_fillreadbuffer(struct connectdata *conn, int bytes)
nread+=2; /* for the added CRLF */
}
return nread;
*nreadp = nread;
return CURLE_OK;
}
/*
@@ -187,6 +196,7 @@ checkhttpprefix(struct SessionHandle *data,
return FALSE;
}
/*
* Curl_readwrite() is the low-level function to be called when data is to
* be read and written to/from the connection.
@@ -442,6 +452,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
FD_ZERO(&k->wkeepfd);
}
#ifndef CURL_DISABLE_HTTP
/*
* When all the headers have been parsed, see if we should give
* up and return an error.
@@ -451,6 +462,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
k->httpcode);
return CURLE_HTTP_RETURNED_ERROR;
}
#endif /* CURL_DISABLE_HTTP */
/* now, only output this if the header AND body are requested:
*/
@@ -488,7 +500,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
return CURLE_HTTP_RANGE_ERROR;
}
}
#ifndef CURL_DISABLE_HTTP
if(!stop_reading) {
/* Curl_http_auth_act() checks what authentication methods
* that are available and decides which one (if any) to
@@ -498,6 +510,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if(result)
return result;
}
#endif /* CURL_DISABLE_HTTP */
if(!k->header) {
/*
@@ -696,6 +709,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
data->info.contenttype[len] = 0; /* zero terminate */
}
}
#ifndef CURL_DISABLE_HTTP
else if((k->httpversion == 10) &&
conn->bits.httpproxy &&
Curl_compareheader(k->p,
@@ -864,6 +878,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
}
#endif
}
#endif /* CURL_DISABLE_HTTP */
/*
* End of header-checks. Write them to the client.
@@ -875,7 +890,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN,
k->p, k->hbuflen);
k->p, k->hbuflen, conn->host.dispname);
result = Curl_client_write(data, writetype, k->p, k->hbuflen);
if(result)
@@ -962,14 +977,17 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if(data->set.verbose) {
if(k->badheader) {
Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
k->hbuflen);
k->hbuflen, conn->host.dispname);
if(k->badheader == HEADER_PARTHEADER)
Curl_debug(data, CURLINFO_DATA_IN, k->str, nread);
Curl_debug(data, CURLINFO_DATA_IN, k->str, nread,
conn->host.dispname);
}
else
Curl_debug(data, CURLINFO_DATA_IN, k->str, nread);
Curl_debug(data, CURLINFO_DATA_IN, k->str, nread,
conn->host.dispname);
}
#ifndef CURL_DISABLE_HTTP
if(conn->bits.chunk) {
/*
* Bless me father for I have sinned. Here comes a chunked
@@ -999,6 +1017,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
}
/* If it returned OK, we just keep going */
}
#endif /* CURL_DISABLE_HTTP */
if((-1 != conn->maxdownload) &&
(k->bytecount + nread >= conn->maxdownload)) {
@@ -1107,6 +1126,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if(!k->upload_done) {
/* HTTP pollution, this should be written nicer to become more
protocol agnostic. */
int fillcount;
if(k->wait100_after_headers &&
(conn->proto.http->sending == HTTPSEND_BODY)) {
@@ -1123,7 +1143,11 @@ CURLcode Curl_readwrite(struct connectdata *conn,
break;
}
nread = Curl_fillreadbuffer(conn, BUFSIZE);
result = Curl_fillreadbuffer(conn, BUFSIZE, &fillcount);
if(result)
return result;
nread = (ssize_t)fillcount;
}
else
nread = 0; /* we're done uploading/reading */
@@ -1187,7 +1211,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if(data->set.verbose)
/* show the data before we change the pointer upload_fromhere */
Curl_debug(data, CURLINFO_DATA_OUT, conn->upload_fromhere,
bytes_written);
bytes_written, conn->host.dispname);
if(conn->upload_present != bytes_written) {
/* we only wrote a part of the buffer (if anything), deal with it! */
@@ -1302,6 +1326,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
return CURLE_OK;
}
/*
* Curl_readwrite_init() inits the readwrite session.
*/
@@ -1517,6 +1542,7 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
data->state.authhost.want = data->set.httpauth;
data->state.authproxy.want = data->set.proxyauth;
#ifndef CURL_DISABLE_HTTP
/* If there was a list of cookie files to read and we haven't done it before,
do it now! */
if(data->change.cookielist) {
@@ -1533,7 +1559,7 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
curl_slist_free_all(data->change.cookielist); /* clean up list */
data->change.cookielist = NULL; /* don't do this again! */
}
#endif /* CURL_DISABLE_HTTP */
/* Allow data->set.use_port to set which port to use. This needs to be
@@ -1919,6 +1945,50 @@ CURLcode Curl_follow(struct SessionHandle *data,
return CURLE_OK;
}
static CURLcode
Curl_connect_host(struct SessionHandle *data,
struct connectdata **conn)
{
CURLcode res = CURLE_OK;
int urlchanged = FALSE;
do {
bool async;
Curl_pgrsTime(data, TIMER_STARTSINGLE);
data->change.url_changed = FALSE;
res = Curl_connect(data, conn, &async);
if((CURLE_OK == res) && async) {
/* Now, if async is TRUE here, we need to wait for the name
to resolve */
res = Curl_wait_for_resolv(*conn, NULL);
if(CURLE_OK == res)
/* Resolved, continue with the connection */
res = Curl_async_resolved(*conn);
}
if(res)
break;
/* If a callback (or something) has altered the URL we should use within
the Curl_connect(), we detect it here and act as if we are redirected
to the new URL */
urlchanged = data->change.url_changed;
if ((CURLE_OK == res) && urlchanged) {
res = Curl_done(conn, res);
if(CURLE_OK == res) {
char *gotourl = strdup(data->change.url);
res = Curl_follow(data, gotourl);
if(res)
free(gotourl);
}
}
} while (urlchanged && res == CURLE_OK);
return res;
}
/*
* Curl_perform() is the internal high-level function that gets called by the
* external curl_easy_perform() function. It inits, performs and cleans up a
@@ -1945,43 +2015,21 @@ CURLcode Curl_perform(struct SessionHandle *data)
*/
do {
int urlchanged = FALSE;
do {
bool async;
Curl_pgrsTime(data, TIMER_STARTSINGLE);
data->change.url_changed = FALSE;
res = Curl_connect(data, &conn, &async);
if((CURLE_OK == res) && async) {
/* Now, if async is TRUE here, we need to wait for the name
to resolve */
res = Curl_wait_for_resolv(conn, NULL);
if(CURLE_OK == res)
/* Resolved, continue with the connection */
res = Curl_async_resolved(conn);
}
if(res)
break;
/* If a callback (or something) has altered the URL we should use within
the Curl_connect(), we detect it here and act as if we are redirected
to the new URL */
urlchanged = data->change.url_changed;
if ((CURLE_OK == res) && urlchanged) {
res = Curl_done(&conn, res);
if(CURLE_OK == res) {
char *gotourl = strdup(data->change.url);
res = Curl_follow(data, gotourl);
if(res)
free(gotourl);
}
}
} while (urlchanged && res == CURLE_OK);
res = Curl_connect_host(data, &conn); /* primary connection */
if(res == CURLE_OK) {
if (data->set.source_host) /* 3rd party transfer */
res = Curl_pretransfersec(conn);
else
conn->sec_conn = NULL;
}
if(res == CURLE_OK) {
res = Curl_do(&conn);
if(res == CURLE_OK) {
/* for non 3rd party transfer only */
if(res == CURLE_OK && !data->set.source_host) {
res = Transfer(conn); /* now fetch that URL please */
if(res == CURLE_OK) {
@@ -2099,3 +2147,37 @@ Curl_Transfer(struct connectdata *c_conn, /* connection data */
return CURLE_OK;
}
/*
* Curl_pretransfersec() prepares the secondary connection (used for 3rd party
* FTP transfers).
*/
CURLcode Curl_pretransfersec(struct connectdata *conn)
{
CURLcode status = CURLE_OK;
struct SessionHandle *data = conn->data;
struct connectdata *sec_conn = NULL; /* secondary connection */
/* update data with source host options */
char *url = aprintf( "%s://%s/", conn->protostr, data->set.source_host);
if(!url)
return CURLE_OUT_OF_MEMORY;
if(data->change.url_alloc)
free(data->change.url);
data->change.url_alloc = TRUE;
data->change.url = url;
data->set.ftpport = data->set.source_port;
data->set.userpwd = data->set.source_userpwd;
/* secondary connection */
status = Curl_connect_host(data, &sec_conn);
if(CURLE_OK == status) {
sec_conn->data = data;
conn->sec_conn = sec_conn;
}
return status;
}

View File

@@ -24,6 +24,7 @@
***************************************************************************/
CURLcode Curl_perform(struct SessionHandle *data);
CURLcode Curl_pretransfer(struct SessionHandle *data);
CURLcode Curl_pretransfersec(struct connectdata *conn);
CURLcode Curl_posttransfer(struct SessionHandle *data);
CURLcode Curl_follow(struct SessionHandle *data, char *newurl);
CURLcode Curl_readwrite(struct connectdata *conn, bool *done);
@@ -34,7 +35,7 @@ void Curl_single_fdset(struct connectdata *conn,
int *max_fd);
CURLcode Curl_readwrite_init(struct connectdata *conn);
int Curl_fillreadbuffer(struct connectdata *conn, int bytes);
CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp);
/* This sets up a forthcoming transfer */
CURLcode

584
lib/url.c
View File

@@ -238,6 +238,8 @@ CURLcode Curl_close(struct SessionHandle *data)
Curl_cookie_cleanup(data->cookies);
}
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
Curl_digest_cleanup(data);
#endif
/* free the connection cache */
@@ -245,8 +247,6 @@ CURLcode Curl_close(struct SessionHandle *data)
Curl_safefree(data->info.contenttype);
Curl_digest_cleanup(data);
#ifdef USE_ARES
/* this destroys the channel and we cannot use it anymore after this */
ares_destroy(data->state.areschannel);
@@ -499,8 +499,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
data->set.http_fail_on_error = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_UPLOAD:
case CURLOPT_PUT:
/*
* We want to sent data to the remote host
* We want to sent data to the remote host. If this is HTTP, that equals
* using the PUT request.
*/
data->set.upload = va_arg(param, long)?TRUE:FALSE;
if(data->set.upload)
@@ -553,27 +555,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
*/
data->set.netrc_file = va_arg(param, char *);
break;
case CURLOPT_FOLLOWLOCATION:
/*
* Follow Location: header hints on a HTTP-server.
*/
data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_UNRESTRICTED_AUTH:
/*
* Send authentication (user+password) when following locations, even when
* hostname changed.
*/
data->set.http_disable_hostname_check_before_authentication =
va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_HTTP_VERSION:
/*
* This sets a requested HTTP version to be used. The value is one of
* the listed enums in curl/curl.h.
*/
data->set.httpversion = va_arg(param, long);
break;
case CURLOPT_TRANSFERTEXT:
/*
* This option was previously named 'FTPASCII'. Renamed to work with
@@ -583,14 +564,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
*/
data->set.ftp_ascii = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_PUT:
/*
* Use the HTTP PUT request to transfer data if this is TRUE. If this is
* FALSE, don't set the httpreq. We can't know what to revert it to!
*/
if(va_arg(param, long))
data->set.httpreq = HTTPREQ_PUT;
break;
case CURLOPT_TIMECONDITION:
/*
* Set HTTP time condition. This must be one of the defines in the
@@ -613,26 +586,135 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
data->set.ssl.version = va_arg(param, long);
break;
case CURLOPT_COOKIESESSION:
#ifndef CURL_DISABLE_HTTP
case CURLOPT_AUTOREFERER:
/*
* Set this option to TRUE to start a new "cookie session". It will
* prevent the forthcoming read-cookies-from-file actions to accept
* cookies that are marked as being session cookies, as they belong to a
* previous session.
*
* In the original Netscape cookie spec, "session cookies" are cookies
* with no expire date set. RFC2109 describes the same action if no
* 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
* a 'Discard' action that can enforce the discard even for cookies that
* have a Max-Age.
*
* We run mostly with the original cookie spec, as hardly anyone implements
* anything else.
* Switch on automatic referer that gets set if curl follows locations.
*/
data->set.cookiesession = (bool)va_arg(param, long);
data->set.http_auto_referer = va_arg(param, long)?1:0;
break;
case CURLOPT_ENCODING:
/*
* String to use at the value of Accept-Encoding header.
*
* If the encoding is set to "" we use an Accept-Encoding header that
* encompasses all the encodings we support.
* If the encoding is set to NULL we don't send an Accept-Encoding header
* and ignore an received Content-Encoding header.
*
*/
data->set.encoding = va_arg(param, char *);
if(data->set.encoding && !*data->set.encoding)
data->set.encoding = (char*)ALL_CONTENT_ENCODINGS;
break;
case CURLOPT_FOLLOWLOCATION:
/*
* Follow Location: header hints on a HTTP-server.
*/
data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_UNRESTRICTED_AUTH:
/*
* Send authentication (user+password) when following locations, even when
* hostname changed.
*/
data->set.http_disable_hostname_check_before_authentication =
va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_MAXREDIRS:
/*
* The maximum amount of hops you allow curl to follow Location:
* headers. This should mostly be used to detect never-ending loops.
*/
data->set.maxredirs = va_arg(param, long);
break;
case CURLOPT_POST:
/* Does this option serve a purpose anymore? Yes it does, when
CURLOPT_POSTFIELDS isn't used and the POST data is read off the
callback! */
if(va_arg(param, long))
data->set.httpreq = HTTPREQ_POST;
break;
case CURLOPT_POSTFIELDS:
/*
* A string with POST data. Makes curl HTTP POST.
*/
data->set.postfields = va_arg(param, char *);
if(data->set.postfields)
data->set.httpreq = HTTPREQ_POST;
break;
case CURLOPT_POSTFIELDSIZE:
/*
* The size of the POSTFIELD data to prevent libcurl to do strlen() to
* figure it out. Enables binary posts.
*/
data->set.postfieldsize = va_arg(param, long);
break;
case CURLOPT_POSTFIELDSIZE_LARGE:
/*
* The size of the POSTFIELD data to prevent libcurl to do strlen() to
* figure it out. Enables binary posts.
*/
data->set.postfieldsize = va_arg(param, curl_off_t);
break;
case CURLOPT_HTTPPOST:
/*
* Set to make us do HTTP POST
*/
data->set.httppost = va_arg(param, struct curl_httppost *);
if(data->set.httppost)
data->set.httpreq = HTTPREQ_POST_FORM;
break;
case CURLOPT_REFERER:
/*
* String to set in the HTTP Referer: field.
*/
if(data->change.referer_alloc) {
free(data->change.referer);
data->change.referer_alloc = FALSE;
}
data->set.set_referer = va_arg(param, char *);
data->change.referer = data->set.set_referer;
break;
case CURLOPT_USERAGENT:
/*
* String to use in the HTTP User-Agent field
*/
data->set.useragent = va_arg(param, char *);
break;
case CURLOPT_HTTPHEADER:
/*
* Set a list with HTTP headers to use (or replace internals with)
*/
data->set.headers = va_arg(param, struct curl_slist *);
break;
case CURLOPT_HTTP200ALIASES:
/*
* Set a list of aliases for HTTP 200 in response header
*/
data->set.http200aliases = va_arg(param, struct curl_slist *);
break;
case CURLOPT_COOKIE:
/*
* Cookie string to send to the remote server in the request.
*/
data->set.cookie = va_arg(param, char *);
break;
#ifndef CURL_DISABLE_HTTP
case CURLOPT_COOKIEFILE:
/*
* Set cookie file to read and parse. Can be used multiple times.
@@ -664,7 +746,131 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
data->cookies = Curl_cookie_init(data, NULL, data->cookies,
data->set.cookiesession);
break;
case CURLOPT_COOKIESESSION:
/*
* Set this option to TRUE to start a new "cookie session". It will
* prevent the forthcoming read-cookies-from-file actions to accept
* cookies that are marked as being session cookies, as they belong to a
* previous session.
*
* In the original Netscape cookie spec, "session cookies" are cookies
* with no expire date set. RFC2109 describes the same action if no
* 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
* a 'Discard' action that can enforce the discard even for cookies that
* have a Max-Age.
*
* We run mostly with the original cookie spec, as hardly anyone implements
* anything else.
*/
data->set.cookiesession = (bool)va_arg(param, long);
break;
case CURLOPT_HTTPGET:
/*
* Set to force us do HTTP GET
*/
if(va_arg(param, long)) {
data->set.httpreq = HTTPREQ_GET;
data->set.upload = FALSE; /* switch off upload */
}
break;
case CURLOPT_HTTP_VERSION:
/*
* This sets a requested HTTP version to be used. The value is one of
* the listed enums in curl/curl.h.
*/
data->set.httpversion = va_arg(param, long);
break;
case CURLOPT_HTTPPROXYTUNNEL:
/*
* Tunnel operations through the proxy instead of normal proxy use
*/
data->set.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_CUSTOMREQUEST:
/*
* Set a custom string to use as request
*/
data->set.customrequest = va_arg(param, char *);
/* we don't set
data->set.httpreq = HTTPREQ_CUSTOM;
here, we continue as if we were using the already set type
and this just changes the actual request keyword */
break;
case CURLOPT_PROXY:
/*
* Set proxy server:port to use as HTTP proxy.
*
* If the proxy is set to "" we explicitly say that we don't want to use a
* proxy (even though there might be environment variables saying so).
*
* Setting it to NULL, means no proxy but allows the environment variables
* to decide for us.
*/
if(data->change.proxy_alloc) {
/*
* The already set string is allocated, free that first
*/
data->change.proxy_alloc=FALSE;;
free(data->change.proxy);
}
data->set.set_proxy = va_arg(param, char *);
data->change.proxy = data->set.set_proxy;
break;
case CURLOPT_PROXYPORT:
/*
* Explicitly set HTTP proxy port number.
*/
data->set.proxyport = va_arg(param, long);
break;
case CURLOPT_HTTPAUTH:
/*
* Set HTTP Authentication type BITMASK.
*/
{
long auth = va_arg(param, long);
/* switch off bits we can't support */
#ifndef USE_SSLEAY
auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
#endif
#ifndef HAVE_GSSAPI
auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
#endif
if(!auth)
return CURLE_FAILED_INIT; /* no supported types left! */
data->set.httpauth = auth;
}
break;
case CURLOPT_PROXYAUTH:
/*
* Set HTTP Authentication type BITMASK.
*/
{
long auth = va_arg(param, long);
/* switch off bits we can't support */
#ifndef USE_SSLEAY
auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
#endif
#ifndef HAVE_GSSAPI
auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
#endif
if(!auth)
return CURLE_FAILED_INIT; /* no supported types left! */
data->set.proxyauth = auth;
}
break;
#endif /* CURL_DISABLE_HTTP */
case CURLOPT_WRITEHEADER:
/*
@@ -672,12 +878,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
*/
data->set.writeheader = (void *)va_arg(param, void *);
break;
case CURLOPT_COOKIE:
/*
* Cookie string to send to the remote server in the request.
*/
data->set.cookie = va_arg(param, char *);
break;
case CURLOPT_ERRORBUFFER:
/*
* Error buffer provided by the caller to get the human readable
@@ -707,42 +907,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_HTTPHEADER:
/*
* Set a list with HTTP headers to use (or replace internals with)
*/
data->set.headers = va_arg(param, struct curl_slist *);
break;
case CURLOPT_CUSTOMREQUEST:
/*
* Set a custom string to use as request
*/
data->set.customrequest = va_arg(param, char *);
/* we don't set
data->set.httpreq = HTTPREQ_CUSTOM;
here, we continue as if we were using the already set type
and this just changes the actual request keyword */
break;
case CURLOPT_HTTPPOST:
/*
* Set to make us do HTTP POST
*/
data->set.httppost = va_arg(param, struct curl_httppost *);
if(data->set.httppost)
data->set.httpreq = HTTPREQ_POST_FORM;
break;
case CURLOPT_HTTPGET:
/*
* Set to force us do HTTP GET
*/
if(va_arg(param, long)) {
data->set.httpreq = HTTPREQ_GET;
data->set.upload = FALSE; /* switch off upload */
}
break;
case CURLOPT_INFILE:
/*
* FILE pointer to read the file to be uploaded from. Or possibly
@@ -797,84 +961,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
*/
data->set.use_port = va_arg(param, long);
break;
case CURLOPT_POST:
/* Does this option serve a purpose anymore? Yes it does, when
CURLOPT_POSTFIELDS isn't used and the POST data is read off the
callback! */
if(va_arg(param, long))
data->set.httpreq = HTTPREQ_POST;
break;
case CURLOPT_POSTFIELDS:
/*
* A string with POST data. Makes curl HTTP POST.
*/
data->set.postfields = va_arg(param, char *);
if(data->set.postfields)
data->set.httpreq = HTTPREQ_POST;
break;
case CURLOPT_POSTFIELDSIZE:
/*
* The size of the POSTFIELD data to prevent libcurl to do strlen() to
* figure it out. Enables binary posts.
*/
data->set.postfieldsize = va_arg(param, long);
break;
case CURLOPT_POSTFIELDSIZE_LARGE:
/*
* The size of the POSTFIELD data to prevent libcurl to do strlen() to
* figure it out. Enables binary posts.
*/
data->set.postfieldsize = va_arg(param, curl_off_t);
break;
case CURLOPT_REFERER:
/*
* String to set in the HTTP Referer: field.
*/
if(data->change.referer_alloc) {
free(data->change.referer);
data->change.referer_alloc = FALSE;
}
data->set.set_referer = va_arg(param, char *);
data->change.referer = data->set.set_referer;
break;
case CURLOPT_AUTOREFERER:
/*
* Switch on automatic referer that gets set if curl follows locations.
*/
data->set.http_auto_referer = va_arg(param, long)?1:0;
break;
case CURLOPT_PROXY:
/*
* Set proxy server:port to use as HTTP proxy.
*
* If the proxy is set to "" we explicitly say that we don't want to use a
* proxy (even though there might be environment variables saying so).
*
* Setting it to NULL, means no proxy but allows the environment variables
* to decide for us.
*/
if(data->change.proxy_alloc) {
/*
* The already set string is allocated, free that first
*/
data->change.proxy_alloc=FALSE;;
free(data->change.proxy);
}
data->set.set_proxy = va_arg(param, char *);
data->change.proxy = data->set.set_proxy;
break;
case CURLOPT_HTTPPROXYTUNNEL:
/*
* Tunnel operations through the proxy instead of normal proxy use
*/
data->set.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_PROXYPORT:
/*
* Explicitly set HTTP proxy port number.
*/
data->set.proxyport = va_arg(param, long);
break;
case CURLOPT_TIMEOUT:
/*
* The maximum time you allow curl to use for a single transfer
@@ -888,73 +974,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
*/
data->set.connecttimeout = va_arg(param, long);
break;
case CURLOPT_MAXREDIRS:
/*
* The maximum amount of hops you allow curl to follow Location:
* headers. This should mostly be used to detect never-ending loops.
*/
data->set.maxredirs = va_arg(param, long);
break;
case CURLOPT_USERAGENT:
/*
* String to use in the HTTP User-Agent field
*/
data->set.useragent = va_arg(param, char *);
break;
case CURLOPT_ENCODING:
/*
* String to use at the value of Accept-Encoding header.
*
* If the encoding is set to "" we use an Accept-Encoding header that
* encompasses all the encodings we support.
* If the encoding is set to NULL we don't send an Accept-Encoding header
* and ignore an received Content-Encoding header.
*
*/
data->set.encoding = va_arg(param, char *);
if(data->set.encoding && !*data->set.encoding)
data->set.encoding = (char*)ALL_CONTENT_ENCODINGS;
break;
case CURLOPT_HTTPAUTH:
/*
* Set HTTP Authentication type BITMASK.
*/
{
long auth = va_arg(param, long);
/* switch off bits we can't support */
#ifndef USE_SSLEAY
auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
#endif
#ifndef HAVE_GSSAPI
auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
#endif
if(!auth)
return CURLE_FAILED_INIT; /* no supported types left! */
data->set.httpauth = auth;
}
break;
case CURLOPT_PROXYAUTH:
/*
* Set HTTP Authentication type BITMASK.
*/
{
long auth = va_arg(param, long);
/* switch off bits we can't support */
#ifndef USE_SSLEAY
auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
#endif
#ifndef HAVE_GSSAPI
auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
#endif
if(!auth)
return CURLE_FAILED_INIT; /* no supported types left! */
data->set.proxyauth = auth;
}
break;
case CURLOPT_USERPWD:
/*
@@ -1268,22 +1287,22 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
data->hostcache = data->share->hostcache;
}
#ifndef CURL_DISABLE_HTTP
if(data->share->cookies) {
/* use shared cookie list, first free own one if any */
if (data->cookies)
Curl_cookie_cleanup(data->cookies);
data->cookies = data->share->cookies;
}
#endif /* CURL_DISABLE_HTTP */
Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
}
#ifndef CURL_DISABLE_HTTP
/* check cookie list is set */
if(!data->cookies)
data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE );
#endif /* CURL_DISABLE_HTTP */
/* check for host cache not needed,
* it will be done by curl_easy_perform */
}
@@ -1303,13 +1322,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
data->set.private = va_arg(param, char *);
break;
case CURLOPT_HTTP200ALIASES:
/*
* Set a list of aliases for HTTP 200 in response header
*/
data->set.http200aliases = va_arg(param, struct curl_slist *);
break;
case CURLOPT_MAXFILESIZE:
/*
* Set the maximum size of a file to download.
@@ -1343,6 +1355,57 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
data->set.tcp_nodelay = (bool)va_arg(param, long);
break;
/*********** 3rd party transfer options ***********/
case CURLOPT_SOURCE_HOST:
/*
* Use SOURCE HOST
*/
data->set.source_host = va_arg(param, char *);
data->set.printhost = (data->set.source_host != NULL);
break;
case CURLOPT_SOURCE_PORT:
/*
* Use SOURCE PORT
*/
data->set.source_port = va_arg(param, char *);
break;
case CURLOPT_SOURCE_USERPWD:
/*
* Use SOURCE USER[:PASSWORD]
*/
data->set.source_userpwd = va_arg(param, char *);
break;
case CURLOPT_SOURCE_PATH:
/*
* Use SOURCE PATH
*/
data->set.source_path = va_arg(param, char *);
break;
case CURLOPT_PASV_HOST:
/*
* Indicates whether source or target host is passive
*/
data->set.pasvHost = va_arg(param, long)?CURL_SOURCE_PASV:CURL_TARGET_PASV;
break;
case CURLOPT_SOURCE_PREQUOTE:
/*
* List of RAW FTP commands to use before a transfer on the source host
*/
data->set.source_prequote = va_arg(param, struct curl_slist *);
break;
case CURLOPT_SOURCE_POSTQUOTE:
/*
* List of RAW FTP commands to use after a transfer on the source host
*/
data->set.source_postquote = va_arg(param, struct curl_slist *);
break;
default:
/* unknown tag and its companion, just ignore: */
return CURLE_FAILED_INIT; /* correct this */
@@ -1829,7 +1892,7 @@ static int handleSock5Proxy(const char *proxy_name,
}
#else
failf(conn->data,
"%s:%d has an internal error an needs to be fixed to work",
"%s:%d has an internal error and needs to be fixed to work",
__FILE__, __LINE__);
#endif
}
@@ -1877,6 +1940,11 @@ static CURLcode ConnectPlease(struct connectdata *conn,
{
CURLcode result;
Curl_ipconnect *addr;
struct SessionHandle *data = conn->data;
char *hostname = data->change.proxy?conn->proxy.name:conn->host.name;
infof(data, "About to connect() to %s port %d\n",
hostname, conn->port);
/*************************************************************
* Connect to server/proxy
@@ -1927,22 +1995,18 @@ static CURLcode ConnectPlease(struct connectdata *conn,
static void verboseconnect(struct connectdata *conn)
{
struct SessionHandle *data = conn->data;
const char *host=NULL;
char addrbuf[256];
char addrbuf[256] = "";
#ifdef ENABLE_IPV6
const Curl_ipconnect *addr = conn->serv_addr;
#else
const Curl_ipconnect *addr = &conn->serv_addr.sin_addr;
#endif
/* Get a printable version of the network address. */
#ifdef ENABLE_IPV6
struct addrinfo *ai = conn->serv_addr;
host = Curl_printable_address(ai->ai_family, ai->ai_addr,
addrbuf, sizeof(addrbuf));
#else
struct in_addr in;
(void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr));
host = Curl_inet_ntop(AF_INET, &in, addrbuf, sizeof(addrbuf));
#endif
Curl_printable_address(addr, addrbuf, sizeof(addrbuf));
infof(data, "Connected to %s (%s) port %d\n",
conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname,
host?host:"", conn->port);
conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname,
addrbuf[0] ? addrbuf : "??", conn->port);
}
/*

View File

@@ -185,6 +185,12 @@ typedef enum {
NTLMSTATE_LAST
} curlntlm;
/* for 3rd party transfers to decide which side that issues PASV */
typedef enum {
CURL_TARGET_PASV,
CURL_SOURCE_PASV
} curl_pasv_side;
/* Struct used for NTLM challenge-response authentication */
struct ntlmdata {
curlntlm state;
@@ -313,6 +319,9 @@ struct ConnectBits {
This is implicit when SSL-protocols are used through
proxies, but can also be enabled explicitly by
apps */
bool authprobe; /* set TRUE when this transfer is done to probe for auth
types, as when asking for "any" type when speaking
HTTP */
};
struct hostname {
@@ -329,16 +338,16 @@ struct hostname {
*/
struct Curl_transfer_keeper {
curl_off_t bytecount; /* total number of bytes read */
int writebytecount; /* number of bytes written */
curl_off_t bytecount; /* total number of bytes read */
curl_off_t writebytecount; /* number of bytes written */
struct timeval start; /* transfer started at this time */
struct timeval now; /* current time */
bool header; /* incoming data has HTTP header */
enum {
HEADER_NORMAL, /* no bad header at all */
HEADER_PARTHEADER, /* part of the chunk is a bad header, the rest is
normal data */
HEADER_ALLBAD /* all was believed to be header */
HEADER_NORMAL, /* no bad header at all */
HEADER_PARTHEADER, /* part of the chunk is a bad header, the rest
is normal data */
HEADER_ALLBAD /* all was believed to be header */
} badheader; /* the header was deemed bad and will be
written as body */
int headerline; /* counts header lines to better track the
@@ -350,7 +359,7 @@ struct Curl_transfer_keeper {
char *end_ptr; /* within buf */
char *p; /* within headerbuff */
bool content_range; /* set TRUE if Content-Range: was found */
curl_off_t offset; /* possible resume offset read from the
curl_off_t offset; /* possible resume offset read from the
Content-Range: header */
int httpcode; /* error code from the 'HTTP/1.? XXX' line */
int httpversion; /* the HTTP version*10 */
@@ -374,7 +383,6 @@ struct Curl_transfer_keeper {
z_stream z; /* State structure for zlib. */
#endif
/* for the low speed checks: */
time_t timeofdoc;
long bodywrites;
@@ -601,6 +609,8 @@ struct connectdata {
/* data used for the asynch name resolve callback */
struct Curl_async async;
#endif
struct connectdata *sec_conn; /* secondary connection for 3rd party
transfer */
};
/* The end of connectdata. */
@@ -845,7 +855,11 @@ struct UserDefined {
bool crlf; /* convert crlf on ftp upload(?) */
struct curl_slist *quote; /* after connection is established */
struct curl_slist *postquote; /* after the transfer */
struct curl_slist *prequote; /* before the transfer, after type (Wesley Laxton)*/
struct curl_slist *prequote; /* before the transfer, after type */
struct curl_slist *source_prequote; /* in 3rd party transfer mode - before
the transfer on source host */
struct curl_slist *source_postquote; /* in 3rd party transfer mode - after
the transfer on source host */
struct curl_slist *telnet_options; /* linked list of telnet options */
curl_TimeCond timecondition; /* kind of time/date comparison */
time_t timevalue; /* what time to compare with */
@@ -874,10 +888,17 @@ struct UserDefined {
curl_off_t max_filesize; /* Maximum file size to download */
char *source_host; /* for 3rd party transfer */
char *source_port; /* for 3rd party transfer */
char *source_userpwd; /* for 3rd party transfer */
char *source_path; /* for 3rd party transfer */
curl_pasv_side pasvHost; /* for 3rd party transfer indicates passive host */
/* Here follows boolean settings that define how to behave during
this session. They are STATIC, set by libcurl users or at least initially
and they don't change during operations. */
bool printhost; /* printing host name in debug info */
bool get_filetime;
bool tunnel_thru_httpproxy;
bool ftp_append;

View File

@@ -1,7 +1,35 @@
# fetch libcurl version number from input file and write them to STDOUT
# ***************************************************************************
# * _ _ ____ _
# * Project ___| | | | _ \| |
# * / __| | | | |_) | |
# * | (__| |_| | _ <| |___
# * \___|\___/|_| \_\_____|
# *
# * Copyright (C) 1998 - 2004, 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.
# *
# * $Id$
# ***************************************************************************
# awk script which fetches libcurl version number and string from input file
# and writes them to STDOUT. Here you can get an awk version for Win32:
# http://www.gknw.com/development/prgtools/awk.zip
#
BEGIN {
while ((getline < ARGV[1]) > 0) {
if (match ($0, /^#define LIBCURL_VERSION_MAJOR [^"]+/)) {
if (match ($0, /^#define LIBCURL_VERSION "[^"]+"/)) {
libcurl_ver_str = substr($3, 2, length($3)-2);
}
else if (match ($0, /^#define LIBCURL_VERSION_MAJOR [^"]+/)) {
libcurl_ver_major = substr($3, 1, length($3));
}
else if (match ($0, /^#define LIBCURL_VERSION_MINOR [^"]+/)) {
@@ -12,9 +40,6 @@ BEGIN {
}
}
libcurl_ver = libcurl_ver_major "," libcurl_ver_minor "," libcurl_ver_patch;
libcurl_ver_str = libcurl_ver_major "." libcurl_ver_minor "." libcurl_ver_patch;
print "LIBCURL_VERSION = " libcurl_ver "";
print "LIBCURL_VERSION_STR = " libcurl_ver_str "";
}

View File

@@ -1,6 +1,7 @@
/* MSK, 02/05/04, Hand edited for trail build on Alpha V7.3, DEC C 6.5-003 */
/* MSK, 03/09/04, Seems to work for all platforms I've built on so far. */
/* Added HAVE_SYS_IOCTL_H, IOCTL_3_ARGS and SIZEOF_CURL_OFF_T defines */
/* MSK, 06/04/04, Added HAVE_INET_NTOP */
/* Define cpu-machine-OS */
#ifdef __ALPHA
@@ -258,3 +259,6 @@
#else
#define SIZEOF_CURL_OFF_T 8
#endif
/* Somewhere around 7.12.0 HAVE_INET_NTOP was introduced. */
#define HAVE_INET_NTOP 1

View File

@@ -1,6 +1,7 @@
/* MSK, 02/05/04, Hand edited for trail build on Alpha V7.3, DEC C 6.5-003 */
/* MSK, 03/09/04, Seems to work for all platforms I've built on so far. */
/* Added HAVE_SYS_IOCTL_H, IOCTL_3_ARGS and SIZEOF_CURL_OFF_T defines */
/* MSK, 06/04/04, Added HAVE_INET_NTOP */
/* Define cpu-machine-OS */
#ifdef __ALPHA
@@ -258,3 +259,6 @@
#else
#define SIZEOF_CURL_OFF_T 8
#endif
/* Somewhere around 7.12.0 HAVE_INET_NTOP was introduced. */
#define HAVE_INET_NTOP 1

View File

@@ -7,9 +7,9 @@
;; First comes a setup that is ideal when you are only working with curl. Just
;; select the next few lines, paste it into your .emacs and change the path to
;; the tools folder. (If you are using more than one style. Look further down
;; the this file.)
;; this file.)
(load-file "<YOUR-PATH-TO-CURL>/tools/curl-style.el")
(load-file "<YOUR-PATH-TO-CURL>/curl-style.el")
(add-hook 'c-mode-common-hook 'curl-c-mode-common-hook)
;; If you are using more than one style in maybe more than one project the

View File

@@ -8,11 +8,13 @@
#################################################################
# Edit the path below to point to the base of your Novell NDK.
BASE = c:/novell
INSTDIR = s:/libcurl
ifndef NDKBASE
NDKBASE = c:/novell
endif
INSTDIR = ..\curl-$(LIBCURL_VERSION_STR)-bin-nw
# Edit the path below to point to the base of your Zlib sources.
ZLIB_PATH = ../../../cw/zlib-src-1.1.4
#ZLIB_PATH = ../../zlib-1.2.1
# Edit the vars below to change NLM target settings.
TARGET = curl
@@ -24,6 +26,8 @@ STACK = 64000
SCREEN = $(TARGET) commandline utility
MODULES = libcurl.nlm
IMPORTS = @../lib/libcurl.imp
# Comment the line below if you dont want to load protected automatically.
LDRING = 3
# Edit the var below to point to your lib architecture.
ifndef LIBARCH
@@ -42,7 +46,7 @@ else
OBJDIR = debug
endif
# Include the version info retrieved from jk_version.h
# Include the version info retrieved from curlver.h
-include $(OBJDIR)/version.inc
# The following line defines your compiler.
@@ -51,52 +55,51 @@ ifdef METROWERKS
else
CC = gcc
endif
CP = cp -afv
# RM = rm -f
# CP = cp -fv
# if you want to mark the target as MTSAFE you will need a tool for
# generating the xdc data for the linker; here's a minimal tool:
# http://www.gknw.de/development/prgtools/mkxdc.zip
# http://www.gknw.com/development/prgtools/mkxdc.zip
MPKXDC = mkxdc
# Global flags for all compilers
CFLAGS = $(OPT) -D$(DB) -DNETWARE -nostdinc
CFLAGS += -DUSE_MANUAL
#CFLAGS += -DHAVE_LIBZ
ifeq ($(CC),mwccnlm)
LD = mwldnlm
LDFLAGS = -nostdlib $(PRELUDE) $(OBJDIR)/*.o -o $(OBJDIR)/$(TARGET).nlm -commandfile
CFLAGS += -gccinc -inline off -opt nointrinsics
CFLAGS += -gccinc -inline off -opt nointrinsics -proc 586
CFLAGS += -relax_pointers
#CFLAGS += -w on
ifeq ($(LIBARCH),LIBC)
PRELUDE = $(SDK_LIBC)/imports/libcpre.o
CFLAGS += -align 4 -inst mmx -proc 686
CFLAGS += -align 4
CFLAGS += -D_POSIX_SOURCE
# CFLAGS += -D__ANSIC__
else
PRELUDE = "$(METROWERKS)/Novell Support/libraries/runtime/prelude.obj"
# CFLAGS += -include "$(METROWERKS)/Novell Support/headers/nlm_prefix.h"
CFLAGS += -align 1 -proc 586
CFLAGS += -align 1
endif
else
LD = nlmconv
LDFLAGS = -T
CFLAGS += -fno-builtin -fpack-struct -fpcc-struct-return
CFLAGS += -Wall #-Wno-main # -pedantic
CFLAGS += -Wall # -pedantic
ifeq ($(LIBARCH),LIBC)
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
CFLAGS += -D_POSIX_SOURCE
# CFLAGS += -D__ANSIC__
else
PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o
CFLAGS += -include $(BASE)/nlmconv/genlm.h
CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h
endif
endif
LDLIBS =
NDK_ROOT = $(BASE)/ndk
NDK_ROOT = $(NDKBASE)/ndk
SDK_CLIB = $(NDK_ROOT)/nwsdk
SDK_LIBC = $(NDK_ROOT)/libc
SDK_LDAP = $(NDK_ROOT)/cldapsdk/netware
@@ -104,26 +107,38 @@ CURL_INC = ../include
CURL_LIB = ../lib
INCLUDES = -I$(CURL_INC) -I$(CURL_LIB)
INCLUDES += -I$(ZLIB_PATH)
ifdef ZLIB_PATH
INCLUDES += -I$(ZLIB_PATH)
CFLAGS += -DHAVE_ZLIB_H -DHAVE_LIBZ
IMPORTS+ = @$(ZLIB_PATH)/nw/zlib.imp
MODULES+ = libz.nlm
endif
ifeq ($(LIBARCH),LIBC)
INCLUDES += -I$(SDK_LIBC)/include -I$(SDK_LIBC)/include/nks
INCLUDES += -I$(SDK_LIBC)/include/winsock
INCLUDES += -I$(SDK_LDAP)/libc/inc
# INCLUDES += -I$(SDK_LDAP)/libc/inc
else
INCLUDES += -I$(SDK_CLIB)/include/nlm -I$(SDK_CLIB)/include
INCLUDES += -I$(SDK_LDAP)/clib/inc
# INCLUDES += -I$(SDK_LDAP)/clib/inc
CFLAGS += -DNETDB_USE_INTERNET
endif
CFLAGS += $(INCLUDES)
ifeq ($(MTSAFE),YES)
XDCOPT = -n
endif
ifeq ($(MTSAFE),NO)
XDCOPT = -u
endif
ifdef XDCOPT
XDCDATA = $(OBJDIR)/$(TARGET).xdc
endif
ifeq ($(OSTYPE),linux)
DL = '
-include $(BASE)/nlmconv/ncpfs.inc
#-include $(NDKBASE)/nlmconv/ncpfs.inc
endif
OBJS = \
@@ -132,31 +147,34 @@ OBJS = \
$(OBJDIR)/urlglob.o \
$(OBJDIR)/writeout.o \
$(OBJDIR)/getpass.o \
$(OBJDIR)/homedir.o
$(OBJDIR)/homedir.o \
$(OBJDIR)/timeval.o
vpath %.c ../lib
all: $(OBJDIR) $(OBJDIR)/version.inc $(OBJDIR)/$(TARGET).nlm
$(OBJDIR)/%.o: %.c
@echo Compiling $<
@$(CC) $(CFLAGS) -c $< -o $@
# @echo Compiling $<
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR)/version.inc: $(CURL_INC)/curl/curl.h $(OBJDIR)
$(OBJDIR)/version.inc: $(CURL_INC)/curl/curlver.h $(OBJDIR)
@echo Creating $@
@awk -f ../packages/netware/get_ver.awk $< > $@
@awk -f ../packages/NetWare/get_ver.awk $< > $@
dist: all
-$(RM) $(OBJDIR)/*.o $(OBJDIR)/$(TARGET).map $(OBJDIR)/$(TARGET).ncv
-$(RM) $(OBJDIR)/$(TARGET).def $(OBJDIR)/version.inc $(XDCDATA)
# -$(CP) ../changes.txt $(OBJDIR)/
install: all
@[ -d $(INSTDIR) ] || mkdir $(INSTDIR)
install: $(INSTDIR) all
@$(CP) $(TARGET).nlm $(INSTDIR)
clean:
-$(RM) -r $(OBJDIR)
$(INSTDIR):
@mkdir $(INSTDIR)
$(OBJDIR):
@mkdir $(OBJDIR)
@@ -195,6 +213,12 @@ endif
ifdef XDCDATA
@echo $(DL)xdcdata $(XDCDATA)$(DL) >> $@
endif
ifeq ($(LDRING),0)
@echo $(DL)flag_on 16$(DL) >> $@
endif
ifeq ($(LDRING),3)
@echo $(DL)flag_on 512$(DL) >> $@
endif
ifeq ($(LIBARCH),CLIB)
@echo $(DL)start _Prelude$(DL) >> $@
@echo $(DL)exit _Stop$(DL) >> $@
@@ -202,25 +226,21 @@ ifeq ($(LIBARCH),CLIB)
@echo $(DL)import @$(SDK_CLIB)/imports/threads.imp$(DL) >> $@
@echo $(DL)import @$(SDK_CLIB)/imports/nlmlib.imp$(DL) >> $@
@echo $(DL)import @$(SDK_CLIB)/imports/socklib.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapsdk.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapssl.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapx.imp$(DL) >> $@
# @echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapsdk.imp$(DL) >> $@
# @echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapssl.imp$(DL) >> $@
# @echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapx.imp$(DL) >> $@
@echo $(DL)module clib$(DL) >> $@
else
ifeq ($(LD),nlmconv)
@echo $(DL)flag_on 64$(DL) >> $@
else
@echo $(DL)autounload$(DL) >> $@
endif
@echo $(DL)pseudopreemption$(DL) >> $@
@echo $(DL)start _LibCPrelude$(DL) >> $@
@echo $(DL)exit _LibCPostlude$(DL) >> $@
@echo $(DL)check _LibCCheckUnload$(DL) >> $@
@echo $(DL)import @$(SDK_LIBC)/imports/libc.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LIBC)/imports/netware.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapsdk.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapssl.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapx.imp$(DL) >> $@
# @echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapsdk.imp$(DL) >> $@
# @echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapssl.imp$(DL) >> $@
# @echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapx.imp$(DL) >> $@
@echo $(DL)module libc$(DL) >> $@
endif
ifdef MODULES
@@ -238,3 +258,8 @@ ifeq ($(LD),nlmconv)
@echo $(DL)output $(TARGET).nlm$(DL) >> $@
endif
hugehelp.c: hugehelp.c.cvs
@echo Creating $@
@$(CP) $< $@

View File

@@ -185,10 +185,6 @@
/* Define to 1 if you have the `ssl' library (-lssl). */
#undef HAVE_LIBSSL
/* If zlib is available */
#undef HAVE_LIBZ
//#define HAVE_LIBZ 1
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
@@ -399,14 +395,17 @@
/* Define to 1 if you have the <x509.h> header file. */
#undef HAVE_X509_H
/* if you have the zlib.h header file */
#define HAVE_ZLIB_H 1
/* if you have the zlib.h header file - set from Makefile */
/* #undef HAVE_ZLIB_H */
/* If zlib is available - set from Makefile */
/* #undef HAVE_LIBZ */
/* need REENTRANT defined */
#undef NEED_REENTRANT
/* cpu-machine-OS */
#define OS "i386-pc-NetWare"
#define OS "i586-pc-NetWare"
/* Name of package */
#undef PACKAGE

View File

@@ -45,12 +45,22 @@
#include descrip
#include starlet
#include iodef
#include iosbdef
/* #include iosbdef */
char *getpass_r(const char *prompt, char *buffer, size_t buflen)
{
long sts;
short chan;
struct _iosb iosb;
/* MSK, 23-JAN-2004, iosbdef.h wasn't in VAX V7.2 or CC 6.4 */
/* distribution so I created this. May revert back later to */
/* struct _iosb iosb; */
struct _iosb
{
short int iosb$w_status; /* status */
short int iosb$w_bcnt; /* byte count */
int unused; /* unused */
} iosb;
$DESCRIPTOR(ttdesc, "TT");
buffer[0]='\0';

View File

@@ -2572,7 +2572,6 @@ int my_trace(CURL *handle, curl_infotype type,
struct Configurable *config = (struct Configurable *)userp;
FILE *output=config->errors;
const char *text;
(void)handle; /* prevent compiler warning */
if(!config->trace_stream) {
@@ -2606,6 +2605,12 @@ int my_trace(CURL *handle, curl_infotype type,
case CURLINFO_DATA_IN:
text = "<= Recv data";
break;
case CURLINFO_SSL_DATA_IN:
text = "<= Recv SSL data";
break;
case CURLINFO_SSL_DATA_OUT:
text = "<= Send SSL data";
break;
}
dump(text, output, data, size, config->trace_ascii);
@@ -2904,7 +2909,7 @@ operate(struct Configurable *config, int argc, char *argv[])
}
/* loop through the list of given URLs */
while(urlnode && !res) {
while(urlnode) {
char *dourl;
/* get the full URL (it might be NULL) */

View File

@@ -1,304 +0,0 @@
#!/bin/sh
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2004, 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.
#
# $Id$
###########################################################################
###########################
# What is This Script?
###########################
# testcurl.sh is the master script to use for automatic testing of CVS-curl.
# This is written for the purpose of being run from a crontab job or similar
# at a regular interval. The output will be suitable to be mailed automaticly
# to "curl-autocompile@haxx.se" to be dealt with automatically. The most
# current build status (with a resonable backlog) will be published on the
# curl site, at http://curl.haxx.se/auto/
# USAGE:
# testcurl.sh [curl-daily-name] > output
# Updated:
# v1.1 6-Nov-03 - to take an optional parameter, the name of a daily-build
# directory. If present, build from that directory, otherwise
# perform a normal CVS build.
# version of this script
version='$Revision$'
fixed=0
# Determine if we're running from CVS or a canned copy of curl
if [ "$#" -ge "1" -a "$1" ]; then
CURLDIR=$1
CVS=0
else
CURLDIR="curl"
CVS=1
fi
LANG="C"
export LANG
log() {
text=$1
if test -n "$text"; then
echo "testcurl: $text"
fi
}
die(){
text=$1
log "$text"
cd $pwd # cd back to the original root dir
if test -n "$pwd/$build"; then
# we have a build directory name, remove the dir
log "removing the $build dir"
rm -rf "$pwd/$build"
fi
if test -r "$buildlog"; then
# we have a build log output file left, remove it
log "removing the $buildlogname file"
rm -rf "$buildlog"
fi
log "ENDING HERE" # last line logged!
exit 1
}
if [ -f setup ]; then
. "./setup"
infixed="$fixed"
else
infixed=0 # so that "additional args to configure" works properly first time...
fi
if [ -z "$name" ]; then
echo "please enter your name"
read name
fixed="1"
fi
if [ -z "$email" ]; then
echo "please enter your contact email address"
read email
fixed="2"
fi
if [ -z "$desc" ]; then
echo "please enter a one line system description"
read desc
fixed="3"
fi
if [ -z "$confopts" ]; then
if [ $infixed -lt 4 ]; then
echo "please enter your additional arguments to configure"
echo "examples: --with-ssl --enable-debug --enable-ipv6 --with-krb4"
read confopts
fixed="4"
fi
fi
if [ "$fixed" -gt "0" ]; then
echo "name='$name'" > setup
echo "email='$email'" >> setup
echo "desc='$desc'" >> setup
echo "confopts='$confopts'" >> setup
echo "fixed='$fixed'" >> setup
fi
log "STARTING HERE" # first line logged
log "NAME = $name"
log "EMAIL = $email"
log "DESC = $desc"
log "CONFOPTS = $confopts"
log "CFLAGS = $CFLAGS"
log "CC = $CC"
log "version = $version"
log "date = `date -u`"
log "testscript = obsolete shell version, use tests/testcurl.pl instead!"
# Make $pwd to become the path without newline. We'll use that in order to cut
# off that path from all possible logs and error messages etc.
ipwd=`pwd`
pwd=`echo $ipwd | sed -e 's/$//g'`
if [ -d "$CURLDIR" ]; then
if [ $CVS -eq 1 -a -d $CURLDIR/CVS ]; then
log "curl is verified to be a fine source dir"
# remove the generated sources to force them to be re-generated each
# time we run this test
rm -f $CURLDIR/lib/getdate.c
rm -f $CURLDIR/src/hugehelp.c
elif [ $CVS -eq 0 -a -f $CURLDIR/testcurl.sh ]; then
log "curl is verified to be a fine daily source dir"
else
die "curl is not a daily source dir or checked out from CVS!"
fi
fi
build="build-$$"
buildlogname="buildlog-$$"
buildlog="$pwd/$buildlogname"
# remove any previous left-overs
rm -rf build-*
rm -rf buildlog-*
# this is to remove old build logs that ended up in the wrong dir
rm -rf $CURLDIR/buildlog-*
# create a dir to build in
mkdir $build
if [ -d $build ]; then
log "build dir $build was created fine"
else
die "failed to create dir $build"
fi
# get in the curl source tree root
cd $CURLDIR
# Do the CVS thing, or not...
if [ $CVS -eq 1 ]; then
# this is a temporary fix to make things work again, remove later
log "remove ares/aclocal.m4"
rm -f ares/aclocal.m4
log "update from CVS"
cvsup() {
# update quietly to the latest CVS
log "run cvs up"
cvs -Q up -dP 2>&1
cvsstat=$?
# return (1 - RETURNVALUE) so that errors return 0 while goodness
# returns 1
return `expr 1 - $cvsstat`
}
att="0"
while cvsup; do
att=`expr $att + 1`
log "failed CVS update attempt number $att."
if [ $att -gt 10 ]; then
cvsstat="111"
break # get out of the loop
fi
sleep 5
done
if [ "$cvsstat" -ne "0" ]; then
die "failed to update from CVS ($cvsstat), exiting"
fi
# remove possible left-overs from the past
rm -f configure
rm -rf autom4te.cache
# generate the build files
log "invoke buildconf, but filter off the silly aclocal warnings"
./buildconf 2>&1 | grep -v "warning: underquoted definition of" | tee $buildlog
if { grep "^buildconf: OK" $buildlog >/dev/null 2>&1; } then
log "buildconf was successful"
else
die "buildconf was NOT successful"
fi
fi
if [ -f configure ]; then
log "configure created"
else
die "no configure created"
fi
# change to build dir
cd "../$build"
# run configure script
../$CURLDIR/configure $confopts 2>&1
if [ -f lib/Makefile ]; then
log "configure seems to have finished fine"
else
die "configure didn't work"
fi
log "display lib/config.h"
grep "^ *#" lib/config.h
log "display src/config.h"
grep "^ *#" src/config.h
if { grep "define USE_ARES" lib/config.h; } then
log "setup to build ares"
log "build ares"
cd ares
make 2>&1 | sed -e "s:$pwd::g"
if [ -f libcares.a ]; then
log "ares is now built successfully"
else
log "ares build failed"
fi
# cd back to the curl build dir
cd ..
fi
log "run make"
make -i 2>&1 | sed -e "s:$pwd::g"
if [ -f src/curl ]; then
log "src/curl was created fine"
else
die "src/curl was not created"
fi
log "display curl --version output"
./src/curl --version
log "run make test-full"
make test-full 2>&1 | sed -e "s:$pwd::g" | tee $buildlog
if { grep "^TEST" $buildlog >/dev/null 2>&1; } then
log "tests were run"
else
die "test suite failure"
fi
if { grep "^TESTFAIL:" $buildlog >/dev/null 2>&1; } then
log "the tests were not successful"
else
log "the tests were successful!"
fi
# die to cleanup
die "ending nicely"

View File

@@ -33,14 +33,26 @@ CLEANFILES = .http.pid .https.pid .ftp.pid .ftps.pid
curl:
@cd $(top_builddir) && $(MAKE)
if CROSSCOMPILING
TEST = @echo "NOTICE: we can't run the tests when cross-compiling!"
TEST_Q = $(TEST)
TEST_F = $(TEST)
TEST_T = $(TEST)
else # if not cross-compiling:
TEST = srcdir=$(srcdir) $(PERL) $(PERLFLAGS) $(srcdir)/runtests.pl
TEST_Q = $(TEST) -s -a
TEST_F = $(TEST) -a -p
TEST_T = $(TEST) -t
endif
test: all
srcdir=$(srcdir) $(PERL) $(PERLFLAGS) $(srcdir)/runtests.pl
$(TEST)
quiet-test: all
srcdir=$(srcdir) $(PERL) $(PERLFLAGS) $(srcdir)/runtests.pl -s -a
$(TEST_Q)
full-test: all
srcdir=$(srcdir) $(PERL) $(PERLFLAGS) $(srcdir)/runtests.pl -a -p
$(TEST_F)
torture-test: all
srcdir=$(srcdir) $(PERL) $(PERLFLAGS) $(srcdir)/runtests.pl -t
$(TEST_T)

View File

@@ -24,7 +24,8 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
test150 test151 test152 test153 test154 test155 test156 test157 \
test158 test159 test511 test160 test161 test162 test163 test164 \
test512 test165 test166 test167 test168 test169 test170 test171 \
test172 test204 test205
test172 test204 test205 test173 test174 test175 test176 test177 \
test513
# The following tests have been removed from the dist since they no longer
# work. We need to fix the test suite's FTPS server first, then bring them

View File

@@ -64,14 +64,14 @@ Pragma: no-cache
Accept: */*
GET http://data.from.server.requiring.digest.hohoho.com/168 HTTP/1.1
Proxy-Authorization: Digest username="digest", realm="weirdorealm", nonce="12345", uri="/168", response="4e79e4fc104ef1f16ab4567e1ad4dede"
Proxy-Authorization: Digest username="foo", realm="weirdorealm", nonce="12345", uri="/168", response="fb8608e00ad9239a3dedb14bc8575976"
User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b zlib/1.1.4 c-ares/1.2.0 libidn/0.4.3
Host: data.from.server.requiring.digest.hohoho.com
Pragma: no-cache
Accept: */*
GET http://data.from.server.requiring.digest.hohoho.com/168 HTTP/1.1
Proxy-Authorization: Digest username="digest", realm="weirdorealm", nonce="12345", uri="/168", response="4e79e4fc104ef1f16ab4567e1ad4dede"
Proxy-Authorization: Digest username="foo", realm="weirdorealm", nonce="12345", uri="/168", response="fb8608e00ad9239a3dedb14bc8575976"
Authorization: Digest username="digest", realm="realmweirdo", nonce="123456", uri="/168", response="ca87f2d768a231e2d637a55698d5c416"
User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.3
Host: data.from.server.requiring.digest.hohoho.com

71
tests/data/test173 Normal file
View File

@@ -0,0 +1,71 @@
# Server-side
<reply>
<data>
HTTP/1.1 200 OK swsclose
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
blablabla
</data>
</reply>
# Client-side
<client>
<server>
http
</server>
<name>
HTTP RFC1867-formpost a file from stdin with "faked" filename
</name>
<command>
http://%HOSTIP:%HOSTPORT/we/want/173 -F field1=contents1 -F "fileupload=@-;filename=/dev/null"
</command>
<stdin>
line1
line2
line3
line4
line5
line6
line7
line8
</stdin>
</client>
# Verify data after the test has been "shot"
<verify>
<strip>
^(User-Agent:|Content-Type: multipart/form-data;|------------).*
</strip>
<protocol>
POST /we/want/173 HTTP/1.1
User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: */*
Content-Length: 359
Expect: 100-continue
Content-Type: multipart/form-data; boundary=----------------------------5dbea401cd8c
------------------------------5dbea401cd8c
Content-Disposition: form-data; name="field1"
contents1
------------------------------5dbea401cd8c
Content-Disposition: form-data; name="fileupload"; filename="/dev/null"
Content-Type: application/octet-stream
line1
line2
line3
line4
line5
line6
line7
line8
------------------------------5dbea401cd8c--
</protocol>
</verify>

71
tests/data/test174 Normal file
View File

@@ -0,0 +1,71 @@
# Server-side
<reply>
<data>
HTTP/1.1 200 beng swsclose swsbounce
Server: Microsoft-IIS/6.0
Authentication-Info: Passport1.4 tname=MSPAuth,tname=MSPProf,tname=MSPConsent,tname=MSPSecAuth
Content-Type: text/html; charset=iso-8859-1
This is not the real page
</data>
<data1>
HTTP/1.1 200 moo swsclose
Server: Microsoft-IIS/6.0
Content-Type: text/html; charset=iso-8859-1
content for you
</data1>
<datacheck>
HTTP/1.1 200 beng swsclose swsbounce
Server: Microsoft-IIS/6.0
Authentication-Info: Passport1.4 tname=MSPAuth,tname=MSPProf,tname=MSPConsent,tname=MSPSecAuth
Content-Type: text/html; charset=iso-8859-1
HTTP/1.1 200 moo swsclose
Server: Microsoft-IIS/6.0
Content-Type: text/html; charset=iso-8859-1
content for you
</datacheck>
</reply>
# Client-side
<client>
#
<server>
http
</server>
<name>
HTTP POST --anyauth to server not requiring any auth at all
</name>
<command>
http://%HOSTIP:%HOSTPORT/174 -u testuser:testpass --anyauth -d "junkelijunk"
</command>
</test>
# Verify data after the test has been "shot"
<verify>
<strip>
^User-Agent:.*
</strip>
<protocol nonewline=yes>
HEAD /174 HTTP/1.1
User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: */*
POST /174 HTTP/1.1
User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: */*
Content-Length: 11
Content-Type: application/x-www-form-urlencoded
junkelijunk
</protocol>
</verify>

71
tests/data/test175 Normal file
View File

@@ -0,0 +1,71 @@
# Server-side
<reply>
<data>
HTTP/1.1 200 beng swsclose swsbounce
Server: Microsoft-IIS/6.0
Authentication-Info: Passport1.4 tname=MSPAuth,tname=MSPProf,tname=MSPConsent,tname=MSPSecAuth
Content-Type: text/html; charset=iso-8859-1
This is not the real page
</data>
<data1>
HTTP/1.1 200 moo swsclose
Server: Microsoft-IIS/6.0
Content-Type: text/html; charset=iso-8859-1
content for you
</data1>
<datacheck>
HTTP/1.1 200 beng swsclose swsbounce
Server: Microsoft-IIS/6.0
Authentication-Info: Passport1.4 tname=MSPAuth,tname=MSPProf,tname=MSPConsent,tname=MSPSecAuth
Content-Type: text/html; charset=iso-8859-1
HTTP/1.1 200 moo swsclose
Server: Microsoft-IIS/6.0
Content-Type: text/html; charset=iso-8859-1
content for you
</datacheck>
</reply>
# Client-side
<client>
#
<server>
http
</server>
<name>
HTTP POST --digest to server not requiring any auth at all
</name>
<command>
http://%HOSTIP:%HOSTPORT/175 -u auser:apasswd --digest -d "junkelijunk"
</command>
</test>
# Verify data after the test has been "shot"
<verify>
<strip>
^User-Agent:.*
</strip>
<protocol nonewline=yes>
HEAD /175 HTTP/1.1
User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: */*
POST /175 HTTP/1.1
User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: */*
Content-Length: 11
Content-Type: application/x-www-form-urlencoded
junkelijunk
</protocol>
</verify>

76
tests/data/test176 Normal file
View File

@@ -0,0 +1,76 @@
# Server-side
<reply>
# the first request has NTLM type-1 included, and then the 1001 is returned
<data1001>
HTTP/1.1 200 beng swsclose swsbounce
Server: Microsoft-IIS/6.0
Authentication-Info: Passport1.4 tname=MSPAuth,tname=MSPProf,tname=MSPConsent,tname=MSPSecAuth
Content-Type: text/html; charset=iso-8859-1
</data1001>
# the second request should be auth-less and then this is returned.
<data>
HTTP/1.1 200 moo swsclose
Server: Microsoft-IIS/6.0
Content-Type: text/html; charset=iso-8859-1
content for you
</data>
<datacheck>
HTTP/1.1 200 beng swsclose swsbounce
Server: Microsoft-IIS/6.0
Authentication-Info: Passport1.4 tname=MSPAuth,tname=MSPProf,tname=MSPConsent,tname=MSPSecAuth
Content-Type: text/html; charset=iso-8859-1
HTTP/1.1 200 moo swsclose
Server: Microsoft-IIS/6.0
Content-Type: text/html; charset=iso-8859-1
content for you
</datacheck>
</reply>
# Client-side
<client>
# require SSL since we need that for NTLM
<features>
SSL
</features>
<server>
http
</server>
<name>
HTTP POST --ntlm to server not requiring any auth at all
</name>
<command>
http://%HOSTIP:%HOSTPORT/176 -u auser:apasswd --ntlm -d "junkelijunk"
</command>
</test>
# Verify data after the test has been "shot"
<verify>
<strip>
^User-Agent:.*
</strip>
<protocol nonewline=yes>
HEAD /176 HTTP/1.1
Authorization: NTLM TlRMTVNTUAABAAAAAgIAAAAAAAAgAAAAAAAAACAAAAA=
User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: */*
POST /176 HTTP/1.1
User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: */*
Content-Length: 11
Content-Type: application/x-www-form-urlencoded
junkelijunk
</protocol>
</verify>

39
tests/data/test177 Normal file
View File

@@ -0,0 +1,39 @@
# Server-side
<reply>
<data>
HTTP/1.1 302 *MOVED* swsclose swsbounce
Server: Microsoft-IIS/6.0
Location: /mooooo/177
Content-Type: text/html; charset=iso-8859-1
</data>
</reply>
# Client-side
<client>
#
<server>
http
</server>
<name>
HTTP POST --digest to server doing a 302-location response
</name>
<command>
http://%HOSTIP:%HOSTPORT/177 -u auser:apasswd --digest -d "junkelijunk"
</command>
</test>
# Verify data after the test has been "shot"
<verify>
<strip>
^User-Agent:.*
</strip>
<protocol>
HEAD /177 HTTP/1.1
User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: */*
</protocol>
</verify>

File diff suppressed because one or more lines are too long

40
tests/data/test513 Normal file
View File

@@ -0,0 +1,40 @@
#
# Server-side
<reply>
</reply>
# Client-side
<client>
<server>
http
</server>
# tool is what to use instead of 'curl'
<tool>
lib513
</tool>
<name>
send HTTP POST using read callback that returns CURL_READFUNC_ABORT
</name>
<command>
http://%HOSTIP:%HOSTPORT/513
</command>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol>
POST /513 HTTP/1.1
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: */*
Content-Length: 1
Content-Type: application/x-www-form-urlencoded
</protocol>
# 42 - aborted by callback
<errorcode>
42
</errorcode>
</verify>

View File

@@ -43,8 +43,7 @@ sub logmsg {
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
localtime(time);
open(FTPLOG, ">>log/ftpd.log");
printf FTPLOG ("%02d:%02d:%02d (%d) ",
$hour, $min, $sec, $$);
printf FTPLOG ("%02d:%02d:%02d ", $hour, $min, $sec);
print FTPLOG @_;
close(FTPLOG);
}
@@ -67,6 +66,7 @@ my $verbose=0; # set to 1 for debugging
my $retrweirdo=0;
my $retrnosize=0;
my $srcdir=".";
my $nosave=0;
my $port = 8921; # just a default
do {
@@ -382,7 +382,10 @@ sub STOR_command {
my $ulsize=0;
while (defined($line = <SOCK>)) {
$ulsize += length($line);
print FILE $line;
print FILE $line if(!$nosave);
}
if($nosave) {
print FILE "$ulsize bytes would've been stored here\n";
}
close(FILE);
close_dataconn();
@@ -497,6 +500,9 @@ my %customcount;
my %delayreply;
sub customize {
undef %customreply;
$nosave = 0; # default is to save as normal
open(CUSTOM, "<log/ftpserver.cmd") ||
return 1;
@@ -505,23 +511,32 @@ sub customize {
while(<CUSTOM>) {
if($_ =~ /REPLY ([A-Z]+) (.*)/) {
$customreply{$1}=$2;
logmsg "FTPD: set custom reply for $1\n";
}
if($_ =~ /COUNT ([A-Z]+) (.*)/) {
# we blank the customreply for this command when having
# been used this number of times
$customcount{$1}=$2;
logmsg "FTPD: blank custom reply for $1 after $2 uses\n";
}
elsif($_ =~ /DELAY ([A-Z]+) (\d*)/) {
$delayreply{$1}=$2;
logmsg "FTPD: delay reply for $1 with $2 seconds\n";
}
elsif($_ =~ /RETRWEIRDO/) {
print "instructed to use RETRWEIRDO\n";
logmsg "FTPD: instructed to use RETRWEIRDO\n";
$retrweirdo=1;
}
elsif($_ =~ /RETRNOSIZE/) {
print "instructed to use RETRNOSIZE\n";
logmsg "FTPD: instructed to use RETRNOSIZE\n";
$retrnosize=1;
}
elsif($_ =~ /NOSAVE/) {
# don't actually store the file we upload - to be used when
# uploading insanely huge amounts
$nosave = 1;
logmsg "FTPD: NOSAVE prevents saving of uploaded data\n";
}
}
close(CUSTOM);
}

View File

@@ -39,7 +39,7 @@ SUPPORTFILES = first.c test.h
# These are all libcurl test programs
noinst_PROGRAMS = lib500 lib501 lib502 lib503 lib504 lib505 lib506 lib507 \
lib508 lib509 lib510 lib511 lib512
lib508 lib509 lib510 lib511 lib512 lib513
lib500_SOURCES = lib500.c $(SUPPORTFILES)
lib500_LDADD = $(LIBDIR)/libcurl.la
@@ -92,3 +92,7 @@ lib511_DEPENDENCIES = $(LIBDIR)/libcurl.la
lib512_SOURCES = lib512.c $(SUPPORTFILES)
lib512_LDADD = $(LIBDIR)/libcurl.la
lib512_DEPENDENCIES = $(LIBDIR)/libcurl.la
lib513_SOURCES = lib513.c $(SUPPORTFILES)
lib513_LDADD = $(LIBDIR)/libcurl.la
lib513_DEPENDENCIES = $(LIBDIR)/libcurl.la

47
tests/libtest/lib513.c Normal file
View File

@@ -0,0 +1,47 @@
#include "test.h"
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
{
(void)ptr;
(void)size;
(void)nmemb;
(void)userp;
return CURL_READFUNC_ABORT;
}
int test(char *URL)
{
CURL *curl;
CURLcode res=CURLE_OK;
curl = curl_easy_init();
if(curl) {
/* First set the URL that is about to receive our POST. */
curl_easy_setopt(curl, CURLOPT_URL, URL);
/* Now specify we want to POST data */
curl_easy_setopt(curl, CURLOPT_POST, TRUE);
/* Set the expected POST size */
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 1);
/* we want to use our own read function */
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
/* pointer to pass to our read function */
curl_easy_setopt(curl, CURLOPT_INFILE, NULL);
/* get verbose debug output please */
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
/* include headers in the output */
curl_easy_setopt(curl, CURLOPT_HEADER, TRUE);
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
}
return (int)res;
}

View File

@@ -748,6 +748,10 @@ sub checkcurl {
die "couldn't run '$CURL'"
}
if(!$curl_debug && $torture) {
die "can't run torture tests since curl was not build with debug";
}
my $hostname=`hostname`;
my $hosttype=`uname -a`;
@@ -1048,6 +1052,17 @@ sub singletest {
my $dumped_core;
my $cmdres;
my @precommand= getpart("client", "precommand");
if($precommand[0]) {
# this is pure perl to eval!
my $code = join("", @precommand);
eval $code;
if($@) {
print "perl: $code\n";
print "precommand: $@";
exit;
}
}
if($gdbthis) {
open(GDBCMD, ">log/gdbcmd");
@@ -1146,8 +1161,22 @@ sub singletest {
}
if(@protocol) {
# verify the sent request
my @out = loadarray($SERVERIN);
my @out;
my $retry = 5;
# Verify the sent request. Sometimes, like in test 513 on some hosts,
# curl will return back faster than the server writes down the request
# to its file, so we might need to wait here for a while to see if the
# file gets written a bit later.
while($retry--) {
@out = loadarray($SERVERIN);
if(!$out[0]) {
# nothing there yet, wait a while and try again
sleep(1);
}
}
# what to cut off from the live protocol sent by curl
my @strip = getpart("verify", "strip");

View File

@@ -191,10 +191,10 @@ static void logmsg(const char *msg, ...)
logfp = fopen(DEFAULT_LOGFILE, "a");
fprintf(logfp?logfp:stderr, /* write to stderr if the logfile doesn't open */
"%02d:%02d:%02d (%d) %s\n",
"%02d:%02d:%02d %s\n",
curr_time->tm_hour,
curr_time->tm_min,
curr_time->tm_sec, (int)getpid(), buffer);
curr_time->tm_sec, buffer);
if(logfp)
fclose(logfp);
}
@@ -447,10 +447,12 @@ void storerequest(char *reqbuf)
dump = fopen(REQUEST_DUMP, "ab"); /* b is for windows-preparing */
if(dump) {
fwrite(reqbuf, 1, strlen(reqbuf), dump);
size_t len = strlen(reqbuf);
fwrite(reqbuf, 1, len, dump);
fclose(dump);
logmsg("Wrote request input to " REQUEST_DUMP);
logmsg("Wrote request (%d bytes) input to " REQUEST_DUMP,
(int)len);
}
else {
logmsg("Failed to write request input to " REQUEST_DUMP);
@@ -482,6 +484,10 @@ static int get_request(int sock, struct httprequest *req)
return DOCNUMBER_INTERNAL;
}
logmsg("Connection closed by client");
reqbuf[req->offset]=0;
/* dump the request receivied so far to the external file */
storerequest(reqbuf);
return DOCNUMBER_INTERNAL;
}
req->offset += got;
@@ -631,7 +637,8 @@ static int send_doc(int sock, struct httprequest *req)
fclose(dump);
logmsg("Response sent (%d bytes)!", responsesize);
logmsg("Response sent (%d bytes) and written to " RESPONSE_DUMP,
responsesize);
if(ptr)
free(ptr);
@@ -769,7 +776,7 @@ int main(int argc, char *argv[])
if (msgsock == -1)
continue;
logmsg("** New client connected");
logmsg("====> Client connect");
do {
if(get_request(msgsock, &req))
@@ -801,7 +808,7 @@ int main(int argc, char *argv[])
/* if we got a CONNECT, loop and get another request as well! */
} while(req.open || (req.testno == DOCNUMBER_CONNECT));
logmsg("** Closing client connection");
logmsg("====> Client disconnect");
sclose(msgsock);
if (req.testno == DOCNUMBER_QUIT)

View File

@@ -35,12 +35,15 @@
# USAGE:
# testcurl.pl [curl-daily-name] > output
# or:
# testcurl.pl --target=your_os > output
# Updated:
# v1.2 8-Mar-04 - rewritten in perl
# v1.1 6-Nov-03 - to take an optional parameter, the name of a daily-build
# directory. If present, build from that directory, otherwise
# perform a normal CVS build.
# v1.7 22-Jun-04 - added --target option for other platform targets.
# v1.2 8-Mar-04 - rewritten in perl
# v1.1 6-Nov-03 - to take an optional parameter, the name of a daily-build
# directory. If present, build from that directory, otherwise
# perform a normal CVS build.
use strict;
@@ -49,20 +52,44 @@ use Cwd;
# Turn on warnings (equivalent to -w, which can't be used with /usr/bin/env)
BEGIN { $^W = 1; }
use vars qw($version $fixed $infixed $CURLDIR $CVS $pwd $build $buildlog $buildlogname $gnulikebuild);
use vars qw($version $fixed $infixed $CURLDIR $CVS $pwd $build $buildlog
$buildlogname $gnulikebuild $targetos $confsuffix $binext);
use vars qw($name $email $desc $confopts);
# version of this script
$version='$Revision$';
$fixed=0;
# Determine if we're running from CVS or a canned copy of curl
# Determine if we're running from CVS or a canned copy of curl,
# or if we got a specific target option
$CURLDIR="curl";
$CVS=1;
if (@ARGV && $ARGV[0]) {
$CURLDIR=$ARGV[0];
$CVS=0;
} else {
$CURLDIR="curl";
$CVS=1;
if ($ARGV[0] =~ /--target=/) {
$targetos = (split(/=/, $ARGV[0]))[1];
} else {
$CURLDIR=$ARGV[0];
$CVS=0;
}
}
# Do the platform-specific stuff here
$gnulikebuild = 1;
$confsuffix = '';
$binext = '';
if ($^O eq 'MSWin32' || defined($targetos)) {
$gnulikebuild = 0;
if (!defined($targetos)) {
# If no target defined on Win32 lets assume vc
$targetos = 'vc';
}
if ($targetos =~ /vc/ || $targetos =~ /mingw32/) {
$confsuffix = '-win32';
$binext = '.exe';
} elsif ($targetos =~ /netware/) {
$confsuffix = '-netware';
$binext = '.nlm';
}
}
$ENV{LANG}="C";
@@ -118,11 +145,6 @@ sub mydie($){
exit 1;
}
$gnulikebuild = 1;
if ($^O eq 'MSWin32') {
$gnulikebuild = 0;
}
if (open(F, "setup")) {
while (<F>) {
if (/(\w+)=(.*)/) {
@@ -183,6 +205,7 @@ logit "DESC = $desc";
logit "CONFOPTS = $confopts";
logit "CFLAGS = ".($ENV{CFLAGS} ? $ENV{CFLAGS} : "");
logit "CC = ".($ENV{CC} ? $ENV{CC} : "");
logit "target = ".($targetos ? $targetos : "");
logit "version = $version";
logit "date = ".(scalar gmtime)." UTC";
@@ -286,7 +309,8 @@ if ($CVS) {
mydie "buildconf was NOT successful";
}
} else {
system("buildconf.bat");
system("buildconf.bat") if ($^O eq 'MSWin32');
# logit "buildconf was successful (dummy message)" if ($^O eq 'linux');
}
}
@@ -314,24 +338,28 @@ if ($gnulikebuild) {
mydie "configure didn't work";
}
} else {
system("xcopy /s /q ..\\$CURLDIR .");
system("xcopy /s /q ..\\$CURLDIR .") if ($^O eq 'MSWin32');
if ($^O eq 'linux') {
system("cp -ar ../$CURLDIR/* .");
system("cp -a ../$CURLDIR/Makefile.dist Makefile");
}
}
logit "display lib/config.h";
open(F, $gnulikebuild ? "lib/config.h" : "lib/config-win32.h") or die;
logit "display lib/config$confsuffix.h";
open(F, "lib/config$confsuffix.h") or die;
while (<F>) {
print if /^ *#/;
}
close(F);
logit "display src/config.h";
open(F, $gnulikebuild ? "src/config.h" : "src/config-win32.h") or die;
logit "display src/config$confsuffix.h";
open(F, "src/config$confsuffix.h") or die;
while (<F>) {
print if /^ *#/;
}
close(F);
if (grepfile("define USE_ARES", $gnulikebuild ? "lib/config.h" : "lib/config-win32.h")) {
if (grepfile("define USE_ARES", "lib/config$confsuffix.h")) {
logit "setup to build ares";
logit "build ares";
@@ -362,7 +390,15 @@ if ($gnulikebuild) {
}
close(F);
} else {
open(F, "nmake -i vc|") or die;
if ($^O eq 'MSWin32') {
if ($targetos =~ /vc/) {
open(F, "nmake -i $targetos|") or die;
} else {
open(F, "make -i $targetos |") or die;
}
} else {
open(F, "make -i $targetos 2>&1 |") or die;
}
while (<F>) {
s/$pwd//g;
print;
@@ -370,16 +406,19 @@ if ($gnulikebuild) {
close(F);
}
my $exe = $gnulikebuild ? "curl" : "curl.exe";
if (-f "src/$exe") {
logit "src/curl was created fine ($exe)";
if (-f "src/curl$binext") {
logit "src/curl was created fine (curl$binext)";
} else {
mydie "src/curl was not created ($exe)";
mydie "src/curl was not created (curl$binext)";
}
logit "display $exe --version output";
if (defined($targetos) && $targetos =~ /netware/) {
#system('../../curlver.sh');
} else {
logit "display curl$binext --version output";
system("./src/$exe --version");
system("./src/curl$binext --version");
}
if ($gnulikebuild) {
logit "run make test-full";