Compare commits
231 Commits
curl-7_9_1
...
curl-7_9_3
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fbe2907599 | ||
![]() |
343da8d4b3 | ||
![]() |
8d97792dbc | ||
![]() |
8d07c87be7 | ||
![]() |
ed21701df3 | ||
![]() |
df01507582 | ||
![]() |
f2bda5fd5b | ||
![]() |
cba9838e8f | ||
![]() |
b6dba9f5dd | ||
![]() |
6e9d1617c6 | ||
![]() |
ea811fee52 | ||
![]() |
7391fd8f6a | ||
![]() |
6c00c58f2a | ||
![]() |
4931fbce49 | ||
![]() |
fefc7ea600 | ||
![]() |
d220389647 | ||
![]() |
a1f910c159 | ||
![]() |
e4866563de | ||
![]() |
47f45aa229 | ||
![]() |
affe334675 | ||
![]() |
ee7e184e26 | ||
![]() |
bec0ebacf1 | ||
![]() |
5bd6d631c6 | ||
![]() |
fd1799f3bb | ||
![]() |
d84a0c51e0 | ||
![]() |
d9a7c7de51 | ||
![]() |
d57e09889a | ||
![]() |
eecb86bfb0 | ||
![]() |
0b1197936c | ||
![]() |
b545ac6391 | ||
![]() |
a922132e4a | ||
![]() |
9474e8d6d2 | ||
![]() |
6328428568 | ||
![]() |
ea9a88a9b8 | ||
![]() |
aec7358ca4 | ||
![]() |
3c334b2bb6 | ||
![]() |
75bba0da92 | ||
![]() |
c0bfe7be15 | ||
![]() |
22ac08e06d | ||
![]() |
87037136ef | ||
![]() |
2182e37433 | ||
![]() |
1de82b220d | ||
![]() |
bd878756fc | ||
![]() |
8d7f402efb | ||
![]() |
d3299beec7 | ||
![]() |
f9192db358 | ||
![]() |
c69c0c0446 | ||
![]() |
deb2911c0e | ||
![]() |
e31a306a38 | ||
![]() |
d9a7773011 | ||
![]() |
2b14916813 | ||
![]() |
1d1530e14c | ||
![]() |
b4fdc025a8 | ||
![]() |
f1c14fe0b4 | ||
![]() |
38306cda54 | ||
![]() |
5a0f0023cf | ||
![]() |
6dcdb8b821 | ||
![]() |
781f52a287 | ||
![]() |
f75ff58b4b | ||
![]() |
ae9bf16dee | ||
![]() |
17a8bf212f | ||
![]() |
4fc76afef4 | ||
![]() |
a31155a72a | ||
![]() |
75601f7924 | ||
![]() |
8b6314ccfb | ||
![]() |
6de7dc5879 | ||
![]() |
6aaee5f23b | ||
![]() |
dd06dcebe1 | ||
![]() |
b35c26b751 | ||
![]() |
128f341635 | ||
![]() |
e48bc1be48 | ||
![]() |
0077b9c0a2 | ||
![]() |
fe37fb5921 | ||
![]() |
221ecd0a30 | ||
![]() |
560492707d | ||
![]() |
dfdf4916fa | ||
![]() |
97a8c98886 | ||
![]() |
62fb70e9d1 | ||
![]() |
8a9098a36c | ||
![]() |
28027c2aa2 | ||
![]() |
d60029d66e | ||
![]() |
226fe8bdf9 | ||
![]() |
33237b4502 | ||
![]() |
af6c394785 | ||
![]() |
558d12d7f6 | ||
![]() |
bfa8a6da26 | ||
![]() |
aa6b3d22a2 | ||
![]() |
2eb355733f | ||
![]() |
e66cdacb93 | ||
![]() |
c67f2da283 | ||
![]() |
e192261788 | ||
![]() |
c63ca99c1c | ||
![]() |
1c99c4ad11 | ||
![]() |
bbcfc10677 | ||
![]() |
47e67eab26 | ||
![]() |
650b95045d | ||
![]() |
5603134e58 | ||
![]() |
d12fd897cb | ||
![]() |
5e95203a5d | ||
![]() |
cad4a571ce | ||
![]() |
139ab3740a | ||
![]() |
7b832e1745 | ||
![]() |
914b9e441b | ||
![]() |
f0f6ab49f5 | ||
![]() |
436d147925 | ||
![]() |
4bd78a7df4 | ||
![]() |
7ee6a9dc25 | ||
![]() |
1b56ae8478 | ||
![]() |
d52c0b6f05 | ||
![]() |
3ff2bfa0e4 | ||
![]() |
aa21a3d5c3 | ||
![]() |
fc33ad8cf2 | ||
![]() |
779043f7a3 | ||
![]() |
265bb99382 | ||
![]() |
7493db2338 | ||
![]() |
c3ad019c99 | ||
![]() |
05b84bfe91 | ||
![]() |
dbfa1e55b6 | ||
![]() |
a0fd63f611 | ||
![]() |
4ec0401529 | ||
![]() |
61e6554b7f | ||
![]() |
f6f3f79aa8 | ||
![]() |
c16c017f8b | ||
![]() |
2f03ef39d1 | ||
![]() |
db33926432 | ||
![]() |
946090b9cd | ||
![]() |
1f7f0fda71 | ||
![]() |
b84d947be4 | ||
![]() |
07c67138c9 | ||
![]() |
10717bd39b | ||
![]() |
302bb4a4b3 | ||
![]() |
81b5af2d1b | ||
![]() |
87c562845c | ||
![]() |
6c81d74626 | ||
![]() |
533c24a471 | ||
![]() |
6a9697387a | ||
![]() |
85c8981b3d | ||
![]() |
6c5b8e1d59 | ||
![]() |
2cc16d89e6 | ||
![]() |
42eb74922d | ||
![]() |
c528a7ee33 | ||
![]() |
eb2da7ec2b | ||
![]() |
01ed950bbe | ||
![]() |
b1076e0a9e | ||
![]() |
332eb7651a | ||
![]() |
cfdcf5c933 | ||
![]() |
820de919b6 | ||
![]() |
a32cd520bd | ||
![]() |
b93a60daf9 | ||
![]() |
e2844f5e04 | ||
![]() |
cabb46db3d | ||
![]() |
d09b436937 | ||
![]() |
10fdb1d743 | ||
![]() |
f0d3fccd4b | ||
![]() |
aff19f64b5 | ||
![]() |
15a56b42d6 | ||
![]() |
d3706814e9 | ||
![]() |
6513dcef68 | ||
![]() |
81f22465ba | ||
![]() |
dccc77a325 | ||
![]() |
13ac89af24 | ||
![]() |
ffefcab1bc | ||
![]() |
0226b53b75 | ||
![]() |
bbf80d0f93 | ||
![]() |
6003f24f78 | ||
![]() |
4382a80b9a | ||
![]() |
9fe920cd90 | ||
![]() |
f0ee7115d3 | ||
![]() |
5986c653ef | ||
![]() |
0e7203be89 | ||
![]() |
52dbc96c32 | ||
![]() |
1c8da21083 | ||
![]() |
8f304d8167 | ||
![]() |
30a0bd9cf5 | ||
![]() |
ae40cdf92f | ||
![]() |
b342fbdcda | ||
![]() |
d1ea596f88 | ||
![]() |
064cf971ef | ||
![]() |
91b1598756 | ||
![]() |
17b18bca3c | ||
![]() |
be3d601217 | ||
![]() |
ca0fd33d2d | ||
![]() |
271f96f78f | ||
![]() |
b0130e6b3b | ||
![]() |
d0c1f3e25b | ||
![]() |
b244710ddb | ||
![]() |
d465291ded | ||
![]() |
84e462d5f6 | ||
![]() |
508466a175 | ||
![]() |
e6dd4a6456 | ||
![]() |
8d62e21072 | ||
![]() |
25fe47f262 | ||
![]() |
fe8365d214 | ||
![]() |
2519a8cc9f | ||
![]() |
b8ff21124a | ||
![]() |
6aafc2dfd2 | ||
![]() |
65b22480f4 | ||
![]() |
60f19269d0 | ||
![]() |
5121499082 | ||
![]() |
3e049a90b7 | ||
![]() |
c5d97df7f1 | ||
![]() |
c2479ccb7a | ||
![]() |
fc07eb45f4 | ||
![]() |
c7cdb0f266 | ||
![]() |
92aedf850e | ||
![]() |
dd157fc349 | ||
![]() |
05f3ca880f | ||
![]() |
a18d41a463 | ||
![]() |
1affbff8f9 | ||
![]() |
c55d0bb804 | ||
![]() |
0ffec712e1 | ||
![]() |
6ebac3dc76 | ||
![]() |
3b976ea9f1 | ||
![]() |
2c16dfb526 | ||
![]() |
fe3a78ab19 | ||
![]() |
1a984ea847 | ||
![]() |
2a0cde3041 | ||
![]() |
3552775b52 | ||
![]() |
818a632e80 | ||
![]() |
00afb0f638 | ||
![]() |
2e32d415c0 | ||
![]() |
3dfc509d33 | ||
![]() |
4379142af7 | ||
![]() |
8a6dc57212 | ||
![]() |
af636c535c | ||
![]() |
2f77b0a4c6 | ||
![]() |
08ad385e0e | ||
![]() |
5623e0bb0e | ||
![]() |
3d438d8d64 | ||
![]() |
d89c495782 | ||
![]() |
f5ba174f4d |
419
CHANGES
419
CHANGES
@@ -6,6 +6,421 @@
|
||||
|
||||
History of Changes
|
||||
|
||||
|
||||
Daniel (16 January 2002)
|
||||
- Mofied the main transfer loop and related stuff to deal with non-blocking
|
||||
sockets in the upload section. While doing this, I've now separated the
|
||||
connection oriented buffers to have one for downloads and one for uploads
|
||||
(as two can happen simultaneously). I also shrunk the buffers to 20K
|
||||
each. As we have a scratch buffer twice the size of the upload buffer, we
|
||||
arrived at 80K for buffers compared with the previous 150K.
|
||||
|
||||
- Added the --cc option to curl-config command as it enables so very cool
|
||||
one-liners. Have a go a this one, building the simple.c example:
|
||||
|
||||
$ `curl-config --cc --cflags --libs` -o example simple.c
|
||||
|
||||
Daniel (14 January 2002)
|
||||
- I made all socket reads (recv) handle EWOULDBLOCK. I hope nicely. Now we
|
||||
only need to address all writes (send) too and then I'm ready for another
|
||||
pre-release...
|
||||
|
||||
- Stoned Elipot patched the in_addr_t configure test to make it work better on
|
||||
more platforms.
|
||||
|
||||
Daniel (9 January 2002)
|
||||
- Cris Bailiff found out that filling up curl's SSL session cache caused a
|
||||
crash!
|
||||
|
||||
- Posted the curl questionnaire on the web site. If you haven't posted your
|
||||
opinions there yet, go there and do it now while it is still there:
|
||||
|
||||
http://curl.haxx.se/q/
|
||||
|
||||
- Georg Horn quickly found out that the SSL reading no longer worked as
|
||||
supposed since the switch to non-blocking sockets. I've made a quick patch
|
||||
(for reading only) but we should improve it even further.
|
||||
|
||||
Version 7.9.3-pre1
|
||||
|
||||
Daniel (7 January 2002)
|
||||
- I made the 'bool' typedef use an "unsigned char". It makes it the same on
|
||||
all platforms, no matter what the platform thinks the default format for
|
||||
char is. This was noticed since we made a silly comparison involving such a
|
||||
bool variable, and only one compiler/platform combination (on Debian Linux)
|
||||
complained about it (that happened to have its char unsigned by default).
|
||||
|
||||
- Bug report #495290 identified a cookie parsing problem that was corrected.
|
||||
When a Set-Cookie: line is received without a trailing semicolon, libcurl
|
||||
didn't read the last "name=value" pair of the line, leading to confusions...
|
||||
|
||||
- Sterling committed his updated DNS cache code.
|
||||
|
||||
- I worked with Georg Horn and comments from G<>tz Babin-Ebell and switched
|
||||
curl's socket operations completely over to non-blocking for the entire
|
||||
operation (previously we used non-blocking only for the connection phase).
|
||||
We had to do this to make the SSL connection phase timeout properly without
|
||||
the use of signals. A little extra code to deal with this was added.
|
||||
|
||||
- T. Bharath pointed out a slightly obscure cookie engine flaw.
|
||||
|
||||
- Pete Su pointed out that libcurl didn't treat HTTP code 204 as it should.
|
||||
204-replies never provides a response-body. This resulted in bad persistant
|
||||
behavior when 204 was received.
|
||||
|
||||
Daniel (5 January 2002)
|
||||
- SM updated the VC++ library Makefiles for the new source files.
|
||||
|
||||
Daniel (4 January 2002)
|
||||
- I discovered that we wrongly used inet_ntoa() (instead of inet_ntoa_r() in
|
||||
two places in the source code). One happened with VERBOSE set on connects,
|
||||
and the other when VERBOSE was on and krb4 over nat was used... I honestly
|
||||
don't think anyone has suffered from these mistakes.
|
||||
|
||||
- I replaced a lot of silly occurances of printf() to instead use the more
|
||||
appropriate Curl_infof() or Curl_failf(). The krb4 and telnet code were
|
||||
affected.
|
||||
|
||||
- Philip Gladstone found a few more problems with 64-bit archs (the 64-bit
|
||||
sparc on solaris 8).
|
||||
|
||||
- After discussions on the libcurl list with Raoul Cridlig, I just made FTP
|
||||
response lines get passed to the header callback if such a one is
|
||||
registered. It'll make it possible for any application to get all the
|
||||
responses an FTP server sends to libcurl.
|
||||
|
||||
Daniel (3 January 2002)
|
||||
- Sterling Hughes brought a few buckets of code. Now, libcurl will
|
||||
automatically cache DNS lookups and re-use the previous results first if any
|
||||
such is available. It greatly improves speed when doing many repeated
|
||||
operations to the same host.
|
||||
|
||||
- As the test case uses --include and then --head, I had to modify src/main.c
|
||||
to deal with this situation slightly better than previously. When done, we
|
||||
have 100% good tests again in the main branch.
|
||||
|
||||
Daniel (2 January 2002)
|
||||
- Made test case 25 run again in the multi-dev branch. But it seems that the
|
||||
changes done on dec-20 made test case 104 cease to work (in both branches).
|
||||
|
||||
- Philip Gladstone pointed out a few portability problems in the source code
|
||||
that didn't compile on 64-bit sparcs using Sun's native compiler...
|
||||
|
||||
Daniel (20 December 2001)
|
||||
- Bj<42>rn Stenberg caught an unpleasent (but hard-to-find) bug that could cause
|
||||
libcurl to hang on transfers over proxy, when the proxy was specified with
|
||||
an environment variable!
|
||||
|
||||
- Added code to make ftp operations treat the NO_BODY and HEADERS options
|
||||
better:
|
||||
|
||||
NO_BODY set TRUE and HEADERS set TRUE:
|
||||
Return a set of headers with file info
|
||||
|
||||
NO_BODY set FALSE
|
||||
Transfer data as usual, HEADERS is ignored
|
||||
|
||||
NO_BODY set TRUE and HEADERS set FALSE
|
||||
Don't transfer any data, don't return any headers. Just perform the set
|
||||
of FTP commands.
|
||||
|
||||
Daniel (17 December 2001)
|
||||
- G<>tz Babin-Ebell dove into the dark dungeons of the OpenSSL ENGINE stuff and
|
||||
made libcurl support it! This allows libcurl to do SSL connections with the
|
||||
private key stored in external hardware.
|
||||
|
||||
To make this good, he had to add a bunch of new library options that'll be
|
||||
useful to others as well:
|
||||
|
||||
CURLOPT_SSLCERTTYPE set SSL cert type (PEM/DER)
|
||||
CURLOPT_SSLKEY set SSL private key (file)
|
||||
CURLOPT_SSLKEYTYPE: set SSL key type (PEM/DER/ENG)
|
||||
CURLOPT_SSLKEYPASSWD: set the passphrase for your private key
|
||||
(CURLOPT_SSLCERTPASSWD is an alias)
|
||||
CURLOPT_SSLENGINE: set the name of the crypto engine
|
||||
(returns CURLE_SSL_ENGINE_NOTFOUND on error)
|
||||
CURLOPT_SSLENGINE_DEFAULT: set the default engine
|
||||
|
||||
There are two new failure codes:
|
||||
|
||||
CURLE_SSL_ENGINE_NOTFOUND
|
||||
CURLE_SSL_ENGINE_SETFAILED
|
||||
|
||||
Daniel (14 December 2001)
|
||||
- We have "branched" the source-tree at a few places. Checkout the CVS sources
|
||||
with the 'multi-dev' label to get the latest multi interface development
|
||||
tree. The idea is to only branch affected files and to restrict the branch
|
||||
to the v8 multi interface development only.
|
||||
|
||||
*NOTE* that if we get bug reports and patches etc, we might need to apply
|
||||
them in both branches!
|
||||
|
||||
The multi-dev branch is what we are gonna use as main branch in the future
|
||||
if it turns out successful. Thus, we must maintain both now in case we need
|
||||
them. The current main branch will be used if we want to release a 7.9.3 or
|
||||
perhaps a 7.10 release before version 8. Which is very likely.
|
||||
|
||||
- Marcus Webster provided code for the new CURLFORM_CONTENTHEADER option for
|
||||
curl_formadd(), that lets an application add a set of headers for that
|
||||
particular part in a multipart/form-post. He also provided a section to the
|
||||
man page that describes the new option.
|
||||
|
||||
Daniel (11 December 2001)
|
||||
- Ben Greear made me aware of the fact that the Curl_failf() usage internally
|
||||
was a bit sloppy with adding newlines or not to the error messages. Let's
|
||||
once and for all say that they do not belong there!
|
||||
|
||||
- When uploading files with -T to give a local file name, and you end the URL
|
||||
with a slash to have the local file name used remote too, we now no longer
|
||||
use the local directory as well. Only the file part of the -T file name
|
||||
will be appended to the right of the slash in the URL.
|
||||
|
||||
Daniel (7 December 2001)
|
||||
- Michal Bonino pointed out that Digital Unix doesn't have gmtime_r so the
|
||||
link failed. Added a configure check and corrected source code.
|
||||
|
||||
Version 7.9.2
|
||||
|
||||
Daniel (5 December 2001)
|
||||
- Jon Travis found out that if you used libcurl and CURLOPT_UPLOAD and then
|
||||
on the same handle used CURLOPT_HTTPGET it would still attempt to upload.
|
||||
His suggested fix was perfect.
|
||||
|
||||
Daniel (4 December 2001)
|
||||
- Incorporated more macos fixes and added four specific files in a new
|
||||
subdirectory below src.
|
||||
|
||||
Daniel (3 December 2001)
|
||||
- Eric Lavigne reported two problems:
|
||||
|
||||
First one in the curl_strnequal() function. I think this problem is rather
|
||||
macos 9 specific, as most platform provides a function to use instead of the
|
||||
one provided by libcurl.
|
||||
|
||||
A second, more important, was in the way we take care of FTP responses. The
|
||||
code would read a large chunk of data and search for the end-of-response
|
||||
line within that chunk. When found, it would just skip the rest of the
|
||||
data. However, when the network connections are special, or perhaps the
|
||||
server is, we could actually get more than one response in that chunk of
|
||||
data so that when the next invoke to this function was done, the response
|
||||
had already been read and thrown away. Now, we cache the data not used in
|
||||
one call, as it could be useful in the subsequent call. Test case 126 was
|
||||
added and the test ftp server modified, to exercise this particular case.
|
||||
|
||||
Version 7.9.2-pre8
|
||||
|
||||
Daniel (2 December 2001)
|
||||
- Bug report #487825 correctly identified a problem when using a proxy and
|
||||
following a redirection from HTTP to HTTPS. libcurl then re-used the same
|
||||
proxy connection but without doing a proper HTTPS request.
|
||||
|
||||
- Fixed win32 compiling quirks.
|
||||
|
||||
Version 7.9.2-pre7
|
||||
|
||||
Daniel (30 November 2001)
|
||||
- Documented --disable-epsv and CURLOPT_FTP_USE_EPSV.
|
||||
|
||||
Daniel (29 November 2001)
|
||||
- Added --disable-epsv as an option. When used, curl won't attempt to use the
|
||||
EPSV command when doing passive FTP downloads. Wrote a test case for it.
|
||||
|
||||
- Eric provided a few more fixes for building on Macs. He also pointed out
|
||||
a flaw in the signal handler restoration code.
|
||||
|
||||
Daniel (28 November 2001)
|
||||
- Fiddled with some Tru64 problems reported by Dimitris Sarris. They appeared
|
||||
only when using VERBOSE ftp transfers. Do we use a too small buffer for
|
||||
gethostbyaddr_r(), was the lack of using in_addr_t wrong or is it that the
|
||||
hostent struct must be blanked before use? With Dimitris help and these
|
||||
patches, the problems seem to be history.
|
||||
|
||||
- CURLOPT_FTP_USE_EPSV was added and can be set to FALSE to prevent libcurl
|
||||
from using the EPSV command before trying the normal PASV. Heikki Korpela
|
||||
pointed out that some firewalls and similar don't like the EPSV so we must
|
||||
be able to shut if off to work everywhere.
|
||||
|
||||
- I added a configure check for 'in_addr_t' and made the ftp code use that to
|
||||
receive the inet_addr() return code in. Works on Solaris and Linux at
|
||||
least. The Linux man page for inet_addr() doesn't even mention in_addr_t...
|
||||
|
||||
- Adjusted (almost) all FTP tests to the new command sequence.
|
||||
|
||||
- FTP command sequence changes:
|
||||
|
||||
EPSV is now always attempted before PASV. It is the final touch to make IPv6
|
||||
passive FTP downloads to work, but EPSV is not restricted to IPv6 but works
|
||||
fine with IPv4 too on the servers that support it.
|
||||
|
||||
SIZE is now always issued before RETR. It makes curl know the actual
|
||||
download size before the download takes place, as it makes it less important
|
||||
to find the size sent in RETR responses. Many sites don't include the size
|
||||
in there.
|
||||
|
||||
Both these changes made it necessary to change the test suite's ftp server
|
||||
code, and all FTP test cases need to be checked and adjusted!
|
||||
|
||||
Daniel (27 November 2001)
|
||||
- Hans Steegers pointed out that the telnet code read from stdout, not stdin
|
||||
as it is supposed to do!
|
||||
|
||||
Version 7.9.2-pre6
|
||||
|
||||
Daniel (27 November 2001)
|
||||
- Eric Lavigne's minor changes to build on MacOS before OS X were applied.
|
||||
|
||||
- greep at mindspring.com provided a main index.html page for our release
|
||||
archive docs directory. It just links to all the existing HTML files, but
|
||||
I think it may come useful to people.
|
||||
|
||||
- There's now some initial code to support the EPSV FTP command. That should
|
||||
be used to do passive transfers IPv6-style. The code is still #if 0'ed in
|
||||
lib/ftp.c as I have no IPv6 ftp server to test this with.
|
||||
|
||||
Daniel (26 November 2001)
|
||||
- Robert Schlabbach had problems to understand how to do resumed transfers,
|
||||
and I clarified the man page -C section somewhat.
|
||||
|
||||
Version 7.9.2-pre5
|
||||
|
||||
Daniel (22 November 2001)
|
||||
- Andr<64>s Garc<72>a helped me out to track down the roots of bug report #479537,
|
||||
which was concerning curl returning the wrong error code when failing to
|
||||
connect. This didn't happen on all systems, and more specificly I've so far
|
||||
only seen this happen on IPv4-only Linux hosts.
|
||||
|
||||
- I applied the fixes for the two bugs Eric Lavigne found when doing his MacOS
|
||||
port. A missing comma in arpa_telnet.h and a pretty wild write in the FTP
|
||||
response reader function. The latter write is however likely to occur in our
|
||||
own buffer unless very big FTP server replies (>25K) are read. I've never
|
||||
seen such a reply ever, so I think this is a relatively minor risk.
|
||||
|
||||
Daniel (21 November 2001)
|
||||
- Moonesamy provided code to prevent junk from being output when libcurl
|
||||
returns an error code but no error description and that corrects how make is
|
||||
run in the Makefile.dist file (that appears as root Makefile in release
|
||||
archives).
|
||||
|
||||
- Eric Lavigne mailed me bugfixes and patches for building libcurl on MacOS
|
||||
(non-X).
|
||||
|
||||
- Kevin Roth modified the cygwin files once again, now to build against the
|
||||
shared OpenSSL DLLs.
|
||||
|
||||
Version 7.9.2-pre4
|
||||
|
||||
Daniel (20 November 2001)
|
||||
- Georg Horn brought a patch that introduced CURLINFO_STARTTRANSFER_TIME,
|
||||
complete with man page updates!
|
||||
|
||||
Daniel (19 November 2001)
|
||||
- Miklos Nemeth provided details enough to update the Borland makefile
|
||||
properly.
|
||||
|
||||
- Lars M Gustafsson found a case with a bad free(). In fact, it was so bad I'm
|
||||
amazed we never saw this before!
|
||||
|
||||
- Kevin Roth patched the cygwin Makfile.
|
||||
|
||||
Daniel (16 November 2001)
|
||||
- Klevtsov Vadim fixed a bug in how time-conditionals were sent when doing
|
||||
HTTP.
|
||||
|
||||
Version 7.9.2-pre3
|
||||
|
||||
Daniel (14 November 2001)
|
||||
- Samuel Listopad patched away the problem with SSL we got when someone call
|
||||
curl_global_init() => curl_global_cleanup() => curl_global_init(). The
|
||||
second init would not "take" and SSL would be unusable with curl from that
|
||||
point. This doesn't change the fact that calling the functions that way is
|
||||
wrong. curl_global_init() should be called exactly once and not more.
|
||||
|
||||
Daniel (13 November 2001)
|
||||
- Fixed some minor variable type mixups in ftp.c that caused compiler warnings
|
||||
on HP-UX 11.00.
|
||||
|
||||
- The FTP fix I did yesterday used an uninitialized variable that caused
|
||||
spurious errors when doing FTP.
|
||||
|
||||
Version 7.9.2-pre2
|
||||
|
||||
Daniel (12 November 2001)
|
||||
- Ricardo Cadime fell over a multiple-requests problem when first a FTP
|
||||
directory fetch failed and then a second request is made after that. The
|
||||
second request happened to get the FTP server response back from the
|
||||
previous request, when it did its initial CWD command.
|
||||
|
||||
- Bjorn Reese pointed out that we could improve the time diff function to
|
||||
prevent truncation a bit.
|
||||
|
||||
- Kai-Uwe Rommel made me aware that -p (http proxy tunnel) silly enough didn't
|
||||
work for plain HTTP requests! So I made that work.
|
||||
|
||||
Version 7.9.2-pre1
|
||||
|
||||
Daniel (12 November 2001)
|
||||
- Rewrote the Curl_ConnectHTTPProxyTunnel(). It should now not only work a lot
|
||||
faster, it should also support such ("broken") proxies that John Lask
|
||||
previously have reported problems with. His proxy sends a trailing zero byte
|
||||
after the end of the (proxy-) headers. I've tested this myself and it seems
|
||||
to work on a proxy the previous version also worked with...! This rewrite is
|
||||
due to the problems John Lask previously experienced.
|
||||
|
||||
- Andr<64>s Garc<72>a found out why the "current speed" meter sometimes showed 2048K
|
||||
for very quick transfers. It turned out the "time diff"-function returned a
|
||||
zero millisecond diff. We now always say it is at least one millisecond! In
|
||||
reality, these timers very rarely have that good resolution so even though
|
||||
the time diff was longer than 1 millisecond, it was reported as no diff.
|
||||
|
||||
- I also modified the getinfo() again when returning times, as Paul Harrington
|
||||
reports that 7.9.1 only returns times with 1 second accuracy, which indeed
|
||||
is wrong.
|
||||
|
||||
Daniel (8 November 2001)
|
||||
- Marcus Webster found out that curl_formadd() could read one byte outside a
|
||||
buffer boundary, which then of course could lead to a crash. Marcus also
|
||||
gracefully provided a patch for this this.
|
||||
|
||||
- Glen Scott ran configure on his Cobalt Qube and it didn't figure out the
|
||||
correct way of calling gethostbyname_r() and thus failed to resolve hosts.
|
||||
This is two errors: it shouldn't continue the configure script if it finds
|
||||
gethostbyname_r() but can't figure out how to use it, and it should really
|
||||
figure out how to use it as it was running Linux and we know how that
|
||||
works...
|
||||
|
||||
Daniel (7 November 2001)
|
||||
- docs/VERSIONS is a new file in the archive that explains the version number
|
||||
system we use in the curl project.
|
||||
|
||||
- Did some more fixes that now makes libcurl only ignore signals as long as
|
||||
it needs to, and then restore (if any) previous signal handler again.
|
||||
|
||||
Daniel (6 November 2001)
|
||||
- Enrik Berkhan posted bug report #478780, in which he very correctly pointed
|
||||
out two bad timeout matters in libcurl: we didn't restore the sigaction
|
||||
struct (the alarm handler for SIGALRM) nor did we restore the previous
|
||||
alarm() timeout that could've been set by a "parent" process or similar.
|
||||
|
||||
- Kevin Roth made the cygwin binary get stripped before install.
|
||||
|
||||
Daniel (5 November 2001)
|
||||
- Detlef Schmier reported that curl didn't compile using Solaris 8 with the
|
||||
native cc compiler. It was due to a bad function prototype. Fixed now.
|
||||
Unfortunately, I can't enable the -Wstrict-prototypes in my debug builds
|
||||
though, as gcc then complains like crazy on OpenSSL include files... :-(
|
||||
|
||||
- John Lask provided SSL over HTTP proxy fixes. They'll need some tweaking
|
||||
to work on all platforms.
|
||||
|
||||
- John Lask added the -1/--TLSv1 options that forces SSL into using TLS
|
||||
version 1 when speaking HTTPS.
|
||||
|
||||
- John Lask brought a brand new VC++ makefile for the lib directory, that
|
||||
works a lot better than the previous!
|
||||
|
||||
- Ramana Mokkapati brought some clever insights on the LDAP failures (bug
|
||||
report #475407), and his suggested changes are now applied.
|
||||
|
||||
Version 7.9.1
|
||||
|
||||
Daniel (4 November 2001)
|
||||
@@ -34,8 +449,8 @@ Daniel (1 November 2001)
|
||||
Version 7.9.1-pre7
|
||||
|
||||
Daniel (31 October 2001)
|
||||
- The curl_easy_getinfo() timers accidentally lost they're subsecond accuracy
|
||||
as the calculations used longs instead of doubles! Paul Harrington reported.
|
||||
- The curl_easy_getinfo() timers accidentally lost their subsecond accuracy as
|
||||
the calculations used longs instead of doubles! Paul Harrington reported.
|
||||
|
||||
- The SSL SocketIsDead() checks weren't good enough (as expected really), so I
|
||||
had to add a generic internal try-it-out system. If the request on a re-used
|
||||
|
835
CHANGES.0
835
CHANGES.0
@@ -1,838 +1,3 @@
|
||||
Daniel (28 December 1999):
|
||||
- Tim Verhoeven correctly identified that curl
|
||||
doesn't support URL formatted file names when getting ftp. Now, there's a
|
||||
problem with getting very weird file names off FTP servers. RFC 959 defines
|
||||
that the file name syntax to use should be the same as in the native OS of
|
||||
the server. Since we don't know the peer server system we currently just
|
||||
translate the URL syntax into plain letters. It is still better and with
|
||||
the solaris 2.6-supplied ftp server it works with spaces in the file names.
|
||||
|
||||
Daniel (27 December 1999):
|
||||
- When curl parsed cookies straight off a remote site, it corrupted the input
|
||||
data, which, if the downloaded headers were stored made very odd characters
|
||||
in the saved data. Correctly identified and reported by Paul Harrington.
|
||||
|
||||
Daniel (13 December 1999):
|
||||
- General cleanups in the library interface. There had been some bad kludges
|
||||
added during times of stress and I did my best to clean them off. It was
|
||||
both regarding the lib API as well as include file confusions.
|
||||
|
||||
Daniel (3 December 1999):
|
||||
- A small --stderr bug was reported by Eetu Ojanen...
|
||||
|
||||
- who also brought the suggestion of extending the -X flag to ftp list as
|
||||
well. So, now it is and the long option is now --request instead. It is
|
||||
only for ftp list for now (and the former http stuff too of course).
|
||||
|
||||
Lars J. Aas (24 November 1999):
|
||||
- Patched curl to compile and build under BeOS. Doesn't work yet though!
|
||||
|
||||
- Corrected the Makefile.am files to allow putting object files in
|
||||
different directories than the sources.
|
||||
|
||||
Version 6.3.1
|
||||
|
||||
Daniel (23 November 1999):
|
||||
- I've had this major disk crash. My good old trust-worthy source disk died
|
||||
along with the machine that hosted it. Thank goodness most of all the
|
||||
things I've done are either backed up elsewhere or stored in this CVS
|
||||
server!
|
||||
|
||||
- Michael S. Steuer pointed out a bug in the -F handling
|
||||
that made curl hang if you posted an empty variable such as '-F name='. It
|
||||
was one of those old bugs that never have worked properly...
|
||||
|
||||
- Jason Baietto pointed out a general flaw in the HTTP
|
||||
download. Curl didn't complain if it was prematurely aborted before the
|
||||
entire download was completed. It does now.
|
||||
|
||||
Daniel (19 November 1999):
|
||||
- Chris Maltby very accurately criticized the lack of
|
||||
return code checks on the fwrite() calls. I did a thorough check for all
|
||||
occurrences and corrected this.
|
||||
|
||||
Daniel (17 November 1999):
|
||||
- Paul Harrington pointed out that the -m/--max-time option
|
||||
doesn't work for the slow system calls like gethostbyname()... I don't have
|
||||
any good fix yet, just a slightly less bad one that makes curl exit hard
|
||||
when the timeout is reached.
|
||||
|
||||
- Bjorn Reese helped me point out a possible problem that might be the reason
|
||||
why Thomas Hurst experience problems in his Amiga version.
|
||||
|
||||
Daniel (12 November 1999):
|
||||
- I found a crash in the new cookie file parser. It crashed when you gave
|
||||
a plain http header file as input...
|
||||
|
||||
Version 6.3
|
||||
|
||||
Daniel (10 November 1999):
|
||||
- I kind of found out that the HTTP time-conditional GETs (-z) aren't always
|
||||
respected by the web server and the document is therefore sent in whole
|
||||
again, even though it doesn't match the requested condition. After reading
|
||||
section 13.3.4 of RFC 2616, I think I'm doing the right thing now when I do
|
||||
my own check as well. If curl thinks the condition isn't met, the transfer
|
||||
is aborted prematurely (after all the headers have been received).
|
||||
|
||||
- After comments from Robert Linden I also rewrote some parts of the man page
|
||||
to better describe how the -F works.
|
||||
|
||||
- Michael Anti put up a new curl download mirror in
|
||||
China: http://www.pshowing.com/curl/
|
||||
|
||||
- I added the list of download mirrors to the README file
|
||||
|
||||
- I did add more explanations to the man page
|
||||
|
||||
Daniel (8 November 1999):
|
||||
- I made the -b/--cookie option capable of reading netscape formatted cookie
|
||||
files as well as normal http-header files. It should be able to
|
||||
transparently figure out what kind of file it got as input.
|
||||
|
||||
Daniel (29 October 1999):
|
||||
- Another one of Sebastiaan van Erk's ideas (that has been requested before
|
||||
but I seem to have forgotten who it was), is to add support for ranges in
|
||||
FTP downloads. As usual, one request is just a request, when they're two
|
||||
it is a demand. I've added simple support for X-Y style fetches. X has to
|
||||
be the lower number, though you may omit one of the numbers. Use the -r/
|
||||
--range switch (previously HTTP-only).
|
||||
|
||||
- Sebastiaan van Erk suggested that curl should be
|
||||
able to show the file size of a specified file. I think this is a splendid
|
||||
idea and the -I flag is now working for FTP. It displays the file size in
|
||||
this manner:
|
||||
Content-Length: XXXX
|
||||
As it resembles normal headers, and leaves us the opportunity to add more
|
||||
info in that display if we can come up with more in the future! It also
|
||||
makes sense since if you access ftp through a HTTP proxy, you'd get the
|
||||
file size the same way.
|
||||
|
||||
I changed the order of the QUOTE command executions. They're now executed
|
||||
just after the login and before any other command. I made this to enable
|
||||
quote commands to run before the -I stuff is done too.
|
||||
|
||||
- I found out that -D/--dump-header and -V/--version weren't documented in
|
||||
the man page.
|
||||
|
||||
- Many HTTP/1.1 servers do not support ranges. Don't ask me why. I did add
|
||||
some text about this in the man page for the range option. The thread in
|
||||
the mailing list that started this was initiated by Michael Anti.
|
||||
|
||||
- I get reports about nroff crashes on solaris 2.6+ when displaying the curl
|
||||
man page. Switch to gnroff instead, it is reported to work(!). Adam Barclay
|
||||
reported and brought the suggestion.
|
||||
|
||||
- In a dialogue with Johannes G. Kristinsson we came
|
||||
up with the idea to let -H/--header specified headers replace the
|
||||
internally generated headers, if you happened to select to add a header
|
||||
that curl normally uses by itself. The advantage with this is not entirely
|
||||
obvious, but in Johannes' case it means that he can use another Host: than
|
||||
the one curl would set.
|
||||
|
||||
Daniel (27 October 1999):
|
||||
- Jongki Suwandi brought a nice patch for (yet another) crash when following
|
||||
a location:. This time you had to follow a https:// server's redirect to
|
||||
get the core.
|
||||
|
||||
Version 6.2
|
||||
|
||||
Daniel (21 October 1999):
|
||||
- I think I managed to remove the suspicious (nil) that has been seen just
|
||||
before the "Host:" in HTTP requests when -v was used.
|
||||
- I found out that if you followed a location: when using a proxy, without
|
||||
having specified http:// in the URL, the protocol part was added once again
|
||||
when moving to the next URL! (The protocol part has to be added to the
|
||||
URL when going through a proxy since it has no protocol-guessing system
|
||||
such as curl has.)
|
||||
- Benjamin Ritcey reported a core dump under solaris 2.6
|
||||
with OpenSSL 0.9.4. It turned out this was due to a bad free() in main.c
|
||||
that occurred after the download was done and completed.
|
||||
- Benjamin found ftp downloads to show the first line of the download meter
|
||||
to get written twice, and I removed that problem. It was introduced with
|
||||
the multiple URL support.
|
||||
- Dan Zitter correctly pointed out that curl 6.1 and earlier versions didn't
|
||||
honor RFC 2616 chapter 4 section 2, "Message Headers": "...Field names are
|
||||
case-insensitive..." HTTP header parsing assumed a certain casing. Dan
|
||||
also provided me with a patch that corrected this, which I took the liberty
|
||||
of editing slightly.
|
||||
- Dan Zitter also provided a nice patch for config.guess to better recognize
|
||||
the Mac OS X
|
||||
- Dan also corrected a minor problem in the lib/Makefile that caused linking
|
||||
to fail on OS X.
|
||||
|
||||
Daniel (19 October 1999):
|
||||
- Len Marinaccio came up with some problems with curl. Since Windows has a
|
||||
crippled shell, it can't redirect stderr and that causes trouble. I added
|
||||
--stderr today which allows the user to redirect the stderr stream to a
|
||||
file or stdout.
|
||||
|
||||
Daniel (18 October 1999):
|
||||
- The configure script now understands the '--without-ssl' flag, which now
|
||||
totally disable SSL/https support. Previously it wasn't possible to force
|
||||
the configure script to leave SSL alone. The previous functionality has
|
||||
been retained. Troy Engel helped test this new one.
|
||||
|
||||
Version 6.1
|
||||
|
||||
Daniel (17 October 1999):
|
||||
- I ifdef'ed or commented all the zlib stuff in the sources and configure
|
||||
script. It turned out we needed to mock more with zlib than I initially
|
||||
thought, to make it capable of downloading compressed HTTP documents and
|
||||
uncompress them on the fly. I didn't mean the zlib parts of curl to become
|
||||
more than minor so this means I halt the zlib expedition for now and wait
|
||||
until someone either writes the code or zlib gets updated and better
|
||||
adjusted for this kind of usage. I won't get into details here, but a
|
||||
short a summary is suitable:
|
||||
- zlib can't automatically detect whether to use zlib or gzip
|
||||
decompression methods.
|
||||
- zlib is very neat for reading gzipped files from a file descriptor,
|
||||
although not as nice for reading buffer-based data such as we would
|
||||
want it.
|
||||
- there are still some problems with the win32 version when reading from
|
||||
a file descriptor if that is a socket
|
||||
|
||||
Daniel (14 October 1999):
|
||||
- Moved the (external) include files for libcurl into a subdirectory named
|
||||
curl and adjusted all #include lines to use <curl/XXXX> to maintain a
|
||||
better name space and control of the headers. This has been requested.
|
||||
|
||||
Daniel (12 October 1999):
|
||||
- I modified the 'maketgz' script to perform a 'make' too before a release
|
||||
archive is put together in an attempt to make the time stamps better and
|
||||
hopefully avoid the double configure-running that use to occur.
|
||||
|
||||
Daniel (11 October 1999):
|
||||
- Applied J<>rn's patches that fixes zlib for mingw32 compiles as well as
|
||||
some other missing zlib #ifdef and more text on the multiple URL docs in
|
||||
the man page.
|
||||
|
||||
Version 6.1beta
|
||||
|
||||
Daniel (6 October 1999):
|
||||
- Douglas E. Wegscheid sent me a patch that made the exact same thing as I
|
||||
just made: the -d switch is now capable of reading post data from a named
|
||||
file or stdin. Use it similarly to the -F. To read the post data from a
|
||||
given file:
|
||||
|
||||
curl -d @path/to/filename www.postsite.com
|
||||
|
||||
or let curl read it out from stdin:
|
||||
|
||||
curl -d @- www.postit.com
|
||||
|
||||
J<>rn Hartroth (3 October 1999):
|
||||
- Brought some more patches for multiple URL functionality. The MIME
|
||||
separation ideas are almost scrapped now, and a custom separator is being
|
||||
used instead. This is still compile-time "flagged".
|
||||
|
||||
Daniel
|
||||
- Updated curl.1 with multiple URL info.
|
||||
|
||||
Daniel (30 September 1999):
|
||||
- Felix von Leitner brought openssl-check fixes for configure.in to work
|
||||
out-of-the-box when the openssl files are installed in the system default
|
||||
dirs.
|
||||
|
||||
Daniel (28 September 1999)
|
||||
- Added libz functionality. This should enable decompressing gzip, compress
|
||||
or deflate encoding HTTP documents. It also makes curl send an accept that
|
||||
it accepts that kind of encoding. Compressed contents usually shortens
|
||||
download time. I *need* someone to tell me a site that uses compressed HTTP
|
||||
documents so that I can test this out properly.
|
||||
|
||||
- As a result of the adding of zlib awareness, I changed the version string
|
||||
a little. I plan to add openldap version reporting in there too.
|
||||
|
||||
Daniel (17 September 1999)
|
||||
- Made the -F option allow stdin when specifying files. By using '-' instead
|
||||
of file name, the data will be read from stdin.
|
||||
|
||||
Version 6.0
|
||||
|
||||
Daniel (13 September 1999)
|
||||
- Added -X/--http-request <request> to enable any HTTP command to be sent.
|
||||
Do not that your server has to support the exact string you enter. This
|
||||
should possibly a string like DELETE or TRACE.
|
||||
|
||||
- Applied Douglas' mingw32-fixes for the makefiles.
|
||||
|
||||
Daniel (10 September 1999)
|
||||
- Douglas E. Wegscheid pointed out a problem. Curl didn't check the FTP
|
||||
servers return code properly after the --quote commands were issued. It
|
||||
took anything non 200 as an error, when all 2XX codes should be accepted as
|
||||
OK.
|
||||
|
||||
- Sending cookies to the same site in multiple lines like curl used to do
|
||||
turned out to be bad and breaking the cookie specs. Curl now sends all
|
||||
cookies on a single Cookie: line. Curl is not yet RFC 2109 compliant, but I
|
||||
doubt that many servers do use that syntax (yet).
|
||||
|
||||
Daniel (8 September 1999)
|
||||
- J<>rn helped me make sure it still compiles nicely with mingw32 under win32.
|
||||
|
||||
Daniel (7 September 1999)
|
||||
- FTP upload through proxy is now turned into a HTTP PUT. Requested by
|
||||
Stefan Kanthak.
|
||||
|
||||
- Added the ldap files to the .m32 makefile.
|
||||
|
||||
Daniel (3 September 1999)
|
||||
- Made cookie matching work while using HTTP proxy.
|
||||
|
||||
Bjorn Reese (31 August 1999)
|
||||
- Passed his ldap:// patch. Note that this requires the openldap shared
|
||||
library to be installed and that LD_LIBRARY_PATH points to the
|
||||
directory where the lib will be found when curl is run with a
|
||||
ldap:// URL.
|
||||
|
||||
J<>rn Hartroth (31 August 1999)
|
||||
- Made the Mingw32 makefiles into single files.
|
||||
- Made file:// work for Win32. The same code is now used for unix as well for
|
||||
performance reasons.
|
||||
|
||||
Douglas E. Wegscheid (30 August 1999)
|
||||
- Patched the Mingw32 makefiles for SSL builds.
|
||||
|
||||
Matthew Clarke (30 August 1999)
|
||||
- Made a cool patch for configure.in to allow --with-ssl to specify the
|
||||
root dir of the openssl installation, as in
|
||||
|
||||
./configure --with-ssl=/usr/ssl_here
|
||||
|
||||
- Corrected the 'reconf' script to work better with some shells.
|
||||
|
||||
J<>rn Hartroth (26 August 1999)
|
||||
- Fixed the Mingw32 makefiles in lib/ and corrected the file.c for win32
|
||||
compiles.
|
||||
|
||||
Version 5.11
|
||||
|
||||
Daniel (25 August 1999)
|
||||
- John Weismiller pointed out a bug in the header-line
|
||||
realloc() system in download.c.
|
||||
|
||||
- I added lib/file.[ch] to offer a first, simple, file:// support. It
|
||||
probably won't do much good on win32 system at this point, but I see it
|
||||
as a start.
|
||||
|
||||
- Made the release archives get a Makefile in the root dir, which can be
|
||||
used to start the compiling/building process easier. I haven't really
|
||||
changed any INSTALL text yet, I wanted to get some feed-back on this
|
||||
first.
|
||||
|
||||
Daniel (17 August 1999)
|
||||
- Another Location: bug. Curl didn't do proper relative locations if the
|
||||
original URL had cgi-parameters that contained a slash. Nusu's page
|
||||
again.
|
||||
|
||||
- Corrected the NO_PROXY usage. It is a list of substrings that if one of
|
||||
them matches the tail of the host name it should connect to, curl should
|
||||
not use a proxy to connect there. Pointed out to me by Douglas
|
||||
E. Wegscheid. I also changed the README text a little regarding this.
|
||||
|
||||
Daniel (16 August 1999)
|
||||
- Fixed a memory bug with http-servers that sent Location: to a Location:
|
||||
page. Nusu's page showed this too.
|
||||
|
||||
- Made cookies work a lot better. Setting the same cookie name several times
|
||||
used to add more cookies instead of replacing the former one which it
|
||||
should've. Nusu <nus at intergorj.ro> brought me an URL that made this
|
||||
painfully visible...
|
||||
|
||||
Troy (15 August 1999)
|
||||
- Brought new .spec files as well as a patch for configure.in that lets the
|
||||
configure script find the openssl files better, even when the include
|
||||
files are in /usr/include/openssl
|
||||
|
||||
Version 5.10
|
||||
|
||||
Daniel (13 August 1999)
|
||||
- SSL_CTX_set_default_passwd_cb() has been modified in the 0.9.4 version of
|
||||
OpenSSL. Now why couldn't they simply add a *new* function instead of
|
||||
modifying the parameters of an already existing function? This way, we get
|
||||
a compiler warning if compiling with 0.9.4 but not with earlier. So, I had
|
||||
to come up with a #if construction that deals with this...
|
||||
|
||||
- Made curl output the SSL version number get displayed properly with 0.9.4.
|
||||
|
||||
Troy (12 August 1999)
|
||||
- Added MingW32 (GCC-2.95) support under Win32. The INSTALL file was also
|
||||
a bit rearranged.
|
||||
|
||||
Daniel (12 August 1999)
|
||||
- I had to copy a good <arpa/telnet.h> include file into the curl source
|
||||
tree to enable the silly win32 systems to compile. The distribution rights
|
||||
allows us to do that as long as the file remains unmodified.
|
||||
|
||||
- I corrected a few minor things that made the compiler complain when
|
||||
-Wall -pedantic was used.
|
||||
|
||||
- I'm moving the official curl web page to http://curl.haxx.nu. I think it
|
||||
will make it easier to remember as it is a lot shorter and less cryptic.
|
||||
The old one still works and shows the same info.
|
||||
|
||||
Daniel (11 August 1999)
|
||||
- Albert Chin-A-Young mailed me another correction for NROFF in the
|
||||
configure.in that is supposed to be better for IRIX users.
|
||||
|
||||
Daniel (10 August 1999)
|
||||
- Albert Chin-A-Young helped me with some stupid Makefile things, as well as
|
||||
some fiddling with the getdate.c stuff that he had problems with under
|
||||
HP-UX v10. getdate.y will now be compiled into getdate.c if the appropriate
|
||||
yacc or bison is found by the configure script. Since this is slightly new,
|
||||
we need to test the output getdate.c with win32 systems to make sure it
|
||||
still compiles there.
|
||||
|
||||
Daniel (5 August 1999)
|
||||
- I've just setup a new mailing list with the intention to keep discussions
|
||||
around libcurl development in it. I mainly expect it to be for thoughts and
|
||||
brainstorming around a "next generation" library, rather than nitpicking
|
||||
about the current implementation or details in the current libcurl.
|
||||
|
||||
To join our happy bunch of future-looking geeks, enter 'subscribe
|
||||
<address>' in the body of a mail and send it to
|
||||
libcurl-request@listserv.fts.frontec.se. Curl bug reports, the usual curl
|
||||
talk and everything else should still be kept in this mailing list. I've
|
||||
started to archive this mailing list and have put the libcurl web page at
|
||||
www.fts.frontec.se/~dast/libcurl/.
|
||||
|
||||
- Stefan Kanthak contacted me regarding a few problems in the configure
|
||||
script which he discovered when trying to make curl compile and build under
|
||||
Siemens SINIX-Z V5.42B2004!
|
||||
|
||||
- Marcus Klein very accurately informed me that src/version.h was not present
|
||||
in the CVS repository. Oh, how silly...
|
||||
|
||||
- Linus Nielsen rewrote the telnet:// part and now curl offers limited telnet
|
||||
support. If you run curl like 'curl telnet://host' you'll get all output on
|
||||
the screen and curl will read input from stdin. You'll be able to login and
|
||||
run commands etc, but since the output is buffered, expect to get a little
|
||||
weird output.
|
||||
|
||||
This is still in its infancy and it might get changed. We need your
|
||||
feed-back and input in how this is best done.
|
||||
|
||||
WIN32 NOTE: I bet we'll get problems when trying to compile the current
|
||||
lib/telnet.c on win32, but I think we can sort them out in time.
|
||||
|
||||
- David Sanderson reported that FORCE_ALLOCA_H or HAVE_ALLOCA_H must be
|
||||
defined for getdate.c to compile properly on HP-UX 11.0. I updated the
|
||||
configure script to check for alloca.h which should make it.
|
||||
|
||||
Daniel (4 August 1999)
|
||||
- I finally got to understand Marcus Klein's ftp download resume problem,
|
||||
which turns out to be due to different outputs from different ftp
|
||||
servers. It makes ftp download resuming a little trickier, but I've made
|
||||
some modifications I really believe will work for most ftp servers and I do
|
||||
hope you report if you have problems with this!
|
||||
|
||||
- Added text about file transfer resuming to README.curl.
|
||||
|
||||
Daniel (2 August 1999)
|
||||
- Applied a progress-bar patch from Lars J. Aas. It offers
|
||||
a new styled progress bar enabled with -#/--progress-bar.
|
||||
|
||||
T. Yamada <tai at imasy.or.jp> (30 July 1999)
|
||||
- It breaks with segfault when 1) curl is using .netrc to obtain
|
||||
username/password (option '-n'), and 2) is automatically redirected to
|
||||
another location (option '-L').
|
||||
|
||||
There is a small bug in lib/url.c (block starting from line 641), which
|
||||
tries to take out username/password from user- supplied command-line
|
||||
argument ('-u' option). This block is never executed on first attempt since
|
||||
CONF_USERPWD bit isn't set at first, but curl later turns it on when it
|
||||
checks for CONF_NETRC bit. So when curl tries to redo everything due to
|
||||
redirection, it segfaults trying to access *data->userpwd.
|
||||
|
||||
Version 5.9.1
|
||||
|
||||
Daniel (30 July 1999)
|
||||
- Steve Walch pointed out that there is a memory leak in the formdata
|
||||
functions. I added a FormFree() function that is now used and supposed to
|
||||
correct this flaw.
|
||||
|
||||
- Mark Wotton reported:
|
||||
'curl -L https://www.cwa.com.au/' core dumps. I managed to cure this by
|
||||
correcting the cleanup procedure. The bug seems to be gone with my OpenSSL
|
||||
0.9.2b, although still occurs when I run the ~100 years old SSLeay 0.8.0. I
|
||||
don't know whether it is curl or SSLeay that is to blame for that.
|
||||
|
||||
- Marcus Klein:
|
||||
Reported an FTP upload resume bug that I really can't repeat nor understand.
|
||||
I leave it here so that it won't be forgotten.
|
||||
|
||||
Daniel (29 July 1999)
|
||||
- Costya Shulyupin suggested support for longer URLs when following Location:
|
||||
and I could only agree and fix it!
|
||||
|
||||
- Leigh Purdie found a problem in the upload/POST department. It turned out
|
||||
that http.c accidentaly cleared the pointer instead of the byte counter
|
||||
when supposed to.
|
||||
|
||||
- Costya Shulyupin pointed out a problem with port numbers and Location:. If
|
||||
you had a server at a non-standard port that redirected to an URL using a
|
||||
standard port number, curl still used that first port number.
|
||||
|
||||
- Ralph Beckmann pointed out a problem when using both CONF_FOLLOWLOCATION
|
||||
and CONF_FAILONERROR simultaneously. Since the CONF_FAILONERROR exits on
|
||||
the 302-code that the follow location header outputs it will never show any
|
||||
html on location: pages. I have now made it look for >=400 codes if
|
||||
CONF_FOLLOWLOCATION is set.
|
||||
|
||||
- 'struct slist' is now renamed to 'struct curl_slist' (as suggested by Ralph
|
||||
Beckmann).
|
||||
|
||||
- Joshua Swink and Rick Welykochy were the first to point out to me that the
|
||||
latest OpenSSL package now have moved the standard include path. It is now
|
||||
in /usr/local/ssl/include/openssl and I have now modified the --enable-ssl
|
||||
option for the configure script to use that as the primary path, and I
|
||||
leave the former path too to work with older packages of OpenSSL too.
|
||||
|
||||
Daniel (9 June 1999)
|
||||
- I finally understood the IRIX problem and now it seem to compile on it!
|
||||
I am gonna remove those #define strcasecmp() things once and for all now.
|
||||
|
||||
Daniel (4 June 1999)
|
||||
- I adjusted the FTP reply 227 parser to make the PASV command work better
|
||||
with more ftp servers. Appearantly the Roxen Challanger server replied
|
||||
something curl 5.9 could deal with! :-( Reported by Ashley Reid-Montanaro
|
||||
and Mark Butler brought a solution for it.
|
||||
|
||||
Daniel (26 May 1999)
|
||||
- Rearranged. README is new, the old one is now README.curl and I added a
|
||||
README.libcurl with text I got from Ralph Beckmann.
|
||||
|
||||
- I also updated the INSTALL text.
|
||||
|
||||
Daniel (25 May 1999)
|
||||
- David Jonathan Lowsky correctly pointed out that curl didn't properly deal
|
||||
with form posting where the variable shouldn't have any content, as in curl
|
||||
-F "form=" www.site.com. It was now fixed.
|
||||
|
||||
Version 5.9
|
||||
|
||||
Daniel (22 May 1999)
|
||||
- I've got a bug report from Aaron Scarisbrick in which he states he has some
|
||||
problems with -L under FreeBSD 3.0. I have previously got another bug
|
||||
report from Stefan Grether which points at an error with similar sympthoms
|
||||
when using win32. I made the allocation of the new url string a bit faster
|
||||
and different, don't know if it actually improves anything though...
|
||||
|
||||
Daniel (20 May 1999)
|
||||
- Made the cookie parser deal with CRLF newlines too.
|
||||
|
||||
Daniel (19 May 1999)
|
||||
- Download() didn't properly deal with failing return codes from the sread()
|
||||
function. Adam Coyne found the problem in the win32 version, and Troy Engel
|
||||
helped me out isolating it.
|
||||
|
||||
Daniel (16 May 1999)
|
||||
- Richard Adams pointed out a bug I introduced in 5.8. --dump-header doesn't
|
||||
work anymore! :-/ I fixed it now.
|
||||
|
||||
- After a suggestion by Joshua Swink I added -S / --show-error to force curl
|
||||
to display the error message in case of an error, even if -s/--silent was
|
||||
used.
|
||||
|
||||
Daniel (10 May 1999)
|
||||
- I moved the stuff concerning HTTP, DICT and TELNET it their own source
|
||||
files now. It is a beginning on my clean-up of the sources to make them
|
||||
layer all those protocols better to enable more to be added easier in the
|
||||
future!
|
||||
|
||||
- Leon Breedt sent me some files I've not put into the main curl
|
||||
archive. They're for creating the Debian package thingie. He also sent me a
|
||||
debian package that I've made available for download at the web page
|
||||
|
||||
Daniel (9 May 1999)
|
||||
- Made it compile on cygwin too.
|
||||
|
||||
Troy Engel (7 May 1999)
|
||||
- Brought a series of patches to allow curl to compile smoothly on MSVC++ 6
|
||||
again!
|
||||
|
||||
Daniel (6 May 1999)
|
||||
- I changed the #ifdef HAVE_STRFTIME placement for the -z code so that it
|
||||
will be easier to discover systems that don't have that function and thus
|
||||
can't use -z successfully. Made the strftime() get used if WIN32 is defined
|
||||
too.
|
||||
|
||||
Version 5.8
|
||||
|
||||
Daniel (5 May 1999)
|
||||
- I've had it with this autoconf/automake mess. It seems to work allright
|
||||
for most people who don't have automake installed, but for those who have
|
||||
there are problems all over.
|
||||
|
||||
I've got like five different bug reports on this only the last
|
||||
week... Claudio Neves and Federico Bianchi and root <duggerj001 at
|
||||
hawaii.rr.com> are some of them reporting this.
|
||||
|
||||
Currently, I have no really good fix since I want to use automake myself to
|
||||
generate the Makefile.in files. I've found out that the @SHELL@-problems
|
||||
can often be fixed by manually invoking 'automake' in the archive root
|
||||
before you run ./configure... I've hacked my maketgz script now to fiddle
|
||||
a bit with this and my tests seem to work better than before at least!
|
||||
|
||||
Daniel (4 May 1999)
|
||||
- mkhelp.pl has been doing badly lately. I corrected a case problem in
|
||||
the regexes.
|
||||
|
||||
- I've now remade the -o option to not touch the file unless it needs to.
|
||||
I had to do this to make -z option really fine, since now you can make a
|
||||
curl fetch and use a local copy's time when downloading to that file, as
|
||||
in:
|
||||
|
||||
curl -z dump -o dump remote.site.com/file.html
|
||||
|
||||
This will only get the file if the remote one is newer than the local.
|
||||
I'm aware that this alters previous behaviour a little. Some scripts out
|
||||
there may depend on that the file is always touched...
|
||||
|
||||
- Corrected a bug in the SSLv2/v3 selection.
|
||||
|
||||
- Felix von Leitner requested that curl should be able to send
|
||||
"If-Modified-Since" headers, which indeed is a fair idea. I implemented it
|
||||
right away! Try -z <expression> where expression is a full GNU date
|
||||
expression or a file name to get the date from!
|
||||
|
||||
Stephan Lagerholm (30 Apr 1999)
|
||||
- Pointed out a problem with the src/Makefile for FreeBSD. The RM variable
|
||||
isn't set and causes the make to fail.
|
||||
|
||||
Daniel (26 April 1999)
|
||||
- Am I silly or what? Irving Wolfe pointed out to me that the curl version
|
||||
number was not set properly. Hasn't been since 5.6. This was due to a bug
|
||||
in my maketgz script!
|
||||
|
||||
David Eriksson (25 Apr 1999)
|
||||
- Found a bug in cookies.c that made it crash at times.
|
||||
|
||||
Version 5.7.1
|
||||
|
||||
Doug Kaufman (23 Apr 1999)
|
||||
- Brought two sunos 4 fixes. One of them being the hostip.c fix mentioned
|
||||
below and the other one a correction in include/stdcheaders.h
|
||||
|
||||
- Added a paragraph about compiling with the US-version of openssl to the
|
||||
INSTALL file.
|
||||
|
||||
Daniel
|
||||
- New mailing list address. Info updated on the web page as well as in the
|
||||
README file
|
||||
|
||||
Greg Onufer (20 Apr 1999)
|
||||
- hostip.c didn't compile properly on SunOS 5.5.1.
|
||||
It needs an #include <sys/types.h>
|
||||
|
||||
Version 5.7
|
||||
|
||||
Daniel (Apr 20 1999)
|
||||
- Decided to upload a non-beta version right now!
|
||||
|
||||
- Made curl support any-length HTTP headers. The destination buffer is now
|
||||
simply enlarged every time it turns out to be too small!
|
||||
|
||||
- Added the FAQ file to the archive. Still a bit smallish, but it is a
|
||||
start.
|
||||
|
||||
Eric Thelin (15 Apr 1999)
|
||||
- Made -D accept '-' instead of filename to write to stdout.
|
||||
|
||||
Version 5.6.3beta
|
||||
|
||||
Daniel (Apr 12 1999)
|
||||
|
||||
- Changed two #ifdef WIN32 to better #ifdef <errorcode> when connect()ing
|
||||
in url.c and ftp.c. Makes cygwin32 deal with them better too. We should
|
||||
try to get some decent win32-replacement there. Anyone?
|
||||
|
||||
- The old -3/--crlf option is now ONLY --crlf!
|
||||
|
||||
- I changed the "SSL fix" to a more lame one, but that doesn't remove as
|
||||
much functionality. Now I've enabled the lib to select what SSL version it
|
||||
should try first. Appearantly some older SSL-servers don't like when you
|
||||
talk v3 with them so you need to be able to force curl to talk v2 from the
|
||||
start. The fix dated April 6 and posted on the mailing list forced curl to
|
||||
use v2 at all times using a modern OpenSSL version, but we don't really
|
||||
want such a crippled solution.
|
||||
|
||||
- Marc Boucher sent me a patch that corrected a math error for the
|
||||
"Curr.Speed" progress meter.
|
||||
|
||||
- Eric Thelin sent me a patch that enables '-K -' to read a config file from
|
||||
stdin.
|
||||
|
||||
- I found out we didn't close the file properly before so I added it!
|
||||
|
||||
Daniel (Apr 9 1999)
|
||||
- Yu Xin pointed out a problem with ftp download resume. It didn't work at
|
||||
all! ;-O
|
||||
|
||||
Daniel (Apr 6 1999)
|
||||
- Corrected the version string part generated for the SSL version.
|
||||
|
||||
- I found a way to make some other SSL page work with openssl 0.9.1+ that
|
||||
previously didn't (ssleay 0.8.0 works with it though!). Trying to get
|
||||
some real info from the OpenSSL guys to see how I should do to behave the
|
||||
best way. SSLeay 0.8.0 shouldn't be that much in use anyway these days!
|
||||
|
||||
Version 5.6.2beta
|
||||
|
||||
Daniel (Apr 4 1999)
|
||||
- Finally have curl more cookie "aware". Now read carefully. This is how
|
||||
it works.
|
||||
To make curl read cookies from an already existing file, in plain header-
|
||||
format (like from the headers of a previous fetch) invoke curl with the
|
||||
-b flag like:
|
||||
|
||||
curl -b file http://site/foo.html
|
||||
|
||||
Curl will then use all cookies it finds matching. The old style that sets
|
||||
a single cookie with -b is still supported and is used if the string
|
||||
following -b includes a '=' letter, as in "-b name=daniel".
|
||||
|
||||
To make curl read the cookies sent in combination with a location: (which
|
||||
sites often do) point curl to read a non-existing file at first (i.e
|
||||
to start with no existing cookies), like:
|
||||
|
||||
curl -b nowhere http://site/setcookieandrelocate.html
|
||||
|
||||
- Added a paragraph in the TODO file about the SSL problems recently
|
||||
reported. Evidently, some kind of SSL-problem curl may need to address.
|
||||
|
||||
- Better "Location:" following.
|
||||
|
||||
Douglas E. Wegscheid (Tue, 30 Mar 1999)
|
||||
- A subsecond display patch.
|
||||
|
||||
Daniel (Mar 14 1999)
|
||||
- I've separated the version number of libcurl and curl now. To make
|
||||
things a little easier, I decided to start the curl numbering from
|
||||
5.6 and the former version number known as "curl" is now the one
|
||||
set for libcurl.
|
||||
|
||||
- Removed the 'enable-no-pass' from configure, I doubt anyone wanted
|
||||
that.
|
||||
|
||||
- Made lots of tiny adjustments to compile smoothly with cygwin under
|
||||
win32. It's a killer for porting this to win32, bye bye VC++! ;-)
|
||||
Compiles and builds out-of-the-box now. See the new wordings in
|
||||
INSTALL for details.
|
||||
|
||||
- Beginning experiments with downloading multiple document from a http
|
||||
server while remaining connected.
|
||||
|
||||
Version 5.6beta
|
||||
|
||||
Daniel (Mar 13 1999)
|
||||
- Since I've changed so much, I thought I'd just go ahead and implement the
|
||||
suggestion from Douglas E. Wegscheid. -D or --dump-header is now storing
|
||||
HTTP headers separately in the specified file.
|
||||
|
||||
- Added new text to INSTALL on what to do to build this on win32 now.
|
||||
|
||||
- Aaargh. I had to take a step back and prefix the shared #include files
|
||||
in the sources with "../include/" to please VC++...
|
||||
|
||||
Daniel (Mar 12 1999)
|
||||
- Split the url.c source into many tiny sources for better readability
|
||||
and smaller size.
|
||||
|
||||
Daniel (Mar 11 1999)
|
||||
- Started to change stuff for a move to make libcurl and a more separate
|
||||
curl application that uses the libcurl. Made the libcurl sources into
|
||||
the new lib directory while the curl application will remain in src as
|
||||
before. New makefiles, adjusted configure script and so.
|
||||
|
||||
libcurl.a built quickly and easily. I better make a better interface to
|
||||
the lib functions though.
|
||||
|
||||
The new root dir include/ is supposed to contain the public information
|
||||
about the new libcurl. It is a little ugly so far :-)
|
||||
|
||||
|
||||
Daniel (Mar 1 1999)
|
||||
- Todd Kaufmann sent me a good link to Netscape's cookie spec as well as the
|
||||
info that RFC 2109 specifies how to use them. The link is now in the
|
||||
README and the RFC in the RESOURCES.
|
||||
|
||||
Daniel (Feb 23 1999)
|
||||
- Finally made configure accept --with-ssl to look for SSL libs and includes
|
||||
in the "standard" place /usr/local/ssl...
|
||||
|
||||
Daniel (Feb 22 1999)
|
||||
- Verified that curl linked fine with OpenSSL 0.9.1c which seems to be
|
||||
the most recent.
|
||||
|
||||
Henri Gomez (Fri Feb 5 1999)
|
||||
- Sent in an updated curl-ssl.spec. I still miss the script that builds an
|
||||
RPM automatically...
|
||||
|
||||
Version 5.5.1
|
||||
|
||||
Mark Butler (27 Jan 1999)
|
||||
- Corrected problems in Download().
|
||||
|
||||
Danitel Stenberg (25 Jan 1999)
|
||||
- Jeremie Petit pointed out a few flaws in the source that prevented it from
|
||||
compile warning free with the native compiler under Digital Unix v4.0d.
|
||||
|
||||
Version 5.5
|
||||
|
||||
Daniel Stenberg (15 Jan 1999)
|
||||
- Added Bjorns small text to the README about the DICT protocol.
|
||||
|
||||
Daniel Stenberg (11 Jan 1999)
|
||||
- <jswink at softcom.net> reported about the win32-versioin: "Doesn't use
|
||||
ALL_PROXY environment variable". Turned out to be because of the static-
|
||||
buffer nature of the win32 environment variable calls!
|
||||
|
||||
Bjorn Reese (10 Jan 1999)
|
||||
- I have attached a simple addition for the DICT protocol (RFC 2229).
|
||||
It performs dictionary lookups. The output still needs to be better
|
||||
formatted.
|
||||
|
||||
To test it try (the exact format, and more examples are described in
|
||||
the RFC)
|
||||
|
||||
dict://dict.org/m:hello
|
||||
dict://dict.org/m:hello::soundex
|
||||
|
||||
|
||||
Vicente Garcia (10 Jan 1999)
|
||||
- Corrected the progress meter for files larger than 20MB.
|
||||
|
||||
Daniel Stenberg (7 Jan 1999)
|
||||
- Corrected the -t and -T help texts. They claimed to be FTP only.
|
||||
|
||||
Version 5.4
|
||||
|
||||
Daniel Stenberg
|
||||
(7 Jan 1999)
|
||||
- Irving Wolfe reported that curl -s didn't always supress the progress
|
||||
reporting. It was the form post that autoamtically always switched it on
|
||||
again. This is now corrected!
|
||||
|
||||
(4 Jan 1999)
|
||||
- Andreas Kostyrka suggested I'd add PUT and he helped me out to test it. If
|
||||
you use -t or -T now on a http or https server, PUT will be used for file
|
||||
upload.
|
||||
|
||||
I removed the former use of -T with HTTP. I doubt anyone ever really used
|
||||
that.
|
||||
|
||||
(4 Jan 1999)
|
||||
- Erik Jacobsen found a width bug in the mprintf() function. I corrected it
|
||||
now.
|
||||
|
||||
(4 Jan 1999)
|
||||
- As John V. Chow pointed out to me, curl accepted very limited URL sizes. It
|
||||
should now accept path parts that are up to at least 4096 bytes.
|
||||
|
||||
- Somehow I screwed up when applying the AIX fix from Gilbert Ramirez, so
|
||||
I redid that now.
|
||||
|
||||
Version 5.3a (win32 only)
|
||||
|
||||
Troy Engel
|
||||
|
835
CHANGES.1999
Normal file
835
CHANGES.1999
Normal file
@@ -0,0 +1,835 @@
|
||||
Daniel (28 December 1999):
|
||||
- Tim Verhoeven correctly identified that curl
|
||||
doesn't support URL formatted file names when getting ftp. Now, there's a
|
||||
problem with getting very weird file names off FTP servers. RFC 959 defines
|
||||
that the file name syntax to use should be the same as in the native OS of
|
||||
the server. Since we don't know the peer server system we currently just
|
||||
translate the URL syntax into plain letters. It is still better and with
|
||||
the solaris 2.6-supplied ftp server it works with spaces in the file names.
|
||||
|
||||
Daniel (27 December 1999):
|
||||
- When curl parsed cookies straight off a remote site, it corrupted the input
|
||||
data, which, if the downloaded headers were stored made very odd characters
|
||||
in the saved data. Correctly identified and reported by Paul Harrington.
|
||||
|
||||
Daniel (13 December 1999):
|
||||
- General cleanups in the library interface. There had been some bad kludges
|
||||
added during times of stress and I did my best to clean them off. It was
|
||||
both regarding the lib API as well as include file confusions.
|
||||
|
||||
Daniel (3 December 1999):
|
||||
- A small --stderr bug was reported by Eetu Ojanen...
|
||||
|
||||
- who also brought the suggestion of extending the -X flag to ftp list as
|
||||
well. So, now it is and the long option is now --request instead. It is
|
||||
only for ftp list for now (and the former http stuff too of course).
|
||||
|
||||
Lars J. Aas (24 November 1999):
|
||||
- Patched curl to compile and build under BeOS. Doesn't work yet though!
|
||||
|
||||
- Corrected the Makefile.am files to allow putting object files in
|
||||
different directories than the sources.
|
||||
|
||||
Version 6.3.1
|
||||
|
||||
Daniel (23 November 1999):
|
||||
- I've had this major disk crash. My good old trust-worthy source disk died
|
||||
along with the machine that hosted it. Thank goodness most of all the
|
||||
things I've done are either backed up elsewhere or stored in this CVS
|
||||
server!
|
||||
|
||||
- Michael S. Steuer pointed out a bug in the -F handling
|
||||
that made curl hang if you posted an empty variable such as '-F name='. It
|
||||
was one of those old bugs that never have worked properly...
|
||||
|
||||
- Jason Baietto pointed out a general flaw in the HTTP
|
||||
download. Curl didn't complain if it was prematurely aborted before the
|
||||
entire download was completed. It does now.
|
||||
|
||||
Daniel (19 November 1999):
|
||||
- Chris Maltby very accurately criticized the lack of
|
||||
return code checks on the fwrite() calls. I did a thorough check for all
|
||||
occurrences and corrected this.
|
||||
|
||||
Daniel (17 November 1999):
|
||||
- Paul Harrington pointed out that the -m/--max-time option
|
||||
doesn't work for the slow system calls like gethostbyname()... I don't have
|
||||
any good fix yet, just a slightly less bad one that makes curl exit hard
|
||||
when the timeout is reached.
|
||||
|
||||
- Bjorn Reese helped me point out a possible problem that might be the reason
|
||||
why Thomas Hurst experience problems in his Amiga version.
|
||||
|
||||
Daniel (12 November 1999):
|
||||
- I found a crash in the new cookie file parser. It crashed when you gave
|
||||
a plain http header file as input...
|
||||
|
||||
Version 6.3
|
||||
|
||||
Daniel (10 November 1999):
|
||||
- I kind of found out that the HTTP time-conditional GETs (-z) aren't always
|
||||
respected by the web server and the document is therefore sent in whole
|
||||
again, even though it doesn't match the requested condition. After reading
|
||||
section 13.3.4 of RFC 2616, I think I'm doing the right thing now when I do
|
||||
my own check as well. If curl thinks the condition isn't met, the transfer
|
||||
is aborted prematurely (after all the headers have been received).
|
||||
|
||||
- After comments from Robert Linden I also rewrote some parts of the man page
|
||||
to better describe how the -F works.
|
||||
|
||||
- Michael Anti put up a new curl download mirror in
|
||||
China: http://www.pshowing.com/curl/
|
||||
|
||||
- I added the list of download mirrors to the README file
|
||||
|
||||
- I did add more explanations to the man page
|
||||
|
||||
Daniel (8 November 1999):
|
||||
- I made the -b/--cookie option capable of reading netscape formatted cookie
|
||||
files as well as normal http-header files. It should be able to
|
||||
transparently figure out what kind of file it got as input.
|
||||
|
||||
Daniel (29 October 1999):
|
||||
- Another one of Sebastiaan van Erk's ideas (that has been requested before
|
||||
but I seem to have forgotten who it was), is to add support for ranges in
|
||||
FTP downloads. As usual, one request is just a request, when they're two
|
||||
it is a demand. I've added simple support for X-Y style fetches. X has to
|
||||
be the lower number, though you may omit one of the numbers. Use the -r/
|
||||
--range switch (previously HTTP-only).
|
||||
|
||||
- Sebastiaan van Erk suggested that curl should be
|
||||
able to show the file size of a specified file. I think this is a splendid
|
||||
idea and the -I flag is now working for FTP. It displays the file size in
|
||||
this manner:
|
||||
Content-Length: XXXX
|
||||
As it resembles normal headers, and leaves us the opportunity to add more
|
||||
info in that display if we can come up with more in the future! It also
|
||||
makes sense since if you access ftp through a HTTP proxy, you'd get the
|
||||
file size the same way.
|
||||
|
||||
I changed the order of the QUOTE command executions. They're now executed
|
||||
just after the login and before any other command. I made this to enable
|
||||
quote commands to run before the -I stuff is done too.
|
||||
|
||||
- I found out that -D/--dump-header and -V/--version weren't documented in
|
||||
the man page.
|
||||
|
||||
- Many HTTP/1.1 servers do not support ranges. Don't ask me why. I did add
|
||||
some text about this in the man page for the range option. The thread in
|
||||
the mailing list that started this was initiated by Michael Anti.
|
||||
|
||||
- I get reports about nroff crashes on solaris 2.6+ when displaying the curl
|
||||
man page. Switch to gnroff instead, it is reported to work(!). Adam Barclay
|
||||
reported and brought the suggestion.
|
||||
|
||||
- In a dialogue with Johannes G. Kristinsson we came
|
||||
up with the idea to let -H/--header specified headers replace the
|
||||
internally generated headers, if you happened to select to add a header
|
||||
that curl normally uses by itself. The advantage with this is not entirely
|
||||
obvious, but in Johannes' case it means that he can use another Host: than
|
||||
the one curl would set.
|
||||
|
||||
Daniel (27 October 1999):
|
||||
- Jongki Suwandi brought a nice patch for (yet another) crash when following
|
||||
a location:. This time you had to follow a https:// server's redirect to
|
||||
get the core.
|
||||
|
||||
Version 6.2
|
||||
|
||||
Daniel (21 October 1999):
|
||||
- I think I managed to remove the suspicious (nil) that has been seen just
|
||||
before the "Host:" in HTTP requests when -v was used.
|
||||
- I found out that if you followed a location: when using a proxy, without
|
||||
having specified http:// in the URL, the protocol part was added once again
|
||||
when moving to the next URL! (The protocol part has to be added to the
|
||||
URL when going through a proxy since it has no protocol-guessing system
|
||||
such as curl has.)
|
||||
- Benjamin Ritcey reported a core dump under solaris 2.6
|
||||
with OpenSSL 0.9.4. It turned out this was due to a bad free() in main.c
|
||||
that occurred after the download was done and completed.
|
||||
- Benjamin found ftp downloads to show the first line of the download meter
|
||||
to get written twice, and I removed that problem. It was introduced with
|
||||
the multiple URL support.
|
||||
- Dan Zitter correctly pointed out that curl 6.1 and earlier versions didn't
|
||||
honor RFC 2616 chapter 4 section 2, "Message Headers": "...Field names are
|
||||
case-insensitive..." HTTP header parsing assumed a certain casing. Dan
|
||||
also provided me with a patch that corrected this, which I took the liberty
|
||||
of editing slightly.
|
||||
- Dan Zitter also provided a nice patch for config.guess to better recognize
|
||||
the Mac OS X
|
||||
- Dan also corrected a minor problem in the lib/Makefile that caused linking
|
||||
to fail on OS X.
|
||||
|
||||
Daniel (19 October 1999):
|
||||
- Len Marinaccio came up with some problems with curl. Since Windows has a
|
||||
crippled shell, it can't redirect stderr and that causes trouble. I added
|
||||
--stderr today which allows the user to redirect the stderr stream to a
|
||||
file or stdout.
|
||||
|
||||
Daniel (18 October 1999):
|
||||
- The configure script now understands the '--without-ssl' flag, which now
|
||||
totally disable SSL/https support. Previously it wasn't possible to force
|
||||
the configure script to leave SSL alone. The previous functionality has
|
||||
been retained. Troy Engel helped test this new one.
|
||||
|
||||
Version 6.1
|
||||
|
||||
Daniel (17 October 1999):
|
||||
- I ifdef'ed or commented all the zlib stuff in the sources and configure
|
||||
script. It turned out we needed to mock more with zlib than I initially
|
||||
thought, to make it capable of downloading compressed HTTP documents and
|
||||
uncompress them on the fly. I didn't mean the zlib parts of curl to become
|
||||
more than minor so this means I halt the zlib expedition for now and wait
|
||||
until someone either writes the code or zlib gets updated and better
|
||||
adjusted for this kind of usage. I won't get into details here, but a
|
||||
short a summary is suitable:
|
||||
- zlib can't automatically detect whether to use zlib or gzip
|
||||
decompression methods.
|
||||
- zlib is very neat for reading gzipped files from a file descriptor,
|
||||
although not as nice for reading buffer-based data such as we would
|
||||
want it.
|
||||
- there are still some problems with the win32 version when reading from
|
||||
a file descriptor if that is a socket
|
||||
|
||||
Daniel (14 October 1999):
|
||||
- Moved the (external) include files for libcurl into a subdirectory named
|
||||
curl and adjusted all #include lines to use <curl/XXXX> to maintain a
|
||||
better name space and control of the headers. This has been requested.
|
||||
|
||||
Daniel (12 October 1999):
|
||||
- I modified the 'maketgz' script to perform a 'make' too before a release
|
||||
archive is put together in an attempt to make the time stamps better and
|
||||
hopefully avoid the double configure-running that use to occur.
|
||||
|
||||
Daniel (11 October 1999):
|
||||
- Applied J<>rn's patches that fixes zlib for mingw32 compiles as well as
|
||||
some other missing zlib #ifdef and more text on the multiple URL docs in
|
||||
the man page.
|
||||
|
||||
Version 6.1beta
|
||||
|
||||
Daniel (6 October 1999):
|
||||
- Douglas E. Wegscheid sent me a patch that made the exact same thing as I
|
||||
just made: the -d switch is now capable of reading post data from a named
|
||||
file or stdin. Use it similarly to the -F. To read the post data from a
|
||||
given file:
|
||||
|
||||
curl -d @path/to/filename www.postsite.com
|
||||
|
||||
or let curl read it out from stdin:
|
||||
|
||||
curl -d @- www.postit.com
|
||||
|
||||
J<>rn Hartroth (3 October 1999):
|
||||
- Brought some more patches for multiple URL functionality. The MIME
|
||||
separation ideas are almost scrapped now, and a custom separator is being
|
||||
used instead. This is still compile-time "flagged".
|
||||
|
||||
Daniel
|
||||
- Updated curl.1 with multiple URL info.
|
||||
|
||||
Daniel (30 September 1999):
|
||||
- Felix von Leitner brought openssl-check fixes for configure.in to work
|
||||
out-of-the-box when the openssl files are installed in the system default
|
||||
dirs.
|
||||
|
||||
Daniel (28 September 1999)
|
||||
- Added libz functionality. This should enable decompressing gzip, compress
|
||||
or deflate encoding HTTP documents. It also makes curl send an accept that
|
||||
it accepts that kind of encoding. Compressed contents usually shortens
|
||||
download time. I *need* someone to tell me a site that uses compressed HTTP
|
||||
documents so that I can test this out properly.
|
||||
|
||||
- As a result of the adding of zlib awareness, I changed the version string
|
||||
a little. I plan to add openldap version reporting in there too.
|
||||
|
||||
Daniel (17 September 1999)
|
||||
- Made the -F option allow stdin when specifying files. By using '-' instead
|
||||
of file name, the data will be read from stdin.
|
||||
|
||||
Version 6.0
|
||||
|
||||
Daniel (13 September 1999)
|
||||
- Added -X/--http-request <request> to enable any HTTP command to be sent.
|
||||
Do not that your server has to support the exact string you enter. This
|
||||
should possibly a string like DELETE or TRACE.
|
||||
|
||||
- Applied Douglas' mingw32-fixes for the makefiles.
|
||||
|
||||
Daniel (10 September 1999)
|
||||
- Douglas E. Wegscheid pointed out a problem. Curl didn't check the FTP
|
||||
servers return code properly after the --quote commands were issued. It
|
||||
took anything non 200 as an error, when all 2XX codes should be accepted as
|
||||
OK.
|
||||
|
||||
- Sending cookies to the same site in multiple lines like curl used to do
|
||||
turned out to be bad and breaking the cookie specs. Curl now sends all
|
||||
cookies on a single Cookie: line. Curl is not yet RFC 2109 compliant, but I
|
||||
doubt that many servers do use that syntax (yet).
|
||||
|
||||
Daniel (8 September 1999)
|
||||
- J<>rn helped me make sure it still compiles nicely with mingw32 under win32.
|
||||
|
||||
Daniel (7 September 1999)
|
||||
- FTP upload through proxy is now turned into a HTTP PUT. Requested by
|
||||
Stefan Kanthak.
|
||||
|
||||
- Added the ldap files to the .m32 makefile.
|
||||
|
||||
Daniel (3 September 1999)
|
||||
- Made cookie matching work while using HTTP proxy.
|
||||
|
||||
Bjorn Reese (31 August 1999)
|
||||
- Passed his ldap:// patch. Note that this requires the openldap shared
|
||||
library to be installed and that LD_LIBRARY_PATH points to the
|
||||
directory where the lib will be found when curl is run with a
|
||||
ldap:// URL.
|
||||
|
||||
J<>rn Hartroth (31 August 1999)
|
||||
- Made the Mingw32 makefiles into single files.
|
||||
- Made file:// work for Win32. The same code is now used for unix as well for
|
||||
performance reasons.
|
||||
|
||||
Douglas E. Wegscheid (30 August 1999)
|
||||
- Patched the Mingw32 makefiles for SSL builds.
|
||||
|
||||
Matthew Clarke (30 August 1999)
|
||||
- Made a cool patch for configure.in to allow --with-ssl to specify the
|
||||
root dir of the openssl installation, as in
|
||||
|
||||
./configure --with-ssl=/usr/ssl_here
|
||||
|
||||
- Corrected the 'reconf' script to work better with some shells.
|
||||
|
||||
J<>rn Hartroth (26 August 1999)
|
||||
- Fixed the Mingw32 makefiles in lib/ and corrected the file.c for win32
|
||||
compiles.
|
||||
|
||||
Version 5.11
|
||||
|
||||
Daniel (25 August 1999)
|
||||
- John Weismiller pointed out a bug in the header-line
|
||||
realloc() system in download.c.
|
||||
|
||||
- I added lib/file.[ch] to offer a first, simple, file:// support. It
|
||||
probably won't do much good on win32 system at this point, but I see it
|
||||
as a start.
|
||||
|
||||
- Made the release archives get a Makefile in the root dir, which can be
|
||||
used to start the compiling/building process easier. I haven't really
|
||||
changed any INSTALL text yet, I wanted to get some feed-back on this
|
||||
first.
|
||||
|
||||
Daniel (17 August 1999)
|
||||
- Another Location: bug. Curl didn't do proper relative locations if the
|
||||
original URL had cgi-parameters that contained a slash. Nusu's page
|
||||
again.
|
||||
|
||||
- Corrected the NO_PROXY usage. It is a list of substrings that if one of
|
||||
them matches the tail of the host name it should connect to, curl should
|
||||
not use a proxy to connect there. Pointed out to me by Douglas
|
||||
E. Wegscheid. I also changed the README text a little regarding this.
|
||||
|
||||
Daniel (16 August 1999)
|
||||
- Fixed a memory bug with http-servers that sent Location: to a Location:
|
||||
page. Nusu's page showed this too.
|
||||
|
||||
- Made cookies work a lot better. Setting the same cookie name several times
|
||||
used to add more cookies instead of replacing the former one which it
|
||||
should've. Nusu <nus at intergorj.ro> brought me an URL that made this
|
||||
painfully visible...
|
||||
|
||||
Troy (15 August 1999)
|
||||
- Brought new .spec files as well as a patch for configure.in that lets the
|
||||
configure script find the openssl files better, even when the include
|
||||
files are in /usr/include/openssl
|
||||
|
||||
Version 5.10
|
||||
|
||||
Daniel (13 August 1999)
|
||||
- SSL_CTX_set_default_passwd_cb() has been modified in the 0.9.4 version of
|
||||
OpenSSL. Now why couldn't they simply add a *new* function instead of
|
||||
modifying the parameters of an already existing function? This way, we get
|
||||
a compiler warning if compiling with 0.9.4 but not with earlier. So, I had
|
||||
to come up with a #if construction that deals with this...
|
||||
|
||||
- Made curl output the SSL version number get displayed properly with 0.9.4.
|
||||
|
||||
Troy (12 August 1999)
|
||||
- Added MingW32 (GCC-2.95) support under Win32. The INSTALL file was also
|
||||
a bit rearranged.
|
||||
|
||||
Daniel (12 August 1999)
|
||||
- I had to copy a good <arpa/telnet.h> include file into the curl source
|
||||
tree to enable the silly win32 systems to compile. The distribution rights
|
||||
allows us to do that as long as the file remains unmodified.
|
||||
|
||||
- I corrected a few minor things that made the compiler complain when
|
||||
-Wall -pedantic was used.
|
||||
|
||||
- I'm moving the official curl web page to http://curl.haxx.nu. I think it
|
||||
will make it easier to remember as it is a lot shorter and less cryptic.
|
||||
The old one still works and shows the same info.
|
||||
|
||||
Daniel (11 August 1999)
|
||||
- Albert Chin-A-Young mailed me another correction for NROFF in the
|
||||
configure.in that is supposed to be better for IRIX users.
|
||||
|
||||
Daniel (10 August 1999)
|
||||
- Albert Chin-A-Young helped me with some stupid Makefile things, as well as
|
||||
some fiddling with the getdate.c stuff that he had problems with under
|
||||
HP-UX v10. getdate.y will now be compiled into getdate.c if the appropriate
|
||||
yacc or bison is found by the configure script. Since this is slightly new,
|
||||
we need to test the output getdate.c with win32 systems to make sure it
|
||||
still compiles there.
|
||||
|
||||
Daniel (5 August 1999)
|
||||
- I've just setup a new mailing list with the intention to keep discussions
|
||||
around libcurl development in it. I mainly expect it to be for thoughts and
|
||||
brainstorming around a "next generation" library, rather than nitpicking
|
||||
about the current implementation or details in the current libcurl.
|
||||
|
||||
To join our happy bunch of future-looking geeks, enter 'subscribe
|
||||
<address>' in the body of a mail and send it to
|
||||
libcurl-request@listserv.fts.frontec.se. Curl bug reports, the usual curl
|
||||
talk and everything else should still be kept in this mailing list. I've
|
||||
started to archive this mailing list and have put the libcurl web page at
|
||||
www.fts.frontec.se/~dast/libcurl/.
|
||||
|
||||
- Stefan Kanthak contacted me regarding a few problems in the configure
|
||||
script which he discovered when trying to make curl compile and build under
|
||||
Siemens SINIX-Z V5.42B2004!
|
||||
|
||||
- Marcus Klein very accurately informed me that src/version.h was not present
|
||||
in the CVS repository. Oh, how silly...
|
||||
|
||||
- Linus Nielsen rewrote the telnet:// part and now curl offers limited telnet
|
||||
support. If you run curl like 'curl telnet://host' you'll get all output on
|
||||
the screen and curl will read input from stdin. You'll be able to login and
|
||||
run commands etc, but since the output is buffered, expect to get a little
|
||||
weird output.
|
||||
|
||||
This is still in its infancy and it might get changed. We need your
|
||||
feed-back and input in how this is best done.
|
||||
|
||||
WIN32 NOTE: I bet we'll get problems when trying to compile the current
|
||||
lib/telnet.c on win32, but I think we can sort them out in time.
|
||||
|
||||
- David Sanderson reported that FORCE_ALLOCA_H or HAVE_ALLOCA_H must be
|
||||
defined for getdate.c to compile properly on HP-UX 11.0. I updated the
|
||||
configure script to check for alloca.h which should make it.
|
||||
|
||||
Daniel (4 August 1999)
|
||||
- I finally got to understand Marcus Klein's ftp download resume problem,
|
||||
which turns out to be due to different outputs from different ftp
|
||||
servers. It makes ftp download resuming a little trickier, but I've made
|
||||
some modifications I really believe will work for most ftp servers and I do
|
||||
hope you report if you have problems with this!
|
||||
|
||||
- Added text about file transfer resuming to README.curl.
|
||||
|
||||
Daniel (2 August 1999)
|
||||
- Applied a progress-bar patch from Lars J. Aas. It offers
|
||||
a new styled progress bar enabled with -#/--progress-bar.
|
||||
|
||||
T. Yamada <tai at imasy.or.jp> (30 July 1999)
|
||||
- It breaks with segfault when 1) curl is using .netrc to obtain
|
||||
username/password (option '-n'), and 2) is automatically redirected to
|
||||
another location (option '-L').
|
||||
|
||||
There is a small bug in lib/url.c (block starting from line 641), which
|
||||
tries to take out username/password from user- supplied command-line
|
||||
argument ('-u' option). This block is never executed on first attempt since
|
||||
CONF_USERPWD bit isn't set at first, but curl later turns it on when it
|
||||
checks for CONF_NETRC bit. So when curl tries to redo everything due to
|
||||
redirection, it segfaults trying to access *data->userpwd.
|
||||
|
||||
Version 5.9.1
|
||||
|
||||
Daniel (30 July 1999)
|
||||
- Steve Walch pointed out that there is a memory leak in the formdata
|
||||
functions. I added a FormFree() function that is now used and supposed to
|
||||
correct this flaw.
|
||||
|
||||
- Mark Wotton reported:
|
||||
'curl -L https://www.cwa.com.au/' core dumps. I managed to cure this by
|
||||
correcting the cleanup procedure. The bug seems to be gone with my OpenSSL
|
||||
0.9.2b, although still occurs when I run the ~100 years old SSLeay 0.8.0. I
|
||||
don't know whether it is curl or SSLeay that is to blame for that.
|
||||
|
||||
- Marcus Klein:
|
||||
Reported an FTP upload resume bug that I really can't repeat nor understand.
|
||||
I leave it here so that it won't be forgotten.
|
||||
|
||||
Daniel (29 July 1999)
|
||||
- Costya Shulyupin suggested support for longer URLs when following Location:
|
||||
and I could only agree and fix it!
|
||||
|
||||
- Leigh Purdie found a problem in the upload/POST department. It turned out
|
||||
that http.c accidentaly cleared the pointer instead of the byte counter
|
||||
when supposed to.
|
||||
|
||||
- Costya Shulyupin pointed out a problem with port numbers and Location:. If
|
||||
you had a server at a non-standard port that redirected to an URL using a
|
||||
standard port number, curl still used that first port number.
|
||||
|
||||
- Ralph Beckmann pointed out a problem when using both CONF_FOLLOWLOCATION
|
||||
and CONF_FAILONERROR simultaneously. Since the CONF_FAILONERROR exits on
|
||||
the 302-code that the follow location header outputs it will never show any
|
||||
html on location: pages. I have now made it look for >=400 codes if
|
||||
CONF_FOLLOWLOCATION is set.
|
||||
|
||||
- 'struct slist' is now renamed to 'struct curl_slist' (as suggested by Ralph
|
||||
Beckmann).
|
||||
|
||||
- Joshua Swink and Rick Welykochy were the first to point out to me that the
|
||||
latest OpenSSL package now have moved the standard include path. It is now
|
||||
in /usr/local/ssl/include/openssl and I have now modified the --enable-ssl
|
||||
option for the configure script to use that as the primary path, and I
|
||||
leave the former path too to work with older packages of OpenSSL too.
|
||||
|
||||
Daniel (9 June 1999)
|
||||
- I finally understood the IRIX problem and now it seem to compile on it!
|
||||
I am gonna remove those #define strcasecmp() things once and for all now.
|
||||
|
||||
Daniel (4 June 1999)
|
||||
- I adjusted the FTP reply 227 parser to make the PASV command work better
|
||||
with more ftp servers. Appearantly the Roxen Challanger server replied
|
||||
something curl 5.9 could deal with! :-( Reported by Ashley Reid-Montanaro
|
||||
and Mark Butler brought a solution for it.
|
||||
|
||||
Daniel (26 May 1999)
|
||||
- Rearranged. README is new, the old one is now README.curl and I added a
|
||||
README.libcurl with text I got from Ralph Beckmann.
|
||||
|
||||
- I also updated the INSTALL text.
|
||||
|
||||
Daniel (25 May 1999)
|
||||
- David Jonathan Lowsky correctly pointed out that curl didn't properly deal
|
||||
with form posting where the variable shouldn't have any content, as in curl
|
||||
-F "form=" www.site.com. It was now fixed.
|
||||
|
||||
Version 5.9
|
||||
|
||||
Daniel (22 May 1999)
|
||||
- I've got a bug report from Aaron Scarisbrick in which he states he has some
|
||||
problems with -L under FreeBSD 3.0. I have previously got another bug
|
||||
report from Stefan Grether which points at an error with similar sympthoms
|
||||
when using win32. I made the allocation of the new url string a bit faster
|
||||
and different, don't know if it actually improves anything though...
|
||||
|
||||
Daniel (20 May 1999)
|
||||
- Made the cookie parser deal with CRLF newlines too.
|
||||
|
||||
Daniel (19 May 1999)
|
||||
- Download() didn't properly deal with failing return codes from the sread()
|
||||
function. Adam Coyne found the problem in the win32 version, and Troy Engel
|
||||
helped me out isolating it.
|
||||
|
||||
Daniel (16 May 1999)
|
||||
- Richard Adams pointed out a bug I introduced in 5.8. --dump-header doesn't
|
||||
work anymore! :-/ I fixed it now.
|
||||
|
||||
- After a suggestion by Joshua Swink I added -S / --show-error to force curl
|
||||
to display the error message in case of an error, even if -s/--silent was
|
||||
used.
|
||||
|
||||
Daniel (10 May 1999)
|
||||
- I moved the stuff concerning HTTP, DICT and TELNET it their own source
|
||||
files now. It is a beginning on my clean-up of the sources to make them
|
||||
layer all those protocols better to enable more to be added easier in the
|
||||
future!
|
||||
|
||||
- Leon Breedt sent me some files I've not put into the main curl
|
||||
archive. They're for creating the Debian package thingie. He also sent me a
|
||||
debian package that I've made available for download at the web page
|
||||
|
||||
Daniel (9 May 1999)
|
||||
- Made it compile on cygwin too.
|
||||
|
||||
Troy Engel (7 May 1999)
|
||||
- Brought a series of patches to allow curl to compile smoothly on MSVC++ 6
|
||||
again!
|
||||
|
||||
Daniel (6 May 1999)
|
||||
- I changed the #ifdef HAVE_STRFTIME placement for the -z code so that it
|
||||
will be easier to discover systems that don't have that function and thus
|
||||
can't use -z successfully. Made the strftime() get used if WIN32 is defined
|
||||
too.
|
||||
|
||||
Version 5.8
|
||||
|
||||
Daniel (5 May 1999)
|
||||
- I've had it with this autoconf/automake mess. It seems to work allright
|
||||
for most people who don't have automake installed, but for those who have
|
||||
there are problems all over.
|
||||
|
||||
I've got like five different bug reports on this only the last
|
||||
week... Claudio Neves and Federico Bianchi and root <duggerj001 at
|
||||
hawaii.rr.com> are some of them reporting this.
|
||||
|
||||
Currently, I have no really good fix since I want to use automake myself to
|
||||
generate the Makefile.in files. I've found out that the @SHELL@-problems
|
||||
can often be fixed by manually invoking 'automake' in the archive root
|
||||
before you run ./configure... I've hacked my maketgz script now to fiddle
|
||||
a bit with this and my tests seem to work better than before at least!
|
||||
|
||||
Daniel (4 May 1999)
|
||||
- mkhelp.pl has been doing badly lately. I corrected a case problem in
|
||||
the regexes.
|
||||
|
||||
- I've now remade the -o option to not touch the file unless it needs to.
|
||||
I had to do this to make -z option really fine, since now you can make a
|
||||
curl fetch and use a local copy's time when downloading to that file, as
|
||||
in:
|
||||
|
||||
curl -z dump -o dump remote.site.com/file.html
|
||||
|
||||
This will only get the file if the remote one is newer than the local.
|
||||
I'm aware that this alters previous behaviour a little. Some scripts out
|
||||
there may depend on that the file is always touched...
|
||||
|
||||
- Corrected a bug in the SSLv2/v3 selection.
|
||||
|
||||
- Felix von Leitner requested that curl should be able to send
|
||||
"If-Modified-Since" headers, which indeed is a fair idea. I implemented it
|
||||
right away! Try -z <expression> where expression is a full GNU date
|
||||
expression or a file name to get the date from!
|
||||
|
||||
Stephan Lagerholm (30 Apr 1999)
|
||||
- Pointed out a problem with the src/Makefile for FreeBSD. The RM variable
|
||||
isn't set and causes the make to fail.
|
||||
|
||||
Daniel (26 April 1999)
|
||||
- Am I silly or what? Irving Wolfe pointed out to me that the curl version
|
||||
number was not set properly. Hasn't been since 5.6. This was due to a bug
|
||||
in my maketgz script!
|
||||
|
||||
David Eriksson (25 Apr 1999)
|
||||
- Found a bug in cookies.c that made it crash at times.
|
||||
|
||||
Version 5.7.1
|
||||
|
||||
Doug Kaufman (23 Apr 1999)
|
||||
- Brought two sunos 4 fixes. One of them being the hostip.c fix mentioned
|
||||
below and the other one a correction in include/stdcheaders.h
|
||||
|
||||
- Added a paragraph about compiling with the US-version of openssl to the
|
||||
INSTALL file.
|
||||
|
||||
Daniel
|
||||
- New mailing list address. Info updated on the web page as well as in the
|
||||
README file
|
||||
|
||||
Greg Onufer (20 Apr 1999)
|
||||
- hostip.c didn't compile properly on SunOS 5.5.1.
|
||||
It needs an #include <sys/types.h>
|
||||
|
||||
Version 5.7
|
||||
|
||||
Daniel (Apr 20 1999)
|
||||
- Decided to upload a non-beta version right now!
|
||||
|
||||
- Made curl support any-length HTTP headers. The destination buffer is now
|
||||
simply enlarged every time it turns out to be too small!
|
||||
|
||||
- Added the FAQ file to the archive. Still a bit smallish, but it is a
|
||||
start.
|
||||
|
||||
Eric Thelin (15 Apr 1999)
|
||||
- Made -D accept '-' instead of filename to write to stdout.
|
||||
|
||||
Version 5.6.3beta
|
||||
|
||||
Daniel (Apr 12 1999)
|
||||
|
||||
- Changed two #ifdef WIN32 to better #ifdef <errorcode> when connect()ing
|
||||
in url.c and ftp.c. Makes cygwin32 deal with them better too. We should
|
||||
try to get some decent win32-replacement there. Anyone?
|
||||
|
||||
- The old -3/--crlf option is now ONLY --crlf!
|
||||
|
||||
- I changed the "SSL fix" to a more lame one, but that doesn't remove as
|
||||
much functionality. Now I've enabled the lib to select what SSL version it
|
||||
should try first. Appearantly some older SSL-servers don't like when you
|
||||
talk v3 with them so you need to be able to force curl to talk v2 from the
|
||||
start. The fix dated April 6 and posted on the mailing list forced curl to
|
||||
use v2 at all times using a modern OpenSSL version, but we don't really
|
||||
want such a crippled solution.
|
||||
|
||||
- Marc Boucher sent me a patch that corrected a math error for the
|
||||
"Curr.Speed" progress meter.
|
||||
|
||||
- Eric Thelin sent me a patch that enables '-K -' to read a config file from
|
||||
stdin.
|
||||
|
||||
- I found out we didn't close the file properly before so I added it!
|
||||
|
||||
Daniel (Apr 9 1999)
|
||||
- Yu Xin pointed out a problem with ftp download resume. It didn't work at
|
||||
all! ;-O
|
||||
|
||||
Daniel (Apr 6 1999)
|
||||
- Corrected the version string part generated for the SSL version.
|
||||
|
||||
- I found a way to make some other SSL page work with openssl 0.9.1+ that
|
||||
previously didn't (ssleay 0.8.0 works with it though!). Trying to get
|
||||
some real info from the OpenSSL guys to see how I should do to behave the
|
||||
best way. SSLeay 0.8.0 shouldn't be that much in use anyway these days!
|
||||
|
||||
Version 5.6.2beta
|
||||
|
||||
Daniel (Apr 4 1999)
|
||||
- Finally have curl more cookie "aware". Now read carefully. This is how
|
||||
it works.
|
||||
To make curl read cookies from an already existing file, in plain header-
|
||||
format (like from the headers of a previous fetch) invoke curl with the
|
||||
-b flag like:
|
||||
|
||||
curl -b file http://site/foo.html
|
||||
|
||||
Curl will then use all cookies it finds matching. The old style that sets
|
||||
a single cookie with -b is still supported and is used if the string
|
||||
following -b includes a '=' letter, as in "-b name=daniel".
|
||||
|
||||
To make curl read the cookies sent in combination with a location: (which
|
||||
sites often do) point curl to read a non-existing file at first (i.e
|
||||
to start with no existing cookies), like:
|
||||
|
||||
curl -b nowhere http://site/setcookieandrelocate.html
|
||||
|
||||
- Added a paragraph in the TODO file about the SSL problems recently
|
||||
reported. Evidently, some kind of SSL-problem curl may need to address.
|
||||
|
||||
- Better "Location:" following.
|
||||
|
||||
Douglas E. Wegscheid (Tue, 30 Mar 1999)
|
||||
- A subsecond display patch.
|
||||
|
||||
Daniel (Mar 14 1999)
|
||||
- I've separated the version number of libcurl and curl now. To make
|
||||
things a little easier, I decided to start the curl numbering from
|
||||
5.6 and the former version number known as "curl" is now the one
|
||||
set for libcurl.
|
||||
|
||||
- Removed the 'enable-no-pass' from configure, I doubt anyone wanted
|
||||
that.
|
||||
|
||||
- Made lots of tiny adjustments to compile smoothly with cygwin under
|
||||
win32. It's a killer for porting this to win32, bye bye VC++! ;-)
|
||||
Compiles and builds out-of-the-box now. See the new wordings in
|
||||
INSTALL for details.
|
||||
|
||||
- Beginning experiments with downloading multiple document from a http
|
||||
server while remaining connected.
|
||||
|
||||
Version 5.6beta
|
||||
|
||||
Daniel (Mar 13 1999)
|
||||
- Since I've changed so much, I thought I'd just go ahead and implement the
|
||||
suggestion from Douglas E. Wegscheid. -D or --dump-header is now storing
|
||||
HTTP headers separately in the specified file.
|
||||
|
||||
- Added new text to INSTALL on what to do to build this on win32 now.
|
||||
|
||||
- Aaargh. I had to take a step back and prefix the shared #include files
|
||||
in the sources with "../include/" to please VC++...
|
||||
|
||||
Daniel (Mar 12 1999)
|
||||
- Split the url.c source into many tiny sources for better readability
|
||||
and smaller size.
|
||||
|
||||
Daniel (Mar 11 1999)
|
||||
- Started to change stuff for a move to make libcurl and a more separate
|
||||
curl application that uses the libcurl. Made the libcurl sources into
|
||||
the new lib directory while the curl application will remain in src as
|
||||
before. New makefiles, adjusted configure script and so.
|
||||
|
||||
libcurl.a built quickly and easily. I better make a better interface to
|
||||
the lib functions though.
|
||||
|
||||
The new root dir include/ is supposed to contain the public information
|
||||
about the new libcurl. It is a little ugly so far :-)
|
||||
|
||||
|
||||
Daniel (Mar 1 1999)
|
||||
- Todd Kaufmann sent me a good link to Netscape's cookie spec as well as the
|
||||
info that RFC 2109 specifies how to use them. The link is now in the
|
||||
README and the RFC in the RESOURCES.
|
||||
|
||||
Daniel (Feb 23 1999)
|
||||
- Finally made configure accept --with-ssl to look for SSL libs and includes
|
||||
in the "standard" place /usr/local/ssl...
|
||||
|
||||
Daniel (Feb 22 1999)
|
||||
- Verified that curl linked fine with OpenSSL 0.9.1c which seems to be
|
||||
the most recent.
|
||||
|
||||
Henri Gomez (Fri Feb 5 1999)
|
||||
- Sent in an updated curl-ssl.spec. I still miss the script that builds an
|
||||
RPM automatically...
|
||||
|
||||
Version 5.5.1
|
||||
|
||||
Mark Butler (27 Jan 1999)
|
||||
- Corrected problems in Download().
|
||||
|
||||
Danitel Stenberg (25 Jan 1999)
|
||||
- Jeremie Petit pointed out a few flaws in the source that prevented it from
|
||||
compile warning free with the native compiler under Digital Unix v4.0d.
|
||||
|
||||
Version 5.5
|
||||
|
||||
Daniel Stenberg (15 Jan 1999)
|
||||
- Added Bjorns small text to the README about the DICT protocol.
|
||||
|
||||
Daniel Stenberg (11 Jan 1999)
|
||||
- <jswink at softcom.net> reported about the win32-versioin: "Doesn't use
|
||||
ALL_PROXY environment variable". Turned out to be because of the static-
|
||||
buffer nature of the win32 environment variable calls!
|
||||
|
||||
Bjorn Reese (10 Jan 1999)
|
||||
- I have attached a simple addition for the DICT protocol (RFC 2229).
|
||||
It performs dictionary lookups. The output still needs to be better
|
||||
formatted.
|
||||
|
||||
To test it try (the exact format, and more examples are described in
|
||||
the RFC)
|
||||
|
||||
dict://dict.org/m:hello
|
||||
dict://dict.org/m:hello::soundex
|
||||
|
||||
|
||||
Vicente Garcia (10 Jan 1999)
|
||||
- Corrected the progress meter for files larger than 20MB.
|
||||
|
||||
Daniel Stenberg (7 Jan 1999)
|
||||
- Corrected the -t and -T help texts. They claimed to be FTP only.
|
||||
|
||||
Version 5.4
|
||||
|
||||
Daniel Stenberg
|
||||
(7 Jan 1999)
|
||||
- Irving Wolfe reported that curl -s didn't always supress the progress
|
||||
reporting. It was the form post that autoamtically always switched it on
|
||||
again. This is now corrected!
|
||||
|
||||
(4 Jan 1999)
|
||||
- Andreas Kostyrka suggested I'd add PUT and he helped me out to test it. If
|
||||
you use -t or -T now on a http or https server, PUT will be used for file
|
||||
upload.
|
||||
|
||||
I removed the former use of -T with HTTP. I doubt anyone ever really used
|
||||
that.
|
||||
|
||||
(4 Jan 1999)
|
||||
- Erik Jacobsen found a width bug in the mprintf() function. I corrected it
|
||||
now.
|
||||
|
||||
(4 Jan 1999)
|
||||
- As John V. Chow pointed out to me, curl accepted very limited URL sizes. It
|
||||
should now accept path parts that are up to at least 4096 bytes.
|
||||
|
||||
- Somehow I screwed up when applying the AIX fix from Gilbert Ramirez, so
|
||||
I redid that now.
|
||||
|
40
CVS-INFO
40
CVS-INFO
@@ -10,14 +10,10 @@ This file is only present in the CVS - never in release archives. It contains
|
||||
information about other files and things that the CVS repository keeps in its
|
||||
inner sanctum.
|
||||
|
||||
Use autoconf 2.50 and no earlier. Also, try having automake 1.5 and libtool
|
||||
1.4.1 at least.
|
||||
|
||||
You will need perl to generate the src/hugehelp.c file. The file
|
||||
src/hugehelp.c.cvs is a one-shot file that you can rename to src/hugehelp.c if
|
||||
you really can't generate the true file yourself!
|
||||
Compile and build instructions follow below.
|
||||
|
||||
CHANGES.0 contains ancient changes.
|
||||
CHANGES.$year contains changes for the particular year.
|
||||
|
||||
memanalyze.pl is for analyzing the output generated by curl if -DMALLOCDEBUG
|
||||
is used when compiling
|
||||
@@ -26,12 +22,38 @@ you really can't generate the true file yourself!
|
||||
|
||||
Makefile.dist is included as the root Makefile in distribution archives
|
||||
|
||||
perl/contrib/ is a subdirectory with various perl scripts
|
||||
|
||||
java/ is a subdirectory with the Java interface to libcurl
|
||||
perl/ is a subdirectory with various perl scripts
|
||||
|
||||
To build after having extracted everything from CVS, do this:
|
||||
|
||||
./buildconf
|
||||
./configure
|
||||
make
|
||||
|
||||
REQUIREMENTS
|
||||
|
||||
You need the following software installed:
|
||||
|
||||
o autoconf 2.50 (or later)
|
||||
o automake 1.5 (or later)
|
||||
o libtool 1.4 (or later)
|
||||
o GNU m4 (required by autoconf)
|
||||
|
||||
o nroff + perl (if you don't have nroff and perl and you for some reason
|
||||
don't want to install them, you can rename the source file
|
||||
src/hugehelp.c.cvs to src/hugehelp.c and avoid having to generate this
|
||||
file. This will of course give you an older version of the file that isn't
|
||||
up-to-date. That file was checked in once and won't be updated very
|
||||
regularly.)
|
||||
|
||||
MAC OS X
|
||||
|
||||
For Mac OS X users, Guido Neitzer write down the following step-by-step guide:
|
||||
|
||||
1. Install fink (http://fink.sourceforge.net)
|
||||
2. Update fink to the newest version (with the installed fink)
|
||||
3. Install the latest version of autoconf, automake and m4 with fink
|
||||
4. Install version 1.4.1 of libtool - you find it in the "unstable" section
|
||||
(read the manual to see how to get unstable versions)
|
||||
5. Get cURL from the cvs
|
||||
6. Build cURL with "./buildconf", "./configure", "make", "sudo make install"
|
||||
|
2
LEGAL
2
LEGAL
@@ -1,4 +1,4 @@
|
||||
Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
Copyright (C) 1998-2001, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license
|
||||
document, but changing it is not allowed.
|
||||
|
@@ -6,13 +6,12 @@ AUTOMAKE_OPTIONS = foreign no-dependencies
|
||||
|
||||
EXTRA_DIST = \
|
||||
CHANGES LEGAL maketgz MITX.txt MPL-1.1.txt \
|
||||
config-win32.h reconf Makefile.dist \
|
||||
curl-config.in build_vms.com config-riscos.h \
|
||||
config-vms.h curl-mode.el
|
||||
reconf Makefile.dist curl-config.in build_vms.com curl-mode.el \
|
||||
config-vms.h config-win32.h config-riscos.h config-mac.h
|
||||
|
||||
bin_SCRIPTS = curl-config
|
||||
|
||||
SUBDIRS = docs lib src include tests packages
|
||||
SUBDIRS = docs lib src include tests packages multi
|
||||
|
||||
# create a root makefile in the distribution:
|
||||
dist-hook:
|
||||
|
@@ -5,7 +5,7 @@
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# In order to be useful for every potential user, curl and libcurl are
|
||||
# dual-licensed under the MPL and the MIT/X-derivate licenses.
|
||||
@@ -43,13 +43,13 @@ mingw32-ssl:
|
||||
|
||||
vc:
|
||||
cd lib
|
||||
nmake -f Makefile.vc6
|
||||
nmake -f Makefile.vc6 cfg=release
|
||||
cd ..\src
|
||||
nmake -f Makefile.vc6
|
||||
|
||||
vc-ssl:
|
||||
cd lib
|
||||
nmake -f Makefile.vc6 release-ssl
|
||||
nmake -f Makefile.vc6 cfg=release-ssl
|
||||
cd ..\src
|
||||
nmake -f Makefile.vc6
|
||||
|
||||
|
2
README
2
README
@@ -26,7 +26,7 @@ README
|
||||
The official download mirror sites are:
|
||||
|
||||
Sweden -- ftp://ftp.sunet.se/pub/www/utilities/curl/
|
||||
Sweden -- ftp://cool.haxx.se/curl/
|
||||
Sweden -- http://cool.haxx.se/curl/
|
||||
Germany -- ftp://ftp.fu-berlin.de/pub/unix/network/curl/
|
||||
|
||||
To download the very latest source off the CVS server do this:
|
||||
|
@@ -62,3 +62,5 @@
|
||||
#undef HAVE_O_NONBLOCK
|
||||
#undef HAVE_DISABLED_NONBLOCKING
|
||||
|
||||
/* Define this to 'int' if in_addr_t is not an available typedefed type */
|
||||
#undef in_addr_t
|
||||
|
45
acinclude.m4
45
acinclude.m4
@@ -143,6 +143,43 @@ AC_DEFUN([TYPE_SOCKLEN_T],
|
||||
#include <sys/socket.h>])
|
||||
])
|
||||
|
||||
dnl Check for in_addr_t: it is used to receive the return code of inet_addr()
|
||||
dnl and a few other things. If not found, we set it to unsigned int, as even
|
||||
dnl 64-bit implementations use to set it to a 32-bit type.
|
||||
AC_DEFUN([TYPE_IN_ADDR_T],
|
||||
[
|
||||
AC_CHECK_TYPE([in_addr_t], ,[
|
||||
AC_MSG_CHECKING([for in_addr_t equivalent])
|
||||
AC_CACHE_VAL([curl_cv_in_addr_t_equiv],
|
||||
[
|
||||
# Systems have either "struct sockaddr *" or
|
||||
# "void *" as the second argument to getpeername
|
||||
curl_cv_in_addr_t_equiv=
|
||||
for t in int size_t unsigned long "unsigned long"; do
|
||||
AC_TRY_COMPILE([
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
],[
|
||||
$t data = inet_addr ("1.2.3.4");
|
||||
],[
|
||||
curl_cv_in_addr_t_equiv="$t"
|
||||
break
|
||||
])
|
||||
done
|
||||
|
||||
if test "x$curl_cv_in_addr_t_equiv" = x; then
|
||||
AC_MSG_ERROR([Cannot find a type to use in place of in_addr_t])
|
||||
fi
|
||||
])
|
||||
AC_MSG_RESULT($curl_cv_in_addr_t_equiv)
|
||||
AC_DEFINE_UNQUOTED(in_addr_t, $curl_cv_in_addr_t_equiv,
|
||||
[type to use in place of in_addr_t if not defined])],
|
||||
[#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>])
|
||||
])
|
||||
|
||||
dnl ************************************************************
|
||||
dnl check for "localhost", if it doesn't exist, we can't do the
|
||||
dnl gethostbyname_r tests!
|
||||
@@ -335,6 +372,8 @@ AC_DEFUN(CURL_CHECK_GETHOSTBYNAME_R,
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#undef NULL
|
||||
#define NULL (void *)0
|
||||
|
||||
int
|
||||
gethostbyname_r(const char *, struct hostent *, struct hostent_data *);],[
|
||||
@@ -350,6 +389,8 @@ gethostbyname_r(NULL, NULL, NULL);],[
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#undef NULL
|
||||
#define NULL (void *)0
|
||||
|
||||
int
|
||||
gethostbyname_r(const char *,struct hostent *, struct hostent_data *);],[
|
||||
@@ -363,6 +404,8 @@ gethostbyname_r(NULL, NULL, NULL);],[
|
||||
AC_TRY_COMPILE([
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#undef NULL
|
||||
#define NULL (void *)0
|
||||
|
||||
struct hostent *
|
||||
gethostbyname_r(const char *, struct hostent *, char *, int, int *);],[
|
||||
@@ -375,6 +418,8 @@ gethostbyname_r(NULL, NULL, NULL, 0, NULL);],[
|
||||
AC_TRY_COMPILE([
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#undef NULL
|
||||
#define NULL (void *)0
|
||||
|
||||
int
|
||||
gethostbyname_r(const char *, struct hostent *, char *, size_t,
|
||||
|
@@ -5,7 +5,7 @@ die(){
|
||||
exit
|
||||
}
|
||||
|
||||
automake || die "The command 'automake $MAKEFILES' failed"
|
||||
aclocal || die "The command 'aclocal' failed"
|
||||
autoheader || die "The command 'autoheader' failed"
|
||||
autoconf || die "The command 'autoconf' failed"
|
||||
automake || die "The command 'automake $MAKEFILES' failed"
|
||||
|
45
config-mac.h
Normal file
45
config-mac.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#define OS "mac"
|
||||
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
#define HAVE_SYS_SELECT_H 1
|
||||
#define HAVE_NETDB_H 1
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
#define HAVE_UNISTD_H 1
|
||||
#define HAVE_NET_IF_H 1
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
#define HAVE_FCNTL_H 1
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
#define HAVE_ALLOCA_H 1
|
||||
#define HAVE_TIME_H 1
|
||||
#define HAVE_STDLIB_H 1
|
||||
#define HAVE_UTIME_H 1
|
||||
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
#define HAVE_STRDUP 1
|
||||
#define HAVE_UTIME 1
|
||||
#define HAVE_INET_NTOA 1
|
||||
#define HAVE_SETVBUF 1
|
||||
#define HAVE_STRFTIME 1
|
||||
#define HAVE_INET_ADDR 1
|
||||
#define HAVE_MEMCPY 1
|
||||
#define HAVE_SELECT 1
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
//#define HAVE_STRICMP 1
|
||||
#define HAVE_SIGACTION 1
|
||||
|
||||
#ifdef MACOS_SSL_SUPPORT
|
||||
# define USE_SSLEAY 1
|
||||
# define USE_OPENSSL 1
|
||||
#endif
|
||||
|
||||
#define HAVE_RAND_STATUS 1
|
||||
#define HAVE_RAND_EGD 1
|
||||
|
||||
#define HAVE_FIONBIO 1
|
||||
|
||||
#include <extra/stricmp.h>
|
||||
#include <extra/strdup.h>
|
@@ -42,7 +42,7 @@
|
||||
#define SIZEOF_LONG_DOUBLE 16
|
||||
|
||||
/* The number of bytes in a long long. */
|
||||
#define SIZEOF_LONG_LONG 8
|
||||
/* #define SIZEOF_LONG_LONG 8 */
|
||||
|
||||
/* Define if you have the gethostbyaddr function. */
|
||||
#define HAVE_GETHOSTBYADDR 1
|
||||
@@ -179,6 +179,9 @@
|
||||
/* Define if you have the RAND_screen function when using SSL */
|
||||
#define HAVE_RAND_SCREEN 1
|
||||
|
||||
/* Define this to if in_addr_t is not an available typedefed type */
|
||||
#define in_addr_t unsigned long
|
||||
|
||||
/*************************************************
|
||||
* This section is for compiler specific defines.*
|
||||
*************************************************/
|
||||
|
@@ -392,6 +392,10 @@ else
|
||||
OPENSSL_ENABLED=1)
|
||||
fi
|
||||
|
||||
dnl Check for the OpenSSL engine header, it is kind of "separated"
|
||||
dnl from the main SSL check
|
||||
AC_CHECK_HEADERS(openssl/engine.h)
|
||||
|
||||
AC_SUBST(OPENSSL_ENABLED)
|
||||
|
||||
fi
|
||||
@@ -469,6 +473,8 @@ else
|
||||
dnl is there a localtime_r()
|
||||
CURL_CHECK_LOCALTIME_R()
|
||||
|
||||
AC_CHECK_FUNCS( gmtime_r )
|
||||
|
||||
fi
|
||||
|
||||
dnl **********************************************************************
|
||||
@@ -492,7 +498,6 @@ AC_CHECK_HEADERS( \
|
||||
sys/stat.h \
|
||||
sys/types.h \
|
||||
sys/time.h \
|
||||
getopt.h \
|
||||
sys/param.h \
|
||||
termios.h \
|
||||
termio.h \
|
||||
@@ -527,6 +532,7 @@ AC_CHECK_SIZEOF(long long, 4)
|
||||
AC_CHECK_TYPE(ssize_t, int)
|
||||
|
||||
TYPE_SOCKLEN_T
|
||||
TYPE_IN_ADDR_T
|
||||
|
||||
dnl Checks for library functions.
|
||||
dnl AC_PROG_GCC_TRADITIONAL
|
||||
@@ -591,6 +597,7 @@ AC_CONFIG_FILES([Makefile \
|
||||
include/Makefile \
|
||||
include/curl/Makefile \
|
||||
src/Makefile \
|
||||
multi/Makefile \
|
||||
lib/Makefile \
|
||||
tests/Makefile \
|
||||
tests/data/Makefile \
|
||||
|
@@ -16,6 +16,7 @@ Usage: curl-config [OPTION]
|
||||
|
||||
Available values for OPTION include:
|
||||
|
||||
--cc compiler
|
||||
--cflags pre-processor and compiler flags
|
||||
--feature newline separated list of enabled features
|
||||
--help display this help and exit
|
||||
@@ -42,6 +43,10 @@ while test $# -gt 0; do
|
||||
esac
|
||||
|
||||
case "$1" in
|
||||
--cc)
|
||||
echo @CC@
|
||||
;;
|
||||
|
||||
--prefix)
|
||||
echo $prefix
|
||||
;;
|
||||
|
22
docs/BUGS
22
docs/BUGS
@@ -1,3 +1,4 @@
|
||||
$Id$
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
@@ -22,11 +23,16 @@ BUGS
|
||||
|
||||
When reporting a bug, you should include information that will help us
|
||||
understand what's wrong, what you expected to happen and how to repeat the
|
||||
bad behaviour. You therefore need to supply your operating system's name and
|
||||
bad behavior. You therefore need to supply your operating system's name and
|
||||
version number (uname -a under a unix is fine), what version of curl you're
|
||||
using (curl -V is fine), what URL you were working with and anything else
|
||||
you think matters.
|
||||
|
||||
Since curl deals with networks, it often helps us a lot if you include a
|
||||
protocol debug dump with your bug report. The output you get by using the -v
|
||||
flag. Usually, you also get more info by using -i so that is likely to be
|
||||
useful when reporting bugs as well.
|
||||
|
||||
If curl crashed, causing a core dump (in unix), there is hardly any use to
|
||||
send that huge file to anyone of us. Unless we have an exact same system
|
||||
setup as you, we can't do much with it. What we instead ask of you is to get
|
||||
@@ -35,23 +41,23 @@ BUGS
|
||||
The address and how to subscribe to the mailing list is detailed in the
|
||||
MANUAL file.
|
||||
|
||||
HOW TO GET A STACK TRACE with a common unix debugger
|
||||
====================================================
|
||||
HOW TO GET A STACK TRACE
|
||||
|
||||
First, you must make sure that you compile all sources with -g and that you
|
||||
don't 'strip' the final executable.
|
||||
don't 'strip' the final executable. Try to avoid optimizing the code as
|
||||
well, remove -O, -O2 etc from the compiler options.
|
||||
|
||||
Run the program until it bangs.
|
||||
Run the program until it dumps core.
|
||||
|
||||
Run your debugger on the core file, like '<debugger> curl core'. <debugger>
|
||||
should be replaced with the name of your debugger, in most cases that will
|
||||
be 'gdb', but 'dbx' and others also occur.
|
||||
|
||||
When the debugger has finished loading the core file and presents you a
|
||||
prompt, you can give the compiler instructions. Enter 'where' (without the
|
||||
quotes) and press return.
|
||||
prompt, enter 'where' (without the quotes) and press return.
|
||||
|
||||
The list that is presented is the stack trace. If everything worked, it is
|
||||
supposed to contain the chain of functions that were called when curl
|
||||
crashed.
|
||||
crashed. Include the stack trace with your detailed bug report. It'll help a
|
||||
lot.
|
||||
|
||||
|
60
docs/FAQ
60
docs/FAQ
@@ -1,4 +1,4 @@
|
||||
Updated: November 1, 2001 (http://curl.haxx.se/docs/faq.shtml)
|
||||
Updated: December 21, 2001 (http://curl.haxx.se/docs/faq.shtml)
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
@@ -33,10 +33,10 @@ FAQ
|
||||
3.6 Does curl support javascript, ASP, XML, XHTML or HTML version Y?
|
||||
3.7 Can I use curl to delete/rename a file through FTP?
|
||||
3.8 How do I tell curl to follow HTTP redirects?
|
||||
3.9 How do I use curl in PHP, Perl, Tcl, Ruby or Java?
|
||||
3.9 How do I use curl in my favourite programming language?
|
||||
3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP?
|
||||
3.11 How do I POST with a different Content-Type?
|
||||
3.12 Why do FTP specific features over HTTP proxy fails?
|
||||
3.12 Why do FTP specific features over HTTP proxy fail?
|
||||
|
||||
4. Running Problems
|
||||
4.1 Problems connecting to SSL servers.
|
||||
@@ -49,6 +49,7 @@ FAQ
|
||||
4.5.3 "403 Forbidden"
|
||||
4.5.4 "404 Not Found"
|
||||
4.5.5 "405 Method Not Allowed"
|
||||
4.5.6 "301 Moved Permanently"
|
||||
4.6 Can you tell me what error code 142 means?
|
||||
4.7 How do I keep user names and passwords secret in Curl command lines?
|
||||
4.8 I found a bug!
|
||||
@@ -154,9 +155,9 @@ FAQ
|
||||
have them inserted in the main sources (of course on the condition that
|
||||
developers agree on that the fixes are good).
|
||||
|
||||
The list of contributors in the bottom of the man page is only a small part
|
||||
of all the people that every day provide us with bug reports, suggestions,
|
||||
ideas and source code.
|
||||
The list of contributors in the docs/THANKS file is only a small part of all
|
||||
the people that every day provide us with bug reports, suggestions, ideas
|
||||
and source code.
|
||||
|
||||
curl is developed by a community, with Daniel at the wheel.
|
||||
|
||||
@@ -171,9 +172,11 @@ FAQ
|
||||
sourceforge.net hosts several project tools we take advantage from like the
|
||||
bug tracker, mailing lists and more.
|
||||
|
||||
If you feel you want to show support our project with a donation, a very
|
||||
nice way of doing that would be to buy "gift certificates" at useful online
|
||||
shopping sites, such as amazon.com or thinkgeek.com.
|
||||
If you want to support our project with a donation or similar, one way of
|
||||
doing that would be to buy "gift certificates" at useful online shopping
|
||||
sites, such as amazon.com or thinkgeek.com. Another way would be to sponsor
|
||||
us through a banner-program or by simply helping us coding, documenting,
|
||||
testing etc.
|
||||
|
||||
1.7 What about CURL from curl.com?
|
||||
|
||||
@@ -332,11 +335,12 @@ FAQ
|
||||
|
||||
curl -L http://redirector.com
|
||||
|
||||
3.9 How do I use curl in PHP, Perl, Tcl, Ruby or Java?
|
||||
3.9 How do I use curl in my favourite programming language?
|
||||
|
||||
There exist many language-interfaces for curl that integrates it better with
|
||||
various languages. If you are fluid in a script language, you may very well
|
||||
opt to use such an interface instead of using the command line tool.
|
||||
There exist many language interfaces/bindings for curl that integrates it
|
||||
better with various languages. If you are fluid in a script language, you
|
||||
may very well opt to use such an interface instead of using the command line
|
||||
tool.
|
||||
|
||||
At the time of writing, there are bindings for the five language mentioned
|
||||
above, but chances are there are even more by the time you read this. Or you
|
||||
@@ -347,16 +351,9 @@ FAQ
|
||||
|
||||
http://curl.haxx.se/libcurl/
|
||||
|
||||
PHP4 has the ability to use libcurl as an internal module if built with that
|
||||
option enabled. You then get a set of extra functions that can be used
|
||||
within your PHP programs. You find all details about those functions in the
|
||||
curl section in the PHP manual, see the online version at:
|
||||
|
||||
http://www.php.net/manual/ref.curl.php
|
||||
|
||||
PHP also offers the option to run a command line, and then you can of course
|
||||
invoke the curl tool using a command line. This is the way to use curl if
|
||||
you're using PHP3 or PHP4 built without curl module support.
|
||||
In December 2001, there are interfaces available for the following
|
||||
languages: C/C++, Cocoa, Dylan, Java, Perl, PHP, Python, Rexx, Ruby, Scheme
|
||||
and Tcl. By the time you read this, additional ones may have appeared!
|
||||
|
||||
3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP?
|
||||
|
||||
@@ -383,8 +380,8 @@ FAQ
|
||||
etc.
|
||||
|
||||
There is one exception to this rule, and that is if you can "tunnel through"
|
||||
the given HTTP proxy. Proxy tunneling is enabled with a special option (-P)
|
||||
and is generally not available as proxy admins usuable disable tunneling to
|
||||
the given HTTP proxy. Proxy tunneling is enabled with a special option (-p)
|
||||
and is generally not available as proxy admins usually disable tunneling to
|
||||
other ports than 443 (which is used for HTTPS access through proxies).
|
||||
|
||||
4. Running Problems
|
||||
@@ -476,11 +473,22 @@ FAQ
|
||||
identified by the Request-URI. The response MUST include an Allow header
|
||||
containing a list of valid methods for the requested resource.
|
||||
|
||||
4.5.6 "301 Moved Permanently"
|
||||
|
||||
If you get this return code and an HTML outpt similar to this:
|
||||
|
||||
<H1>Moved Permanently</H1> The document has moved <A
|
||||
HREF="http://same_url_now_with_a_trailing_slash/">here</A>.
|
||||
|
||||
it might be because you request a directory URL but without the trailing
|
||||
slash. Try the same operation again _with_ the trailing URL, or use the
|
||||
-L/--location option to follow the redirection.
|
||||
|
||||
4.6. Can you tell me what error code 142 means?
|
||||
|
||||
All error codes that are larger than the highest documented error code means
|
||||
that curl has exited due to a crash. This is a serious error, and we
|
||||
appriciate a detailed bug report from you that describes how we could go
|
||||
appreciate a detailed bug report from you that describes how we could go
|
||||
ahead and repeat this!
|
||||
|
||||
4.7. How do I keep user names and passwords secret in Curl command lines?
|
||||
|
@@ -56,7 +56,7 @@ FTP
|
||||
- download
|
||||
- authentication
|
||||
- kerberos security
|
||||
- PORT or PASV
|
||||
- active/passive using PORT, EPRT, PASV or EPSV
|
||||
- single file size information (compare to HTTP HEAD)
|
||||
- 'type=' URL support
|
||||
- dir listing
|
||||
|
48
docs/INSTALL
48
docs/INSTALL
@@ -36,8 +36,7 @@ UNIX
|
||||
The configure script always tries to find a working SSL library unless
|
||||
explicitly told not to. If you have OpenSSL installed in the default search
|
||||
path for your compiler/linker, you don't need to do anything special. If
|
||||
you have OpenSSL installed in e.g /usr/local/ssl, you can run configure
|
||||
like:
|
||||
you have OpenSSL installed in /usr/local/ssl, you can run configure like:
|
||||
|
||||
./configure --with-ssl
|
||||
|
||||
@@ -46,13 +45,13 @@ UNIX
|
||||
|
||||
./configure --with-ssl=/opt/OpenSSL
|
||||
|
||||
If you insist on forcing a build *without* SSL support, even though you may
|
||||
have it installed in your system, you can run configure like this:
|
||||
If you insist on forcing a build without SSL support, even though you may
|
||||
have OpenSSL installed in your system, you can run configure like this:
|
||||
|
||||
./configure --without-ssl
|
||||
|
||||
If you have OpenSSL installed, but with the libraries in one place and the
|
||||
header files somewhere else, you'll have to set the LDFLAGS and CPPFLAGS
|
||||
header files somewhere else, you have to set the LDFLAGS and CPPFLAGS
|
||||
environment variables prior to running configure. Something like this
|
||||
should work:
|
||||
|
||||
@@ -72,7 +71,7 @@ UNIX
|
||||
LIBS=-lRSAglue -lrsaref
|
||||
(as suggested by Doug Kaufman)
|
||||
|
||||
KNOWN PROBLEMS
|
||||
KNOWN PROBLEMS (these ones should not happen anymore)
|
||||
|
||||
If you happen to have autoconf installed, but a version older than 2.12
|
||||
you will get into trouble. Then you can still build curl by issuing these
|
||||
@@ -101,8 +100,8 @@ UNIX
|
||||
|
||||
MORE OPTIONS
|
||||
|
||||
Remember, to force configure to use the standard cc compiler if both
|
||||
cc and gcc are present, run configure like
|
||||
To force configure to use the standard cc compiler if both cc and gcc are
|
||||
present, run configure like
|
||||
|
||||
CC=cc ./configure
|
||||
or
|
||||
@@ -130,11 +129,6 @@ UNIX
|
||||
|
||||
./configure --with-krb4=/usr/athena
|
||||
|
||||
If your system support shared libraries, but you want to built a static
|
||||
version only, you can disable building the shared version by using:
|
||||
|
||||
./configure --disable-shared
|
||||
|
||||
If you're a curl developer and use gcc, you might want to enable more
|
||||
debug options with the --enable-debug option.
|
||||
|
||||
@@ -177,9 +171,9 @@ Win32
|
||||
Make the sources in the src/ drawer be a "win32 console application"
|
||||
project. Name it curl.
|
||||
|
||||
With VC++, add 'wsock32.lib' to the link libs when you build curl!
|
||||
Borland seems to do that itself magically. Of course you have to
|
||||
make sure it links with the libcurl too!
|
||||
With VC++, add 'ws2_32.lib' to the link libs when you build curl!
|
||||
Borland seems to do that itself magically. Of course you have to make
|
||||
sure it links with the libcurl too!
|
||||
|
||||
For VC++ 6, there's an included Makefile.vc6 that should be possible
|
||||
to use out-of-the-box.
|
||||
@@ -328,6 +322,20 @@ VMS
|
||||
13-jul-2001
|
||||
N. Baggus
|
||||
|
||||
QNX
|
||||
===
|
||||
(This section was graciously brought to us by David Bentham)
|
||||
|
||||
As QNX is targetted for resource constrained environments, the QNX headers
|
||||
set conservative limits. This includes the FD_SETSIZE macro, set by default
|
||||
to 32. Socket descriptors returned within the CURL library may exceed this,
|
||||
resulting in memory faults/SIGSEGV crashes when passed into select(..)
|
||||
calls using fd_set macros.
|
||||
|
||||
A good all-round solution to this is to override the default when building
|
||||
libcurl, by overriding CFLAGS during configure, example
|
||||
# configure CFLAGS='-DFD_SETSIZE=64 -g -O2'
|
||||
|
||||
CROSS COMPILE
|
||||
=============
|
||||
|
||||
@@ -370,7 +378,8 @@ CROSS COMPILE
|
||||
PORTS
|
||||
=====
|
||||
This is a probably incomplete list of known hardware and operating systems
|
||||
that curl has been compiled for:
|
||||
that curl has been compiled for. If you know one system curl compiles and
|
||||
runs on, that isn't listed, please let us know!
|
||||
|
||||
- Alpha DEC OSF 4
|
||||
- Alpha Digital UNIX v3.2
|
||||
@@ -379,10 +388,13 @@ PORTS
|
||||
- Alpha OpenVMS V7.1-1H2
|
||||
- Alpha Tru64 v5.0 5.1
|
||||
- HP-PA HP-UX 9.X 10.X 11.X
|
||||
- HP-PA Linux
|
||||
- MIPS IRIX 6.2, 6.5
|
||||
- MIPS Linux
|
||||
- Power AIX 4.2, 4.3.1, 4.3.2
|
||||
- PowerPC Darwin 1.0
|
||||
- PowerPC Linux
|
||||
- PowerPC Mac OS 9
|
||||
- PowerPC Mac OS X
|
||||
- SINIX-Z v5
|
||||
- Sparc Linux
|
||||
@@ -394,6 +406,7 @@ PORTS
|
||||
- Ultrix 4.3a
|
||||
- i386 BeOS
|
||||
- i386 FreeBSD
|
||||
- i386 HURD
|
||||
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4
|
||||
- i386 NetBSD
|
||||
- i386 OS/2
|
||||
@@ -403,6 +416,7 @@ PORTS
|
||||
- i386 Windows 95, 98, ME, NT, 2000
|
||||
- ia64 Linux 2.3.99
|
||||
- m68k AmigaOS 3
|
||||
- m68k Linux
|
||||
- m68k OpenBSD
|
||||
- s390 Linux
|
||||
|
||||
|
@@ -601,15 +601,15 @@ RESUMING FILE TRANSFERS
|
||||
|
||||
Continue downloading a document:
|
||||
|
||||
curl -c -o file ftp://ftp.server.com/path/file
|
||||
curl -C - -o file ftp://ftp.server.com/path/file
|
||||
|
||||
Continue uploading a document(*1):
|
||||
|
||||
curl -c -T file ftp://ftp.server.com/path/file
|
||||
curl -C - -T file ftp://ftp.server.com/path/file
|
||||
|
||||
Continue downloading a document from a web server(*2):
|
||||
|
||||
curl -c -o file http://www.server.com/
|
||||
curl -C - -o file http://www.server.com/
|
||||
|
||||
(*1) = This requires that the ftp server supports the non-standard command
|
||||
SIZE. If it doesn't, curl will say so.
|
||||
|
@@ -56,12 +56,13 @@ HTMLPAGES = \
|
||||
curl_mprintf.html \
|
||||
curl_global_init.html \
|
||||
curl_global_cleanup.html \
|
||||
libcurl.html
|
||||
libcurl.html \
|
||||
index.html
|
||||
|
||||
EXTRA_DIST = $(man_MANS) \
|
||||
MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS \
|
||||
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS \
|
||||
$(HTMLPAGES)
|
||||
VERSIONS $(HTMLPAGES)
|
||||
|
||||
MAN2HTML= gnroff -man $< | man2html >$@
|
||||
|
||||
|
@@ -12,18 +12,11 @@ README.win32
|
||||
systems. While not being the main develop target, a fair share of curl users
|
||||
are win32-based.
|
||||
|
||||
Some documentation in this archive will be tricky to read for Windows
|
||||
people, as they come in unix-style man pages. You can either download a
|
||||
freely available nroff binary for win32 (*pointers appriciated*), convert
|
||||
the files into plain-text on your neighbor's unix machine or run over to the
|
||||
curl web site and view them as plain HTML.
|
||||
The unix-style man pages are tricky to read on windows, so therefore are all
|
||||
those pages also converted to HTML and those are also included in the
|
||||
release archives.
|
||||
|
||||
The main curl.1 man page is "built-in". Use a command line similar to this
|
||||
in order to extract a separate text file:
|
||||
The main curl.1 man page is also "built-in" in the command line tool. Use a
|
||||
command line similar to this in order to extract a separate text file:
|
||||
|
||||
curl -M >manual.txt
|
||||
|
||||
Download all the libcurl man pages in HTML format using the link on the
|
||||
bottom of this page:
|
||||
|
||||
http://curl.haxx.se/libcurl/c/
|
||||
|
@@ -53,7 +53,7 @@ that have contributed with non-trivial parts:
|
||||
- Albert Chin-A-Young <china@thewrittenword.com>
|
||||
- Stephen Kick <skick@epicrealm.com>
|
||||
- Martin Hedenfalk <mhe@stacken.kth.se>
|
||||
- Richard Prescott
|
||||
- Richard Prescott <rip at step.polymtl.ca>
|
||||
- Jason S. Priebe <priebe@wral-tv.com>
|
||||
- T. Bharath <TBharath@responsenetworks.com>
|
||||
- Alexander Kourakos <awk@users.sourceforge.net>
|
||||
@@ -75,3 +75,7 @@ that have contributed with non-trivial parts:
|
||||
- Andrew Francis <locust@familyhealth.com.au>
|
||||
- Tomasz Lacki <Tomasz.Lacki@primark.pl>
|
||||
- Georg Huettenegger <georg@ist.org>
|
||||
- John Lask <johnlask@hotmail.com>
|
||||
- Eric Lavigne <erlavigne@wanadoo.fr>
|
||||
- Marcus Webster <marcus.webster@phocis.com>
|
||||
- G<>tz Babin-Ebell <babin<69>ebell@trustcenter.de>
|
||||
|
25
docs/TODO
25
docs/TODO
@@ -34,6 +34,8 @@ TODO
|
||||
|
||||
* Add asynchronous name resolving. http://curl.haxx.se/dev/async-resolver.txt
|
||||
|
||||
* Strip any trailing CR from the error message when Curl_failf() is used.
|
||||
|
||||
DOCUMENTATION
|
||||
|
||||
* Document all CURLcode error codes, why they happen and what most likely
|
||||
@@ -58,9 +60,6 @@ TODO
|
||||
likely that we know the size when downloading. Some sites support SIZE but
|
||||
don't show the size in the RETR response!
|
||||
|
||||
* Make FTP PASV work with IPv6 support. RFC 2428 "FTP Extensions for IPv6 and
|
||||
NATs" is interesting.
|
||||
|
||||
HTTP
|
||||
|
||||
* HTTP PUT for files passed on stdin *OR* when the --crlf option is
|
||||
@@ -101,14 +100,30 @@ TODO
|
||||
|
||||
SSL
|
||||
|
||||
* Add an interface to libcurl that enables "session IDs" to get
|
||||
exported/imported. Cris Bailiff said: "OpenSSL has functions which can
|
||||
serialise the current SSL state to a buffer of your choice, and
|
||||
recover/reset the state from such a buffer at a later date - this is used
|
||||
by mod_ssl for apache to implement and SSL session ID cache"
|
||||
|
||||
* Make curl's SSL layer option capable of using other free SSL libraries.
|
||||
Such as the Mozilla Security Services
|
||||
(http://www.mozilla.org/projects/security/pki/nss/) and GNUTLS
|
||||
(http://gnutls.hellug.gr/)
|
||||
|
||||
LDAP
|
||||
CLIENT
|
||||
|
||||
* Multiple URL requests don't work. [http://sourceforge.net/tracker/index.php?func=detail&aid=475407&group_id=976&atid=100976]
|
||||
* "curl ftp://site.com/*.txt"
|
||||
|
||||
* Several URLs can be specified to get downloaded. We should be able to use
|
||||
the same syntax to specify several files to get uploaded (using the same
|
||||
persistant connection), using -T.
|
||||
|
||||
* Say you have a list of FTP addresses to download in a file named
|
||||
ftp-list.txt: "cat ftp-list.txt | xargs curl -O -O -O [...]". curl _needs_
|
||||
an "-Oalways" flag -- all addresses on the command line use the base
|
||||
filename to store locally. Else a script must precount the # of URLs,
|
||||
construct the proper number of "-O"s...
|
||||
|
||||
TEST SUITE
|
||||
|
||||
|
64
docs/VERSIONS
Normal file
64
docs/VERSIONS
Normal file
@@ -0,0 +1,64 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
Version Numbers and Releases
|
||||
|
||||
Curl is not only curl. Curl is also libcurl. They're actually individually
|
||||
versioned, but they mostly follow each other rather closely.
|
||||
|
||||
The version numbering is always built up using the same system:
|
||||
|
||||
X.Y[.Z][-preN]
|
||||
|
||||
Where
|
||||
X is main version number
|
||||
Y is release number
|
||||
Z is patch number
|
||||
N is pre-release number
|
||||
|
||||
One of these numbers will get bumped in each new release. The numbers to the
|
||||
right of a bumped number will be reset to zero. If Z is zero, it is not
|
||||
included in the version number. The pre release number is only included in
|
||||
pre releases (they're never used in public, official, releases).
|
||||
|
||||
The main version number will get bumped when *really* big, world colliding
|
||||
changes are made. The release number is bumped when big changes are
|
||||
performed. The patch number is bumped when the changes are mere bugfixes and
|
||||
only minor feature changes. The pre-release is a counter, to identify which
|
||||
pre-release a certain release is.
|
||||
|
||||
When reaching the end of a pre-release period, the version without the
|
||||
pre-release part will be released as a public release.
|
||||
|
||||
It means that after release 1.2.3, we can release 2.0 if something really big
|
||||
has been made, 1.3 if not that big changes were made or 1.2.4 if mostly bugs
|
||||
were fixed. Before 1.2.4 is released, we might release a 1.2.4-pre1 release
|
||||
for the brave people to try before the actual release.
|
||||
|
||||
Bumping, as in increasing the number with 1, is unconditionally only
|
||||
affecting one of the numbers (except the ones to the right of it, that may be
|
||||
set to zero). 1 becomes 2, 3 becomes 4, 9 becomes 10, 88 becomes 89 and 99
|
||||
becomes 100. So, after 1.2.9 comes 1.2.10. After 3.99.3, 3.100 might come.
|
||||
|
||||
All original curl source release archives are named according to the libcurl
|
||||
version (not according to the curl client version that, as said before, might
|
||||
differ).
|
||||
|
||||
As a service to any application that might want to support new libcurl
|
||||
features while still being able to build with older versions, all releases
|
||||
have the libcurl version stored in the curl/curl.h file using a static
|
||||
numbering scheme that can be used for comparison. The version number is
|
||||
defined as:
|
||||
|
||||
#define LIBCURL_VERSION_NUM 0xXXYYZZ
|
||||
|
||||
Where XX, YY and ZZ are the main version, release and patch numbers in
|
||||
hexadecimal. All three numbers are always represented using two digits. 1.2
|
||||
would appear as "0x010200" while version 9.11.7 appears as "0x090b07".
|
||||
|
||||
This 6-digit hexadecimal number does not show pre-release number, and it is
|
||||
always a greater number in a more recent release. It makes comparisons with
|
||||
greater than and less than work.
|
45
docs/curl.1
45
docs/curl.1
@@ -2,10 +2,9 @@
|
||||
.\" nroff -man curl.1
|
||||
.\" Written by Daniel Stenberg
|
||||
.\"
|
||||
.TH curl 1 "30 Oct 2001" "Curl 7.9.1" "Curl Manual"
|
||||
.TH curl 1 "30 Nov 2001" "Curl 7.9.2" "Curl Manual"
|
||||
.SH NAME
|
||||
curl \- get a URL with FTP, TELNET, LDAP, GOPHER, DICT, FILE, HTTP or
|
||||
HTTPS syntax.
|
||||
curl \- transfer a URL
|
||||
.SH SYNOPSIS
|
||||
.B curl [options]
|
||||
.I [URL...]
|
||||
@@ -117,13 +116,13 @@ be written to stdout. (Option added in curl 7.9)
|
||||
If this option is used several times, the last specfied file name will be
|
||||
used.
|
||||
.IP "-C/--continue-at <offset>"
|
||||
Continue/Resume a previous file transfer at the given offset. The
|
||||
given offset is the exact number of bytes that will be skipped
|
||||
counted from the beginning of the source file before it is transfered
|
||||
to the destination.
|
||||
If used with uploads, the ftp server command SIZE will not be used by
|
||||
curl. Upload resume is for FTP only.
|
||||
HTTP resume is only possible with HTTP/1.1 or later servers.
|
||||
Continue/Resume a previous file transfer at the given offset. The given offset
|
||||
is the exact number of bytes that will be skipped counted from the beginning
|
||||
of the source file before it is transfered to the destination. If used with
|
||||
uploads, the ftp server command SIZE will not be used by curl.
|
||||
|
||||
Use "-C -" to tell curl to automatically find out where/how to resume the
|
||||
transfer. It then uses the given output/input files to figure that out.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "-d/--data <data>"
|
||||
@@ -161,10 +160,14 @@ using this option the entire context of the posted data is kept as-is. If you
|
||||
want to post a binary file without the strip-newlines feature of the
|
||||
--data-ascii option, this is for you.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
|
||||
If this option is used several times, the ones following the first will
|
||||
append data.
|
||||
.IP "--disable-epsv"
|
||||
(FTP) Tell curl to disable the use of the EPSV command when doing passive FTP
|
||||
downloads. Curl will normally always first attempt to use EPSV before PASV,
|
||||
but with this option, it will not try using EPSV.
|
||||
|
||||
IF this option is used several times, each occurrence will toggle this on/off.
|
||||
.IP "-D/--dump-header <file>"
|
||||
(HTTP/FTP)
|
||||
Write the HTTP headers to this file. Write the FTP file info to this
|
||||
@@ -569,6 +572,11 @@ The time, in seconds, it took from the start until the file transfer is just
|
||||
about to begin. This includes all pre-transfer commands and negotiations that
|
||||
are specific to the particular protocol(s) involved.
|
||||
.TP
|
||||
.B time_starttransfer
|
||||
The time, in seconds, it took from the start until the first byte is just about
|
||||
to be transfered. This includes time_pretransfer and also the time the
|
||||
server needs to calculate the result.
|
||||
.TP
|
||||
.B size_download
|
||||
The total amount of bytes that were downloaded.
|
||||
.TP
|
||||
@@ -668,7 +676,7 @@ If this option is used several times, the last one will be used.
|
||||
Default config file.
|
||||
|
||||
.SH ENVIRONMENT
|
||||
.IP "HTTP_PROXY [protocol://]<host>[:port]"
|
||||
.IP "http_proxy [protocol://]<host>[:port]"
|
||||
Sets proxy server to use for HTTP.
|
||||
.IP "HTTPS_PROXY [protocol://]<host>[:port]"
|
||||
Sets proxy server to use for HTTPS.
|
||||
@@ -679,11 +687,8 @@ Sets proxy server to use for GOPHER.
|
||||
.IP "ALL_PROXY [protocol://]<host>[:port]"
|
||||
Sets proxy server to use if no protocol-specific proxy is set.
|
||||
.IP "NO_PROXY <comma-separated list of hosts>"
|
||||
list of host names that shouldn't go through any proxy. If set to a
|
||||
asterisk '*' only, it matches all hosts.
|
||||
.IP "COLUMNS <integer>"
|
||||
The width of the terminal. This variable only affects curl when the
|
||||
--progress-bar option is used.
|
||||
list of host names that shouldn't go through any proxy. If set to a asterisk
|
||||
'*' only, it matches all hosts.
|
||||
.SH EXIT CODES
|
||||
There exists a bunch of different error codes and their corresponding error
|
||||
messages that may appear during bad conditions. At the time of this writing,
|
||||
@@ -790,6 +795,10 @@ Too many redirects. When following redirects, curl hit the maximum amount.
|
||||
Unknown TELNET option specified.
|
||||
.IP 49
|
||||
Malformed telnet option.
|
||||
.IP 51
|
||||
The remote peer's SSL certificate wasn't ok
|
||||
.IP 52
|
||||
The server didn't reply anything, which here is considered an error.
|
||||
.IP XX
|
||||
There will appear more error codes here in future releases. The existing ones
|
||||
are meant to never change.
|
||||
|
@@ -52,6 +52,12 @@ start until the file transfer is just about to begin. This includes all
|
||||
pre-transfer commands and negotiations that are specific to the particular
|
||||
protocol(s) involved.
|
||||
.TP
|
||||
.B CURLINFO_STARTTRANSFER_TIME
|
||||
Pass a pointer to a double to receive the time, in seconds, it took from the
|
||||
start until the first byte is just about to be transfered. This includes
|
||||
CURLINFO_PRETRANSFER_TIME and also the time the server needs to calculate
|
||||
the result.
|
||||
.TP
|
||||
.B CURLINFO_SIZE_UPLOAD
|
||||
Pass a pointer to a double to receive the total amount of bytes that were
|
||||
uploaded.
|
||||
|
@@ -2,7 +2,7 @@
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_easy_setopt 3 "11 Oct 2001" "libcurl 7.9.1" "libcurl Manual"
|
||||
.TH curl_easy_setopt 3 "10 Dec 2001" "libcurl 7.9.2" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_setopt - Set curl easy-session options
|
||||
.SH SYNOPSIS
|
||||
@@ -77,9 +77,8 @@ function gets called by libcurl as soon as it needs to read data in order to
|
||||
send it to the peer. The data area pointed at by the pointer \fIptr\fP may be
|
||||
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 -1 will signal an error to the library and cause
|
||||
it to abort the current transfer immediately (with a \fICURLE_READ_ERROR\fP
|
||||
return code).
|
||||
that memory area. Returning 0 will signal end-of-file to the library and cause
|
||||
it to stop the current transfer.
|
||||
.TP
|
||||
.B CURLOPT_INFILESIZE
|
||||
When uploading a file to a remote site, this option should be used to tell
|
||||
@@ -320,13 +319,54 @@ with \fIcurl_easy_cleanup(3)\fP.
|
||||
.TP
|
||||
.B CURLOPT_SSLCERT
|
||||
Pass a pointer to a zero terminated string as parameter. The string should be
|
||||
the file name of your certificate in PEM format.
|
||||
the file name of your certificate. The default format is "PEM" and can be
|
||||
changed with \fICURLOPT_SSLCERTTYPE\fP.
|
||||
.TP
|
||||
.B CURLOPT_SSLCERTTYPE
|
||||
Pass a pointer to a zero terminated string as parameter. The string should be
|
||||
the format of your certificate. Supported formats are "PEM" and "DER".
|
||||
.TP
|
||||
.B CURLOPT_SSLCERTPASSWD
|
||||
Pass a pointer to a zero terminated string as parameter. It will be used as
|
||||
the password required to use the CURLOPT_SSLCERT certificate. If the password
|
||||
is not supplied, you will be prompted for it. \fICURLOPT_PASSWDFUNCTION\fP can
|
||||
be used to set your own prompt function.
|
||||
|
||||
\fBNOTE:\fPThis option is replaced by \fICURLOPT_SSLKEYPASSWD\fP and only
|
||||
cept for backward compatibility. You never needed a pass phrase to load
|
||||
a certificate but you need one to load your private key.
|
||||
.TP
|
||||
.B CURLOPT_SSLKEY
|
||||
Pass a pointer to a zero terminated string as parameter. The string should be
|
||||
the file name of your private key. The default format is "PEM" and can be
|
||||
changed with \fICURLOPT_SSLKEYTYPE\fP.
|
||||
.TP
|
||||
.B CURLOPT_SSLKEYTYPE
|
||||
Pass a pointer to a zero terminated string as parameter. The string should be
|
||||
the format of your private key. Supported formats are "PEM", "DER" and "ENG".
|
||||
|
||||
\fBNOTE:\fPThe format "ENG" enables you to load the private key from a crypto
|
||||
engine. in this case \fICURLOPT_SSLKEY\fP is used as an identifier passed to
|
||||
the engine. You have to set the crypto engine with \fICURLOPT_SSL_ENGINE\fP.
|
||||
.TP
|
||||
.B CURLOPT_SSLKEYASSWD
|
||||
Pass a pointer to a zero terminated string as parameter. It will be used as
|
||||
the password required to use the \fICURLOPT_SSLKEY\fP private key. If the password
|
||||
is not supplied, you will be prompted for it. \fICURLOPT_PASSWDFUNCTION\fP can
|
||||
be used to set your own prompt function.
|
||||
.TP
|
||||
.B CURLOPT_SSL_ENGINE
|
||||
Pass a pointer to a zero terminated string as parameter. It will be used as
|
||||
the identifier for the crypto engine you want to use for your private key.
|
||||
|
||||
\fBNOTE:\fPIf the crypto device cannot be loaded, \fICURLE_SSL_ENGINE_NOTFOUND\fP
|
||||
is returned.
|
||||
.TP
|
||||
.B CURLOPT_SSL_ENGINEDEFAULT
|
||||
Sets the actual crypto engine as the default for (asymetric) crypto operations.
|
||||
|
||||
\fBNOTE:\fPIf the crypto device cannot be set, \fICURLE_SSL_ENGINE_SETFAILED\fP
|
||||
is returned.
|
||||
.TP
|
||||
.B CURLOPT_CRLF
|
||||
Convert Unix newlines to CRLF newlines on FTP uploads.
|
||||
@@ -336,13 +376,15 @@ Pass a pointer to a linked list of FTP commands to pass to the server prior to
|
||||
your ftp request. The linked list should be a fully valid list of 'struct
|
||||
curl_slist' structs properly filled in. Use \fIcurl_slist_append(3)\fP to
|
||||
append strings (commands) to the list, and clear the entire list afterwards
|
||||
with \fIcurl_slist_free_all(3)\fP.
|
||||
with \fIcurl_slist_free_all(3)\fP. Disable this operation again by setting a
|
||||
NULL to this option.
|
||||
.TP
|
||||
.B CURLOPT_POSTQUOTE
|
||||
Pass a pointer to a linked list of FTP commands to pass to the server after
|
||||
your ftp transfer request. The linked list should be a fully valid list of
|
||||
struct curl_slist structs properly filled in as described for
|
||||
\fICURLOPT_QUOTE\fP.
|
||||
\fICURLOPT_QUOTE\fP. Disable this operation again by setting a NULL to this
|
||||
option.
|
||||
.TP
|
||||
.B CURLOPT_WRITEHEADER
|
||||
Pass a pointer to be used to write the header part of the received data to. If
|
||||
@@ -545,6 +587,29 @@ compile OpenSSL.
|
||||
|
||||
You'll find more details about cipher lists on this URL:
|
||||
\fIhttp://www.openssl.org/docs/apps/ciphers.html\fP
|
||||
.TP
|
||||
.B CURLOPT_HTTP_VERSION
|
||||
Pass a long, set to one of the values described below. They force libcurl to
|
||||
use the specific HTTP versions. This is not sensible to do unless you have a
|
||||
good reason.
|
||||
.RS
|
||||
.TP 5
|
||||
.B CURL_HTTP_VERSION_NONE
|
||||
We don't care about what version the library uses. libcurl will use whatever
|
||||
it thinks fit.
|
||||
.TP
|
||||
.B CURL_HTTP_VERSION_1_0
|
||||
Enforce HTTP 1.0 requests.
|
||||
.TP
|
||||
.B CURL_HTTP_VERSION_1_1
|
||||
Enforce HTTP 1.1 requests.
|
||||
.RE
|
||||
.TP
|
||||
.B CURLOPT_FTP_USE_EPSV
|
||||
Pass a long. If the value is non-zero, it tells curl to use the EPSV command
|
||||
when doing passive FTP downloads (which is always does by default). Using EPSV
|
||||
means that it will first attempt to use EPSV before using PASV, but if you
|
||||
pass FALSE (zero) to this option, it will not try using EPSV, only plain PASV.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
CURLE_OK (zero) means that the option was set properly, non-zero means an
|
||||
|
@@ -58,6 +58,13 @@ are allowed. The effect of this parameter is the same as giving multiple
|
||||
\fBCURLFORM_FILE\fP options possibly with \fBCURLFORM_CONTENTTYPE\fP after or
|
||||
before each \fBCURLFORM_FILE\fP option.
|
||||
|
||||
Should you need to specify extra headers for the form POST section, use
|
||||
\fBCURLFORM_CONTENTHEADER\fP. This takes a curl_slist prepared in the usual way
|
||||
using \fBcurl_slist_append\fP and appends the list of headers to those Curl
|
||||
automatically generates for \fBCURLFORM_CONTENTTYPE\fP and the content
|
||||
disposition. The list must exist while the POST occurs, if you free it before
|
||||
the post completes you may experience problems.
|
||||
|
||||
The last argument in such an array must always be \fBCURLFORM_END\fP.
|
||||
|
||||
The pointers \fI*firstitem\fP and \fI*lastitem\fP should both be pointing to
|
||||
|
@@ -2,7 +2,7 @@
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_formparse 3 "21 May 2001" "libcurl 7.7.4" "libcurl Manual"
|
||||
.TH curl_formparse 3 "17 Dec 2001" "libcurl 7.9.2" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_formparse - add a section to a multipart/formdata HTTP POST:
|
||||
deprecated (use curl_formadd instead)
|
||||
@@ -13,75 +13,6 @@ deprecated (use curl_formadd instead)
|
||||
.BI "struct HttpPost ** " lastitem ");"
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
curl_formparse() is used to append sections when building a multipart/formdata
|
||||
HTTP POST (sometimes refered to as rfc1867-style posts). Append one section at
|
||||
a time until you've added all the sections you want included and then you pass
|
||||
the \fIfirstitem\fP pointer as parameter to \fBCURLOPT_HTTPPOST\fP.
|
||||
\fIlastitem\fP is set after each call and on repeated invokes it should be
|
||||
left as set to allow repeated invokes to find the end of the list in a faster
|
||||
way. \fIstring\fP must be a zero terminated string abiding to the syntax
|
||||
described in a section below
|
||||
|
||||
The pointers \fI*firstitem\fP and \fI*lastitem\fP should both be pointing to
|
||||
NULL in the first call to this function. All list-data will be allocated by
|
||||
the function itself. You must call \fIcurl_formfree\fP after the form post has
|
||||
been done to free the resources again.
|
||||
|
||||
This function will copy all input data and keep its own version of it
|
||||
allocated until you call \fIcurl_formfree\fP. When you've passed the pointer
|
||||
to \fIcurl_easy_setopt\fP, you must not free the list until after you've
|
||||
called \fIcurl_easy_cleanup\fP for the curl handle.
|
||||
|
||||
See example below.
|
||||
.SH "FORM PARSE STRINGS"
|
||||
The
|
||||
.I string
|
||||
parameter must be using one of the following patterns. Note that the []
|
||||
letters should not be included in the real-life string.
|
||||
.TP 0.8i
|
||||
.B [name]=[contents]
|
||||
Add a form field named 'name' with the contents 'contents'. This is the
|
||||
typcial contents of the HTML tag <input type=text>.
|
||||
.TP
|
||||
.B [name]=@[filename]
|
||||
Add a form field named 'name' with the contents as read from the local file
|
||||
named 'filename'. This is the typcial contents of the HTML tag <input
|
||||
type=file>.
|
||||
.TP
|
||||
.B [name]=@[filename1,filename2,...]
|
||||
Add a form field named 'name' with the contents as read from the local files
|
||||
named 'filename1' and 'filename2'. This is identical to the upper, except that
|
||||
you get the contents of several files in one section.
|
||||
.TP
|
||||
.B [name]=@[filename];[type=<content-type>]
|
||||
Whenever you specify a file to read from, you can optionally specify the
|
||||
content-type as well. The content-type is passed to the server together with
|
||||
the contents of the file. curl_formparse() will guess content-type for a
|
||||
number of well-known extensions and otherwise it will set it to binary. You
|
||||
can override the internal decision by using this option.
|
||||
.TP
|
||||
.B [name]=@[filename1,filename2,...];[type=<content-type>]
|
||||
When you specify several files to read the contents from, you can set the
|
||||
content-type for all of them in the same way as with a single file.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
Returns non-zero if an error occurs.
|
||||
.SH EXAMPLE
|
||||
|
||||
HttpPost* post = NULL;
|
||||
HttpPost* last = NULL;
|
||||
|
||||
/* Add an image section */
|
||||
curl_formparse("picture=@my-face.jpg", &post, &last);
|
||||
/* Add a normal text section */
|
||||
curl_formparse("name=FooBar", &post, &last);
|
||||
/* Set the form info */
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_easy_setopt "(3), "
|
||||
.BR curl_formadd "(3), "
|
||||
.BR curl_formfree "(3)
|
||||
.SH BUGS
|
||||
Surely there are some, you tell me!
|
||||
|
||||
This has been removed deliberately. The \fBcurl_formadd\fP has been introduced
|
||||
to replace this function. Do not use this. Convert to the new function
|
||||
now. curl_formparse() will be removed from a future version of libcurl.
|
||||
|
@@ -2,7 +2,7 @@
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_global_init 3 "14 August 2001" "libcurl 7.8.1" "libcurl Manual"
|
||||
.TH curl_global_init 3 "13 Nov 2001" "libcurl 7.9.1" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_global_init - Global libcurl initialisation
|
||||
.SH SYNOPSIS
|
||||
@@ -11,8 +11,8 @@ curl_global_init - Global libcurl initialisation
|
||||
.BI "CURLcode curl_global_init(long " flags ");"
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
This function should be called once (no matter how many threads or libcurl
|
||||
sessions that'll be used) by every application that uses libcurl.
|
||||
This function should only be called once (no matter how many threads or
|
||||
libcurl sessions that'll be used) by every application that uses libcurl.
|
||||
|
||||
If this function hasn't been invoked when \fIcurl_easy_init\fP is called, it
|
||||
will be done automatically by libcurl.
|
||||
@@ -23,6 +23,8 @@ init, as described below. Set the desired bits by ORing the values together.
|
||||
You must however \fBalways\fP use the \fIcurl_global_cleanup\fP function, as
|
||||
that cannot be called automatically for you by libcurl.
|
||||
|
||||
Calling this function more than once will cause unpredictable results.
|
||||
|
||||
This function was added in libcurl 7.8.
|
||||
.SH FLAGS
|
||||
.TP 5
|
||||
|
@@ -6,7 +6,8 @@ AUTOMAKE_OPTIONS = foreign no-dependencies
|
||||
|
||||
EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit.c postit2.c \
|
||||
win32sockets.c persistant.c ftpget.c Makefile.example \
|
||||
multithread.c getinmemory.c ftpupload.c httpput.c
|
||||
multithread.c getinmemory.c ftpupload.c httpput.c \
|
||||
simplessl.c ftpgetresp.c http-post.c
|
||||
|
||||
all:
|
||||
@echo "done"
|
||||
|
@@ -10,6 +10,10 @@ them for submission in future packages and on the web site.
|
||||
The Makefile.example is an example makefile that could be used to build these
|
||||
examples. Just edit the file according to your system and requirements first.
|
||||
|
||||
Most examples should build fine using a command line like this:
|
||||
|
||||
$ gcc `curl-config --cflags` `curl-config --libs` -o example example.c
|
||||
|
||||
Try the php/examples/ directory for PHP programming snippets!
|
||||
|
||||
*PLEASE* do not use the curl.haxx.se site as a test target for your libcurl
|
||||
|
@@ -14,31 +14,70 @@
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
/* to make this work under windows, use the win32-functions from the
|
||||
win32socket.c file as well */
|
||||
/*
|
||||
* This is an example showing how to get a single file from an FTP server.
|
||||
* It delays the actual destination file creation until the first write
|
||||
* callback so that it won't create an empty file in case the remote file
|
||||
* doesn't exist or something else fails.
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
struct FtpFile {
|
||||
char *filename;
|
||||
FILE *stream;
|
||||
};
|
||||
|
||||
int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
struct FtpFile *out=(struct FtpFile *)stream;
|
||||
if(out && !out->stream) {
|
||||
/* open file for writing */
|
||||
out->stream=fopen(out->filename, "wb");
|
||||
if(!out->stream)
|
||||
return -1; /* failure, can't open file to write */
|
||||
}
|
||||
return fwrite(buffer, size, nmemb, out->stream);
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
FILE *ftpfile;
|
||||
struct FtpFile ftpfile={
|
||||
"curl.tar.gz", /* name to store the file as if succesful */
|
||||
NULL
|
||||
};
|
||||
|
||||
/* local file name to store the file as */
|
||||
ftpfile = fopen("curl.tar.gz", "wb"); /* b is binary for win */
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Get curl 7.7 from sunet.se's FTP site: */
|
||||
/* Get curl 7.9.2 from sunet.se's FTP site: */
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"ftp://ftp.sunet.se/pub/www/utilities/curl/curl-7.7.tar.gz");
|
||||
curl_easy_setopt(curl, CURLOPT_FILE, ftpfile);
|
||||
"ftp://ftp.sunet.se/pub/www/utilities/curl/curl-7.9.2.tar.gz");
|
||||
/* Define our callback to get called when there's data to be written */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
|
||||
/* Set a pointer to our struct to pass to the callback */
|
||||
curl_easy_setopt(curl, CURLOPT_FILE, &ftpfile);
|
||||
|
||||
/* Switch on full protocol/debug output */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if(CURLE_OK != res) {
|
||||
/* we failed */
|
||||
fprintf(stderr, "curl told us %d\n", res);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(ftpfile); /* close the local file */
|
||||
if(ftpfile.stream)
|
||||
fclose(ftpfile.stream); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
61
docs/examples/ftpgetresp.c
Normal file
61
docs/examples/ftpgetresp.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
/*
|
||||
* Similar to ftpget.c but this also stores the received response-lines
|
||||
* in a separate file using our own callback!
|
||||
*
|
||||
* This functionality was introduced in libcurl 7.9.3.
|
||||
*/
|
||||
|
||||
size_t
|
||||
write_response(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
FILE *writehere = (FILE *)data;
|
||||
return fwrite(ptr, size, nmemb, writehere);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
FILE *ftpfile;
|
||||
FILE *respfile;
|
||||
|
||||
/* local file name to store the file as */
|
||||
ftpfile = fopen("ftp-list", "wb"); /* b is binary, needed on win32 */
|
||||
|
||||
/* local file name to store the FTP server's response lines in */
|
||||
respfile = fopen("ftp-responses", "wb"); /* b is binary, needed on win32 */
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Get a file listing from sunet */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "ftp://ftp.sunet.se/");
|
||||
curl_easy_setopt(curl, CURLOPT_FILE, ftpfile);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_response);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEHEADER, respfile);
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
fclose(ftpfile); /* close the local file */
|
||||
fclose(respfile); /* close the response file */
|
||||
|
||||
return 0;
|
||||
}
|
35
docs/examples/http-post.c
Normal file
35
docs/examples/http-post.c
Normal file
@@ -0,0 +1,35 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* First set the URL that is about to receive our POST. This URL can
|
||||
just as well be a https:// URL if that is what should receive the
|
||||
data. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://postit.example.com/moo.cgi");
|
||||
/* Now specify the POST data */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=daniel&project=curl");
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
@@ -9,27 +9,16 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
/* to make this work under windows, use the win32-functions from the
|
||||
win32socket.c file as well */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
FILE *headerfile;
|
||||
|
||||
headerfile = fopen("dumpit", "w");
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* what call to write: */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se");
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEHEADER, headerfile);
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
|
115
docs/examples/simplessl.c
Normal file
115
docs/examples/simplessl.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
|
||||
/* some requirements for this to work:
|
||||
1. set pCertFile to the file with the client certificate
|
||||
2. if the key is passphrase protected, set pPassphrase to the
|
||||
passphrase you use
|
||||
3. if you are using a crypto engine:
|
||||
3.1. set a #define USE_ENGINE
|
||||
3.2. set pEngine to the name of the crypto engine you use
|
||||
3.3. set pKeyName to the key identifier you want to use
|
||||
4. if you don't use a crypto engine:
|
||||
4.1. set pKeyName to the file name of your client key
|
||||
4.2. if the format of the key file is DER, set pKeyType to "DER"
|
||||
|
||||
!! verify of the server certificate is not implemented here !!
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
FILE *headerfile;
|
||||
|
||||
const char *pCertFile = "testcert.pem";
|
||||
const char *pCACertFile="cacert.pem"
|
||||
|
||||
const char *pKeyName;
|
||||
const char *pKeyType;
|
||||
|
||||
const char *pEngine;
|
||||
|
||||
#if USE_ENGINE
|
||||
pKeyName = "rsa_test";
|
||||
pKeyType = "ENG";
|
||||
pEngine = "chil"; /* for nChiper HSM... */
|
||||
#else
|
||||
pKeyName = "testkey.pem";
|
||||
pKeyType = "PEM";
|
||||
pEngine = NULL;
|
||||
#endif
|
||||
|
||||
const char *pPassphrase = NULL;
|
||||
|
||||
headerfile = fopen("dumpit", "w");
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* what call to write: */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "HTTPS://curl.haxx.se");
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEHEADER, headerfile);
|
||||
|
||||
while(1) /* do some ugly short cut... */
|
||||
{
|
||||
if (pEngine) /* use crypto engine */
|
||||
{
|
||||
if (curl_easy_setopt(curl, CURLOPT_SSLENGINE,pEngine) != CURLE_OK)
|
||||
{ /* load the crypto engine */
|
||||
fprintf(stderr,"can't set crypto engine\n");
|
||||
break;
|
||||
}
|
||||
if (curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT,1) != CURLE_OK)
|
||||
{ /* set the crypto engine as default */
|
||||
/* only needed for the first time you load
|
||||
a engine in a curl object... */
|
||||
fprintf(stderr,"can't set crypto engine as default\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* cert is stored PEM coded in file... */
|
||||
/* since PEM is default, we needn't set it for PEM */
|
||||
curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");
|
||||
/* set the cert for client authentication */
|
||||
curl_easy_setopt(curl,CURLOPT_SSLCERT,pCertFile);
|
||||
/* sorry, for engine we must set the passphrase
|
||||
(if the key has one...) */
|
||||
if (pPassphrase)
|
||||
curl_easy_setopt(curl,CURLOPT_SSLKEYPASSWD,pPassphrase);
|
||||
/* if we use a key stored in a crypto engine,
|
||||
we must set the key type to "ENG" */
|
||||
curl_easy_setopt(curl,CURLOPT_SSLKEYTYPE,pKeyType);
|
||||
/* set the private key (file or ID in engine) */
|
||||
curl_easy_setopt(curl,CURLOPT_SSLKEY,pKeyName);
|
||||
/* set the file with the certs vaildating the server */
|
||||
curl_easy_setopt(curl,CURLOPT_CAINFO,pCACertFile);
|
||||
/* disconnect if we can't validate server's cert */
|
||||
curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,1);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
break; /* we are done... */
|
||||
}
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
38
docs/index.html
Normal file
38
docs/index.html
Normal file
@@ -0,0 +1,38 @@
|
||||
HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||
<TITLE>Index to Curl documentation</TITLE>
|
||||
</HEAD>
|
||||
|
||||
<BODY>
|
||||
<H1 ALIGN="CENTER">Index to Curl documentation</H1>
|
||||
|
||||
<H2>Programs</H2>
|
||||
<P><A HREF="curl-config.html">curl-config.html</A>
|
||||
<P><A HREF="curl.html">curl.html</A>
|
||||
|
||||
<H2>Library routines</H2>
|
||||
<P><A HREF="libcurl.html">libcurl.html</A>
|
||||
<P><A HREF="curl_easy_cleanup.html">curl_easy_cleanup.html</A>
|
||||
<P><A HREF="curl_easy_duphandle.html">curl_easy_duphandle.html</A>
|
||||
<P><A HREF="curl_easy_getinfo.html">curl_easy_getinfo.html</A>
|
||||
<P><A HREF="curl_easy_init.html">curl_easy_init.html</A>
|
||||
<P><A HREF="curl_easy_perform.html">curl_easy_perform.html</A>
|
||||
<P><A HREF="curl_easy_setopt.html">curl_easy_setopt.html</A>
|
||||
<P><A HREF="curl_escape.html">curl_escape.html</A>
|
||||
<P><A HREF="curl_formadd.html">curl_formadd.html</A>
|
||||
<P><A HREF="curl_formfree.html">curl_formfree.html</A>
|
||||
<P><A HREF="curl_formparse.html">curl_formparse.html</A>
|
||||
<P><A HREF="curl_getdate.html">curl_getdate.html</A>
|
||||
<P><A HREF="curl_getenv.html">curl_getenv.html</A>
|
||||
<P><A HREF="curl_global_cleanup.html">curl_global_cleanup.html</A>
|
||||
<P><A HREF="curl_global_init.html">curl_global_init.html</A>
|
||||
<P><A HREF="curl_mprintf.html">curl_mprintf.html</A>
|
||||
<P><A HREF="curl_slist_append.html">curl_slist_append.html</A>
|
||||
<P><A HREF="curl_slist_free_all.html">curl_slist_free_all.html</A>
|
||||
<P><A HREF="curl_strequal.html">curl_strequal.html</A>
|
||||
<P><A HREF="curl_strnequal.html">curl_strnequal.html</A>
|
||||
<P><A HREF="curl_unescape.html">curl_unescape.html</A>
|
||||
<P><A HREF="curl_version.html">curl_version.html</A>
|
||||
</BODY>
|
||||
</HTML>
|
209
docs/libcurl-the-guide
Normal file
209
docs/libcurl-the-guide
Normal file
@@ -0,0 +1,209 @@
|
||||
$Id$
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
PROGRAMMING WITH LIBCURL
|
||||
|
||||
About this Document
|
||||
|
||||
This document will attempt to describe the general principle and some basic
|
||||
approach to consider when programming with libcurl. The text will focus
|
||||
mainly on the C/C++ interface but might apply fairly well on other interfaces
|
||||
as well as they usually follow the C one pretty closely.
|
||||
|
||||
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
|
||||
source code that you write that is using libcurl for transfers. The program
|
||||
is outside libcurl and libcurl is outside of the program.
|
||||
|
||||
|
||||
Building
|
||||
|
||||
Compiling the Program
|
||||
|
||||
Linking the Program with libcurl
|
||||
|
||||
SSL or Not
|
||||
|
||||
|
||||
Global Preparation
|
||||
|
||||
The program must initialize some of the libcurl functionality globally. That
|
||||
means it should be done exactly once, no matter how many times you intend to
|
||||
use the library. Once for your program's entire life time. This is done using
|
||||
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
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
|
||||
the case, libcurl runs the function itself with a guessed bit pattern. Please
|
||||
note that depending solely on this is not considered nice nor very good.
|
||||
|
||||
When the program no longer uses libcurl, it should call
|
||||
curl_global_cleanup(), which is the opposite of the init call. It will then
|
||||
do the reversed operations to cleanup the resources the curl_global_init()
|
||||
call initialized.
|
||||
|
||||
Repeated calls to curl_global_init() and curl_global_cleanup() should be
|
||||
avoided. They should be called once each.
|
||||
|
||||
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'.
|
||||
|
||||
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!
|
||||
|
||||
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
|
||||
should use one handle for every thread you plan to use for transferring. You
|
||||
must never share the same handle in multiple threads.
|
||||
|
||||
Get an easy handle with
|
||||
|
||||
easyhandle = curl_easy_init();
|
||||
|
||||
It returns an easy handle. Using that you proceed to the next step: setting
|
||||
up your preferred actions. A handle is just a logic entity for the upcoming
|
||||
transfer or series of transfers. One of the most basic properties to set in
|
||||
the handle is the URL. You set your preferred URL to transfer with
|
||||
CURLOPT_URL in a manner similar to:
|
||||
|
||||
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
|
||||
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
|
||||
your own function that matches this prototype:
|
||||
|
||||
size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp);
|
||||
|
||||
You tell libcurl to pass all data to this function by issuing a function
|
||||
similar to this:
|
||||
|
||||
curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, write_data);
|
||||
|
||||
You can control what data your function get in the forth argument by setting
|
||||
another property:
|
||||
|
||||
curl_easy_setopt(easyhandle, CURLOPT_FILE, &internal_struct);
|
||||
|
||||
Using that property, you can easily pass local data between your application
|
||||
and the function that gets invoked by libcurl. libcurl itself won't touch the
|
||||
data you pass with CURLOPT_FILE.
|
||||
|
||||
There are of course many more options you can set, and we'll get back to a
|
||||
few of them later. Let's instead continue to the actual transfer:
|
||||
|
||||
success = curl_easy_perform(easyhandle);
|
||||
|
||||
The curl_easy_perform() will connect to the remote site, do the necessary
|
||||
commands and receive the transfer. Whenever it receives data, it calls the
|
||||
callback function we previously set. The function may get one byte at a time,
|
||||
or it may get many kilobytes at once. libcurl delivers as much as possible as
|
||||
often as possible. Your callback function should return the number of bytes
|
||||
it "took care of". If that is not the exact same amount of bytes that was
|
||||
passed to it, libcurl will abort the operation and return with an error code.
|
||||
|
||||
When the transfer is complete, the function returns a return code that
|
||||
informs you if it succeeded in its mission or not. If a return code isn't
|
||||
enough for you, you can use the CURLOPT_ERRORBUFFER to point libcurl to a
|
||||
buffer of yours where it'll store a human readable error message as well.
|
||||
|
||||
If you then want to transfer another file, the handle is ready to be used
|
||||
again. Mind you, it is even preferred that you re-use an existing handle if
|
||||
you intend to make another transfer. libcurl will then attempt to re-use the
|
||||
previous
|
||||
|
||||
When It Doesn't Work
|
||||
|
||||
There will always be times when the transfer fails for some reason. You might
|
||||
have set the wrong libcurl option or misunderstood what the libcurl option
|
||||
actually does, or the remote server might return non-standard replies that
|
||||
confuse the library which then confuses your program.
|
||||
|
||||
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
|
||||
(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
|
||||
output with CURLOPT_HEADER set TRUE.
|
||||
|
||||
Upload Data to a Remote Site
|
||||
|
||||
libcurl tries to keep a protocol independent approach to most transfers, thus
|
||||
uploading to a remote FTP site is very similar to uploading data to a HTTP
|
||||
server with a PUT request.
|
||||
|
||||
Of course, first you either create an easy handle or you re-use one existing
|
||||
one. Then you set the URL to operate on just like before. This is the remote
|
||||
URL, that we now will upload.
|
||||
|
||||
Since we write an application, we most likely want libcurl to get the upload
|
||||
data by asking us for it. To make it do that, we set the read callback and
|
||||
the custom pointer libcurl will pass to our read callback. The read callback
|
||||
should have a prototype similar to:
|
||||
|
||||
size_t function(char *buffer, size_t size, size_t nitems, void *userp);
|
||||
|
||||
Where buffer is the pointer to a buffer we fill in with data to upload and
|
||||
size*nitems is the size of the buffer. The 'userp' pointer is the custom
|
||||
pointer we set to point to a struct of ours to pass private data between the
|
||||
application and the callback.
|
||||
|
||||
curl_easy_setopt(easyhandle, CURLOPT_READFUNCTION, read_function);
|
||||
|
||||
curl_easy_setopt(easyhandle, CURLOPT_INFILE, &filedata);
|
||||
|
||||
Tell libcurl that we want to upload:
|
||||
|
||||
curl_easy_setopt(easyhandle, CURLOPT_UPLOAD, TRUE);
|
||||
|
||||
A few protocols won't behave properly when uploads are done without any prior
|
||||
knowledge of the expected file size. HTTP PUT is one example [1]. So, set the
|
||||
upload file size using the CURLOPT_INFILESIZE like this:
|
||||
|
||||
curl_easy_setopt(easyhandle, CURLOPT_INFILESIZE, file_size);
|
||||
|
||||
So, then you call curl_easy_perform() this time, it'll perform all necessary
|
||||
operations and when it has invoked the upload it'll call your supplied
|
||||
callback to get the data to upload. The program should return as much data as
|
||||
possible in every invoke, as that is likely to make the upload perform as
|
||||
fast as possible. The callback should return the number of bytes it wrote in
|
||||
the buffer. Returning 0 will signal the end of the upload.
|
||||
|
||||
|
||||
-----
|
||||
Footnotes:
|
||||
|
||||
[1] = HTTP PUT without knowing the size prior to transfer is indeed possible,
|
||||
but libcurl does not support the chunked transfers on uploading that is
|
||||
necessary for this feature to work. We'd gratefully appreciate patches
|
||||
that bring this functionality...
|
@@ -62,6 +62,7 @@ struct HttpPost {
|
||||
char *contents; /* pointer to allocated data contents */
|
||||
long contentslength; /* length of contents field */
|
||||
char *contenttype; /* Content-Type */
|
||||
struct curl_slist* contentheader; /* list of extra headers for this form */
|
||||
struct HttpPost *more; /* if one field name has more than one file, this
|
||||
link should link to following files */
|
||||
long flags; /* as defined below */
|
||||
@@ -155,6 +156,8 @@ typedef enum {
|
||||
CURLE_OBSOLETE, /* 50 - removed after 7.7.3 */
|
||||
CURLE_SSL_PEER_CERTIFICATE, /* 51 - peer's certificate wasn't ok */
|
||||
CURLE_GOT_NOTHING, /* 52 - when this is a specific error */
|
||||
CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */
|
||||
CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as default */
|
||||
|
||||
CURL_LAST /* never use! */
|
||||
} CURLcode;
|
||||
@@ -212,10 +215,8 @@ typedef enum {
|
||||
in the CURLOPT_FLAGS to activate this */
|
||||
CINIT(RANGE, OBJECTPOINT, 7),
|
||||
|
||||
#if 0
|
||||
/* Configuration flags */
|
||||
CINIT(FLAGS, LONG, 8),
|
||||
#endif
|
||||
/* not used */
|
||||
|
||||
/* Specified file stream to upload from (use as input): */
|
||||
CINIT(INFILE, OBJECTPOINT, 9),
|
||||
|
||||
@@ -280,8 +281,10 @@ typedef enum {
|
||||
/* name of the file keeping your private SSL-certificate */
|
||||
CINIT(SSLCERT, OBJECTPOINT, 25),
|
||||
|
||||
/* password for the SSL-certificate */
|
||||
/* password for the SSL-private key, keep this for compatibility */
|
||||
CINIT(SSLCERTPASSWD, OBJECTPOINT, 26),
|
||||
/* password for the SSL private key */
|
||||
CINIT(SSLKEYPASSWD, OBJECTPOINT, 26),
|
||||
|
||||
/* send TYPE parameter? */
|
||||
CINIT(CRLF, LONG, 27),
|
||||
@@ -298,7 +301,7 @@ typedef enum {
|
||||
CINIT(COOKIEFILE, OBJECTPOINT, 31),
|
||||
|
||||
/* What version to specifly try to use.
|
||||
3 = SSLv3, 2 = SSLv2, all else makes it try v3 first then v2 */
|
||||
See CURL_SSLVERSION defines below. */
|
||||
CINIT(SSLVERSION, LONG, 32),
|
||||
|
||||
/* What kind of HTTP time condition to use, see defines */
|
||||
@@ -321,11 +324,8 @@ typedef enum {
|
||||
/* HTTP request, for odd commands like DELETE, TRACE and others */
|
||||
CINIT(STDERR, OBJECTPOINT, 37),
|
||||
|
||||
#if 0
|
||||
/* Progress mode set alternative progress mode displays. Alternative
|
||||
ones should now be made by the client, not the lib! */
|
||||
CINIT(PROGRESSMODE, LONG, 38),
|
||||
#endif
|
||||
/* 38 is not used */
|
||||
|
||||
/* send linked-list of post-transfer QUOTE commands */
|
||||
CINIT(POSTQUOTE, OBJECTPOINT, 39),
|
||||
|
||||
@@ -466,6 +466,34 @@ typedef enum {
|
||||
CURL_HTTP_VERSION* enums set below. */
|
||||
CINIT(HTTP_VERSION, LONG, 84),
|
||||
|
||||
/* Specificly switch on or off the FTP engine's use of the EPSV command. By
|
||||
default, that one will always be attempted before the more traditional
|
||||
PASV command. */
|
||||
CINIT(FTP_USE_EPSV, LONG, 85),
|
||||
|
||||
/* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */
|
||||
CINIT(SSLCERTTYPE, OBJECTPOINT, 86),
|
||||
|
||||
/* name of the file keeping your private SSL-key */
|
||||
CINIT(SSLKEY, OBJECTPOINT, 87),
|
||||
|
||||
/* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */
|
||||
CINIT(SSLKEYTYPE, OBJECTPOINT, 88),
|
||||
|
||||
/* crypto engine for the SSL-sub system */
|
||||
CINIT(SSLENGINE, OBJECTPOINT, 89),
|
||||
|
||||
/* set the crypto engine for the SSL-sub system as default
|
||||
the param has no meaning...
|
||||
*/
|
||||
CINIT(SSLENGINE_DEFAULT, LONG, 90),
|
||||
|
||||
/* Non-zero value means to use the global dns cache */
|
||||
CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91),
|
||||
|
||||
/* DNS cache timeout */
|
||||
CINIT(DNS_CACHE_TIMEOUT, LONG, 92),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unusued */
|
||||
} CURLoption;
|
||||
|
||||
@@ -480,6 +508,15 @@ enum {
|
||||
CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
|
||||
};
|
||||
|
||||
enum {
|
||||
CURL_SSLVERSION_DEFAULT,
|
||||
CURL_SSLVERSION_TLSv1,
|
||||
CURL_SSLVERSION_SSLv2,
|
||||
CURL_SSLVERSION_SSLv3,
|
||||
|
||||
CURL_SSLVERSION_LAST /* never use, keep last */
|
||||
};
|
||||
|
||||
|
||||
typedef enum {
|
||||
TIMECOND_NONE,
|
||||
@@ -534,6 +571,7 @@ typedef enum {
|
||||
CFINIT(ARRAY_START), /* below are the options allowed within a array */
|
||||
CFINIT(FILE),
|
||||
CFINIT(CONTENTTYPE),
|
||||
CFINIT(CONTENTHEADER),
|
||||
CFINIT(END),
|
||||
CFINIT(ARRAY_END), /* up are the options allowed within a array */
|
||||
|
||||
@@ -575,8 +613,8 @@ CURLcode curl_global_init(long flags);
|
||||
void curl_global_cleanup(void);
|
||||
|
||||
/* This is the version number */
|
||||
#define LIBCURL_VERSION "7.9.1"
|
||||
#define LIBCURL_VERSION_NUM 0x070901
|
||||
#define LIBCURL_VERSION "7.9.3-pre2"
|
||||
#define LIBCURL_VERSION_NUM 0x070903
|
||||
|
||||
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
|
||||
struct curl_slist {
|
||||
@@ -626,7 +664,9 @@ typedef enum {
|
||||
CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15,
|
||||
CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16,
|
||||
|
||||
CURLINFO_LASTONE = 17
|
||||
CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17,
|
||||
|
||||
CURLINFO_LASTONE = 18
|
||||
} CURLINFO;
|
||||
|
||||
/* unfortunately, the easy.h include file needs the options and info stuff
|
||||
|
@@ -10,9 +10,6 @@ EXTRA_DIST = getdate.y \
|
||||
|
||||
lib_LTLIBRARIES = libcurl.la
|
||||
|
||||
# Some flags needed when trying to cause warnings ;-)
|
||||
# CFLAGS = -DMALLOCDEBUG -g # -Wall #-pedantic
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
|
||||
|
||||
@@ -59,7 +56,9 @@ escape.c mprintf.c telnet.c \
|
||||
escape.h getpass.c netrc.c telnet.h \
|
||||
getinfo.c getinfo.h transfer.c strequal.c strequal.h easy.c \
|
||||
security.h security.c krb4.c krb4.h memdebug.c memdebug.h inet_ntoa_r.h \
|
||||
http_chunks.c http_chunks.h strtok.c strtok.h connect.c connect.h
|
||||
http_chunks.c http_chunks.h strtok.c strtok.h connect.c connect.h \
|
||||
llist.c llist.h hash.c hash.h multi.c multi.h
|
||||
|
||||
|
||||
noinst_HEADERS = setup.h transfer.h
|
||||
|
||||
|
@@ -23,7 +23,7 @@ INCDIRS = -I$(CURNTDIR);$(TOPDIR)/include/
|
||||
# 'BCCDIR' has to be set up in your c:\autoexec.bat
|
||||
# i.e. SET BCCDIR = c:\Borland\BCC55
|
||||
# where c:\Borland\BCC55 is the compiler is installed
|
||||
LINKLIB = $(BCCDIR)/lib/psdk/wsock32.lib
|
||||
LINKLIB = $(BCCDIR)/lib/psdk/ws2_32.lib
|
||||
LIBCURLLIB = libcurl.lib
|
||||
|
||||
.SUFFIXES: .c
|
||||
|
@@ -27,5 +27,5 @@
|
||||
+version.obj &
|
||||
+easy.obj &
|
||||
+strequal.obj &
|
||||
+strtok.obj
|
||||
|
||||
+strtok.obj &
|
||||
+connect.obj
|
||||
|
548
lib/Makefile.vc6
548
lib/Makefile.vc6
@@ -1,377 +1,219 @@
|
||||
#############################################################
|
||||
#
|
||||
## Makefile for building libcurl.lib with MSVC6
|
||||
## Use: nmake -f makefile.vc6 [release | release-ssl | debug]
|
||||
## (default is release)
|
||||
##
|
||||
## Originally written by: Troy Engel <tengel@sonic.net>
|
||||
## Updated by: Craig Davison <cd@securityfocus.com>
|
||||
## Updated by: SM <sm@technologist.com>
|
||||
# Makefile for building libcurl with MSVC6
|
||||
#
|
||||
# Usage: see usage message below
|
||||
# Should be invoked from \lib directory
|
||||
# Edit the paths and desired library name
|
||||
# SSL path is only required if you intend compiling
|
||||
# with SSL.
|
||||
#
|
||||
# This make file leaves the result either a .lib or .dll file
|
||||
# in the \lib directory. It should be called from the \lib
|
||||
# directory.
|
||||
#
|
||||
# An option would have been to allow the source directory to
|
||||
# be specified, but I saw no requirement.
|
||||
#
|
||||
# Another option would have been to leave the .lib and .dll
|
||||
# files in the "cfg" directory, but then the make file
|
||||
# in \src would need to be changed.
|
||||
#
|
||||
##############################################################
|
||||
# CHANGE LOG
|
||||
# ------------------------------------------------------------
|
||||
# 05.11.2001 John Lask Initial Release
|
||||
#
|
||||
#
|
||||
##############################################################
|
||||
|
||||
PROGRAM_NAME = libcurl.lib
|
||||
PROGRAM_NAME_DEBUG = libcurld.lib
|
||||
#OPENSSL_PATH = ../../openssl-0.9.6b
|
||||
LIB_NAME = libcurl
|
||||
LIB_NAME_DEBUG = libcurld
|
||||
OPENSSL_PATH = ../../openssl-0.9.6
|
||||
|
||||
########################################################
|
||||
#############################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
## Release
|
||||
CCR = cl.exe /MD /O2 /D "NDEBUG"
|
||||
LINKR = link.exe -lib /out:$(PROGRAM_NAME)
|
||||
|
||||
## Debug
|
||||
CCD = cl.exe /MDd /Gm /ZI /Od /D "_DEBUG" /GZ
|
||||
LINKD = link.exe -lib /out:$(PROGRAM_NAME_DEBUG)
|
||||
|
||||
## SSL Release
|
||||
CCRS = cl.exe /MD /O2 /D "NDEBUG" /D "USE_SSLEAY" /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
LINKRS = link.exe -lib /out:$(PROGRAM_NAME) /LIBPATH:$(OPENSSL_PATH)/out32dll
|
||||
|
||||
CCNODBG = cl.exe /MD /O2 /D "NDEBUG"
|
||||
CCDEBUG = cl.exe /MDd /Od /Gm /Zi /D "_DEBUG" /GZ
|
||||
CFLAGSSSL = /D "USE_SSLEAY" /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
CFLAGS = /I "../include" /nologo /W3 /GX /D "WIN32" /D "VC6" /D "_MBCS" /D "_LIB" /YX /FD /c /D "MSDOS"
|
||||
|
||||
LNKDLL = link.exe /DLL /def:libcurl.def
|
||||
LNKLIB = link.exe -lib
|
||||
LFLAGS = /nologo
|
||||
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)/out32dll
|
||||
LINKLIBS = ws2_32.lib
|
||||
LINKSLIBS = libeay32.lib ssleay32.lib RSAglue.lib
|
||||
SSLLIBS = libeay32.lib ssleay32.lib RSAglue.lib
|
||||
CFGSET = FALSE
|
||||
|
||||
RELEASE_OBJS= \
|
||||
base64r.obj \
|
||||
cookier.obj \
|
||||
transferr.obj \
|
||||
escaper.obj \
|
||||
formdatar.obj \
|
||||
ftpr.obj \
|
||||
httpr.obj \
|
||||
http_chunksr.obj \
|
||||
ldapr.obj \
|
||||
dictr.obj \
|
||||
telnetr.obj \
|
||||
getdater.obj \
|
||||
getenvr.obj \
|
||||
getpassr.obj \
|
||||
hostipr.obj \
|
||||
if2ipr.obj \
|
||||
mprintfr.obj \
|
||||
netrcr.obj \
|
||||
progressr.obj \
|
||||
sendfr.obj \
|
||||
speedcheckr.obj \
|
||||
ssluser.obj \
|
||||
timevalr.obj \
|
||||
urlr.obj \
|
||||
filer.obj \
|
||||
getinfor.obj \
|
||||
versionr.obj \
|
||||
easyr.obj \
|
||||
strequalr.obj \
|
||||
strtokr.obj \
|
||||
connectr.obj
|
||||
######################
|
||||
# release
|
||||
|
||||
DEBUG_OBJS= \
|
||||
base64d.obj \
|
||||
cookied.obj \
|
||||
transferd.obj \
|
||||
escaped.obj \
|
||||
formdatad.obj \
|
||||
ftpd.obj \
|
||||
httpd.obj \
|
||||
http_chunksd.obj \
|
||||
ldapd.obj \
|
||||
dictd.obj \
|
||||
telnetd.obj \
|
||||
getdated.obj \
|
||||
getenvd.obj \
|
||||
getpassd.obj \
|
||||
hostipd.obj \
|
||||
if2ipd.obj \
|
||||
mprintfd.obj \
|
||||
netrcd.obj \
|
||||
progressd.obj \
|
||||
sendfd.obj \
|
||||
speedcheckd.obj \
|
||||
sslused.obj \
|
||||
timevald.obj \
|
||||
urld.obj \
|
||||
filed.obj \
|
||||
getinfod.obj \
|
||||
versiond.obj \
|
||||
easyd.obj \
|
||||
strequald.obj \
|
||||
strtokd.obj \
|
||||
connectd.obj
|
||||
!IF "$(CFG)" == "release"
|
||||
TARGET =$(LIB_NAME).lib
|
||||
DIROBJ =.\$(CFG)
|
||||
LNK = $(LNKLIB) /out:$(TARGET)
|
||||
CC = $(CCNODBG)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
RELEASE_SSL_OBJS= \
|
||||
base64rs.obj \
|
||||
cookiers.obj \
|
||||
transferrs.obj \
|
||||
escapers.obj \
|
||||
formdatars.obj \
|
||||
ftprs.obj \
|
||||
httprs.obj \
|
||||
http_chunksrs.obj \
|
||||
ldaprs.obj \
|
||||
dictrs.obj \
|
||||
telnetrs.obj \
|
||||
getdaters.obj \
|
||||
getenvrs.obj \
|
||||
getpassrs.obj \
|
||||
hostiprs.obj \
|
||||
if2iprs.obj \
|
||||
mprintfrs.obj \
|
||||
netrcrs.obj \
|
||||
progressrs.obj \
|
||||
sendfrs.obj \
|
||||
speedcheckrs.obj \
|
||||
sslusers.obj \
|
||||
timevalrs.obj \
|
||||
urlrs.obj \
|
||||
filers.obj \
|
||||
getinfors.obj \
|
||||
versionrs.obj \
|
||||
easyrs.obj \
|
||||
strequalrs.obj \
|
||||
strtokrs.obj \
|
||||
connectrs.obj
|
||||
######################
|
||||
# release-dll
|
||||
|
||||
LINK_OBJS= \
|
||||
base64.obj \
|
||||
cookie.obj \
|
||||
transfer.obj \
|
||||
escape.obj \
|
||||
formdata.obj \
|
||||
ftp.obj \
|
||||
http.obj \
|
||||
http_chunks.obj \
|
||||
ldap.obj \
|
||||
dict.obj \
|
||||
telnet.obj \
|
||||
getdate.obj \
|
||||
getenv.obj \
|
||||
getpass.obj \
|
||||
hostip.obj \
|
||||
if2ip.obj \
|
||||
mprintf.obj \
|
||||
netrc.obj \
|
||||
progress.obj \
|
||||
sendf.obj \
|
||||
speedcheck.obj \
|
||||
ssluse.obj \
|
||||
timeval.obj \
|
||||
url.obj \
|
||||
file.obj \
|
||||
getinfo.obj \
|
||||
version.obj \
|
||||
easy.obj \
|
||||
strequal.obj \
|
||||
strtok.obj \
|
||||
connect.obj
|
||||
!IF "$(CFG)" == "release-dll"
|
||||
TARGET =$(LIB_NAME).dll
|
||||
DIROBJ =.\$(CFG)
|
||||
LNK = $(LNKDLL) /out:$(TARGET) /IMPLIB:"$(LIB_NAME).lib"
|
||||
CC = $(CCNODBG)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
all : release
|
||||
######################
|
||||
# release-ssl
|
||||
|
||||
release: $(RELEASE_OBJS)
|
||||
$(LINKR) $(LFLAGS) $(LINKLIBS) $(LINK_OBJS)
|
||||
!IF "$(CFG)" == "release-ssl"
|
||||
TARGET =$(LIB_NAME).lib
|
||||
DIROBJ =.\$(CFG)
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(TARGET)
|
||||
LINKLIBS = $(LINKLIBS) $(SSLLIBS)
|
||||
CC = $(CCNODBG) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
debug: $(DEBUG_OBJS)
|
||||
$(LINKD) $(LFLAGS) $(LINKLIBS) $(LINK_OBJS)
|
||||
######################
|
||||
# release-ssl-dll
|
||||
|
||||
release-ssl: $(RELEASE_SSL_OBJS)
|
||||
$(LINKRS) $(LFLAGS) $(LINKLIBS) $(LINKSLIBS) $(LINK_OBJS)
|
||||
!IF "$(CFG)" == "release-ssl-dll"
|
||||
TARGET =$(LIB_NAME).dll
|
||||
DIROBJ =.\$(CFG)
|
||||
LNK = $(LNKDLL) $(LFLAGSSSL) /out:$(TARGET) /IMPLIB:"$(LIB_NAME).lib"
|
||||
LINKLIBS = $(LINKLIBS) $(SSLLIBS)
|
||||
CC = $(CCNODBG) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
## Release
|
||||
base64r.obj: base64.c
|
||||
$(CCR) $(CFLAGS) base64.c
|
||||
cookier.obj: cookie.c
|
||||
$(CCR) $(CFLAGS) cookie.c
|
||||
transferr.obj: transfer.c
|
||||
$(CCR) $(CFLAGS) transfer.c
|
||||
escaper.obj: escape.c
|
||||
$(CCR) $(CFLAGS) escape.c
|
||||
formdatar.obj: formdata.c
|
||||
$(CCR) $(CFLAGS) formdata.c
|
||||
ftpr.obj: ftp.c
|
||||
$(CCR) $(CFLAGS) ftp.c
|
||||
httpr.obj: http.c
|
||||
$(CCR) $(CFLAGS) http.c
|
||||
http_chunksr.obj: http_chunks.c
|
||||
$(CCR) $(CFLAGS) http_chunks.c
|
||||
ldapr.obj: ldap.c
|
||||
$(CCR) $(CFLAGS) ldap.c
|
||||
dictr.obj: dict.c
|
||||
$(CCR) $(CFLAGS) dict.c
|
||||
telnetr.obj: telnet.c
|
||||
$(CCR) $(CFLAGS) telnet.c
|
||||
getdater.obj: getdate.c
|
||||
$(CCR) $(CFLAGS) getdate.c
|
||||
getenvr.obj: getenv.c
|
||||
$(CCR) $(CFLAGS) getenv.c
|
||||
getpassr.obj: getpass.c
|
||||
$(CCR) $(CFLAGS) getpass.c
|
||||
hostipr.obj: hostip.c
|
||||
$(CCR) $(CFLAGS) hostip.c
|
||||
if2ipr.obj: if2ip.c
|
||||
$(CCR) $(CFLAGS) if2ip.c
|
||||
mprintfr.obj: mprintf.c
|
||||
$(CCR) $(CFLAGS) mprintf.c
|
||||
netrcr.obj: netrc.c
|
||||
$(CCR) $(CFLAGS) netrc.c
|
||||
progressr.obj: progress.c
|
||||
$(CCR) $(CFLAGS) progress.c
|
||||
sendfr.obj: sendf.c
|
||||
$(CCR) $(CFLAGS) sendf.c
|
||||
speedcheckr.obj: speedcheck.c
|
||||
$(CCR) $(CFLAGS) speedcheck.c
|
||||
ssluser.obj: ssluse.c
|
||||
$(CCR) $(CFLAGS) ssluse.c
|
||||
timevalr.obj: timeval.c
|
||||
$(CCR) $(CFLAGS) timeval.c
|
||||
urlr.obj: url.c
|
||||
$(CCR) $(CFLAGS) url.c
|
||||
filer.obj: file.c
|
||||
$(CCR) $(CFLAGS) file.c
|
||||
getinfor.obj: getinfo.c
|
||||
$(CCR) $(CFLAGS) getinfo.c
|
||||
versionr.obj: version.c
|
||||
$(CCR) $(CFLAGS) version.c
|
||||
easyr.obj: easy.c
|
||||
$(CCR) $(CFLAGS) easy.c
|
||||
strequalr.obj: strequal.c
|
||||
$(CCR) $(CFLAGS) strequal.c
|
||||
strtokr.obj:strtok.c
|
||||
$(CCR) $(CFLAGS) strtok.c
|
||||
connectr.obj:connect.c
|
||||
$(CCR) $(CFLAGS) connect.c
|
||||
|
||||
## Debug
|
||||
base64d.obj: base64.c
|
||||
$(CCD) $(CFLAGS) base64.c
|
||||
cookied.obj: cookie.c
|
||||
$(CCD) $(CFLAGS) cookie.c
|
||||
transferd.obj: transfer.c
|
||||
$(CCD) $(CFLAGS) transfer.c
|
||||
escaped.obj: escape.c
|
||||
$(CCD) $(CFLAGS) escape.c
|
||||
formdatad.obj: formdata.c
|
||||
$(CCD) $(CFLAGS) formdata.c
|
||||
ftpd.obj: ftp.c
|
||||
$(CCD) $(CFLAGS) ftp.c
|
||||
httpd.obj: http.c
|
||||
$(CCD) $(CFLAGS) http.c
|
||||
http_chunksd.obj: http_chunks.c
|
||||
$(CCD) $(CFLAGS) http_chunks.c
|
||||
ldapd.obj: ldap.c
|
||||
$(CCD) $(CFLAGS) ldap.c
|
||||
dictd.obj: dict.c
|
||||
$(CCD) $(CFLAGS) dict.c
|
||||
telnetd.obj: telnet.c
|
||||
$(CCD) $(CFLAGS) telnet.c
|
||||
getdated.obj: getdate.c
|
||||
$(CCD) $(CFLAGS) getdate.c
|
||||
getenvd.obj: getenv.c
|
||||
$(CCD) $(CFLAGS) getenv.c
|
||||
getpassd.obj: getpass.c
|
||||
$(CCD) $(CFLAGS) getpass.c
|
||||
hostipd.obj: hostip.c
|
||||
$(CCD) $(CFLAGS) hostip.c
|
||||
if2ipd.obj: if2ip.c
|
||||
$(CCD) $(CFLAGS) if2ip.c
|
||||
mprintfd.obj: mprintf.c
|
||||
$(CCD) $(CFLAGS) mprintf.c
|
||||
netrcd.obj: netrc.c
|
||||
$(CCD) $(CFLAGS) netrc.c
|
||||
progressd.obj: progress.c
|
||||
$(CCD) $(CFLAGS) progress.c
|
||||
sendfd.obj: sendf.c
|
||||
$(CCD) $(CFLAGS) sendf.c
|
||||
speedcheckd.obj: speedcheck.c
|
||||
$(CCD) $(CFLAGS) speedcheck.c
|
||||
sslused.obj: ssluse.c
|
||||
$(CCD) $(CFLAGS) ssluse.c
|
||||
timevald.obj: timeval.c
|
||||
$(CCD) $(CFLAGS) timeval.c
|
||||
urld.obj: url.c
|
||||
$(CCD) $(CFLAGS) url.c
|
||||
filed.obj: file.c
|
||||
$(CCD) $(CFLAGS) file.c
|
||||
getinfod.obj: getinfo.c
|
||||
$(CCD) $(CFLAGS) getinfo.c
|
||||
versiond.obj: version.c
|
||||
$(CCD) $(CFLAGS) version.c
|
||||
easyd.obj: easy.c
|
||||
$(CCD) $(CFLAGS) easy.c
|
||||
strequald.obj: strequal.c
|
||||
$(CCD) $(CFLAGS) strequal.c
|
||||
strtokd.obj:strtok.c
|
||||
$(CCD) $(CFLAGS) strtok.c
|
||||
connectd.obj:connect.c
|
||||
$(CCR) $(CFLAGS) connect.c
|
||||
|
||||
## Release SSL
|
||||
base64rs.obj: base64.c
|
||||
$(CCRS) $(CFLAGS) base64.c
|
||||
cookiers.obj: cookie.c
|
||||
$(CCRS) $(CFLAGS) cookie.c
|
||||
transferrs.obj: transfer.c
|
||||
$(CCRS) $(CFLAGS) transfer.c
|
||||
escapers.obj: escape.c
|
||||
$(CCRS) $(CFLAGS) escape.c
|
||||
formdatars.obj: formdata.c
|
||||
$(CCRS) $(CFLAGS) formdata.c
|
||||
ftprs.obj: ftp.c
|
||||
$(CCRS) $(CFLAGS) ftp.c
|
||||
httprs.obj: http.c
|
||||
$(CCRS) $(CFLAGS) http.c
|
||||
http_chunksrs.obj: http_chunks.c
|
||||
$(CCRS) $(CFLAGS) http_chunks.c
|
||||
ldaprs.obj: ldap.c
|
||||
$(CCRS) $(CFLAGS) ldap.c
|
||||
dictrs.obj: dict.c
|
||||
$(CCRS) $(CFLAGS) dict.c
|
||||
telnetrs.obj: telnet.c
|
||||
$(CCRS) $(CFLAGS) telnet.c
|
||||
getdaters.obj: getdate.c
|
||||
$(CCRS) $(CFLAGS) getdate.c
|
||||
getenvrs.obj: getenv.c
|
||||
$(CCRS) $(CFLAGS) getenv.c
|
||||
getpassrs.obj: getpass.c
|
||||
$(CCRS) $(CFLAGS) getpass.c
|
||||
hostiprs.obj: hostip.c
|
||||
$(CCRS) $(CFLAGS) hostip.c
|
||||
if2iprs.obj: if2ip.c
|
||||
$(CCRS) $(CFLAGS) if2ip.c
|
||||
mprintfrs.obj: mprintf.c
|
||||
$(CCRS) $(CFLAGS) mprintf.c
|
||||
netrcrs.obj: netrc.c
|
||||
$(CCRS) $(CFLAGS) netrc.c
|
||||
progressrs.obj: progress.c
|
||||
$(CCRS) $(CFLAGS) progress.c
|
||||
sendfrs.obj: sendf.c
|
||||
$(CCRS) $(CFLAGS) sendf.c
|
||||
speedcheckrs.obj: speedcheck.c
|
||||
$(CCRS) $(CFLAGS) speedcheck.c
|
||||
sslusers.obj: ssluse.c
|
||||
$(CCRS) $(CFLAGS) ssluse.c
|
||||
timevalrs.obj: timeval.c
|
||||
$(CCRS) $(CFLAGS) timeval.c
|
||||
urlrs.obj: url.c
|
||||
$(CCRS) $(CFLAGS) url.c
|
||||
filers.obj: file.c
|
||||
$(CCRS) $(CFLAGS) file.c
|
||||
getinfors.obj: getinfo.c
|
||||
$(CCRS) $(CFLAGS) getinfo.c
|
||||
versionrs.obj: version.c
|
||||
$(CCRS) $(CFLAGS) version.c
|
||||
easyrs.obj: easy.c
|
||||
$(CCRS) $(CFLAGS) easy.c
|
||||
strequalrs.obj: strequal.c
|
||||
$(CCRS) $(CFLAGS) strequal.c
|
||||
strtokrs.obj:strtok.c
|
||||
$(CCRS) $(CFLAGS) strtok.c
|
||||
connectrs.obj:connect.c
|
||||
$(CCR) $(CFLAGS) connect.c
|
||||
|
||||
######################
|
||||
# debug
|
||||
|
||||
!IF "$(CFG)" == "debug"
|
||||
TARGET =$(LIB_NAME_DEBUG).lib
|
||||
DIROBJ =.\$(CFG)
|
||||
LNK = $(LNKLIB) /out:$(TARGET)
|
||||
CC = $(CCDEBUG)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll"
|
||||
TARGET =$(LIB_NAME_DEBUG).dll
|
||||
DIROBJ =.\$(CFG)
|
||||
LNK = $(LNKDLL) /out:$(TARGET) /IMPLIB:"$(LIB_NAME_DEBUG).lib"
|
||||
CC = $(CCDEBUG)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl
|
||||
#todo
|
||||
!IF "$(CFG)" == "debug-ssl"
|
||||
TARGET = $(LIB_NAME_DEBUG).lib
|
||||
DIROBJ =.\$(CFG)
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(TARGET)
|
||||
LINKLIBS = $(LINKLIBS) $(SSLLIBS)
|
||||
CC = $(CCDEBUG) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll"
|
||||
TARGET =$(LIB_NAME_DEBUG).dll
|
||||
DIROBJ =.\$(CFG)
|
||||
LNK = $(LNKDLL) $(LFLAGSSSL) /out:$(TARGET) /IMPLIB:"$(LIB_NAME_DEBUG).lib"
|
||||
LINKLIBS = $(LINKLIBS) $(SSLLIBS)
|
||||
CC = $(CCDEBUG) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Usage
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE"
|
||||
!MESSAGE Usage: nmake -f makefile.vc6 CFG=<config> <target>
|
||||
!MESSAGE where <config> is one of:
|
||||
!MESSAGE release - release static library
|
||||
!MESSAGE release-dll - release dll
|
||||
!MESSAGE release-ssl - release static library with ssl
|
||||
!MESSAGE release-ssl-dll - release dll library with ssl
|
||||
!MESSAGE debug - debug static library
|
||||
!MESSAGE debug-dll - debug dll
|
||||
!MESSAGE debug-ssl - debug static library with ssl
|
||||
!MESSAGE debug-ssl-dll - debug dll library with ssl
|
||||
!MESSAGE <target> can be left blank in which case all is assumed
|
||||
!ERROR please choose a valid configuration "$(CFG)"
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
#
|
||||
X_OBJS= \
|
||||
$(DIROBJ)\base64.obj \
|
||||
$(DIROBJ)\cookie.obj \
|
||||
$(DIROBJ)\transfer.obj \
|
||||
$(DIROBJ)\escape.obj \
|
||||
$(DIROBJ)\formdata.obj \
|
||||
$(DIROBJ)\ftp.obj \
|
||||
$(DIROBJ)\http.obj \
|
||||
$(DIROBJ)\http_chunks.obj \
|
||||
$(DIROBJ)\ldap.obj \
|
||||
$(DIROBJ)\dict.obj \
|
||||
$(DIROBJ)\telnet.obj \
|
||||
$(DIROBJ)\getdate.obj \
|
||||
$(DIROBJ)\getenv.obj \
|
||||
$(DIROBJ)\getpass.obj \
|
||||
$(DIROBJ)\hostip.obj \
|
||||
$(DIROBJ)\if2ip.obj \
|
||||
$(DIROBJ)\mprintf.obj \
|
||||
$(DIROBJ)\netrc.obj \
|
||||
$(DIROBJ)\progress.obj \
|
||||
$(DIROBJ)\sendf.obj \
|
||||
$(DIROBJ)\speedcheck.obj \
|
||||
$(DIROBJ)\ssluse.obj \
|
||||
$(DIROBJ)\timeval.obj \
|
||||
$(DIROBJ)\url.obj \
|
||||
$(DIROBJ)\file.obj \
|
||||
$(DIROBJ)\getinfo.obj \
|
||||
$(DIROBJ)\version.obj \
|
||||
$(DIROBJ)\easy.obj \
|
||||
$(DIROBJ)\strequal.obj \
|
||||
$(DIROBJ)\strtok.obj \
|
||||
$(DIROBJ)\connect.obj \
|
||||
$(DIROBJ)\hash.obj \
|
||||
$(DIROBJ)\llist.obj
|
||||
|
||||
all : $(TARGET)
|
||||
|
||||
|
||||
$(TARGET): $(X_OBJS)
|
||||
$(LNK) $(LFLAGS) $(LINKLIBS) $(X_OBJS)
|
||||
|
||||
$(X_OBJS): $(DIROBJ)
|
||||
|
||||
$(DIROBJ):
|
||||
@if not exist "$(DIROBJ)" mkdir $(DIROBJ)
|
||||
|
||||
.SUFFIXES: .c .obj
|
||||
|
||||
{.\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
clean:
|
||||
-@erase *.obj
|
||||
-@erase $(DIROBJ)\*.obj
|
||||
-@erase vc60.idb
|
||||
-@erase vc60.pch
|
||||
|
||||
distrib: clean
|
||||
-@erase $(PROGRAM_NAME)
|
||||
|
||||
|
@@ -42,7 +42,7 @@
|
||||
static const char *telnetoptions[]=
|
||||
{
|
||||
"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD",
|
||||
"NAME", "STATUS" "TIMING MARK", "RCTE",
|
||||
"NAME", "STATUS", "TIMING MARK", "RCTE",
|
||||
"NAOL", "NAOP", "NAOCRD", "NAOHTS",
|
||||
"NAOHTD", "NAOFFD", "NAOVTS", "NAOVTD",
|
||||
"NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
|
||||
|
@@ -44,6 +44,10 @@
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* required for free() prototype, without it, this crashes
|
||||
on macos 68K */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
@@ -61,6 +65,7 @@
|
||||
#include <winsock.h>
|
||||
#define EINPROGRESS WSAEINPROGRESS
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#define EISCONN WSAEISCONN
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
@@ -188,7 +193,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
#ifdef HAVE_INET_NTOA
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE (unsigned long) ~0
|
||||
#define INADDR_NONE (in_addr_t) ~0
|
||||
#endif
|
||||
|
||||
struct SessionHandle *data = conn->data;
|
||||
@@ -202,14 +207,14 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
char *hostdataptr=NULL;
|
||||
size_t size;
|
||||
char myhost[256] = "";
|
||||
unsigned long in;
|
||||
in_addr_t in;
|
||||
|
||||
if(Curl_if2ip(data->set.device, myhost, sizeof(myhost))) {
|
||||
h = Curl_getaddrinfo(data, myhost, 0, &hostdataptr);
|
||||
h = Curl_resolv(data, myhost, 0, &hostdataptr);
|
||||
}
|
||||
else {
|
||||
if(strlen(data->set.device)>1) {
|
||||
h = Curl_getaddrinfo(data, data->set.device, 0, &hostdataptr);
|
||||
h = Curl_resolv(data, data->set.device, 0, &hostdataptr);
|
||||
}
|
||||
if(h) {
|
||||
/* we know data->set.device is shorter than the myhost array */
|
||||
@@ -224,14 +229,13 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
hostent_buf,
|
||||
sizeof(hostent_buf));
|
||||
*/
|
||||
if(hostdataptr)
|
||||
free(hostdataptr); /* allocated by Curl_getaddrinfo() */
|
||||
return CURLE_HTTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
infof(data, "We bind local end to %s\n", myhost);
|
||||
|
||||
if ( (in=inet_addr(myhost)) != INADDR_NONE ) {
|
||||
in=inet_addr(myhost);
|
||||
if (INADDR_NONE != in) {
|
||||
|
||||
if ( h ) {
|
||||
memset((char *)&sa, 0, sizeof(sa));
|
||||
@@ -279,7 +283,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
failf(data, "Insufficient kernel memory was available: %d", errno);
|
||||
break;
|
||||
default:
|
||||
failf(data, "errno %d\n", errno);
|
||||
failf(data, "errno %d", errno);
|
||||
break;
|
||||
} /* end of switch(errno) */
|
||||
|
||||
@@ -298,9 +302,6 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
return CURLE_HTTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
if(hostdataptr)
|
||||
free(hostdataptr); /* allocated by Curl_getaddrinfo() */
|
||||
|
||||
return CURLE_OK;
|
||||
|
||||
} /* end of device selection support */
|
||||
@@ -309,9 +310,8 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
|
||||
return CURLE_HTTP_PORT_FAILED;
|
||||
}
|
||||
#else /* end of ipv4-specific section */
|
||||
#endif /* end of ipv4-specific section */
|
||||
|
||||
/* we only use socketerror() on IPv6-enabled machines */
|
||||
static
|
||||
int socketerror(int sockfd)
|
||||
{
|
||||
@@ -324,7 +324,6 @@ int socketerror(int sockfd)
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TCP connect to the given host with timeout, proxy or remote doesn't matter.
|
||||
@@ -449,8 +448,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
/* now disable the non-blocking mode again */
|
||||
Curl_nonblock(sockfd, FALSE);
|
||||
/* leave the socket in non-blocking mode */
|
||||
|
||||
if(addr)
|
||||
*addr = ai; /* the address we ended up connected to */
|
||||
@@ -525,6 +523,16 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
}
|
||||
}
|
||||
|
||||
if(0 == rc) {
|
||||
int err = socketerror(sockfd);
|
||||
if ((0 == err) || (EISCONN == err)) {
|
||||
/* we are connected, awesome! */
|
||||
break;
|
||||
}
|
||||
/* nope, not connected for real */
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
if(0 != rc) {
|
||||
/* get a new timeout for next attempt */
|
||||
after = Curl_tvnow();
|
||||
@@ -542,11 +550,11 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
/* no good connect was made */
|
||||
sclose(sockfd);
|
||||
*sockconn = -1;
|
||||
failf(data, "Couldn't connect to host");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
/* now disable the non-blocking mode again */
|
||||
Curl_nonblock(sockfd, FALSE);
|
||||
/* leave the socket in non-blocking mode */
|
||||
|
||||
if(addr)
|
||||
/* this is the address we've connected to */
|
||||
|
@@ -28,7 +28,7 @@ int Curl_nonblock(int socket, /* operate on this */
|
||||
|
||||
CURLcode Curl_connecthost(struct connectdata *conn,
|
||||
Curl_addrinfo *host, /* connect to this */
|
||||
long port, /* connect to this port number */
|
||||
int port, /* connect to this port number */
|
||||
int *sockconn, /* not set if error is returned */
|
||||
Curl_ipconnect **addr /* the one we used */
|
||||
); /* index we used */
|
||||
|
14
lib/cookie.c
14
lib/cookie.c
@@ -194,6 +194,11 @@ Curl_cookie_add(struct CookieInfo *c,
|
||||
while(ptr && *ptr && isspace((int)*ptr))
|
||||
ptr++;
|
||||
semiptr=strchr(ptr, ';'); /* now, find the next semicolon */
|
||||
|
||||
if(!semiptr && *ptr)
|
||||
/* There are no more semicolons, but there's a final name=value pair
|
||||
coming up */
|
||||
semiptr=ptr;
|
||||
} while(semiptr);
|
||||
|
||||
if(NULL == co->domain)
|
||||
@@ -377,8 +382,15 @@ Curl_cookie_add(struct CookieInfo *c,
|
||||
|
||||
free(co); /* free the newly alloced memory */
|
||||
co = clist; /* point to the previous struct instead */
|
||||
}
|
||||
|
||||
/* We have replaced a cookie, now skip the rest of the list but
|
||||
make sure the 'lastc' pointer is properly set */
|
||||
do {
|
||||
lastc = clist;
|
||||
clist = clist->next;
|
||||
} while(clist);
|
||||
break;
|
||||
}
|
||||
}
|
||||
lastc = clist;
|
||||
clist = clist->next;
|
||||
|
@@ -151,6 +151,10 @@ SOURCE=.\getpass.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\hash.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\hostip.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -179,6 +183,10 @@ SOURCE=.\libcurl.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\llist.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\memdebug.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@@ -121,7 +121,7 @@ CURLcode Curl_dict(struct connectdata *conn)
|
||||
}
|
||||
|
||||
if ((word == NULL) || (*word == (char)0)) {
|
||||
failf(data, "lookup word is missing\n");
|
||||
failf(data, "lookup word is missing");
|
||||
}
|
||||
if ((database == NULL) || (*database == (char)0)) {
|
||||
database = (char *)"!";
|
||||
@@ -174,7 +174,7 @@ CURLcode Curl_dict(struct connectdata *conn)
|
||||
}
|
||||
|
||||
if ((word == NULL) || (*word == (char)0)) {
|
||||
failf(data, "lookup word is missing\n");
|
||||
failf(data, "lookup word is missing");
|
||||
}
|
||||
if ((database == NULL) || (*database == (char)0)) {
|
||||
database = (char *)"!";
|
||||
|
15
lib/easy.c
15
lib/easy.c
@@ -76,6 +76,7 @@
|
||||
#include "ssluse.h"
|
||||
#include "url.h"
|
||||
#include "getinfo.h"
|
||||
#include "hostip.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -162,6 +163,8 @@ void curl_global_cleanup(void)
|
||||
if (!initialized)
|
||||
return;
|
||||
|
||||
Curl_global_host_cache_dtor();
|
||||
|
||||
if (init_flags & CURL_GLOBAL_SSL)
|
||||
Curl_SSL_cleanup();
|
||||
|
||||
@@ -230,12 +233,24 @@ CURLcode curl_easy_perform(CURL *curl)
|
||||
{
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
|
||||
if (!data->hostcache) {
|
||||
if (Curl_global_host_cache_use(data)) {
|
||||
data->hostcache = Curl_global_host_cache_get();
|
||||
}
|
||||
else {
|
||||
data->hostcache = curl_hash_alloc(7, Curl_freeaddrinfo);
|
||||
}
|
||||
}
|
||||
|
||||
return Curl_perform(data);
|
||||
}
|
||||
|
||||
void curl_easy_cleanup(CURL *curl)
|
||||
{
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
if (!Curl_global_host_cache_use(data)) {
|
||||
curl_hash_destroy(data->hostcache);
|
||||
}
|
||||
Curl_close(data);
|
||||
}
|
||||
|
||||
|
@@ -402,6 +402,7 @@ static struct HttpPost * AddHttpPost (char * name,
|
||||
long contentslength,
|
||||
char *contenttype,
|
||||
long flags,
|
||||
struct curl_slist* contentHeader,
|
||||
struct HttpPost *parent_post,
|
||||
struct HttpPost **httppost,
|
||||
struct HttpPost **last_post)
|
||||
@@ -415,6 +416,7 @@ static struct HttpPost * AddHttpPost (char * name,
|
||||
post->contents = value;
|
||||
post->contentslength = contentslength;
|
||||
post->contenttype = contenttype;
|
||||
post->contentheader = contentHeader;
|
||||
post->flags = flags;
|
||||
}
|
||||
else
|
||||
@@ -823,6 +825,21 @@ FORMcode FormAdd(struct HttpPost **httppost,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CURLFORM_CONTENTHEADER:
|
||||
{
|
||||
struct curl_slist* list = NULL;
|
||||
if( array_state )
|
||||
list = (struct curl_slist*)array_value;
|
||||
else
|
||||
list = va_arg(params,struct curl_slist*);
|
||||
|
||||
if( current_form->contentheader )
|
||||
return_value = FORMADD_OPTION_TWICE;
|
||||
else
|
||||
current_form->contentheader = list;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fprintf (stderr, "got unknown CURLFORM_OPTION: %d\n", option);
|
||||
return_value = FORMADD_UNKNOWN_OPTION;
|
||||
@@ -872,13 +889,16 @@ FORMcode FormAdd(struct HttpPost **httppost,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( (post = AddHttpPost(form->name, form->namelength,
|
||||
post = AddHttpPost(form->name, form->namelength,
|
||||
form->value, form->contentslength,
|
||||
form->contenttype, form->flags,
|
||||
form->contentheader,
|
||||
post, httppost,
|
||||
last_post)) == NULL) {
|
||||
last_post);
|
||||
|
||||
if(!post)
|
||||
return_value = FORMADD_MEMORY;
|
||||
}
|
||||
|
||||
if (form->contenttype)
|
||||
prevtype = form->contenttype;
|
||||
}
|
||||
@@ -923,7 +943,7 @@ static int AddFormData(struct FormData **formp,
|
||||
length = strlen((char *)line);
|
||||
|
||||
newform->line = (char *)malloc(length+1);
|
||||
memcpy(newform->line, line, length+1);
|
||||
memcpy(newform->line, line, length);
|
||||
newform->length = length;
|
||||
newform->line[length]=0; /* zero terminate for easier debugging */
|
||||
|
||||
@@ -1029,6 +1049,8 @@ struct FormData *Curl_getFormData(struct HttpPost *post,
|
||||
int size =0;
|
||||
char *boundary;
|
||||
char *fileboundary=NULL;
|
||||
struct curl_slist* curList;
|
||||
|
||||
|
||||
if(!post)
|
||||
return NULL; /* no input => no output! */
|
||||
@@ -1090,6 +1112,13 @@ struct FormData *Curl_getFormData(struct HttpPost *post,
|
||||
file->contenttype);
|
||||
}
|
||||
|
||||
curList = file->contentheader;
|
||||
while( curList ) {
|
||||
/* Process the additional headers specified for this form */
|
||||
size += AddFormDataf( &form, "\r\n%s", curList->data );
|
||||
curList = curList->next;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* The header Content-Transfer-Encoding: seems to confuse some receivers
|
||||
* (like the built-in PHP engine). While I can't see any reason why it
|
||||
|
@@ -44,6 +44,7 @@ typedef struct FormInfo {
|
||||
long contentslength;
|
||||
char *contenttype;
|
||||
long flags;
|
||||
struct curl_slist* contentheader;
|
||||
struct FormInfo *more;
|
||||
} FormInfo;
|
||||
|
||||
|
300
lib/ftp.c
300
lib/ftp.c
@@ -84,6 +84,10 @@
|
||||
#include "ssluse.h"
|
||||
#include "connect.h"
|
||||
|
||||
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
||||
#include "inet_ntoa_r.h"
|
||||
#endif
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
@@ -193,10 +197,15 @@ int Curl_GetFTPResponse(char *buf,
|
||||
int code=0; /* default "error code" to return */
|
||||
|
||||
#define SELECT_OK 0
|
||||
#define SELECT_ERROR 1
|
||||
#define SELECT_TIMEOUT 2
|
||||
#define SELECT_ERROR 1 /* select() problems */
|
||||
#define SELECT_TIMEOUT 2 /* took too long */
|
||||
#define SELECT_MEMORY 3 /* no available memory */
|
||||
#define SELECT_CALLBACK 4 /* aborted by callback */
|
||||
|
||||
int error = SELECT_OK;
|
||||
|
||||
struct FTP *ftp = conn->proto.ftp;
|
||||
|
||||
if (ftpcode)
|
||||
*ftpcode = 0; /* 0 for errors */
|
||||
|
||||
@@ -229,6 +238,7 @@ int Curl_GetFTPResponse(char *buf,
|
||||
interval.tv_sec = timeout;
|
||||
interval.tv_usec = 0;
|
||||
|
||||
if(!ftp->cache)
|
||||
switch (select (sockfd+1, &readfd, NULL, NULL, &interval)) {
|
||||
case -1: /* select() error, stop reading */
|
||||
error = SELECT_ERROR;
|
||||
@@ -239,13 +249,37 @@ int Curl_GetFTPResponse(char *buf,
|
||||
failf(data, "Transfer aborted due to timeout");
|
||||
break;
|
||||
default:
|
||||
error = SELECT_OK;
|
||||
break;
|
||||
}
|
||||
if(SELECT_OK == error) {
|
||||
/*
|
||||
* This code previously didn't use the kerberos sec_read() code
|
||||
* to read, but when we use Curl_read() it may do so. Do confirm
|
||||
* that this is still ok and then remove this comment!
|
||||
*/
|
||||
if(CURLE_OK != Curl_read(conn, sockfd, ptr, BUFSIZE-nread, &gotbytes))
|
||||
if(ftp->cache) {
|
||||
/* we had data in the "cache", copy that instead of doing an actual
|
||||
read */
|
||||
memcpy(ptr, ftp->cache, ftp->cache_size);
|
||||
gotbytes = ftp->cache_size;
|
||||
free(ftp->cache); /* free the cache */
|
||||
ftp->cache = NULL; /* clear the pointer */
|
||||
ftp->cache_size = 0; /* zero the size just in case */
|
||||
}
|
||||
else {
|
||||
int res = Curl_read(conn, sockfd, ptr,
|
||||
BUFSIZE-nread, &gotbytes);
|
||||
if(res < 0)
|
||||
/* EWOULDBLOCK */
|
||||
continue; /* go looping again */
|
||||
|
||||
if(CURLE_OK != res)
|
||||
keepon = FALSE;
|
||||
}
|
||||
|
||||
if(!keepon)
|
||||
;
|
||||
else if(gotbytes <= 0) {
|
||||
keepon = FALSE;
|
||||
error = SELECT_ERROR;
|
||||
@@ -263,6 +297,7 @@ int Curl_GetFTPResponse(char *buf,
|
||||
if(*ptr=='\n') {
|
||||
/* a newline is CRLF in ftp-talk, so the CR is ignored as
|
||||
the line isn't really terminated until the LF comes */
|
||||
CURLcode result;
|
||||
|
||||
/* output debug output if that is requested */
|
||||
if(data->set.verbose) {
|
||||
@@ -271,6 +306,16 @@ int Curl_GetFTPResponse(char *buf,
|
||||
/* no need to output LF here, it is part of the data */
|
||||
}
|
||||
|
||||
/*
|
||||
* We pass all response-lines to the callback function registered
|
||||
* for "headers". The response lines can be seen as a kind of
|
||||
* headers.
|
||||
*/
|
||||
result = Curl_client_write(data, CLIENTWRITE_HEADER,
|
||||
line_start, perline);
|
||||
if(result)
|
||||
return -SELECT_CALLBACK;
|
||||
|
||||
#define lastline(line) (isdigit((int)line[0]) && isdigit((int)line[1]) && \
|
||||
isdigit((int)line[2]) && (' ' == line[3]))
|
||||
|
||||
@@ -279,20 +324,35 @@ int Curl_GetFTPResponse(char *buf,
|
||||
* line to the start of the buffer and zero terminate,
|
||||
* for old times sake (and krb4)! */
|
||||
char *meow;
|
||||
int i;
|
||||
for(meow=line_start, i=0; meow<ptr; meow++, i++)
|
||||
buf[i] = *meow;
|
||||
meow[i]=0; /* zero terminate */
|
||||
int n;
|
||||
for(meow=line_start, n=0; meow<ptr; meow++, n++)
|
||||
buf[n] = *meow;
|
||||
*meow=0; /* zero terminate */
|
||||
keepon=FALSE;
|
||||
line_start = ptr+1; /* advance pointer */
|
||||
i++; /* skip this before getting out */
|
||||
break;
|
||||
}
|
||||
perline=0; /* line starts over here */
|
||||
line_start = ptr+1;
|
||||
}
|
||||
}
|
||||
if(!keepon && (i != gotbytes)) {
|
||||
/* We found the end of the response lines, but we didn't parse the
|
||||
full chunk of data we have read from the server. We therefore
|
||||
need to store the rest of the data to be checked on the next
|
||||
invoke as it may actually contain another end of response
|
||||
already! Cleverly figured out by Eric Lavigne in December
|
||||
2001. */
|
||||
ftp->cache_size = gotbytes - i;
|
||||
ftp->cache = (char *)malloc(ftp->cache_size);
|
||||
if(ftp->cache)
|
||||
memcpy(ftp->cache, line_start, ftp->cache_size);
|
||||
else
|
||||
return -SELECT_MEMORY; /**BANG**/
|
||||
}
|
||||
break;
|
||||
} /* switch */
|
||||
} /* there was data */
|
||||
} /* if(no error) */
|
||||
} /* while there's buffer left and loop is requested */
|
||||
|
||||
if(!error)
|
||||
@@ -558,6 +618,7 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
|
||||
ssize_t nread;
|
||||
char *buf = data->state.buffer; /* this is our buffer */
|
||||
int ftpcode;
|
||||
CURLcode result=CURLE_OK;
|
||||
|
||||
if(data->set.upload) {
|
||||
if((-1 != data->set.infilesize) && (data->set.infilesize != *ftp->bytecountp)) {
|
||||
@@ -575,8 +636,12 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
|
||||
else if(!conn->bits.resume_done &&
|
||||
!data->set.no_body &&
|
||||
(0 == *ftp->bytecountp)) {
|
||||
/* We consider this an error, but there's no true FTP error received
|
||||
why we need to continue to "read out" the server response too.
|
||||
We don't want to leave a "waiting" server reply if we'll get told
|
||||
to make a second request on this same connection! */
|
||||
failf(data, "No data was received!");
|
||||
return CURLE_FTP_COULDNT_RETR_FILE;
|
||||
result = CURLE_FTP_COULDNT_RETR_FILE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -604,12 +669,10 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
|
||||
conn->bits.resume_done = FALSE; /* clean this for next connection */
|
||||
|
||||
/* Send any post-transfer QUOTE strings? */
|
||||
if(data->set.postquote) {
|
||||
CURLcode result = ftp_sendquote(conn, data->set.postquote);
|
||||
return result;
|
||||
}
|
||||
if(!result && data->set.postquote)
|
||||
result = ftp_sendquote(conn, data->set.postquote);
|
||||
|
||||
return CURLE_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -633,8 +696,7 @@ CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote)
|
||||
if (item->data) {
|
||||
FTPSENDF(conn, "%s", item->data);
|
||||
|
||||
nread = Curl_GetFTPResponse(
|
||||
conn->data->state.buffer, conn, &ftpcode);
|
||||
nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, &ftpcode);
|
||||
if (nread < 0)
|
||||
return CURLE_OPERATION_TIMEOUTED;
|
||||
|
||||
@@ -810,24 +872,35 @@ ftp_pasv_verbose(struct connectdata *conn,
|
||||
#ifdef HAVE_INET_NTOA_R
|
||||
char ntoa_buf[64];
|
||||
#endif
|
||||
char hostent_buf[8192];
|
||||
/* The array size trick below is to make this a large chunk of memory
|
||||
suitably 8-byte aligned on 64-bit platforms. This was thoughtfully
|
||||
suggested by Philip Gladstone. */
|
||||
long bigbuf[9000 / sizeof(long)];
|
||||
|
||||
#if defined(HAVE_INET_ADDR)
|
||||
unsigned long address;
|
||||
in_addr_t address;
|
||||
# if defined(HAVE_GETHOSTBYADDR_R)
|
||||
int h_errnop;
|
||||
# endif
|
||||
char *hostent_buf = (char *)bigbuf; /* get a char * to the buffer */
|
||||
|
||||
address = inet_addr(newhost);
|
||||
# ifdef HAVE_GETHOSTBYADDR_R
|
||||
|
||||
# ifdef HAVE_GETHOSTBYADDR_R_5
|
||||
/* AIX, Digital Unix style:
|
||||
/* AIX, Digital Unix (OSF1, Tru64) style:
|
||||
extern int gethostbyaddr_r(char *addr, size_t len, int type,
|
||||
struct hostent *htent, struct hostent_data *ht_data); */
|
||||
|
||||
/* Fred Noz helped me try this out, now it at least compiles! */
|
||||
|
||||
/* Bjorn Reese (November 28 2001):
|
||||
The Tru64 man page on gethostbyaddr_r() says that
|
||||
the hostent struct must be filled with zeroes before the call to
|
||||
gethostbyaddr_r(). */
|
||||
|
||||
memset(hostent_buf, 0, sizeof(struct hostent));
|
||||
|
||||
if(gethostbyaddr_r((char *) &address,
|
||||
sizeof(address), AF_INET,
|
||||
(struct hostent *)hostent_buf,
|
||||
@@ -1125,30 +1198,30 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
||||
struct sockaddr_in sa;
|
||||
struct hostent *h=NULL;
|
||||
char *hostdataptr=NULL;
|
||||
size_t size;
|
||||
unsigned short porttouse;
|
||||
char myhost[256] = "";
|
||||
|
||||
if(data->set.ftpport) {
|
||||
if(Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) {
|
||||
h = Curl_getaddrinfo(data, myhost, 0, &hostdataptr);
|
||||
h = Curl_resolv(data, myhost, 0, &hostdataptr);
|
||||
}
|
||||
else {
|
||||
if(strlen(data->set.ftpport)>1)
|
||||
h = Curl_getaddrinfo(data, data->set.ftpport, 0, &hostdataptr);
|
||||
int len = strlen(data->set.ftpport);
|
||||
if(len>1)
|
||||
h = Curl_resolv(data, data->set.ftpport, 0, &hostdataptr);
|
||||
if(h)
|
||||
strcpy(myhost, data->set.ftpport); /* buffer overflow risk */
|
||||
}
|
||||
}
|
||||
if(! *myhost) {
|
||||
h=Curl_getaddrinfo(data,
|
||||
getmyhost(myhost, sizeof(myhost)),
|
||||
0, &hostdataptr);
|
||||
char *tmp_host = getmyhost(myhost, sizeof(myhost));
|
||||
h=Curl_resolv(data, tmp_host, 0, &hostdataptr);
|
||||
}
|
||||
infof(data, "We connect from %s\n", myhost);
|
||||
|
||||
if ( h ) {
|
||||
if( (portsock = socket(AF_INET, SOCK_STREAM, 0)) >= 0 ) {
|
||||
int size;
|
||||
|
||||
/* we set the secondary socket variable to this for now, it
|
||||
is only so that the cleanup function will close it in case
|
||||
@@ -1167,10 +1240,10 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
||||
if(bind(portsock, (struct sockaddr *)&sa, size) >= 0) {
|
||||
/* we succeeded to bind */
|
||||
struct sockaddr_in add;
|
||||
size = sizeof(add);
|
||||
socklen_t socksize = sizeof(add);
|
||||
|
||||
if(getsockname(portsock, (struct sockaddr *) &add,
|
||||
(socklen_t *)&size)<0) {
|
||||
&socksize)<0) {
|
||||
failf(data, "getsockname() failed");
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
@@ -1193,9 +1266,6 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
||||
free(hostdataptr);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
if(hostdataptr)
|
||||
/* free the memory used for name lookup */
|
||||
Curl_freeaddrinfo(hostdataptr);
|
||||
}
|
||||
else {
|
||||
failf(data, "could't find my own IP address (%s)", myhost);
|
||||
@@ -1256,23 +1326,53 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
|
||||
char *buf = data->state.buffer; /* this is our buffer */
|
||||
int ftpcode; /* receive FTP response codes in this */
|
||||
CURLcode result;
|
||||
Curl_addrinfo *addr=NULL;
|
||||
Curl_ipconnect *conninfo;
|
||||
|
||||
/*
|
||||
Here's the excecutive summary on what to do:
|
||||
|
||||
PASV is RFC959, expect:
|
||||
227 Entering Passive Mode (a1,a2,a3,a4,p1,p2)
|
||||
|
||||
LPSV is RFC1639, expect:
|
||||
228 Entering Long Passive Mode (4,4,a1,a2,a3,a4,2,p1,p2)
|
||||
|
||||
EPSV is RFC2428, expect:
|
||||
229 Entering Extended Passive Mode (|||port|)
|
||||
|
||||
*/
|
||||
|
||||
#if 1
|
||||
const char *mode[] = { "EPSV", "PASV", NULL };
|
||||
int results[] = { 229, 227, 0 };
|
||||
#else
|
||||
#if 0
|
||||
/* no support for IPv6 passive mode yet */
|
||||
char *mode[] = { "EPSV", "LPSV", "PASV", NULL };
|
||||
int results[] = { 229, 228, 227, 0 };
|
||||
#else
|
||||
const char *mode[] = { "PASV", NULL };
|
||||
int results[] = { 227, 0 };
|
||||
#endif
|
||||
#endif
|
||||
int modeoff;
|
||||
unsigned short connectport; /* the local port connect() should use! */
|
||||
unsigned short newport; /* remote port, not necessary the local one */
|
||||
char *hostdataptr=NULL;
|
||||
|
||||
for (modeoff = 0; mode[modeoff]; modeoff++) {
|
||||
FTPSENDF(conn, mode[modeoff], "");
|
||||
/* newhost must be able to hold a full IP-style address in ASCII, which
|
||||
in the IPv6 case means 5*8-1 = 39 letters */
|
||||
char newhost[48];
|
||||
char *newhostp=NULL;
|
||||
|
||||
for (modeoff = (data->set.ftp_use_epsv?0:1);
|
||||
mode[modeoff]; modeoff++) {
|
||||
result = Curl_ftpsendf(conn, mode[modeoff]);
|
||||
if(result)
|
||||
return result;
|
||||
nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
|
||||
if(nread < 0)
|
||||
return CURLE_OPERATION_TIMEOUTED;
|
||||
|
||||
if (ftpcode == results[modeoff])
|
||||
break;
|
||||
}
|
||||
@@ -1281,16 +1381,9 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
|
||||
failf(data, "Odd return code after PASV");
|
||||
return CURLE_FTP_WEIRD_PASV_REPLY;
|
||||
}
|
||||
else if (strcmp(mode[modeoff], "PASV") == 0) {
|
||||
else if (227 == results[modeoff]) {
|
||||
int ip[4];
|
||||
int port[2];
|
||||
unsigned short newport; /* remote port, not necessary the local one */
|
||||
unsigned short connectport; /* the local port connect() should use! */
|
||||
char newhost[32];
|
||||
|
||||
Curl_addrinfo *addr;
|
||||
char *hostdataptr=NULL;
|
||||
Curl_ipconnect *conninfo;
|
||||
char *str=buf;
|
||||
|
||||
/*
|
||||
@@ -1318,7 +1411,40 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
|
||||
}
|
||||
|
||||
sprintf(newhost, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||
newhostp = newhost;
|
||||
newport = (port[0]<<8) + port[1];
|
||||
}
|
||||
#if 1
|
||||
else if (229 == results[modeoff]) {
|
||||
char *ptr = strchr(buf, '(');
|
||||
if(ptr) {
|
||||
unsigned int num;
|
||||
char separator[4];
|
||||
ptr++;
|
||||
if(5 == sscanf(ptr, "%c%c%c%u%c",
|
||||
&separator[0],
|
||||
&separator[1],
|
||||
&separator[2],
|
||||
&num,
|
||||
&separator[3])) {
|
||||
/* the four separators should be identical */
|
||||
newport = num;
|
||||
|
||||
/* we should use the same host we already are connected to */
|
||||
newhostp = conn->name;
|
||||
}
|
||||
else
|
||||
ptr=NULL;
|
||||
}
|
||||
if(!ptr) {
|
||||
failf(data, "Weirdly formatted EPSV reply");
|
||||
return CURLE_FTP_WEIRD_PASV_REPLY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return CURLE_FTP_CANT_RECONNECT;
|
||||
|
||||
if(data->change.proxy) {
|
||||
/*
|
||||
* This is a tunnel through a http proxy and we need to connect to the
|
||||
@@ -1331,7 +1457,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
|
||||
}
|
||||
else {
|
||||
/* normal, direct, ftp connection */
|
||||
addr = Curl_getaddrinfo(data, newhost, newport, &hostdataptr);
|
||||
addr = Curl_resolv(data, newhostp, newport, &hostdataptr);
|
||||
if(!addr) {
|
||||
failf(data, "Can't resolve new host %s", newhost);
|
||||
return CURLE_FTP_CANT_GET_HOST;
|
||||
@@ -1350,9 +1476,6 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
|
||||
/* this just dumps information about this second connection */
|
||||
ftp_pasv_verbose(conn, conninfo, newhost, connectport);
|
||||
|
||||
if(hostdataptr)
|
||||
Curl_freeaddrinfo(hostdataptr);
|
||||
|
||||
if(CURLE_OK != result)
|
||||
return result;
|
||||
|
||||
@@ -1363,9 +1486,6 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
|
||||
if(CURLE_OK != result)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
return CURLE_FTP_CANT_RECONNECT;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -1420,9 +1540,10 @@ CURLcode ftp_perform(struct connectdata *conn)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* If we have selected NOBODY, it means that we only want file information.
|
||||
Which in FTP can't be much more than the file size! */
|
||||
if(data->set.no_body) {
|
||||
/* If we have selected NOBODY and HEADER, it means that we only want file
|
||||
information. Which in FTP can't be much more than the file size and
|
||||
date. */
|
||||
if(data->set.no_body && data->set.include_header) {
|
||||
/* The SIZE command is _not_ RFC 959 specified, and therefor many servers
|
||||
may not support it! It is however the only way we have to get a file's
|
||||
size! */
|
||||
@@ -1468,20 +1589,27 @@ CURLcode ftp_perform(struct connectdata *conn)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
if(data->set.no_body)
|
||||
/* don't transfer the data */
|
||||
;
|
||||
/* Get us a second connection up and connected */
|
||||
if(data->set.ftp_use_port)
|
||||
else if(data->set.ftp_use_port) {
|
||||
/* We have chosen to use the PORT command */
|
||||
result = ftp_use_port(conn);
|
||||
else
|
||||
if(CURLE_OK == result)
|
||||
/* we have the data connection ready */
|
||||
infof(data, "Connected the data stream with PORT!\n");
|
||||
}
|
||||
else {
|
||||
/* We have chosen (this is default) to use the PASV command */
|
||||
result = ftp_use_pasv(conn);
|
||||
if(CURLE_OK == result)
|
||||
infof(data, "Connected the data stream with PASV!\n");
|
||||
}
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* we have the data connection ready */
|
||||
infof(data, "Connected the data stream!\n");
|
||||
|
||||
if(data->set.upload) {
|
||||
|
||||
/* Set type to binary (unless specified ASCII) */
|
||||
@@ -1506,11 +1634,13 @@ CURLcode ftp_perform(struct connectdata *conn)
|
||||
if(conn->resume_from < 0 ) {
|
||||
/* we could've got a specified offset from the command line,
|
||||
but now we know we didn't */
|
||||
ssize_t gottensize;
|
||||
|
||||
if(CURLE_OK != ftp_getsize(conn, ftp->file, &conn->resume_from)) {
|
||||
if(CURLE_OK != ftp_getsize(conn, ftp->file, &gottensize)) {
|
||||
failf(data, "Couldn't get remote file size");
|
||||
return CURLE_FTP_COULDNT_GET_SIZE;
|
||||
}
|
||||
conn->resume_from = gottensize;
|
||||
}
|
||||
|
||||
if(conn->resume_from) {
|
||||
@@ -1535,7 +1665,7 @@ CURLcode ftp_perform(struct connectdata *conn)
|
||||
|
||||
passed += actuallyread;
|
||||
if(actuallyread != readthisamountnow) {
|
||||
failf(data, "Could only read %d bytes from the input\n", passed);
|
||||
failf(data, "Could only read %d bytes from the input", passed);
|
||||
return CURLE_FTP_COULDNT_USE_REST;
|
||||
}
|
||||
}
|
||||
@@ -1602,7 +1732,7 @@ CURLcode ftp_perform(struct connectdata *conn)
|
||||
return result;
|
||||
|
||||
}
|
||||
else {
|
||||
else if(!data->set.no_body) {
|
||||
/* Retrieve file or directory */
|
||||
bool dirlist=FALSE;
|
||||
long downloadsize=-1;
|
||||
@@ -1665,22 +1795,32 @@ CURLcode ftp_perform(struct connectdata *conn)
|
||||
(data->set.ftp_list_only?"NLST":"LIST"));
|
||||
}
|
||||
else {
|
||||
ssize_t foundsize;
|
||||
|
||||
/* Set type to binary (unless specified ASCII) */
|
||||
result = ftp_transfertype(conn, data->set.ftp_ascii);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Attempt to get the size, it'll be useful in some cases: for resumed
|
||||
downloads and when talking to servers that don't give away the size
|
||||
in the RETR response line. */
|
||||
result = ftp_getsize(conn, ftp->file, &foundsize);
|
||||
if(CURLE_OK == result)
|
||||
downloadsize = foundsize;
|
||||
|
||||
if(conn->resume_from) {
|
||||
|
||||
/* Daniel: (August 4, 1999)
|
||||
*
|
||||
* We start with trying to use the SIZE command to figure out the size
|
||||
* of the file we're gonna get. If we can get the size, this is by far
|
||||
* the best way to know if we're trying to resume beyond the EOF. */
|
||||
int foundsize=-1;
|
||||
|
||||
result = ftp_getsize(conn, ftp->file, &foundsize);
|
||||
|
||||
* the best way to know if we're trying to resume beyond the EOF.
|
||||
*
|
||||
* Daniel, November 28, 2001. We *always* get the size on downloads
|
||||
* now, so it is done before this even when not doing resumes. I saved
|
||||
* the comment above for nostalgical reasons! ;-)
|
||||
*/
|
||||
if(CURLE_OK != result) {
|
||||
infof(data, "ftp server doesn't support SIZE\n");
|
||||
/* We couldn't get the size and therefore we can't know if there
|
||||
@@ -1918,9 +2058,11 @@ CURLcode Curl_ftp(struct connectdata *conn)
|
||||
CURLcode Curl_ftpsendf(struct connectdata *conn,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
size_t bytes_written;
|
||||
ssize_t bytes_written;
|
||||
char s[256];
|
||||
size_t write_len;
|
||||
ssize_t write_len;
|
||||
char *sptr=s;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
@@ -1934,9 +2076,23 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
|
||||
|
||||
bytes_written=0;
|
||||
write_len = strlen(s);
|
||||
Curl_write(conn, conn->firstsocket, s, write_len, &bytes_written);
|
||||
|
||||
return (bytes_written==write_len)?CURLE_OK:CURLE_WRITE_ERROR;
|
||||
do {
|
||||
res = Curl_write(conn, conn->firstsocket, sptr, write_len,
|
||||
&bytes_written);
|
||||
|
||||
if(CURLE_OK != res)
|
||||
break;
|
||||
|
||||
if(bytes_written != write_len) {
|
||||
write_len -= bytes_written;
|
||||
sptr += bytes_written;
|
||||
}
|
||||
else
|
||||
break;
|
||||
} while(1);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -1954,6 +2110,8 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
|
||||
if(ftp) {
|
||||
if(ftp->entrypath)
|
||||
free(ftp->entrypath);
|
||||
if(ftp->cache)
|
||||
free(ftp->cache);
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
@@ -28,7 +28,7 @@ CURLcode Curl_ftp_done(struct connectdata *conn);
|
||||
CURLcode Curl_ftp_connect(struct connectdata *conn);
|
||||
CURLcode Curl_ftp_disconnect(struct connectdata *conn);
|
||||
|
||||
size_t Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
|
||||
CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
|
||||
|
||||
/* The kerberos stuff needs this: */
|
||||
int Curl_GetFTPResponse(char *buf, struct connectdata *conn,
|
||||
|
@@ -21,6 +21,8 @@
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -53,7 +55,6 @@ char *GetEnv(const char *variable)
|
||||
if (env && strcmp("HOME",variable) == 0) {
|
||||
env = decc$translate_vms(env);
|
||||
}
|
||||
/* printf ("Getenv: %s=%s\n",variable,env); */
|
||||
#else
|
||||
/* no length control */
|
||||
char *env = getenv(variable);
|
||||
|
@@ -43,6 +43,7 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
|
||||
pro->t_nslookup = 0;
|
||||
pro->t_connect = 0;
|
||||
pro->t_pretransfer = 0;
|
||||
pro->t_starttransfer = 0;
|
||||
|
||||
info->httpcode = 0;
|
||||
info->httpversion=0;
|
||||
@@ -107,6 +108,9 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
|
||||
case CURLINFO_PRETRANSFER_TIME:
|
||||
*param_doublep = data->progress.t_pretransfer;
|
||||
break;
|
||||
case CURLINFO_STARTTRANSFER_TIME:
|
||||
*param_doublep = data->progress.t_starttransfer;
|
||||
break;
|
||||
case CURLINFO_SIZE_UPLOAD:
|
||||
*param_doublep = data->progress.uploaded;
|
||||
break;
|
||||
|
@@ -35,9 +35,7 @@
|
||||
* Daniel Stenberg <daniel@haxx.se>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "setup.h" /* setup.h is required for read() prototype */
|
||||
|
||||
#ifndef HAVE_GETPASS_R
|
||||
|
||||
|
282
lib/hash.c
Normal file
282
lib/hash.c
Normal file
@@ -0,0 +1,282 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al
|
||||
*
|
||||
* In order to be useful for every potential user, curl and libcurl are
|
||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
||||
*
|
||||
* 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 MPL or the MIT/X-derivate
|
||||
* licenses. You may pick one of these licenses.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "hash.h"
|
||||
#include "llist.h"
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
/* this must be the last include file */
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
|
||||
static unsigned long
|
||||
curl_hash_str(const char *key, unsigned int key_length)
|
||||
{
|
||||
register unsigned long h = 0;
|
||||
register unsigned long g;
|
||||
register char *p = (char *) key;
|
||||
register char *end = (char *) key + key_length;
|
||||
|
||||
while (p < end) {
|
||||
h = (h << 4) + *p++;
|
||||
if ((g = (h & 0xF0000000))) {
|
||||
h = h ^ (g >> 24);
|
||||
h = h ^ g;
|
||||
}
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
curl_hash_num(unsigned long key)
|
||||
{
|
||||
key += ~(key << 15);
|
||||
key ^= (key >> 10);
|
||||
key += (key << 3);
|
||||
key ^= (key >> 6);
|
||||
key += (key << 11);
|
||||
key ^= (key >> 16);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static void
|
||||
hash_element_dtor(void *u, void *ele)
|
||||
{
|
||||
curl_hash_element *e = (curl_hash_element *) ele;
|
||||
curl_hash *h = (curl_hash *) u;
|
||||
|
||||
if (e->key.type == CURL_HASH_KEY_IS_STRING) {
|
||||
free(e->key.value.str.val);
|
||||
}
|
||||
h->dtor(e->ptr);
|
||||
|
||||
free(e);
|
||||
e = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor)
|
||||
{
|
||||
int i;
|
||||
|
||||
h->dtor = dtor;
|
||||
h->size = 0;
|
||||
h->slots = slots;
|
||||
|
||||
h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *));
|
||||
for (i = 0; i < h->slots; ++i) {
|
||||
h->table[i] = curl_llist_alloc((curl_llist_dtor) hash_element_dtor);
|
||||
}
|
||||
}
|
||||
|
||||
curl_hash *
|
||||
curl_hash_alloc(int slots, curl_hash_dtor dtor)
|
||||
{
|
||||
curl_hash *h;
|
||||
|
||||
h = malloc(sizeof(curl_hash));
|
||||
curl_hash_init(h, slots, dtor);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
#define FIND_SLOT(__h, __s_key, __s_key_len, __n_key) \
|
||||
((__s_key ? curl_hash_str(__s_key, __s_key_len) : curl_hash_num(__n_key)) % (__h)->slots)
|
||||
|
||||
#define KEY_CREATE(__k, __s_key, __s_key_len, __n_key, __dup) \
|
||||
if (__s_key) { \
|
||||
if (__dup) { \
|
||||
(__k)->value.str.val = (char *) malloc(__s_key_len); \
|
||||
memcpy((__k)->value.str.val, __s_key, __s_key_len); \
|
||||
} else { \
|
||||
(__k)->value.str.val = __s_key; \
|
||||
} \
|
||||
(__k)->value.str.len = __s_key_len; \
|
||||
(__k)->type = CURL_HASH_KEY_IS_STRING; \
|
||||
} else { \
|
||||
(__k)->value.num = __n_key; \
|
||||
(__k)->type = CURL_HASH_KEY_IS_NUM; \
|
||||
}
|
||||
|
||||
#define MIN(a, b) (a > b ? b : a)
|
||||
|
||||
static int
|
||||
curl_hash_key_compare(curl_hash_key *key1, curl_hash_key *key2)
|
||||
{
|
||||
if (key1->type == CURL_HASH_KEY_IS_NUM) {
|
||||
if (key2->type == CURL_HASH_KEY_IS_STRING)
|
||||
return 0;
|
||||
|
||||
if (key1->value.num == key2->value.num)
|
||||
return 1;
|
||||
} else {
|
||||
if (key2->type == CURL_HASH_KEY_IS_NUM)
|
||||
return 0;
|
||||
|
||||
if (memcmp(key1->value.str.val, key2->value.str.val,
|
||||
MIN(key1->value.str.len, key2->value.str.len)) == 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
curl_hash_add_or_update(curl_hash *h, char *str_key, unsigned int str_key_len,
|
||||
unsigned long num_key, const void *p)
|
||||
{
|
||||
curl_hash_element *e;
|
||||
curl_hash_key tmp;
|
||||
curl_llist *l;
|
||||
curl_llist_element *le;
|
||||
int slot;
|
||||
|
||||
slot = FIND_SLOT(h, str_key, str_key_len, num_key);
|
||||
l = h->table[slot];
|
||||
KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0);
|
||||
for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) {
|
||||
if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) {
|
||||
curl_hash_element *to_update = CURL_LLIST_VALP(le);
|
||||
h->dtor(to_update->ptr);
|
||||
to_update->ptr = (void *) p;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
e = (curl_hash_element *) malloc(sizeof(curl_hash_element));
|
||||
KEY_CREATE(&e->key, str_key, str_key_len, num_key, 1);
|
||||
e->ptr = (void *) p;
|
||||
|
||||
if (curl_llist_insert_next(l, CURL_LLIST_TAIL(l), e)) {
|
||||
++h->size;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
curl_hash_extended_delete(curl_hash *h, char *str_key, unsigned int str_key_len,
|
||||
unsigned long num_key)
|
||||
{
|
||||
curl_llist *l;
|
||||
curl_llist_element *le;
|
||||
curl_hash_key tmp;
|
||||
int slot;
|
||||
|
||||
slot = FIND_SLOT(h, str_key, str_key_len, num_key);
|
||||
l = h->table[slot];
|
||||
|
||||
KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0);
|
||||
for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) {
|
||||
if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) {
|
||||
curl_llist_remove(l, le, (void *) h);
|
||||
--h->size;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
curl_hash_extended_find(curl_hash *h, char *str_key, unsigned int str_key_len,
|
||||
unsigned long num_key, void **p)
|
||||
{
|
||||
curl_llist *l;
|
||||
curl_llist_element *le;
|
||||
curl_hash_key tmp;
|
||||
int slot;
|
||||
|
||||
slot = FIND_SLOT(h, str_key, str_key_len, num_key);
|
||||
l = h->table[slot];
|
||||
|
||||
KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0);
|
||||
for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) {
|
||||
if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) {
|
||||
*p = ((curl_hash_element *) CURL_LLIST_VALP(le))->ptr;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *))
|
||||
{
|
||||
curl_llist_element *le;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < h->slots; ++i) {
|
||||
for (le = CURL_LLIST_HEAD(h->table[i]); le != NULL; le = CURL_LLIST_NEXT(le)) {
|
||||
cb(user, (curl_hash_element *) CURL_LLIST_VALP(le));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
curl_hash_clean(curl_hash *h)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < h->slots; ++i) {
|
||||
curl_llist_destroy(h->table[i], (void *) h);
|
||||
}
|
||||
|
||||
free(h->table);
|
||||
h->table = NULL;
|
||||
}
|
||||
|
||||
size_t
|
||||
curl_hash_count(curl_hash *h)
|
||||
{
|
||||
return h->size;
|
||||
}
|
||||
|
||||
void
|
||||
curl_hash_destroy(curl_hash *h)
|
||||
{
|
||||
if (!h) {
|
||||
return;
|
||||
}
|
||||
|
||||
curl_hash_clean(h);
|
||||
free(h);
|
||||
h = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* local variables:
|
||||
* eval: (load-file "../curl-mode.el")
|
||||
* end:
|
||||
* vim600: fdm=marker
|
||||
* vim: et sw=2 ts=2 sts=2 tw=78
|
||||
*/
|
85
lib/hash.h
Normal file
85
lib/hash.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#ifndef __HASH_H
|
||||
#define __HASH_H
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* In order to be useful for every potential user, curl and libcurl are
|
||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
||||
*
|
||||
* 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 MPL or the MIT/X-derivate
|
||||
* licenses. You may pick one of these licenses.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "llist.h"
|
||||
|
||||
#define CURL_HASH_KEY_IS_STRING 0
|
||||
#define CURL_HASH_KEY_IS_NUM 1
|
||||
|
||||
typedef void (*curl_hash_dtor)(void *);
|
||||
|
||||
typedef struct _curl_hash {
|
||||
curl_llist **table;
|
||||
curl_hash_dtor dtor;
|
||||
int slots;
|
||||
size_t size;
|
||||
} curl_hash;
|
||||
|
||||
typedef struct _curl_hash_key {
|
||||
union {
|
||||
struct {
|
||||
char *val;
|
||||
unsigned int len;
|
||||
} str;
|
||||
|
||||
unsigned long num;
|
||||
} value;
|
||||
|
||||
int type;
|
||||
} curl_hash_key;
|
||||
|
||||
typedef struct _curl_hash_element {
|
||||
curl_hash_key key;
|
||||
void *ptr;
|
||||
} curl_hash_element;
|
||||
|
||||
|
||||
void curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor);
|
||||
curl_hash *curl_hash_alloc(int slots, curl_hash_dtor dtor);
|
||||
int curl_hash_add_or_update(curl_hash *h, char *str_key, unsigned int str_key_len,
|
||||
unsigned long num_key, const void *p);
|
||||
int curl_hash_extended_delete(curl_hash *h, char *str_key, unsigned int str_key_len,
|
||||
unsigned long num_key);
|
||||
int curl_hash_extended_find(curl_hash *h, char *str_key, unsigned int str_key_len,
|
||||
unsigned long num_key, void **p);
|
||||
void curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *));
|
||||
size_t curl_hash_count(curl_hash *h);
|
||||
void curl_hash_clean(curl_hash *h);
|
||||
void curl_hash_destroy(curl_hash *h);
|
||||
|
||||
#define curl_hash_find(h, key, key_len, p) curl_hash_extended_find(h, key, key_len, 0, p)
|
||||
#define curl_hash_delete(h, key, key_len) curl_hash_extended_delete(h, key, key_len, 0)
|
||||
#define curl_hash_add(h, key, key_len, p) curl_hash_add_or_update(h, key, key_len, 0, p)
|
||||
#define curl_hash_update curl_hash_add
|
||||
#define curl_hash_index_find(h, key, p) curl_hash_extended_find(h, NULL, 0, key, p)
|
||||
#define curl_hash_index_delete(h, key) curl_hash_extended_delete(h, NULL, 0, key)
|
||||
#define curl_hash_index_add(h, key, p) curl_hash_add_or_update(h, NULL, 0, key, p)
|
||||
#define curl_hash_index_update curl_hash_index_add
|
||||
|
||||
#endif
|
100
lib/hostip.c
100
lib/hostip.c
@@ -28,7 +28,6 @@
|
||||
|
||||
#define _REENTRANT
|
||||
|
||||
|
||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||
#include <winsock.h>
|
||||
#else
|
||||
@@ -47,6 +46,9 @@
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* required for free() prototypes */
|
||||
#endif
|
||||
#ifdef VMS
|
||||
#include <inet.h>
|
||||
#include <stdlib.h>
|
||||
@@ -56,6 +58,7 @@
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
|
||||
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
||||
#include "inet_ntoa_r.h"
|
||||
@@ -66,6 +69,86 @@
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
static curl_hash hostname_cache;
|
||||
static int host_cache_initialized;
|
||||
|
||||
void Curl_global_host_cache_init(void)
|
||||
{
|
||||
if (!host_cache_initialized) {
|
||||
curl_hash_init(&hostname_cache, 7, Curl_freeaddrinfo);
|
||||
host_cache_initialized = 1;
|
||||
}
|
||||
}
|
||||
|
||||
curl_hash *Curl_global_host_cache_get(void)
|
||||
{
|
||||
return &hostname_cache;
|
||||
}
|
||||
|
||||
void Curl_global_host_cache_dtor(void)
|
||||
{
|
||||
if (host_cache_initialized) {
|
||||
curl_hash_clean(&hostname_cache);
|
||||
host_cache_initialized = 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct curl_dns_cache_entry {
|
||||
Curl_addrinfo *addr;
|
||||
time_t timestamp;
|
||||
};
|
||||
|
||||
Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
||||
char *hostname,
|
||||
int port,
|
||||
char **bufp)
|
||||
{
|
||||
struct curl_dns_cache_entry *p = NULL;
|
||||
size_t hostname_len;
|
||||
time_t now;
|
||||
|
||||
/* If the host cache timeout is 0, we don't do DNS cach'ing
|
||||
so fall through */
|
||||
if (data->set.dns_cache_timeout == 0) {
|
||||
return Curl_getaddrinfo(data, hostname, port, bufp);
|
||||
}
|
||||
|
||||
hostname_len = strlen(hostname)+1;
|
||||
|
||||
time(&now);
|
||||
/* See if its already in our dns cache */
|
||||
if (curl_hash_find(data->hostcache, hostname, hostname_len, (void **) &p)) {
|
||||
/* Do we need to check for a cache timeout? */
|
||||
if (data->set.dns_cache_timeout != -1) {
|
||||
/* Return if the entry has not timed out */
|
||||
if ((now - p->timestamp) < data->set.dns_cache_timeout) {
|
||||
return p->addr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return p->addr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a new cache entry */
|
||||
p = (struct curl_dns_cache_entry *)
|
||||
malloc(sizeof(struct curl_dns_cache_entry));
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
p->addr = Curl_getaddrinfo(data, hostname, port, bufp);
|
||||
if (!p->addr) {
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
p->timestamp = now;
|
||||
|
||||
/* Save it in our host cache */
|
||||
curl_hash_update(data->hostcache, hostname, hostname_len, (const void *) p);
|
||||
|
||||
return p->addr;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a wrapper function for freeing name information in a protocol
|
||||
* independent way. This takes care of using the appropriate underlaying
|
||||
@@ -73,11 +156,15 @@
|
||||
*/
|
||||
void Curl_freeaddrinfo(void *freethis)
|
||||
{
|
||||
struct curl_dns_cache_entry *p = (struct curl_dns_cache_entry *) freethis;
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
freeaddrinfo(freethis);
|
||||
freeaddrinfo(p->addr);
|
||||
#else
|
||||
free(freethis);
|
||||
free(p->addr);
|
||||
#endif
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
/* --- resolve name or IP-number --- */
|
||||
@@ -100,7 +187,7 @@ int curl_getaddrinfo(char *hostname, char *service,
|
||||
/* success */
|
||||
if(logfile)
|
||||
fprintf(logfile, "ADDR %s:%d getaddrinfo() = %p\n",
|
||||
source, line, *result);
|
||||
source, line, (void *)*result);
|
||||
}
|
||||
else {
|
||||
if(logfile)
|
||||
@@ -116,7 +203,7 @@ void curl_freeaddrinfo(struct addrinfo *freethis,
|
||||
(freeaddrinfo)(freethis);
|
||||
if(logfile)
|
||||
fprintf(logfile, "ADDR %s:%d freeaddrinfo(%p)\n",
|
||||
source, line, freethis);
|
||||
source, line, (void *)freethis);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -263,7 +350,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
|
||||
char **bufp)
|
||||
{
|
||||
struct hostent *h = NULL;
|
||||
unsigned long in;
|
||||
in_addr_t in;
|
||||
int ret; /* this variable is unused on several platforms but used on some */
|
||||
|
||||
#define CURL_NAMELOOKUP_SIZE 9000
|
||||
@@ -370,3 +457,4 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
|
||||
* vim600: fdm=marker
|
||||
* vim: et sw=2 ts=2 sts=2 tw=78
|
||||
*/
|
||||
|
||||
|
13
lib/hostip.h
13
lib/hostip.h
@@ -23,10 +23,23 @@
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "hash.h"
|
||||
|
||||
struct addrinfo;
|
||||
struct hostent;
|
||||
struct SessionHandle;
|
||||
|
||||
void Curl_global_host_cache_init(void);
|
||||
void Curl_global_host_cache_dtor(void);
|
||||
curl_hash *Curl_global_host_cache_get(void);
|
||||
|
||||
#define Curl_global_host_cache_use(__p) ((__p)->set.global_dns_cache)
|
||||
|
||||
Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
||||
char *hostname,
|
||||
int port,
|
||||
char **bufp);
|
||||
|
||||
/* Get name info */
|
||||
Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
|
||||
char *hostname,
|
||||
|
200
lib/http.c
200
lib/http.c
@@ -128,8 +128,10 @@ static
|
||||
CURLcode add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in,
|
||||
long *bytes_written)
|
||||
{
|
||||
size_t amount;
|
||||
CURLcode result;
|
||||
ssize_t amount;
|
||||
CURLcode res;
|
||||
char *ptr;
|
||||
int size;
|
||||
|
||||
if(conn->data->set.verbose) {
|
||||
fputs("> ", conn->data->set.err);
|
||||
@@ -137,7 +139,25 @@ CURLcode add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in,
|
||||
fwrite(in->buffer, in->size_used, 1, conn->data->set.err);
|
||||
}
|
||||
|
||||
result = Curl_write(conn, sockfd, in->buffer, in->size_used, &amount);
|
||||
/* The looping below is required since we use non-blocking sockets, but due
|
||||
to the circumstances we will just loop and try again and again etc */
|
||||
|
||||
ptr = in->buffer;
|
||||
size = in->size_used;
|
||||
do {
|
||||
res = Curl_write(conn, sockfd, ptr, size, &amount);
|
||||
|
||||
if(CURLE_OK != res)
|
||||
break;
|
||||
|
||||
if(amount != size) {
|
||||
size += amount;
|
||||
ptr += amount;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
} while(1);
|
||||
|
||||
if(in->buffer)
|
||||
free(in->buffer);
|
||||
@@ -145,7 +165,7 @@ CURLcode add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in,
|
||||
|
||||
*bytes_written = amount;
|
||||
|
||||
return result;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -204,28 +224,6 @@ CURLcode add_buffer(send_buffer *in, const void *inptr, size_t size)
|
||||
/* end of the add_buffer functions */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Read everything until a newline.
|
||||
*/
|
||||
|
||||
static
|
||||
int GetLine(int sockfd, char *ptr, struct connectdata *conn)
|
||||
{
|
||||
ssize_t nread;
|
||||
|
||||
/* get us a full line, terminated with a newline */
|
||||
for(nread=0; (nread<BUFSIZE); nread++, ptr++) {
|
||||
if((CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &nread)) ||
|
||||
(nread <= 0) || (*ptr == '\n'))
|
||||
break;
|
||||
}
|
||||
*ptr=0; /* zero terminate */
|
||||
|
||||
return nread>0?nread:0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This function checks the linked list of custom HTTP headers for a particular
|
||||
* header (prefix).
|
||||
@@ -257,6 +255,23 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
||||
int subversion=0;
|
||||
struct SessionHandle *data=conn->data;
|
||||
CURLcode result;
|
||||
int res;
|
||||
|
||||
int nread; /* total size read */
|
||||
int perline; /* count bytes per line */
|
||||
bool keepon=TRUE;
|
||||
ssize_t gotbytes;
|
||||
char *ptr;
|
||||
int timeout = 3600; /* default timeout in seconds */
|
||||
struct timeval interval;
|
||||
fd_set rkeepfd;
|
||||
fd_set readfd;
|
||||
char *line_start;
|
||||
|
||||
#define SELECT_OK 0
|
||||
#define SELECT_ERROR 1
|
||||
#define SELECT_TIMEOUT 2
|
||||
int error = SELECT_OK;
|
||||
|
||||
infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
|
||||
|
||||
@@ -276,19 +291,109 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
/* wait for the proxy to send us a HTTP/1.0 200 OK header */
|
||||
while(GetLine(tunnelsocket, data->state.buffer, conn)) {
|
||||
if('\r' == data->state.buffer[0])
|
||||
break; /* end of headers */
|
||||
if(data->set.verbose)
|
||||
fprintf(data->set.err, "< %s\n", data->state.buffer);
|
||||
/* Now, read the full reply we get from the proxy */
|
||||
|
||||
if(2 == sscanf(data->state.buffer, "HTTP/1.%d %d",
|
||||
|
||||
if(data->set.timeout) {
|
||||
/* if timeout is requested, find out how much remaining time we have */
|
||||
timeout = data->set.timeout - /* timeout time */
|
||||
Curl_tvdiff(Curl_tvnow(), conn->now)/1000; /* spent time */
|
||||
if(timeout <=0 ) {
|
||||
failf(data, "Transfer aborted due to timeout");
|
||||
return -SELECT_TIMEOUT; /* already too little time */
|
||||
}
|
||||
}
|
||||
|
||||
FD_ZERO (&readfd); /* clear it */
|
||||
FD_SET (tunnelsocket, &readfd); /* read socket */
|
||||
|
||||
/* get this in a backup variable to be able to restore it on each lap in the
|
||||
select() loop */
|
||||
rkeepfd = readfd;
|
||||
|
||||
ptr=data->state.buffer;
|
||||
line_start = ptr;
|
||||
|
||||
nread=0;
|
||||
perline=0;
|
||||
keepon=TRUE;
|
||||
|
||||
while((nread<BUFSIZE) && (keepon && !error)) {
|
||||
readfd = rkeepfd; /* set every lap */
|
||||
interval.tv_sec = timeout;
|
||||
interval.tv_usec = 0;
|
||||
|
||||
switch (select (tunnelsocket+1, &readfd, NULL, NULL, &interval)) {
|
||||
case -1: /* select() error, stop reading */
|
||||
error = SELECT_ERROR;
|
||||
failf(data, "Transfer aborted due to select() error");
|
||||
break;
|
||||
case 0: /* timeout */
|
||||
error = SELECT_TIMEOUT;
|
||||
failf(data, "Transfer aborted due to timeout");
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* This code previously didn't use the kerberos sec_read() code
|
||||
* to read, but when we use Curl_read() it may do so. Do confirm
|
||||
* that this is still ok and then remove this comment!
|
||||
*/
|
||||
res= Curl_read(conn, tunnelsocket, ptr, BUFSIZE-nread,
|
||||
&gotbytes);
|
||||
if(res< 0)
|
||||
/* EWOULDBLOCK */
|
||||
continue; /* go loop yourself */
|
||||
else if(res)
|
||||
keepon = FALSE;
|
||||
else if(gotbytes <= 0) {
|
||||
keepon = FALSE;
|
||||
error = SELECT_ERROR;
|
||||
failf(data, "Connection aborted");
|
||||
}
|
||||
else {
|
||||
/* we got a whole chunk of data, which can be anything from one
|
||||
* byte to a set of lines and possibly just a piece of the last
|
||||
* line */
|
||||
int i;
|
||||
|
||||
nread += gotbytes;
|
||||
for(i = 0; i < gotbytes; ptr++, i++) {
|
||||
perline++; /* amount of bytes in this line so far */
|
||||
if(*ptr=='\n') {
|
||||
/* a newline is CRLF in ftp-talk, so the CR is ignored as
|
||||
the line isn't really terminated until the LF comes */
|
||||
|
||||
/* output debug output if that is requested */
|
||||
if(data->set.verbose) {
|
||||
fputs("< ", data->set.err);
|
||||
fwrite(line_start, perline, 1, data->set.err);
|
||||
/* no need to output LF here, it is part of the data */
|
||||
}
|
||||
|
||||
if('\r' == line_start[0]) {
|
||||
/* end of headers */
|
||||
keepon=FALSE;
|
||||
break; /* breaks out of loop, not switch */
|
||||
}
|
||||
|
||||
if(2 == sscanf(line_start, "HTTP/1.%d %d",
|
||||
&subversion,
|
||||
&httperror)) {
|
||||
;
|
||||
}
|
||||
|
||||
perline=0; /* line starts over here */
|
||||
line_start = ptr+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
} /* switch */
|
||||
} /* while there's buffer left and loop is requested */
|
||||
|
||||
if(error)
|
||||
return CURLE_READ_ERROR;
|
||||
|
||||
if(200 != httperror) {
|
||||
if(407 == httperror)
|
||||
/* Added Nov 6 1998 */
|
||||
@@ -318,15 +423,18 @@ CURLcode Curl_http_connect(struct connectdata *conn)
|
||||
* us to the host we want to talk to. Only after the connect
|
||||
* has occured, can we start talking SSL
|
||||
*/
|
||||
if (conn->protocol & PROT_HTTPS) {
|
||||
if (data->change.proxy) {
|
||||
/* HTTPS through a proxy can only be done with a tunnel */
|
||||
|
||||
if(data->change.proxy &&
|
||||
((conn->protocol & PROT_HTTPS) || data->set.tunnel_thru_httpproxy)) {
|
||||
|
||||
/* either HTTPS over proxy, OR explicitly asked for a tunnel */
|
||||
result = Curl_ConnectHTTPProxyTunnel(conn, conn->firstsocket,
|
||||
conn->hostname, conn->remote_port);
|
||||
if(CURLE_OK != result)
|
||||
return result;
|
||||
}
|
||||
|
||||
if(conn->protocol & PROT_HTTPS) {
|
||||
/* now, perform the SSL initialization for this socket */
|
||||
result = Curl_SSLConnect(conn);
|
||||
if(result)
|
||||
@@ -366,7 +474,7 @@ CURLcode Curl_http_done(struct connectdata *conn)
|
||||
if(0 == (http->readbytecount + conn->headerbytecount)) {
|
||||
/* nothing was read from the HTTP server, this can't be right
|
||||
so we return an error here */
|
||||
failf(data, "Empty reply from server\n");
|
||||
failf(data, "Empty reply from server");
|
||||
return CURLE_GOT_NOTHING;
|
||||
}
|
||||
|
||||
@@ -450,7 +558,9 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
host, ppath,
|
||||
conn->protocol&PROT_HTTPS?TRUE:FALSE);
|
||||
}
|
||||
if ((data->change.proxy) && !(conn->protocol&PROT_HTTPS)) {
|
||||
if (data->change.proxy &&
|
||||
!data->set.tunnel_thru_httpproxy &&
|
||||
!(conn->protocol&PROT_HTTPS)) {
|
||||
/* The path sent to the proxy is in fact the entire URL */
|
||||
ppath = data->change.url;
|
||||
}
|
||||
@@ -525,7 +635,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
|
||||
passed += actuallyread;
|
||||
if(actuallyread != readthisamountnow) {
|
||||
failf(data, "Could only read %d bytes from the input\n",
|
||||
failf(data, "Could only read %d bytes from the input",
|
||||
passed);
|
||||
return CURLE_READ_ERROR;
|
||||
}
|
||||
@@ -536,7 +646,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
data->set.infilesize -= conn->resume_from;
|
||||
|
||||
if(data->set.infilesize <= 0) {
|
||||
failf(data, "File already completely uploaded\n");
|
||||
failf(data, "File already completely uploaded");
|
||||
return CURLE_PARTIAL_FILE;
|
||||
}
|
||||
}
|
||||
@@ -650,10 +760,8 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
* equal to UTC (Coordinated Universal Time)." (see page 20 of RFC2616).
|
||||
*/
|
||||
|
||||
#ifdef HAVE_LOCALTIME_R
|
||||
#ifdef HAVE_GMTIME_R
|
||||
/* thread-safe version */
|
||||
/* We assume that the presense of localtime_r() proves the presense
|
||||
of gmtime_r() which is a bit ugly but might work */
|
||||
struct tm keeptime;
|
||||
thistime = (struct tm *)gmtime_r(&data->set.timevalue, &keeptime);
|
||||
#else
|
||||
@@ -666,7 +774,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
|
||||
#ifdef HAVE_STRFTIME
|
||||
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
|
||||
strftime(buf, BUFSIZE-1, "%a, %d %b %Y %H:%M:%S %Z", thistime);
|
||||
strftime(buf, BUFSIZE-1, "%a, %d %b %Y %H:%M:%S GMT", thistime);
|
||||
#else
|
||||
/* TODO: Right, we *could* write a replacement here */
|
||||
strcpy(buf, "no strftime() support");
|
||||
@@ -710,7 +818,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
char contentType[256];
|
||||
int linelength=0;
|
||||
if(Curl_FormInit(&http->form, http->sendit)) {
|
||||
failf(data, "Internal HTTP POST error!\n");
|
||||
failf(data, "Internal HTTP POST error!");
|
||||
return CURLE_HTTP_POST_ERROR;
|
||||
}
|
||||
|
||||
@@ -741,7 +849,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
1,
|
||||
(FILE *)&http->form);
|
||||
if(linelength == -1) {
|
||||
failf(data, "Could not get Content-Type header line!\n");
|
||||
failf(data, "Could not get Content-Type header line!");
|
||||
return CURLE_HTTP_POST_ERROR;
|
||||
}
|
||||
add_buffer(req_buffer, contentType, linelength);
|
||||
|
59
lib/krb4.c
59
lib/krb4.c
@@ -57,6 +57,10 @@
|
||||
#include "ftp.h"
|
||||
#include "sendf.h"
|
||||
|
||||
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
||||
#include "inet_ntoa_r.h"
|
||||
#endif
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#include "memdebug.h"
|
||||
@@ -193,10 +197,10 @@ krb4_auth(void *app_data, struct connectdata *conn)
|
||||
int checksum;
|
||||
u_int32_t cs;
|
||||
struct krb4_data *d = app_data;
|
||||
struct sockaddr_in *localaddr = (struct sockaddr_in *)LOCAL_ADDR;
|
||||
char *host = conn->hostaddr->h_name;
|
||||
ssize_t nread;
|
||||
int l = sizeof(conn->local_addr);
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
if(getsockname(conn->firstsocket,
|
||||
(struct sockaddr *)LOCAL_ADDR, &l) < 0)
|
||||
@@ -207,66 +211,62 @@ krb4_auth(void *app_data, struct connectdata *conn)
|
||||
if(ret == KDC_PR_UNKNOWN)
|
||||
ret = mk_auth(d, &adat, "rcmd", host, checksum);
|
||||
if(ret) {
|
||||
printf("%s\n", krb_get_err_text(ret));
|
||||
Curl_infof(data, "%s\n", krb_get_err_text(ret));
|
||||
return AUTH_CONTINUE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_KRB_GET_OUR_IP_FOR_REALM
|
||||
if (krb_get_config_bool("nat_in_use")) {
|
||||
struct sockaddr_in *localaddr = (struct sockaddr_in *)LOCAL_ADDR;
|
||||
struct in_addr natAddr;
|
||||
|
||||
if (krb_get_our_ip_for_realm(krb_realmofhost(host),
|
||||
&natAddr) != KSUCCESS
|
||||
&& krb_get_our_ip_for_realm(NULL, &natAddr) != KSUCCESS)
|
||||
printf("Can't get address for realm %s\n",
|
||||
Curl_infof(data, "Can't get address for realm %s\n",
|
||||
krb_realmofhost(host));
|
||||
else {
|
||||
if (natAddr.s_addr != localaddr->sin_addr.s_addr) {
|
||||
printf("Using NAT IP address (%s) for kerberos 4\n",
|
||||
(char *)inet_ntoa(natAddr));
|
||||
#ifdef HAVE_INET_NTOA_R
|
||||
char ntoa_buf[64];
|
||||
char *ip = (char *)inet_ntoa_r(natAddr, ntoa_buf, sizeof(ntoa_buf));
|
||||
#else
|
||||
char *ip = (char *)inet_ntoa(natAddr);
|
||||
#endif
|
||||
Curl_infof(data, "Using NAT IP address (%s) for kerberos 4\n", ip);
|
||||
localaddr->sin_addr = natAddr;
|
||||
|
||||
/*
|
||||
* This not the best place to do this, but it is here we know that
|
||||
* (probably) NAT is in use! */
|
||||
|
||||
/*passivemode = 1;***/
|
||||
/*printf("Setting: Passive mode on.\n");***/
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*printf("Local address is %s\n", inet_ntoa(localaddr->sin_addr));***/
|
||||
/*printf("Remote address is %s\n", inet_ntoa(remoteaddr->sin_addr));***/
|
||||
|
||||
if(Curl_base64_encode(adat.dat, adat.length, &p) < 0) {
|
||||
printf("Out of memory base64-encoding.\n");
|
||||
Curl_failf(data, "Out of memory base64-encoding");
|
||||
return AUTH_CONTINUE;
|
||||
}
|
||||
|
||||
if(Curl_ftpsendf(conn, "ADAT %s", p))
|
||||
return -2;
|
||||
|
||||
nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, NULL);
|
||||
nread = Curl_GetFTPResponse(data->state.buffer, conn, NULL);
|
||||
if(nread < 0)
|
||||
return -1;
|
||||
free(p);
|
||||
|
||||
if(/*ret != COMPLETE*/conn->data->state.buffer[0] != '2'){
|
||||
printf("Server didn't accept auth data.\n");
|
||||
if(data->state.buffer[0] != '2'){
|
||||
Curl_failf(data, "Server didn't accept auth data");
|
||||
return AUTH_ERROR;
|
||||
}
|
||||
|
||||
p = strstr(conn->data->state.buffer, "ADAT=");
|
||||
p = strstr(data->state.buffer, "ADAT=");
|
||||
if(!p) {
|
||||
printf("Remote host didn't send adat reply.\n");
|
||||
Curl_failf(data, "Remote host didn't send adat reply");
|
||||
return AUTH_ERROR;
|
||||
}
|
||||
p += 5;
|
||||
len = Curl_base64_decode(p, adat.dat);
|
||||
if(len < 0) {
|
||||
printf("Failed to decode base64 from server.\n");
|
||||
Curl_failf(data, "Failed to decode base64 from server");
|
||||
return AUTH_ERROR;
|
||||
}
|
||||
adat.length = len;
|
||||
@@ -274,13 +274,13 @@ krb4_auth(void *app_data, struct connectdata *conn)
|
||||
(struct sockaddr_in *)hisctladdr,
|
||||
(struct sockaddr_in *)myctladdr, &msg_data);
|
||||
if(ret) {
|
||||
printf("Error reading reply from server: %s.\n",
|
||||
Curl_failf(data, "Error reading reply from server: %s",
|
||||
krb_get_err_text(ret));
|
||||
return AUTH_ERROR;
|
||||
}
|
||||
krb_get_int(msg_data.app_data, &cs, 4, 0);
|
||||
if(cs - checksum != 1) {
|
||||
printf("Bad checksum returned from server.\n");
|
||||
Curl_failf(data, "Bad checksum returned from server");
|
||||
return AUTH_ERROR;
|
||||
}
|
||||
return AUTH_OK;
|
||||
@@ -321,15 +321,14 @@ void Curl_krb_kauth(struct connectdata *conn)
|
||||
if(nread < 0)
|
||||
return /*CURLE_OPERATION_TIMEOUTED*/;
|
||||
|
||||
if(/*ret != CONTINUE*/conn->data->state.buffer[0] != '3'){
|
||||
if(conn->data->state.buffer[0] != '3'){
|
||||
Curl_set_command_prot(conn, save);
|
||||
/*code = -1;***/
|
||||
return;
|
||||
}
|
||||
|
||||
p = strstr(conn->data->state.buffer, "T=");
|
||||
if(!p) {
|
||||
printf("Bad reply from server.\n");
|
||||
Curl_failf(conn->data, "Bad reply from server");
|
||||
Curl_set_command_prot(conn, save);
|
||||
return;
|
||||
}
|
||||
@@ -337,7 +336,7 @@ void Curl_krb_kauth(struct connectdata *conn)
|
||||
p += 2;
|
||||
tmp = Curl_base64_decode(p, &tkt.dat);
|
||||
if(tmp < 0) {
|
||||
printf("Failed to decode base64 in reply.\n");
|
||||
Curl_failf(conn->data, "Failed to decode base64 in reply.\n");
|
||||
Curl_set_command_prot(conn, save);
|
||||
return;
|
||||
}
|
||||
@@ -346,7 +345,7 @@ void Curl_krb_kauth(struct connectdata *conn)
|
||||
|
||||
p = strstr(conn->data->state.buffer, "P=");
|
||||
if(!p) {
|
||||
printf("Bad reply from server.\n");
|
||||
Curl_failf(conn->data, "Bad reply from server");
|
||||
Curl_set_command_prot(conn, save);
|
||||
return;
|
||||
}
|
||||
@@ -374,7 +373,7 @@ void Curl_krb_kauth(struct connectdata *conn)
|
||||
memset(schedule, 0, sizeof(schedule));
|
||||
memset(passwd, 0, sizeof(passwd));
|
||||
if(Curl_base64_encode(tktcopy.dat, tktcopy.length, &p) < 0) {
|
||||
failf(conn->data, "Out of memory base64-encoding.\n");
|
||||
failf(conn->data, "Out of memory base64-encoding.");
|
||||
Curl_set_command_prot(conn, save);
|
||||
return;
|
||||
}
|
||||
|
@@ -95,9 +95,11 @@ static void DynaClose(void)
|
||||
#if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL)
|
||||
if (libldap) {
|
||||
dlclose(libldap);
|
||||
libldap=NULL;
|
||||
}
|
||||
if (liblber) {
|
||||
dlclose(liblber);
|
||||
liblber=NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -174,7 +176,9 @@ CURLcode Curl_ldap(struct connectdata *conn)
|
||||
conn->hostname, conn->port);
|
||||
status = CURLE_COULDNT_CONNECT;
|
||||
} else {
|
||||
rc = ldap_simple_bind_s(server, data->state.user, data->state.passwd);
|
||||
rc = ldap_simple_bind_s(server,
|
||||
conn->bits.user_passwd?data->state.user:NULL,
|
||||
conn->bits.user_passwd?data->state.passwd:NULL);
|
||||
if (rc != 0) {
|
||||
failf(data, "LDAP: %s", ldap_err2string(rc));
|
||||
status = CURLE_LDAP_CANNOT_BIND;
|
||||
|
165
lib/llist.c
Normal file
165
lib/llist.c
Normal file
@@ -0,0 +1,165 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al
|
||||
*
|
||||
* In order to be useful for every potential user, curl and libcurl are
|
||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
||||
*
|
||||
* 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 MPL or the MIT/X-derivate
|
||||
* licenses. You may pick one of these licenses.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "llist.h"
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
/* this must be the last include file */
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
void
|
||||
curl_llist_init(curl_llist *l, curl_llist_dtor dtor)
|
||||
{
|
||||
l->size = 0;
|
||||
l->dtor = dtor;
|
||||
l->head = NULL;
|
||||
l->tail = NULL;
|
||||
}
|
||||
|
||||
curl_llist *
|
||||
curl_llist_alloc(curl_llist_dtor dtor)
|
||||
{
|
||||
curl_llist *list;
|
||||
|
||||
list = malloc(sizeof(curl_llist));
|
||||
curl_llist_init(list, dtor);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
int
|
||||
curl_llist_insert_next(curl_llist *list, curl_llist_element *e, const void *p)
|
||||
{
|
||||
curl_llist_element *ne;
|
||||
|
||||
ne = (curl_llist_element *) malloc(sizeof(curl_llist_element));
|
||||
ne->ptr = (void *) p;
|
||||
if (list->size == 0) {
|
||||
list->head = ne;
|
||||
list->head->prev = NULL;
|
||||
list->head->next = NULL;
|
||||
list->tail = ne;
|
||||
} else {
|
||||
ne->next = e->next;
|
||||
ne->prev = e;
|
||||
if (e->next) {
|
||||
e->next->prev = ne;
|
||||
} else {
|
||||
list->tail = ne;
|
||||
}
|
||||
e->next = ne;
|
||||
}
|
||||
|
||||
++list->size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
curl_llist_insert_prev(curl_llist *list, curl_llist_element *e, const void *p)
|
||||
{
|
||||
curl_llist_element *ne;
|
||||
|
||||
ne = (curl_llist_element *) malloc(sizeof(curl_llist_element));
|
||||
ne->ptr = (void *) p;
|
||||
if (list->size == 0) {
|
||||
list->head = ne;
|
||||
list->head->prev = NULL;
|
||||
list->head->next = NULL;
|
||||
list->tail = ne;
|
||||
} else {
|
||||
ne->next = e;
|
||||
ne->prev = e->prev;
|
||||
if (e->prev)
|
||||
e->prev->next = ne;
|
||||
else
|
||||
list->head = ne;
|
||||
e->prev = ne;
|
||||
}
|
||||
|
||||
++list->size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
curl_llist_remove(curl_llist *list, curl_llist_element *e, void *user)
|
||||
{
|
||||
if (e == NULL || list->size == 0)
|
||||
return 1;
|
||||
|
||||
if (e == list->head) {
|
||||
list->head = e->next;
|
||||
|
||||
if (list->head == NULL)
|
||||
list->tail = NULL;
|
||||
else
|
||||
e->next->prev = NULL;
|
||||
} else {
|
||||
e->prev->next = e->next;
|
||||
if (!e->next)
|
||||
list->tail = e->prev;
|
||||
else
|
||||
e->next->prev = e->prev;
|
||||
}
|
||||
|
||||
list->dtor(user, e->ptr);
|
||||
free(e);
|
||||
--list->size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
curl_llist_remove_next(curl_llist *list, curl_llist_element *e, void *user)
|
||||
{
|
||||
return curl_llist_remove(list, e->next, user);
|
||||
}
|
||||
|
||||
int
|
||||
curl_llist_remove_prev(curl_llist *list, curl_llist_element *e, void *user)
|
||||
{
|
||||
return curl_llist_remove(list, e->prev, user);
|
||||
}
|
||||
|
||||
size_t
|
||||
curl_llist_count(curl_llist *list)
|
||||
{
|
||||
return list->size;
|
||||
}
|
||||
|
||||
void
|
||||
curl_llist_destroy(curl_llist *list, void *user)
|
||||
{
|
||||
while (list->size > 0) {
|
||||
curl_llist_remove(list, CURL_LLIST_TAIL(list), user);
|
||||
}
|
||||
|
||||
free(list);
|
||||
list = NULL;
|
||||
}
|
64
lib/llist.h
Normal file
64
lib/llist.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef __LLIST_H
|
||||
#define __LLIST_H
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al
|
||||
*
|
||||
* In order to be useful for every potential user, curl and libcurl are
|
||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
||||
*
|
||||
* 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 MPL or the MIT/X-derivate
|
||||
* licenses. You may pick one of these licenses.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
#include <stddef.h>
|
||||
|
||||
typedef void (*curl_llist_dtor)(void *, void *);
|
||||
|
||||
typedef struct _curl_llist_element {
|
||||
void *ptr;
|
||||
|
||||
struct _curl_llist_element *prev;
|
||||
struct _curl_llist_element *next;
|
||||
} curl_llist_element;
|
||||
|
||||
typedef struct _curl_llist {
|
||||
curl_llist_element *head;
|
||||
curl_llist_element *tail;
|
||||
|
||||
curl_llist_dtor dtor;
|
||||
|
||||
size_t size;
|
||||
} curl_llist;
|
||||
|
||||
void curl_llist_init(curl_llist *, curl_llist_dtor);
|
||||
curl_llist *curl_llist_alloc(curl_llist_dtor);
|
||||
int curl_llist_insert_next(curl_llist *, curl_llist_element *, const void *);
|
||||
int curl_llist_insert_prev(curl_llist *, curl_llist_element *, const void *);
|
||||
int curl_llist_remove(curl_llist *, curl_llist_element *, void *);
|
||||
int curl_llist_remove_next(curl_llist *, curl_llist_element *, void *);
|
||||
size_t curl_llist_count(curl_llist *);
|
||||
void curl_llist_destroy(curl_llist *, void *);
|
||||
|
||||
#define CURL_LLIST_HEAD(__l) ((__l)->head)
|
||||
#define CURL_LLIST_TAIL(__l) ((__l)->tail)
|
||||
#define CURL_LLIST_NEXT(__e) ((__e)->next)
|
||||
#define CURL_LLIST_PREV(__e) ((__e)->prev)
|
||||
#define CURL_LLIST_VALP(__e) ((__e)->ptr)
|
||||
#define CURL_LLIST_IS_TAIL(__e) ((__e)->next ? 0 : 1)
|
||||
#define CURL_LLIST_IS_HEAD(__e) ((__e)->prev ? 0 : 1)
|
||||
|
||||
#endif
|
@@ -70,6 +70,9 @@ void curl_memdebug(const char *logname)
|
||||
void *curl_domalloc(size_t size, int line, const char *source)
|
||||
{
|
||||
void *mem=(malloc)(size);
|
||||
if(mem)
|
||||
/* fill memory with junk */
|
||||
memset(mem, 0xA5, size);
|
||||
if(logfile)
|
||||
fprintf(logfile, "MEM %s:%d malloc(%d) = %p\n",
|
||||
source, line, size, mem);
|
||||
|
@@ -1,6 +1,14 @@
|
||||
#ifdef MALLOCDEBUG
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
|
@@ -92,14 +92,7 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static const char rcsid[] = "@(#)$Id$";
|
||||
|
||||
/*
|
||||
* To test:
|
||||
*
|
||||
* Use WIDTH, PRECISION and NUMBERED ARGUMENT combined.
|
||||
*/
|
||||
|
||||
#include "setup.h"
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -909,14 +902,14 @@ static int dprintf_formatf(
|
||||
}
|
||||
else {
|
||||
/* Write "(nil)" for a nil pointer. */
|
||||
static char nil[] = "(nil)";
|
||||
static char strnil[] = "(nil)";
|
||||
register char *point;
|
||||
|
||||
width -= sizeof(nil) - 1;
|
||||
width -= sizeof(strnil) - 1;
|
||||
if (p->flags & FLAGS_LEFT)
|
||||
while (width-- > 0)
|
||||
OUTCHAR(' ');
|
||||
for (point = nil; *point != '\0'; ++point)
|
||||
for (point = strnil; *point != '\0'; ++point)
|
||||
OUTCHAR(*point);
|
||||
if (! (p->flags & FLAGS_LEFT))
|
||||
while (width-- > 0)
|
||||
|
361
lib/multi.c
Normal file
361
lib/multi.c
Normal file
@@ -0,0 +1,361 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* In order to be useful for every potential user, curl and libcurl are
|
||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
||||
*
|
||||
* 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 MPL or the MIT/X-derivate
|
||||
* licenses. You may pick one of these licenses.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "multi.h" /* will become <curl/multi.h> soon */
|
||||
|
||||
#include "urldata.h"
|
||||
#include "transfer.h"
|
||||
#include "url.h"
|
||||
|
||||
struct Curl_message {
|
||||
/* the 'CURLMsg' is the part that is visible to the external user */
|
||||
struct CURLMsg extmsg;
|
||||
struct Curl_message *next;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
CURLM_STATE_INIT,
|
||||
CURLM_STATE_CONNECT,
|
||||
CURLM_STATE_DO,
|
||||
CURLM_STATE_PERFORM,
|
||||
CURLM_STATE_DONE,
|
||||
CURLM_STATE_COMPLETED,
|
||||
|
||||
CURLM_STATE_LAST /* not a true state, never use this */
|
||||
} CURLMstate;
|
||||
|
||||
struct Curl_one_easy {
|
||||
/* first, two fields for the linked list of these */
|
||||
struct Curl_one_easy *next;
|
||||
struct Curl_one_easy *prev;
|
||||
|
||||
struct SessionHandle *easy_handle; /* the easy handle for this unit */
|
||||
struct connectdata *easy_conn; /* the "unit's" connection */
|
||||
|
||||
CURLMstate state; /* the handle's state */
|
||||
CURLcode result; /* previous result */
|
||||
};
|
||||
|
||||
|
||||
#define CURL_MULTI_HANDLE 0x000bab1e
|
||||
|
||||
#define GOOD_MULTI_HANDLE(x) ((x)&&(((struct Curl_multi *)x)->type == CURL_MULTI_HANDLE))
|
||||
#define GOOD_EASY_HANDLE(x) (x)
|
||||
|
||||
/* This is the struct known as CURLM on the outside */
|
||||
struct Curl_multi {
|
||||
/* First a simple identifier to easier detect if a user mix up
|
||||
this multi handle with an easy handle. Set this to CURL_MULTI_HANDLE. */
|
||||
long type;
|
||||
|
||||
/* We have a linked list with easy handles */
|
||||
struct Curl_one_easy easy;
|
||||
/* This is the amount of entries in the linked list above. */
|
||||
int num_easy;
|
||||
|
||||
/* this is a linked list of posted messages */
|
||||
struct Curl_message *msgs;
|
||||
/* amount of messages in the queue */
|
||||
int num_msgs;
|
||||
/* Hostname cache */
|
||||
curl_hash *hostcache;
|
||||
};
|
||||
|
||||
|
||||
CURLM *curl_multi_init(void)
|
||||
{
|
||||
struct Curl_multi *multi;
|
||||
|
||||
multi = (void *)malloc(sizeof(struct Curl_multi));
|
||||
|
||||
if(multi) {
|
||||
memset(multi, 0, sizeof(struct Curl_multi));
|
||||
multi->type = CURL_MULTI_HANDLE;
|
||||
}
|
||||
|
||||
return (CURLM *) multi;
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
CURL *easy_handle)
|
||||
{
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
struct Curl_one_easy *easy;
|
||||
|
||||
/* First, make some basic checks that the CURLM handle is a good handle */
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
return CURLM_BAD_HANDLE;
|
||||
|
||||
/* Verify that we got a somewhat good easy handle too */
|
||||
if(!GOOD_EASY_HANDLE(easy_handle))
|
||||
return CURLM_BAD_EASY_HANDLE;
|
||||
|
||||
/* Now, time to add an easy handle to the multi stack */
|
||||
easy = (struct Curl_one_easy *)malloc(sizeof(struct Curl_one_easy));
|
||||
if(!easy)
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
|
||||
/* clean it all first (just to be sure) */
|
||||
memset(easy, 0, sizeof(struct Curl_one_easy));
|
||||
|
||||
/* set the easy handle */
|
||||
easy->easy_handle = easy_handle;
|
||||
easy->state = CURLM_STATE_INIT;
|
||||
|
||||
/* We add this new entry first in the list. We make our 'next' point to the
|
||||
previous next and our 'prev' point back to the 'first' struct */
|
||||
easy->next = multi->easy.next;
|
||||
easy->prev = &multi->easy;
|
||||
|
||||
/* make 'easy' the first node in the chain */
|
||||
multi->easy.next = easy;
|
||||
|
||||
/* if there was a next node, make sure its 'prev' pointer links back to
|
||||
the new node */
|
||||
if(easy->next)
|
||||
easy->next->prev = easy;
|
||||
|
||||
/* increase the node-counter */
|
||||
multi->num_easy++;
|
||||
|
||||
return CURLM_CALL_MULTI_PERFORM;
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
||||
CURL *curl_handle)
|
||||
{
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
struct Curl_one_easy *easy;
|
||||
|
||||
/* First, make some basic checks that the CURLM handle is a good handle */
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
return CURLM_BAD_HANDLE;
|
||||
|
||||
/* Verify that we got a somewhat good easy handle too */
|
||||
if(!GOOD_EASY_HANDLE(curl_handle))
|
||||
return CURLM_BAD_EASY_HANDLE;
|
||||
|
||||
/* scan through the list and remove the 'curl_handle' */
|
||||
easy = multi->easy.next;
|
||||
while(easy) {
|
||||
if(easy->easy_handle == curl_handle)
|
||||
break;
|
||||
easy=easy->next;
|
||||
}
|
||||
if(easy) {
|
||||
/* If the 'state' is not INIT or COMPLETED, we might need to do something
|
||||
nice to put the easy_handle in a good known state when this returns. */
|
||||
|
||||
/* make the previous node point to our next */
|
||||
if(easy->prev)
|
||||
easy->prev->next = easy->next;
|
||||
/* make our next point to our previous node */
|
||||
if(easy->next)
|
||||
easy->next->prev = easy->prev;
|
||||
|
||||
/* NOTE NOTE NOTE
|
||||
We do not touch the easy handle here! */
|
||||
free(easy);
|
||||
|
||||
multi->num_easy--; /* one less to care about now */
|
||||
|
||||
return CURLM_OK;
|
||||
}
|
||||
else
|
||||
return CURLM_BAD_EASY_HANDLE; /* twasn't found */
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
||||
fd_set *read_fd_set, fd_set *write_fd_set,
|
||||
fd_set *exc_fd_set, int *max_fd)
|
||||
{
|
||||
/* Scan through all the easy handles to get the file descriptors set.
|
||||
Some easy handles may not have connected to the remote host yet,
|
||||
and then we must make sure that is done. */
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
struct Curl_one_easy *easy;
|
||||
int this_max_fd=-1;
|
||||
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
return CURLM_BAD_HANDLE;
|
||||
|
||||
*max_fd = -1; /* so far none! */
|
||||
|
||||
easy=multi->easy.next;
|
||||
while(easy) {
|
||||
switch(easy->state) {
|
||||
default:
|
||||
break;
|
||||
case CURLM_STATE_PERFORM:
|
||||
/* This should have a set of file descriptors for us to set. */
|
||||
/* after the transfer is done, go DONE */
|
||||
|
||||
Curl_single_fdset(easy->easy_conn,
|
||||
read_fd_set, write_fd_set,
|
||||
exc_fd_set, &this_max_fd);
|
||||
|
||||
/* remember the maximum file descriptor */
|
||||
if(this_max_fd > *max_fd)
|
||||
*max_fd = this_max_fd;
|
||||
|
||||
break;
|
||||
}
|
||||
easy = easy->next; /* check next handle */
|
||||
}
|
||||
|
||||
return CURLM_OK;
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
||||
{
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
struct Curl_one_easy *easy;
|
||||
bool done;
|
||||
CURLMcode result=CURLM_OK;
|
||||
|
||||
*running_handles = 0; /* bump this once for every living handle */
|
||||
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
return CURLM_BAD_HANDLE;
|
||||
|
||||
easy=multi->easy.next;
|
||||
while(easy) {
|
||||
switch(easy->state) {
|
||||
case CURLM_STATE_INIT:
|
||||
/* init this transfer. */
|
||||
easy->result=Curl_pretransfer(easy->easy_handle);
|
||||
if(CURLE_OK == easy->result) {
|
||||
/* after init, go CONNECT */
|
||||
easy->state = CURLM_STATE_CONNECT;
|
||||
result = CURLM_CALL_MULTI_PERFORM;
|
||||
}
|
||||
break;
|
||||
case CURLM_STATE_CONNECT:
|
||||
if (Curl_global_host_cache_use(easy->easy_handle)) {
|
||||
easy->easy_handle->hostcache = Curl_global_host_cache_get();
|
||||
}
|
||||
else {
|
||||
if (multi->hostcache == NULL) {
|
||||
multi->hostcache = curl_hash_alloc(7, Curl_freeaddrinfo);
|
||||
}
|
||||
|
||||
easy->easy_handle->hostcache = multi->hostcache;
|
||||
}
|
||||
|
||||
/* Connect. We get a connection identifier filled in. */
|
||||
easy->result = Curl_connect(easy->easy_handle, &easy->easy_conn);
|
||||
|
||||
/* after connect, go DO */
|
||||
if(CURLE_OK == easy->result) {
|
||||
easy->state = CURLM_STATE_DO;
|
||||
result = CURLM_CALL_MULTI_PERFORM;
|
||||
}
|
||||
break;
|
||||
case CURLM_STATE_DO:
|
||||
/* Do the fetch or put request */
|
||||
easy->result = Curl_do(&easy->easy_conn);
|
||||
/* after do, go PERFORM */
|
||||
if(CURLE_OK == easy->result) {
|
||||
if(CURLE_OK == Curl_readwrite_init(easy->easy_conn)) {
|
||||
easy->state = CURLM_STATE_PERFORM;
|
||||
result = CURLM_CALL_MULTI_PERFORM;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CURLM_STATE_PERFORM:
|
||||
/* read/write data if it is ready to do so */
|
||||
easy->result = Curl_readwrite(easy->easy_conn, &done);
|
||||
/* hm, when we follow redirects, we may need to go back to the CONNECT
|
||||
state */
|
||||
/* after the transfer is done, go DONE */
|
||||
if(TRUE == done) {
|
||||
/* call this even if the readwrite function returned error */
|
||||
easy->result = Curl_posttransfer(easy->easy_handle);
|
||||
easy->state = CURLM_STATE_DONE;
|
||||
result = CURLM_CALL_MULTI_PERFORM;
|
||||
}
|
||||
break;
|
||||
case CURLM_STATE_DONE:
|
||||
/* post-transfer command */
|
||||
easy->result = Curl_done(easy->easy_conn);
|
||||
/* after we have DONE what we're supposed to do, go COMPLETED */
|
||||
if(CURLE_OK == easy->result)
|
||||
easy->state = CURLM_STATE_COMPLETED;
|
||||
break;
|
||||
case CURLM_STATE_COMPLETED:
|
||||
/* this is a completed transfer, it is likely to still be connected */
|
||||
|
||||
/* This node should be delinked from the list now and we should post
|
||||
an information message that we are complete. */
|
||||
break;
|
||||
default:
|
||||
return CURLM_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if((CURLM_STATE_COMPLETED != easy->state) &&
|
||||
(CURLE_OK != easy->result)) {
|
||||
/*
|
||||
* If an error was returned, and we aren't in completed now,
|
||||
* then we go to completed and consider this transfer aborted.
|
||||
*/
|
||||
easy->state = CURLM_STATE_COMPLETED;
|
||||
}
|
||||
else if(CURLM_STATE_COMPLETED != easy->state)
|
||||
/* this one still lives! */
|
||||
(*running_handles)++;
|
||||
|
||||
easy = easy->next; /* operate on next handle */
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
||||
{
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
if(GOOD_MULTI_HANDLE(multi)) {
|
||||
multi->type = 0; /* not good anymore */
|
||||
curl_hash_destroy(multi->hostcache);
|
||||
/* remove all easy handles */
|
||||
|
||||
free(multi);
|
||||
|
||||
return CURLM_OK;
|
||||
}
|
||||
else
|
||||
return CURLM_BAD_HANDLE;
|
||||
}
|
||||
|
||||
CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue);
|
||||
|
||||
/*
|
||||
* local variables:
|
||||
* eval: (load-file "../curl-mode.el")
|
||||
* end:
|
||||
* vim600: fdm=marker
|
||||
* vim: et sw=2 ts=2 sts=2 tw=78
|
||||
*/
|
185
lib/multi.h
Normal file
185
lib/multi.h
Normal file
@@ -0,0 +1,185 @@
|
||||
#ifndef __CURL_MULTI_H
|
||||
#define __CURL_MULTI_H
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* In order to be useful for every potential user, curl and libcurl are
|
||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
||||
*
|
||||
* 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 MPL or the MIT/X-derivate
|
||||
* licenses. You may pick one of these licenses.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
/*
|
||||
This is meant to be the "external" header file. Don't give away any
|
||||
internals here!
|
||||
|
||||
This document presents a mixture of ideas from at least:
|
||||
- Daniel Stenberg
|
||||
- Steve Dekorte
|
||||
- Sterling Hughes
|
||||
- Ben Greear
|
||||
|
||||
-------------------------------------------
|
||||
GOALS
|
||||
|
||||
o Enable a "pull" interface. The application that uses libcurl decides where
|
||||
and when to ask libcurl to get/send data.
|
||||
|
||||
o Enable multiple simultaneous transfers in the same thread without making it
|
||||
complicated for the application.
|
||||
|
||||
o Enable the application to select() on its own file descriptors and curl's
|
||||
file descriptors simultaneous easily.
|
||||
|
||||
Example source using this interface: http://curl.haxx.se/dev/multi-app.c
|
||||
|
||||
*/
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#include <curl/curl.h>
|
||||
|
||||
typedef void CURLM;
|
||||
|
||||
typedef enum {
|
||||
CURLM_CALL_MULTI_PERFORM=-1, /* please call curl_multi_perform() soon */
|
||||
CURLM_OK,
|
||||
CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */
|
||||
CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
|
||||
CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
|
||||
CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
|
||||
CURLM_LAST
|
||||
} CURLMcode;
|
||||
|
||||
typedef enum {
|
||||
CURLMSG_NONE, /* first, not used */
|
||||
CURLMSG_DONE, /* This easy handle has completed. 'whatever' points to
|
||||
the CURLcode of the transfer */
|
||||
CURLMSG_LAST /* last, not used */
|
||||
} CURLMSG;
|
||||
|
||||
struct CURLMsg {
|
||||
CURLMSG msg; /* what this message means */
|
||||
CURL *easy_handle; /* the handle it concerns */
|
||||
union {
|
||||
void *whatever; /* message-specific data */
|
||||
CURLcode result; /* return code for transfer */
|
||||
} data;
|
||||
};
|
||||
typedef struct CURLMsg CURLMsg;
|
||||
|
||||
/*
|
||||
* Name: curl_multi_init()
|
||||
*
|
||||
* Desc: inititalize multi-style curl usage
|
||||
* Returns: a new CURLM handle to use in all 'curl_multi' functions.
|
||||
*/
|
||||
CURLM *curl_multi_init(void);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_add_handle()
|
||||
*
|
||||
* Desc: add a standard curl handle to the multi stack
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
CURL *curl_handle);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_remove_handle()
|
||||
*
|
||||
* Desc: removes a curl handle from the multi stack again
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
||||
CURL *curl_handle);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_fdset()
|
||||
*
|
||||
* Desc: Ask curl for its fd_set sets. The app can use these to select() or
|
||||
* poll() on. We want curl_multi_perform() called as soon as one of
|
||||
* them are ready.
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
||||
fd_set *read_fd_set,
|
||||
fd_set *write_fd_set,
|
||||
fd_set *exc_fd_set,
|
||||
int *max_fd);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_perform()
|
||||
*
|
||||
* Desc: When the app thinks there's data available for curl it calls this
|
||||
* function to read/write whatever there is right now. This returns
|
||||
* as soon as the reads and writes are done. This function does not
|
||||
* require that there actually is data available for reading or that
|
||||
* data can be written, it can be called just in case. It returns
|
||||
* the number of handles that still transfer data in the second
|
||||
* argument's integer-pointer.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code. *NOTE* that this only
|
||||
* returns errors etc regarding the whole multi stack. There might
|
||||
* still have occurred problems on invidual transfers even when this
|
||||
* returns OK.
|
||||
*/
|
||||
CURLMcode curl_multi_perform(CURLM *multi_handle,
|
||||
int *running_handles);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_cleanup()
|
||||
*
|
||||
* Desc: Cleans up and removes a whole multi stack. It does not free or
|
||||
* touch any individual easy handles in any way. We need to define
|
||||
* in what state those handles will be if this function is called
|
||||
* in the middle of a transfer.
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURLMcode curl_multi_cleanup(CURLM *multi_handle);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_info_read()
|
||||
*
|
||||
* Desc: Ask the multi handle if there's any messages/informationals from
|
||||
* the individual transfers. Messages include informationals such as
|
||||
* error code from the transfer or just the fact that a transfer is
|
||||
* completed. More details on these should be written down as well.
|
||||
*
|
||||
* Repeated calls to this function will return a new struct each
|
||||
* time, until a special "end of msgs" struct is returned as a signal
|
||||
* that there is no more to get at this point.
|
||||
*
|
||||
* The data the returned pointer points to will not survive calling
|
||||
* curl_multi_cleanup().
|
||||
*
|
||||
* The 'CURLMsg' struct is meant to be very simple and only contain
|
||||
* very basic informations. If more involved information is wanted,
|
||||
* we will provide the particular "transfer handle" in that struct
|
||||
* and that should/could/would be used in subsequent
|
||||
* curl_easy_getinfo() calls (or similar). The point being that we
|
||||
* must never expose complex structs to applications, as then we'll
|
||||
* undoubtably get backwards compatibility problems in the future.
|
||||
*
|
||||
* Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
|
||||
* of structs. It also writes the number of messages left in the
|
||||
* queue (after this read) in the integer the second argument points
|
||||
* to.
|
||||
*/
|
||||
CURLMsg *curl_multi_info_read(CURLM *multi_handle,
|
||||
int *msgs_in_queue);
|
||||
|
||||
#endif
|
@@ -111,23 +111,25 @@ void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
|
||||
/* mistake filter */
|
||||
break;
|
||||
case TIMER_STARTSINGLE:
|
||||
/* This is set at the start of a single fetch, there may be several
|
||||
fetches within an operation, why we add all other times relative
|
||||
to this one */
|
||||
/* This is set at the start of a single fetch */
|
||||
data->progress.t_startsingle = Curl_tvnow();
|
||||
break;
|
||||
|
||||
case TIMER_NAMELOOKUP:
|
||||
data->progress.t_nslookup +=
|
||||
(double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000;
|
||||
data->progress.t_nslookup =
|
||||
(double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000.0;
|
||||
break;
|
||||
case TIMER_CONNECT:
|
||||
data->progress.t_connect +=
|
||||
(double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000;
|
||||
data->progress.t_connect =
|
||||
(double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000.0;
|
||||
break;
|
||||
case TIMER_PRETRANSFER:
|
||||
data->progress.t_pretransfer +=
|
||||
(double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000;
|
||||
data->progress.t_pretransfer =
|
||||
(double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000.0;
|
||||
break;
|
||||
case TIMER_STARTTRANSFER:
|
||||
data->progress.t_starttransfer =
|
||||
(double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000.0;
|
||||
break;
|
||||
case TIMER_POSTRANSFER:
|
||||
/* this is the normal end-of-transfer thing */
|
||||
@@ -227,7 +229,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
|
||||
/* The exact time spent so far (from the start) */
|
||||
timespent = (double)Curl_tvdiff (now, data->progress.start)/1000;
|
||||
|
||||
data->progress.timespent = (long)timespent;
|
||||
data->progress.timespent = timespent;
|
||||
|
||||
/* The average download speed this far */
|
||||
data->progress.dlspeed =
|
||||
@@ -275,6 +277,8 @@ int Curl_pgrsUpdate(struct connectdata *conn)
|
||||
/* Figure out the exact time for the time span */
|
||||
span_ms = Curl_tvdiff(now,
|
||||
data->progress.speeder_time[checkindex]);
|
||||
if(0 == span_ms)
|
||||
span_ms=1; /* at least one millisecond MUST have passed */
|
||||
|
||||
/* Calculate the average speed the last 'countindex' seconds */
|
||||
data->progress.current_speed =
|
||||
|
@@ -31,6 +31,7 @@ typedef enum {
|
||||
TIMER_NAMELOOKUP,
|
||||
TIMER_CONNECT,
|
||||
TIMER_PRETRANSFER,
|
||||
TIMER_STARTTRANSFER,
|
||||
TIMER_POSTRANSFER,
|
||||
TIMER_STARTSINGLE,
|
||||
TIMER_LAST /* must be last */
|
||||
|
@@ -362,11 +362,11 @@ Curl_sec_vfprintf(struct connectdata *conn, FILE *f, const char *fmt, va_list ap
|
||||
conn);
|
||||
free(buf);
|
||||
if(len < 0) {
|
||||
failf(conn->data, "Failed to encode command.\n");
|
||||
failf(conn->data, "Failed to encode command.");
|
||||
return -1;
|
||||
}
|
||||
if(Curl_base64_encode(enc, len, &buf) < 0){
|
||||
failf(conn->data, "Out of memory base64-encoding.\n");
|
||||
failf(conn->data, "Out of memory base64-encoding.");
|
||||
return -1;
|
||||
}
|
||||
if(conn->command_prot == prot_safe)
|
||||
@@ -421,7 +421,7 @@ sec_prot_internal(struct connectdata *conn, int level)
|
||||
return -1;
|
||||
|
||||
if(conn->data->state.buffer[0] != '2'){
|
||||
failf(conn->data, "Failed to set protection buffer size.\n");
|
||||
failf(conn->data, "Failed to set protection buffer size.");
|
||||
return -1;
|
||||
}
|
||||
conn->buffer_size = s;
|
||||
@@ -441,7 +441,7 @@ sec_prot_internal(struct connectdata *conn, int level)
|
||||
return -1;
|
||||
|
||||
if(conn->data->state.buffer[0] != '2'){
|
||||
failf(conn->data, "Failed to set protection level.\n");
|
||||
failf(conn->data, "Failed to set protection level.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
104
lib/sendf.c
104
lib/sendf.c
@@ -26,6 +26,13 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h> /* required for send() & recv() prototypes */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
@@ -133,8 +140,9 @@ void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
|
||||
}
|
||||
}
|
||||
|
||||
/* Curl_failf() is for messages stating why we failed, the LAST one will be
|
||||
returned for the user (if requested) */
|
||||
/* Curl_failf() is for messages stating why we failed.
|
||||
* The message SHALL NOT include any LF or CR.
|
||||
*/
|
||||
|
||||
void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
|
||||
{
|
||||
@@ -152,7 +160,7 @@ CURLcode Curl_sendf(int sockfd, struct connectdata *conn,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
size_t bytes_written;
|
||||
ssize_t bytes_written;
|
||||
CURLcode result;
|
||||
char *s;
|
||||
va_list ap;
|
||||
@@ -179,25 +187,30 @@ CURLcode Curl_sendf(int sockfd, struct connectdata *conn,
|
||||
*/
|
||||
CURLcode Curl_write(struct connectdata *conn, int sockfd,
|
||||
void *mem, size_t len,
|
||||
size_t *written)
|
||||
ssize_t *written)
|
||||
{
|
||||
size_t bytes_written;
|
||||
ssize_t bytes_written;
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
/* SSL_write() is said to return 'int' while write() and send() returns
|
||||
'size_t' */
|
||||
int ssl_bytes;
|
||||
if (conn->ssl.use) {
|
||||
int loop=100; /* just a precaution to never loop endlessly */
|
||||
while(loop--) {
|
||||
ssl_bytes = SSL_write(conn->ssl.handle, mem, len);
|
||||
if((0 >= ssl_bytes) ||
|
||||
(SSL_ERROR_WANT_WRITE != SSL_get_error(conn->ssl.handle,
|
||||
ssl_bytes) )) {
|
||||
/* this converts from signed to unsigned... */
|
||||
bytes_written = ssl_bytes;
|
||||
break;
|
||||
int err;
|
||||
int rc = SSL_write(conn->ssl.handle, mem, len);
|
||||
|
||||
if(rc < 0) {
|
||||
err = SSL_get_error(conn->ssl.handle, rc);
|
||||
|
||||
switch(err) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
/* this is basicly the EWOULDBLOCK equivalent */
|
||||
*written = 0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
/* a true error */
|
||||
failf(conn->data, "SSL_write() return error %d\n", err);
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -208,13 +221,27 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
|
||||
}
|
||||
else
|
||||
#endif /* KRB4 */
|
||||
{
|
||||
bytes_written = swrite(sockfd, mem, len);
|
||||
}
|
||||
if(-1 == bytes_written) {
|
||||
#ifdef WIN32
|
||||
if(EWOULDBLOCK == GetLastError())
|
||||
#else
|
||||
if(EWOULDBLOCK == errno)
|
||||
#endif
|
||||
{
|
||||
/* this is just a case of EWOULDBLOCK */
|
||||
*written=0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
}
|
||||
#ifdef USE_SSLEAY
|
||||
}
|
||||
#endif
|
||||
|
||||
*written = bytes_written;
|
||||
return (bytes_written==len)?CURLE_OK:CURLE_WRITE_ERROR;
|
||||
return (-1 != bytes_written)?CURLE_OK:CURLE_WRITE_ERROR;
|
||||
}
|
||||
|
||||
/* client_write() sends data to the write callback(s)
|
||||
@@ -258,26 +285,47 @@ CURLcode Curl_client_write(struct SessionHandle *data,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Internal read-from-socket function. This is meant to deal with plain
|
||||
* sockets, SSL sockets and kerberos sockets.
|
||||
*
|
||||
* If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
|
||||
* a regular CURLcode value.
|
||||
*/
|
||||
CURLcode Curl_read(struct connectdata *conn, int sockfd,
|
||||
char *buf, size_t buffersize,
|
||||
int Curl_read(struct connectdata *conn,
|
||||
int sockfd,
|
||||
char *buf,
|
||||
size_t buffersize,
|
||||
ssize_t *n)
|
||||
{
|
||||
ssize_t nread;
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
if (conn->ssl.use) {
|
||||
int loop=100; /* just a precaution to never loop endlessly */
|
||||
while(loop--) {
|
||||
bool loop=TRUE;
|
||||
int err;
|
||||
do {
|
||||
nread = SSL_read(conn->ssl.handle, buf, buffersize);
|
||||
if((-1 != nread) ||
|
||||
(SSL_ERROR_WANT_READ != SSL_get_error(conn->ssl.handle, nread) ))
|
||||
|
||||
if(nread > 0)
|
||||
/* successful read */
|
||||
break;
|
||||
|
||||
err = SSL_get_error(conn->ssl.handle, nread);
|
||||
|
||||
switch(err) {
|
||||
case SSL_ERROR_NONE: /* this is not an error */
|
||||
case SSL_ERROR_ZERO_RETURN: /* no more data */
|
||||
loop=0; /* get out of loop */
|
||||
break;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
/* if there's data pending, then we re-invoke SSL_read() */
|
||||
break;
|
||||
}
|
||||
} while(0);
|
||||
if(loop && SSL_pending(conn->ssl.handle))
|
||||
return -1; /* basicly EWOULDBLOCK */
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
@@ -287,6 +335,16 @@ CURLcode Curl_read(struct connectdata *conn, int sockfd,
|
||||
else
|
||||
#endif
|
||||
nread = sread (sockfd, buf, buffersize);
|
||||
|
||||
if(-1 == nread) {
|
||||
#ifdef WIN32
|
||||
if(EWOULDBLOCK == GetLastError())
|
||||
#else
|
||||
if(EWOULDBLOCK == errno)
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
}
|
||||
#endif /* USE_SSLEAY */
|
||||
|
@@ -45,12 +45,12 @@ CURLcode Curl_client_write(struct SessionHandle *data, int type, char *ptr,
|
||||
size_t len);
|
||||
|
||||
/* internal read-function, does plain socket, SSL and krb4 */
|
||||
CURLcode Curl_read(struct connectdata *conn, int sockfd,
|
||||
int Curl_read(struct connectdata *conn, int sockfd,
|
||||
char *buf, size_t buffersize,
|
||||
ssize_t *n);
|
||||
/* internal write-function, does plain socket, SSL and krb4 */
|
||||
CURLcode Curl_write(struct connectdata *conn, int sockfd,
|
||||
void *mem, size_t len,
|
||||
size_t *written);
|
||||
ssize_t *written);
|
||||
|
||||
#endif
|
||||
|
20
lib/setup.h
20
lib/setup.h
@@ -34,20 +34,26 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
||||
#ifdef VMS
|
||||
#include "config-vms.h"
|
||||
#include "../config-vms.h"
|
||||
#else
|
||||
#include "config.h" /* the configure script results */
|
||||
#include "../config.h" /* the configure script results */
|
||||
#endif
|
||||
|
||||
#else
|
||||
#ifdef WIN32
|
||||
/* include the hand-modified win32 adjusted config.h! */
|
||||
/* hand-modified win32 config.h! */
|
||||
#include "../config-win32.h"
|
||||
#endif
|
||||
#ifdef macintosh
|
||||
/* hand-modified MacOS config.h! */
|
||||
#include "../config-mac.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus /* (rabe) */
|
||||
typedef char bool;
|
||||
typedef unsigned char bool;
|
||||
#define typedef_bool
|
||||
#endif /* (rabe) */
|
||||
|
||||
#ifdef NEED_REENTRANT
|
||||
@@ -110,13 +116,13 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
|
||||
#define sclose(x) closesocket(x)
|
||||
#define sread(x,y,z) recv(x,y,z,0)
|
||||
#define swrite(x,y,z) (size_t)send(x,y,z,0)
|
||||
#define myalarm(x) /* win32 is a silly system */
|
||||
#undef HAVE_ALARM
|
||||
#else
|
||||
/* gcc-for-win is still good :) */
|
||||
#define sclose(x) close(x)
|
||||
#define sread(x,y,z) recv(x,y,z,0)
|
||||
#define swrite(x,y,z) send(x,y,z,0)
|
||||
#define myalarm(x) alarm(x)
|
||||
#define HAVE_ALARM
|
||||
#endif
|
||||
|
||||
#define PATH_CHAR ";"
|
||||
@@ -127,7 +133,7 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
|
||||
#define sclose(x) close(x)
|
||||
#define sread(x,y,z) recv(x,y,z,0)
|
||||
#define swrite(x,y,z) send(x,y,z,0)
|
||||
#define myalarm(x) alarm(x)
|
||||
#define HAVE_ALARM
|
||||
|
||||
#define PATH_CHAR ":"
|
||||
#define DIR_CHAR "/"
|
||||
|
234
lib/ssluse.c
234
lib/ssluse.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* In order to be useful for every potential user, curl and libcurl are
|
||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
||||
@@ -22,11 +22,12 @@
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* The original SSL code was written by
|
||||
* The original SSL code for curl was written by
|
||||
* Linas Vepstas <linas@linas.org> and Sampo Kellomaki <sampo@iki.fi>
|
||||
*/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -171,37 +172,59 @@ int random_the_seed(struct connectdata *conn)
|
||||
return nread;
|
||||
}
|
||||
|
||||
#ifndef SSL_FILETYPE_ENGINE
|
||||
#define SSL_FILETYPE_ENGINE 42
|
||||
#endif
|
||||
static int do_file_type(const char *type)
|
||||
{
|
||||
if (!type || !type[0])
|
||||
return SSL_FILETYPE_PEM;
|
||||
if (curl_strequal(type, "PEM"))
|
||||
return SSL_FILETYPE_PEM;
|
||||
if (curl_strequal(type, "DER"))
|
||||
return SSL_FILETYPE_ASN1;
|
||||
if (curl_strequal(type, "ENG"))
|
||||
return SSL_FILETYPE_ENGINE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static
|
||||
int cert_stuff(struct connectdata *conn,
|
||||
char *cert_file,
|
||||
char *key_file)
|
||||
const char *cert_type,
|
||||
char *key_file,
|
||||
const char *key_type)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
int file_type;
|
||||
|
||||
if (cert_file != NULL) {
|
||||
SSL *ssl;
|
||||
X509 *x509;
|
||||
|
||||
if(data->set.cert_passwd) {
|
||||
if(data->set.key_passwd) {
|
||||
#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
|
||||
/*
|
||||
* If password has been given, we store that in the global
|
||||
* area (*shudder*) for a while:
|
||||
*/
|
||||
strcpy(global_passwd, data->set.cert_passwd);
|
||||
strcpy(global_passwd, data->set.key_passwd);
|
||||
#else
|
||||
/*
|
||||
* We set the password in the callback userdata
|
||||
*/
|
||||
SSL_CTX_set_default_passwd_cb_userdata(conn->ssl.ctx, data->set.cert_passwd);
|
||||
SSL_CTX_set_default_passwd_cb_userdata(conn->ssl.ctx,
|
||||
data->set.key_passwd);
|
||||
#endif
|
||||
/* Set passwd callback: */
|
||||
SSL_CTX_set_default_passwd_cb(conn->ssl.ctx, passwd_callback);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (SSL_CTX_use_certificate_file(conn->ssl.ctx,
|
||||
cert_file,
|
||||
SSL_FILETYPE_PEM) != 1) {
|
||||
failf(data, "unable to set certificate file (wrong password?)\n");
|
||||
failf(data, "unable to set certificate file (wrong password?)");
|
||||
return(0);
|
||||
}
|
||||
if (key_file == NULL)
|
||||
@@ -210,9 +233,86 @@ int cert_stuff(struct connectdata *conn,
|
||||
if (SSL_CTX_use_PrivateKey_file(conn->ssl.ctx,
|
||||
key_file,
|
||||
SSL_FILETYPE_PEM) != 1) {
|
||||
failf(data, "unable to set public key file\n");
|
||||
failf(data, "unable to set public key file");
|
||||
return(0);
|
||||
}
|
||||
#else
|
||||
/* The '#ifdef 0' section above was removed on 17-dec-2001 */
|
||||
|
||||
file_type = do_file_type(cert_type);
|
||||
|
||||
switch(file_type) {
|
||||
case SSL_FILETYPE_PEM:
|
||||
case SSL_FILETYPE_ASN1:
|
||||
if (SSL_CTX_use_certificate_file(conn->ssl.ctx,
|
||||
cert_file,
|
||||
file_type) != 1) {
|
||||
failf(data, "unable to set certificate file (wrong password?)");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case SSL_FILETYPE_ENGINE:
|
||||
failf(data, "file type ENG for certificate not implemented");
|
||||
return 0;
|
||||
|
||||
default:
|
||||
failf(data, "not supported file type '%s' for certificate", cert_type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
file_type = do_file_type(key_type);
|
||||
|
||||
switch(file_type) {
|
||||
case SSL_FILETYPE_PEM:
|
||||
if (key_file == NULL)
|
||||
/* cert & key can only be in PEM case in the same file */
|
||||
key_file=cert_file;
|
||||
case SSL_FILETYPE_ASN1:
|
||||
if (SSL_CTX_use_PrivateKey_file(conn->ssl.ctx,
|
||||
key_file,
|
||||
file_type) != 1) {
|
||||
failf(data, "unable to set private key file\n");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case SSL_FILETYPE_ENGINE:
|
||||
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||
{ /* XXXX still needs some work */
|
||||
EVP_PKEY *priv_key = NULL;
|
||||
if (conn && conn->data && conn->data->engine) {
|
||||
if (!key_file || !key_file[0]) {
|
||||
failf(data, "no key set to load from crypto engine\n");
|
||||
return 0;
|
||||
}
|
||||
priv_key = ENGINE_load_private_key(conn->data->engine,key_file,
|
||||
data->set.key_passwd);
|
||||
if (!priv_key) {
|
||||
failf(data, "failed to load private key from crypto engine\n");
|
||||
return 0;
|
||||
}
|
||||
if (SSL_CTX_use_PrivateKey(conn->ssl.ctx, priv_key) != 1) {
|
||||
failf(data, "unable to set private key\n");
|
||||
EVP_PKEY_free(priv_key);
|
||||
return 0;
|
||||
}
|
||||
EVP_PKEY_free(priv_key); /* we don't need the handle any more... */
|
||||
}
|
||||
else {
|
||||
failf(data, "crypto engine not set, can't load private key\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
failf(data, "file type ENG for private key not supported\n");
|
||||
return 0;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
failf(data, "not supported file type for private key\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ssl=SSL_new(conn->ssl.ctx);
|
||||
x509=SSL_get_certificate(ssl);
|
||||
@@ -229,7 +329,7 @@ int cert_stuff(struct connectdata *conn,
|
||||
/* Now we know that a key and cert have been set against
|
||||
* the SSL context */
|
||||
if (!SSL_CTX_check_private_key(conn->ssl.ctx)) {
|
||||
failf(data, "Private key does not match the certificate public key\n");
|
||||
failf(data, "Private key does not match the certificate public key");
|
||||
return(0);
|
||||
}
|
||||
#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
|
||||
@@ -269,6 +369,10 @@ void Curl_SSL_init(void)
|
||||
|
||||
init_ssl++; /* never again */
|
||||
|
||||
#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES
|
||||
ENGINE_load_builtin_engines();
|
||||
#endif
|
||||
|
||||
/* Lets get nice error messages */
|
||||
SSL_load_error_strings();
|
||||
|
||||
@@ -292,6 +396,12 @@ void Curl_SSL_cleanup(void)
|
||||
/* EVP_cleanup() removes all ciphers and digests from the
|
||||
table. */
|
||||
EVP_cleanup();
|
||||
|
||||
#ifdef HAVE_ENGINE_cleanup
|
||||
ENGINE_cleanup();
|
||||
#endif
|
||||
|
||||
init_ssl=0; /* not inited any more */
|
||||
}
|
||||
#else
|
||||
/* SSL disabled, do nothing */
|
||||
@@ -426,6 +536,13 @@ int Curl_SSL_Close_All(struct SessionHandle *data)
|
||||
/* free the cache data */
|
||||
free(data->state.session);
|
||||
}
|
||||
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||
if (data->engine)
|
||||
{
|
||||
ENGINE_free(data->engine);
|
||||
data->engine = NULL;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -435,9 +552,9 @@ int Curl_SSL_Close_All(struct SessionHandle *data)
|
||||
static int Store_SSL_Session(struct connectdata *conn)
|
||||
{
|
||||
SSL_SESSION *ssl_sessionid;
|
||||
struct curl_ssl_session *store;
|
||||
int i;
|
||||
struct SessionHandle *data=conn->data; /* the mother of all structs */
|
||||
struct curl_ssl_session *store = &data->state.session[0];
|
||||
int oldest_age=data->state.session[0].age; /* zero if unused */
|
||||
|
||||
/* ask OpenSSL, say please */
|
||||
@@ -451,7 +568,8 @@ static int Store_SSL_Session(struct connectdata *conn)
|
||||
the oldest if necessary) */
|
||||
|
||||
/* find an empty slot for us, or find the oldest */
|
||||
for(i=0; (i<data->set.ssl.numsessions) && data->state.session[i].sessionid; i++) {
|
||||
for(i=1; (i<data->set.ssl.numsessions) &&
|
||||
data->state.session[i].sessionid; i++) {
|
||||
if(data->state.session[i].age < oldest_age) {
|
||||
oldest_age = data->state.session[i].age;
|
||||
store = &data->state.session[i];
|
||||
@@ -541,14 +659,20 @@ Curl_SSLConnect(struct connectdata *conn)
|
||||
/* Make funny stuff to get random input */
|
||||
random_the_seed(conn);
|
||||
|
||||
/* check to see if we've been told to use an explicit SSL/TLS version */
|
||||
switch(data->set.ssl.version) {
|
||||
default:
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
/* we try to figure out version */
|
||||
req_method = SSLv23_client_method();
|
||||
break;
|
||||
case 2:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
req_method = TLSv1_client_method();
|
||||
break;
|
||||
case CURL_SSLVERSION_SSLv2:
|
||||
req_method = SSLv2_client_method();
|
||||
break;
|
||||
case 3:
|
||||
case CURL_SSLVERSION_SSLv3:
|
||||
req_method = SSLv3_client_method();
|
||||
break;
|
||||
}
|
||||
@@ -561,7 +685,11 @@ Curl_SSLConnect(struct connectdata *conn)
|
||||
}
|
||||
|
||||
if(data->set.cert) {
|
||||
if (!cert_stuff(conn, data->set.cert, data->set.cert)) {
|
||||
if (!cert_stuff(conn,
|
||||
data->set.cert,
|
||||
data->set.cert_type,
|
||||
data->set.key,
|
||||
data->set.key_type)) {
|
||||
/* failf() is already done in cert_stuff() */
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
@@ -570,7 +698,7 @@ Curl_SSLConnect(struct connectdata *conn)
|
||||
if(data->set.ssl.cipher_list) {
|
||||
if (!SSL_CTX_set_cipher_list(conn->ssl.ctx,
|
||||
data->set.ssl.cipher_list)) {
|
||||
failf(data, "failed setting cipher list\n");
|
||||
failf(data, "failed setting cipher list");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -583,7 +711,7 @@ Curl_SSLConnect(struct connectdata *conn)
|
||||
if (!SSL_CTX_load_verify_locations(conn->ssl.ctx,
|
||||
data->set.ssl.CAfile,
|
||||
data->set.ssl.CApath)) {
|
||||
failf(data,"error setting cerficate verify locations\n");
|
||||
failf(data,"error setting cerficate verify locations");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -610,8 +738,80 @@ Curl_SSLConnect(struct connectdata *conn)
|
||||
|
||||
/* pass the raw socket into the SSL layers */
|
||||
SSL_set_fd(conn->ssl.handle, conn->firstsocket);
|
||||
|
||||
do {
|
||||
int what;
|
||||
fd_set writefd;
|
||||
fd_set readfd;
|
||||
struct timeval interval;
|
||||
long timeout_ms;
|
||||
|
||||
err = SSL_connect(conn->ssl.handle);
|
||||
|
||||
what = SSL_get_error(conn->ssl.handle, err);
|
||||
|
||||
FD_ZERO(&writefd);
|
||||
FD_ZERO(&readfd);
|
||||
|
||||
if(SSL_ERROR_WANT_READ == what)
|
||||
FD_SET(conn->firstsocket, &readfd);
|
||||
else if(SSL_ERROR_WANT_WRITE == what)
|
||||
FD_SET(conn->firstsocket, &writefd);
|
||||
else
|
||||
break; /* untreated error */
|
||||
|
||||
/* Find out if any timeout is set. If not, use 300 seconds.
|
||||
Otherwise, figure out the most strict timeout of the two possible one
|
||||
and then how much time that has elapsed to know how much time we
|
||||
allow for the connect call */
|
||||
if(data->set.timeout || data->set.connecttimeout) {
|
||||
double has_passed;
|
||||
|
||||
/* 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))
|
||||
timeout_ms = data->set.timeout*1000;
|
||||
else
|
||||
timeout_ms = data->set.connecttimeout*1000;
|
||||
|
||||
/* subtract the passed time */
|
||||
timeout_ms -= (long)has_passed;
|
||||
|
||||
if(timeout_ms < 0) {
|
||||
/* a precaution, no need to continue if time already is up */
|
||||
failf(data, "SSL connection timeout");
|
||||
return CURLE_OPERATION_TIMEOUTED;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* no particular time-out has been set */
|
||||
timeout_ms=300000; /* milliseconds, default to five minutes */
|
||||
|
||||
interval.tv_sec = timeout_ms/1000;
|
||||
timeout_ms -= interval.tv_sec*1000;
|
||||
|
||||
interval.tv_usec = timeout_ms*1000;
|
||||
|
||||
what = select(conn->firstsocket+1, &readfd, &writefd, NULL, &interval);
|
||||
if(what > 0)
|
||||
/* reabable or writable, go loop yourself */
|
||||
continue;
|
||||
else if(0 == what) {
|
||||
/* timeout */
|
||||
failf(data, "SSL connection timeout");
|
||||
return CURLE_OPERATION_TIMEOUTED;
|
||||
}
|
||||
else
|
||||
break; /* get out of loop */
|
||||
} while(1);
|
||||
|
||||
/* 1 is fine
|
||||
0 is "not successful but was shut down controlled"
|
||||
<0 is "handshake was not successful, because a fatal error occurred" */
|
||||
@@ -705,7 +905,7 @@ Curl_SSLConnect(struct connectdata *conn)
|
||||
if(data->set.ssl.verifypeer) {
|
||||
data->set.ssl.certverifyresult=SSL_get_verify_result(conn->ssl.handle);
|
||||
if (data->set.ssl.certverifyresult != X509_V_OK) {
|
||||
failf(data, "SSL certificate verify result: %d\n",
|
||||
failf(data, "SSL certificate verify result: %d",
|
||||
data->set.ssl.certverifyresult);
|
||||
retcode = CURLE_SSL_PEER_CERTIFICATE;
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include "setup.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
int curl_strequal(const char *first, const char *second)
|
||||
{
|
||||
@@ -62,6 +63,9 @@ int curl_strnequal(const char *first, const char *second, size_t max)
|
||||
first++;
|
||||
second++;
|
||||
}
|
||||
if(0 == max)
|
||||
return 1; /* they are equal this far */
|
||||
|
||||
return toupper(*first) == toupper(*second);
|
||||
#endif
|
||||
}
|
||||
|
70
lib/telnet.c
70
lib/telnet.c
@@ -226,9 +226,9 @@ static void printoption(struct SessionHandle *data,
|
||||
if (cmd == IAC)
|
||||
{
|
||||
if (TELCMD_OK(option))
|
||||
printf("%s IAC %s\n", direction, TELCMD(option));
|
||||
Curl_infof(data, "%s IAC %s\n", direction, TELCMD(option));
|
||||
else
|
||||
printf("%s IAC %d\n", direction, option);
|
||||
Curl_infof(data, "%s IAC %d\n", direction, option);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -244,12 +244,12 @@ static void printoption(struct SessionHandle *data,
|
||||
opt = NULL;
|
||||
|
||||
if(opt)
|
||||
printf("%s %s %s\n", direction, fmt, opt);
|
||||
Curl_infof(data, "%s %s %s\n", direction, fmt, opt);
|
||||
else
|
||||
printf("%s %s %d\n", direction, fmt, option);
|
||||
Curl_infof(data, "%s %s %d\n", direction, fmt, option);
|
||||
}
|
||||
else
|
||||
printf("%s %d %d\n", direction, cmd, option);
|
||||
Curl_infof(data, "%s %d %d\n", direction, cmd, option);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -638,7 +638,7 @@ static void printsub(struct SessionHandle *data,
|
||||
{
|
||||
if (direction)
|
||||
{
|
||||
printf("%s IAC SB ", (direction == '<')? "RCVD":"SENT");
|
||||
Curl_infof(data, "%s IAC SB ", (direction == '<')? "RCVD":"SENT");
|
||||
if (length >= 3)
|
||||
{
|
||||
int j;
|
||||
@@ -648,27 +648,27 @@ static void printsub(struct SessionHandle *data,
|
||||
|
||||
if (i != IAC || j != SE)
|
||||
{
|
||||
printf("(terminated by ");
|
||||
Curl_infof(data, "(terminated by ");
|
||||
if (TELOPT_OK(i))
|
||||
printf("%s ", TELOPT(i));
|
||||
Curl_infof(data, "%s ", TELOPT(i));
|
||||
else if (TELCMD_OK(i))
|
||||
printf("%s ", TELCMD(i));
|
||||
Curl_infof(data, "%s ", TELCMD(i));
|
||||
else
|
||||
printf("%d ", i);
|
||||
Curl_infof(data, "%d ", i);
|
||||
if (TELOPT_OK(j))
|
||||
printf("%s", TELOPT(j));
|
||||
Curl_infof(data, "%s", TELOPT(j));
|
||||
else if (TELCMD_OK(j))
|
||||
printf("%s", TELCMD(j));
|
||||
Curl_infof(data, "%s", TELCMD(j));
|
||||
else
|
||||
printf("%d", j);
|
||||
printf(", not IAC SE!) ");
|
||||
Curl_infof(data, "%d", j);
|
||||
Curl_infof(data, ", not IAC SE!) ");
|
||||
}
|
||||
}
|
||||
length -= 2;
|
||||
}
|
||||
if (length < 1)
|
||||
{
|
||||
printf("(Empty suboption?)");
|
||||
Curl_infof(data, "(Empty suboption?)");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -677,28 +677,28 @@ static void printsub(struct SessionHandle *data,
|
||||
case TELOPT_TTYPE:
|
||||
case TELOPT_XDISPLOC:
|
||||
case TELOPT_NEW_ENVIRON:
|
||||
printf("%s", TELOPT(pointer[0]));
|
||||
Curl_infof(data, "%s", TELOPT(pointer[0]));
|
||||
break;
|
||||
default:
|
||||
printf("%s (unsupported)", TELOPT(pointer[0]));
|
||||
Curl_infof(data, "%s (unsupported)", TELOPT(pointer[0]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
printf("%d (unknown)", pointer[i]);
|
||||
Curl_infof(data, "%d (unknown)", pointer[i]);
|
||||
|
||||
switch(pointer[1]) {
|
||||
case TELQUAL_IS:
|
||||
printf(" IS");
|
||||
Curl_infof(data, " IS");
|
||||
break;
|
||||
case TELQUAL_SEND:
|
||||
printf(" SEND");
|
||||
Curl_infof(data, " SEND");
|
||||
break;
|
||||
case TELQUAL_INFO:
|
||||
printf(" INFO/REPLY");
|
||||
Curl_infof(data, " INFO/REPLY");
|
||||
break;
|
||||
case TELQUAL_NAME:
|
||||
printf(" NAME");
|
||||
Curl_infof(data, " NAME");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -706,21 +706,21 @@ static void printsub(struct SessionHandle *data,
|
||||
case TELOPT_TTYPE:
|
||||
case TELOPT_XDISPLOC:
|
||||
pointer[length] = 0;
|
||||
printf(" \"%s\"", &pointer[2]);
|
||||
Curl_infof(data, " \"%s\"", &pointer[2]);
|
||||
break;
|
||||
case TELOPT_NEW_ENVIRON:
|
||||
if(pointer[1] == TELQUAL_IS) {
|
||||
printf(" ");
|
||||
Curl_infof(data, " ");
|
||||
for(i = 3;i < length;i++) {
|
||||
switch(pointer[i]) {
|
||||
case NEW_ENV_VAR:
|
||||
printf(", ");
|
||||
Curl_infof(data, ", ");
|
||||
break;
|
||||
case NEW_ENV_VALUE:
|
||||
printf(" = ");
|
||||
Curl_infof(data, " = ");
|
||||
break;
|
||||
default:
|
||||
printf("%c", pointer[i]);
|
||||
Curl_infof(data, "%c", pointer[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -728,13 +728,13 @@ static void printsub(struct SessionHandle *data,
|
||||
break;
|
||||
default:
|
||||
for (i = 2; i < length; i++)
|
||||
printf(" %.2x", pointer[i]);
|
||||
Curl_infof(data, " %.2x", pointer[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (direction)
|
||||
{
|
||||
printf("\n");
|
||||
Curl_infof(data, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1090,7 +1090,7 @@ CURLcode Curl_telnet(struct connectdata *conn)
|
||||
{
|
||||
unsigned char outbuf[2];
|
||||
int out_count = 0;
|
||||
size_t bytes_written;
|
||||
ssize_t bytes_written;
|
||||
char *buffer = buf;
|
||||
|
||||
if(!ReadFile(stdin_handle, buf, 255, &nread, NULL)) {
|
||||
@@ -1116,6 +1116,7 @@ CURLcode Curl_telnet(struct connectdata *conn)
|
||||
{
|
||||
if(events.lNetworkEvents & FD_READ)
|
||||
{
|
||||
/* This reallu OUGHT to check its return code. */
|
||||
Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
|
||||
|
||||
telrcv(conn, (unsigned char *)buf, nread);
|
||||
@@ -1142,7 +1143,7 @@ CURLcode Curl_telnet(struct connectdata *conn)
|
||||
#else
|
||||
FD_ZERO (&readfd); /* clear it */
|
||||
FD_SET (sockfd, &readfd);
|
||||
FD_SET (1, &readfd);
|
||||
FD_SET (0, &readfd);
|
||||
|
||||
keepfd = readfd;
|
||||
|
||||
@@ -1156,13 +1157,13 @@ CURLcode Curl_telnet(struct connectdata *conn)
|
||||
case 0: /* timeout */
|
||||
break;
|
||||
default: /* read! */
|
||||
if(FD_ISSET(1, &readfd)) { /* read from stdin */
|
||||
if(FD_ISSET(0, &readfd)) { /* read from stdin */
|
||||
unsigned char outbuf[2];
|
||||
int out_count = 0;
|
||||
size_t bytes_written;
|
||||
ssize_t bytes_written;
|
||||
char *buffer = buf;
|
||||
|
||||
nread = read(1, buf, 255);
|
||||
nread = read(0, buf, 255);
|
||||
|
||||
while(nread--) {
|
||||
outbuf[0] = *buffer++;
|
||||
@@ -1176,6 +1177,7 @@ CURLcode Curl_telnet(struct connectdata *conn)
|
||||
}
|
||||
|
||||
if(FD_ISSET(sockfd, &readfd)) {
|
||||
/* This OUGHT to check the return code... */
|
||||
Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
|
||||
|
||||
/* if we receive 0 or less here, the server closed the connection and
|
||||
|
@@ -69,10 +69,10 @@ struct timeval Curl_tvnow (void)
|
||||
* Make sure that the first argument is the more recent time, as otherwise
|
||||
* we'll get a weird negative time-diff back...
|
||||
*/
|
||||
long Curl_tvdiff (struct timeval t1, struct timeval t2)
|
||||
long Curl_tvdiff (struct timeval newer, struct timeval older)
|
||||
{
|
||||
return (t1.tv_sec*1000 + t1.tv_usec/1000)-
|
||||
(t2.tv_sec*1000 + t2.tv_usec/1000);
|
||||
return (newer.tv_sec-older.tv_sec)*1000+
|
||||
(499+newer.tv_usec-older.tv_usec)/1000;
|
||||
}
|
||||
|
||||
long Curl_tvlong (struct timeval t1)
|
||||
|
@@ -42,7 +42,7 @@ struct timeval {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct timeval Curl_tvnow ();
|
||||
struct timeval Curl_tvnow (void);
|
||||
|
||||
/* the diff is from now on returned in number of milliseconds! */
|
||||
long Curl_tvdiff (struct timeval t1, struct timeval t2);
|
||||
|
833
lib/transfer.c
833
lib/transfer.c
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* In order to be useful for every potential user, curl and libcurl are
|
||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
||||
@@ -24,6 +24,17 @@
|
||||
*****************************************************************************/
|
||||
CURLcode Curl_perform(struct SessionHandle *data);
|
||||
|
||||
CURLcode Curl_pretransfer(struct SessionHandle *data);
|
||||
CURLcode Curl_posttransfer(struct SessionHandle *data);
|
||||
|
||||
CURLcode Curl_readwrite(struct connectdata *conn, bool *done);
|
||||
void Curl_single_fdset(struct connectdata *conn,
|
||||
fd_set *read_fd_set,
|
||||
fd_set *write_fd_set,
|
||||
fd_set *exc_fd_set,
|
||||
int *max_fd);
|
||||
CURLcode Curl_readwrite_init(struct connectdata *conn);
|
||||
|
||||
/* This sets up a forthcoming transfer */
|
||||
CURLcode
|
||||
Curl_Transfer (struct connectdata *data,
|
||||
|
340
lib/url.c
340
lib/url.c
@@ -72,7 +72,6 @@
|
||||
#include <inet.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_SELECT
|
||||
#error "We can't compile without select() support!"
|
||||
#endif
|
||||
@@ -111,6 +110,10 @@
|
||||
|
||||
#include <curl/types.h>
|
||||
|
||||
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
||||
#include "inet_ntoa_r.h"
|
||||
#endif
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
@@ -144,13 +147,23 @@ RETSIGTYPE alarmfunc(int signal)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* This is the internal function curl_easy_cleanup() calls. This should
|
||||
* cleanup and free all resources associated with this sessionhandle.
|
||||
*
|
||||
* NOTE: if we ever add something that attempts to write to a socket or
|
||||
* similar here, we must ignore SIGPIPE first. It is currently only done
|
||||
* when curl_easy_perform() is invoked.
|
||||
*/
|
||||
|
||||
CURLcode Curl_close(struct SessionHandle *data)
|
||||
{
|
||||
/* Loop through all open connections and kill them one by one */
|
||||
while(-1 != ConnectionKillOne(data));
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
/* Close down all open info open SSL and sessions */
|
||||
/* Close down all open SSL info and sessions */
|
||||
Curl_SSL_Close_All(data);
|
||||
#endif
|
||||
|
||||
@@ -200,10 +213,6 @@ CURLcode Curl_open(struct SessionHandle **curl)
|
||||
{
|
||||
/* We don't yet support specifying the URL at this point */
|
||||
struct SessionHandle *data;
|
||||
#ifdef HAVE_SIGACTION
|
||||
struct sigaction sigact;
|
||||
#endif
|
||||
|
||||
/* Very simple start-up: alloc the struct, init it with zeroes and return */
|
||||
data = (struct SessionHandle *)malloc(sizeof(struct SessionHandle));
|
||||
if(!data)
|
||||
@@ -240,6 +249,9 @@ CURLcode Curl_open(struct SessionHandle **curl)
|
||||
data->state.current_speed = -1; /* init to negative == impossible */
|
||||
|
||||
data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
|
||||
data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
|
||||
|
||||
data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
|
||||
|
||||
/* make libcurl quiet by default: */
|
||||
data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
|
||||
@@ -263,31 +275,6 @@ CURLcode Curl_open(struct SessionHandle **curl)
|
||||
|
||||
*curl = data;
|
||||
|
||||
/*************************************************************
|
||||
* Set signal handler to catch SIGALRM
|
||||
*************************************************************/
|
||||
#ifdef HAVE_SIGACTION
|
||||
sigaction(SIGALRM, NULL, &sigact);
|
||||
sigact.sa_handler = alarmfunc;
|
||||
#ifdef SA_RESTART
|
||||
/* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
|
||||
sigact.sa_flags &= ~SA_RESTART;
|
||||
#endif
|
||||
sigaction(SIGALRM, &sigact, NULL);
|
||||
#else
|
||||
/* no sigaction(), revert to the much lamer signal() */
|
||||
#ifdef HAVE_SIGNAL
|
||||
signal(SIGALRM, alarmfunc);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*************************************************************
|
||||
* Tell signal handler to ignore SIGPIPE
|
||||
*************************************************************/
|
||||
#if defined(HAVE_SIGNAL) && defined(SIGPIPE)
|
||||
(void) signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -299,6 +286,19 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
||||
va_start(param, option);
|
||||
|
||||
switch(option) {
|
||||
case CURLOPT_DNS_CACHE_TIMEOUT:
|
||||
data->set.dns_cache_timeout = va_arg(param, int);
|
||||
break;
|
||||
case CURLOPT_DNS_USE_GLOBAL_CACHE:
|
||||
{
|
||||
int use_cache = va_arg(param, int);
|
||||
if (use_cache) {
|
||||
Curl_global_host_cache_init();
|
||||
}
|
||||
|
||||
data->set.global_dns_cache = use_cache;
|
||||
}
|
||||
break;
|
||||
case CURLOPT_SSL_CIPHER_LIST:
|
||||
/* set a list of cipher we want to use in the SSL connection */
|
||||
data->set.ssl.cipher_list = va_arg(param, char *);
|
||||
@@ -543,6 +543,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
||||
data->set.ftpport = va_arg(param, char *);
|
||||
data->set.ftp_use_port = data->set.ftpport?1:0;
|
||||
break;
|
||||
|
||||
case CURLOPT_FTP_USE_EPSV:
|
||||
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)
|
||||
@@ -570,8 +575,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
||||
/*
|
||||
* Set to force us do HTTP GET
|
||||
*/
|
||||
if(va_arg(param, long))
|
||||
if(va_arg(param, long)) {
|
||||
data->set.httpreq = HTTPREQ_GET;
|
||||
data->set.upload = FALSE; /* switch off upload */
|
||||
}
|
||||
break;
|
||||
|
||||
case CURLOPT_INFILE:
|
||||
@@ -802,11 +809,75 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
||||
*/
|
||||
data->set.cert = va_arg(param, char *);
|
||||
break;
|
||||
case CURLOPT_SSLCERTPASSWD:
|
||||
case CURLOPT_SSLCERTTYPE:
|
||||
/*
|
||||
* String that holds the SSL certificate password.
|
||||
* String that holds file type of the SSL certificate to use
|
||||
*/
|
||||
data->set.cert_passwd = va_arg(param, char *);
|
||||
data->set.cert_type = va_arg(param, char *);
|
||||
break;
|
||||
case CURLOPT_SSLKEY:
|
||||
/*
|
||||
* String that holds file name of the SSL certificate to use
|
||||
*/
|
||||
data->set.key = va_arg(param, char *);
|
||||
break;
|
||||
case CURLOPT_SSLKEYTYPE:
|
||||
/*
|
||||
* String that holds file type of the SSL certificate to use
|
||||
*/
|
||||
data->set.key_type = va_arg(param, char *);
|
||||
break;
|
||||
case CURLOPT_SSLKEYPASSWD:
|
||||
/*
|
||||
* String that holds the SSL private key password.
|
||||
*/
|
||||
data->set.key_passwd = va_arg(param, char *);
|
||||
break;
|
||||
case CURLOPT_SSLENGINE:
|
||||
/*
|
||||
* String that holds the SSL crypto engine.
|
||||
*/
|
||||
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||
{
|
||||
const char *cpTemp = va_arg(param, char *);
|
||||
ENGINE *e;
|
||||
if (cpTemp && cpTemp[0]) {
|
||||
e = ENGINE_by_id(cpTemp);
|
||||
if (e) {
|
||||
if (data->engine) {
|
||||
ENGINE_free(data->engine);
|
||||
}
|
||||
data->engine = e;
|
||||
}
|
||||
else {
|
||||
failf(data, "SSL Engine '%s' not found", cpTemp);
|
||||
return CURLE_SSL_ENGINE_NOTFOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
return CURLE_SSL_ENGINE_NOTFOUND;
|
||||
#endif
|
||||
break;
|
||||
case CURLOPT_SSLENGINE_DEFAULT:
|
||||
/*
|
||||
* flag to set engine as default.
|
||||
*/
|
||||
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||
if (data->engine) {
|
||||
if (ENGINE_set_default(data->engine, ENGINE_METHOD_ALL) > 0) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,"set default crypto engine\n");
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
failf(data, "set default crypto engine failed");
|
||||
#endif
|
||||
return CURLE_SSL_ENGINE_SETFAILED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case CURLOPT_CRLF:
|
||||
/*
|
||||
@@ -888,9 +959,6 @@ CURLcode Curl_disconnect(struct connectdata *conn)
|
||||
if(conn->proto.generic)
|
||||
free(conn->proto.generic);
|
||||
|
||||
if(conn->hostent_buf) /* host name info */
|
||||
Curl_freeaddrinfo(conn->hostent_buf);
|
||||
|
||||
if(conn->newurl)
|
||||
free(conn->newurl);
|
||||
|
||||
@@ -957,9 +1025,9 @@ static bool SocketIsDead(int sock)
|
||||
}
|
||||
|
||||
/*
|
||||
* Given one filled in connection struct, this function should detect if there
|
||||
* already is one that have all the significant details exactly the same and
|
||||
* thus should be used instead.
|
||||
* Given one filled in connection struct (named needle), this function should
|
||||
* detect if there already is one that have all the significant details
|
||||
* exactly the same and thus should be used instead.
|
||||
*/
|
||||
static bool
|
||||
ConnectionExists(struct SessionHandle *data,
|
||||
@@ -978,8 +1046,14 @@ ConnectionExists(struct SessionHandle *data,
|
||||
if(!check)
|
||||
/* NULL pointer means not filled-in entry */
|
||||
continue;
|
||||
if(!needle->bits.httpproxy) {
|
||||
/* The requested connection does not use a HTTP proxy */
|
||||
if(!needle->bits.httpproxy || needle->protocol&PROT_SSL) {
|
||||
/* The requested connection does not use a HTTP proxy or it
|
||||
uses SSL. */
|
||||
|
||||
if(!(needle->protocol&PROT_SSL) && check->bits.httpproxy)
|
||||
/* we don't do SSL but the cached connection has a proxy,
|
||||
then don't match this */
|
||||
continue;
|
||||
|
||||
if(strequal(needle->protostr, check->protostr) &&
|
||||
strequal(needle->name, check->name) &&
|
||||
@@ -1159,17 +1233,31 @@ static CURLcode ConnectPlease(struct connectdata *conn)
|
||||
}
|
||||
|
||||
static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
struct connectdata **in_connect,
|
||||
bool allow_port) /* allow set.use_port? */
|
||||
struct connectdata **in_connect)
|
||||
{
|
||||
char *tmp;
|
||||
char *buf;
|
||||
CURLcode result;
|
||||
CURLcode result=CURLE_OK;
|
||||
char resumerange[40]="";
|
||||
struct connectdata *conn;
|
||||
struct connectdata *conn_temp;
|
||||
char endbracket;
|
||||
int urllen;
|
||||
#ifdef HAVE_INET_NTOA_R
|
||||
char ntoa_buf[64];
|
||||
#endif
|
||||
#ifdef HAVE_ALARM
|
||||
unsigned int prev_alarm;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
struct sigaction keep_sigact; /* store the old struct here */
|
||||
bool keep_copysig; /* did copy it? */
|
||||
#else
|
||||
#ifdef HAVE_SIGNAL
|
||||
void *keep_sigact; /* store the old handler here */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*************************************************************
|
||||
* Check input data
|
||||
@@ -1496,6 +1584,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
/* we have a proxy here to set */
|
||||
data->change.proxy = proxy;
|
||||
data->change.proxy_alloc=TRUE; /* this needs to be freed later */
|
||||
conn->bits.httpproxy = TRUE;
|
||||
}
|
||||
} /* if (!nope) - it wasn't specified non-proxy */
|
||||
} /* NO_PROXY wasn't specified or '*' */
|
||||
@@ -1546,19 +1635,21 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
*************************************************************/
|
||||
|
||||
if (strequal(conn->protostr, "HTTP")) {
|
||||
conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_HTTP;
|
||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||
data->set.use_port:PORT_HTTP;
|
||||
conn->remote_port = PORT_HTTP;
|
||||
conn->protocol |= PROT_HTTP;
|
||||
conn->curl_do = Curl_http;
|
||||
conn->curl_done = Curl_http_done;
|
||||
conn->curl_connect = Curl_http_connect;
|
||||
}
|
||||
else if (strequal(conn->protostr, "HTTPS")) {
|
||||
#ifdef USE_SSLEAY
|
||||
|
||||
conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_HTTPS;
|
||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||
data->set.use_port:PORT_HTTPS;
|
||||
conn->remote_port = PORT_HTTPS;
|
||||
conn->protocol |= PROT_HTTP;
|
||||
conn->protocol |= PROT_HTTPS;
|
||||
conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL;
|
||||
|
||||
conn->curl_do = Curl_http;
|
||||
conn->curl_done = Curl_http_done;
|
||||
@@ -1571,7 +1662,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
#endif /* !USE_SSLEAY */
|
||||
}
|
||||
else if (strequal(conn->protostr, "GOPHER")) {
|
||||
conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_GOPHER;
|
||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||
data->set.use_port:PORT_GOPHER;
|
||||
conn->remote_port = PORT_GOPHER;
|
||||
/* Skip /<item-type>/ in path if present */
|
||||
if (isdigit((int)conn->path[1])) {
|
||||
@@ -1589,7 +1681,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
|
||||
if(strequal(conn->protostr, "FTPS")) {
|
||||
#ifdef USE_SSLEAY
|
||||
conn->protocol |= PROT_FTPS;
|
||||
conn->protocol |= PROT_FTPS|PROT_SSL;
|
||||
#else
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with SSL disabled, ftps: not supported!");
|
||||
@@ -1597,7 +1689,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
#endif /* !USE_SSLEAY */
|
||||
}
|
||||
|
||||
conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_FTP;
|
||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||
data->set.use_port:PORT_FTP;
|
||||
conn->remote_port = PORT_FTP;
|
||||
conn->protocol |= PROT_FTP;
|
||||
|
||||
@@ -1652,21 +1745,24 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
/* telnet testing factory */
|
||||
conn->protocol |= PROT_TELNET;
|
||||
|
||||
conn->port = (data->set.use_port && allow_port)?data->set.use_port: PORT_TELNET;
|
||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||
data->set.use_port: PORT_TELNET;
|
||||
conn->remote_port = PORT_TELNET;
|
||||
conn->curl_do = Curl_telnet;
|
||||
conn->curl_done = Curl_telnet_done;
|
||||
}
|
||||
else if (strequal(conn->protostr, "DICT")) {
|
||||
conn->protocol |= PROT_DICT;
|
||||
conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_DICT;
|
||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||
data->set.use_port:PORT_DICT;
|
||||
conn->remote_port = PORT_DICT;
|
||||
conn->curl_do = Curl_dict;
|
||||
conn->curl_done = NULL; /* no DICT-specific done */
|
||||
}
|
||||
else if (strequal(conn->protostr, "LDAP")) {
|
||||
conn->protocol |= PROT_LDAP;
|
||||
conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_LDAP;
|
||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||
data->set.use_port:PORT_LDAP;
|
||||
conn->remote_port = PORT_LDAP;
|
||||
conn->curl_do = Curl_ldap;
|
||||
conn->curl_done = NULL; /* no LDAP-specific done */
|
||||
@@ -1937,17 +2033,45 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
* Set timeout if that is being used
|
||||
*************************************************************/
|
||||
if(data->set.timeout || data->set.connecttimeout) {
|
||||
/*************************************************************
|
||||
* Set signal handler to catch SIGALRM
|
||||
* Store the old value to be able to set it back later!
|
||||
*************************************************************/
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
struct sigaction sigact;
|
||||
sigaction(SIGALRM, NULL, &sigact);
|
||||
keep_sigact = sigact;
|
||||
keep_copysig = TRUE; /* yes, we have a copy */
|
||||
sigact.sa_handler = alarmfunc;
|
||||
#ifdef SA_RESTART
|
||||
/* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
|
||||
sigact.sa_flags &= ~SA_RESTART;
|
||||
#endif
|
||||
/* now set the new struct */
|
||||
sigaction(SIGALRM, &sigact, NULL);
|
||||
#else
|
||||
/* no sigaction(), revert to the much lamer signal() */
|
||||
#ifdef HAVE_SIGNAL
|
||||
keep_sigact = signal(SIGALRM, alarmfunc);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* We set the timeout on the name resolving phase first, separately from
|
||||
* the download/upload part to allow a maximum time on everything. This is
|
||||
* a signal-based timeout, why it won't work and shouldn't be used in
|
||||
* multi-threaded environments. */
|
||||
|
||||
/* myalarm() makes a signal get sent when the timeout fires off, and that
|
||||
#ifdef HAVE_ALARM
|
||||
/* alarm() makes a signal get sent when the timeout fires off, and that
|
||||
will abort system calls */
|
||||
if(data->set.connecttimeout)
|
||||
myalarm(data->set.connecttimeout);
|
||||
else
|
||||
myalarm(data->set.timeout);
|
||||
prev_alarm = alarm(data->set.connecttimeout?
|
||||
data->set.connecttimeout:
|
||||
data->set.timeout);
|
||||
/* We can expect the conn->created time to be "now", as that was just
|
||||
recently set in the beginning of this function and nothing slow
|
||||
has been done since then until now. */
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
@@ -1961,12 +2085,13 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
/* Resolve target host right on */
|
||||
if(!conn->hostaddr) {
|
||||
/* it might already be set if reusing a connection */
|
||||
conn->hostaddr = Curl_getaddrinfo(data, conn->name, conn->port,
|
||||
conn->hostaddr = Curl_resolv(data, conn->name, conn->port,
|
||||
&conn->hostent_buf);
|
||||
}
|
||||
if(!conn->hostaddr) {
|
||||
failf(data, "Couldn't resolve host '%s'", conn->name);
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
result = CURLE_COULDNT_RESOLVE_HOST;
|
||||
/* don't return yet, we need to clean up the timeout first */
|
||||
}
|
||||
}
|
||||
else if(!conn->hostaddr) {
|
||||
@@ -1975,18 +2100,57 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
|
||||
/* resolve proxy */
|
||||
/* it might already be set if reusing a connection */
|
||||
conn->hostaddr = Curl_getaddrinfo(data, conn->proxyhost, conn->port,
|
||||
conn->hostaddr = Curl_resolv(data, conn->proxyhost, conn->port,
|
||||
&conn->hostent_buf);
|
||||
|
||||
if(!conn->hostaddr) {
|
||||
failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost);
|
||||
return CURLE_COULDNT_RESOLVE_PROXY;
|
||||
result = CURLE_COULDNT_RESOLVE_PROXY;
|
||||
/* don't return yet, we need to clean up the timeout first */
|
||||
}
|
||||
}
|
||||
Curl_pgrsTime(data, TIMER_NAMELOOKUP);
|
||||
if(data->set.timeout || data->set.connecttimeout)
|
||||
/* switch off signal-based timeouts */
|
||||
myalarm(0);
|
||||
#ifdef HAVE_ALARM
|
||||
if(data->set.timeout || data->set.connecttimeout) {
|
||||
#ifdef HAVE_SIGACTION
|
||||
if(keep_copysig) {
|
||||
/* we got a struct as it looked before, now put that one back nice
|
||||
and clean */
|
||||
sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */
|
||||
}
|
||||
#else
|
||||
#ifdef HAVE_SIGNAL
|
||||
/* restore the previous SIGALRM handler */
|
||||
signal(SIGALRM, keep_sigact);
|
||||
#endif
|
||||
#endif
|
||||
/* switch back the alarm() to either zero or to what it was before minus
|
||||
the time we spent until now! */
|
||||
if(prev_alarm) {
|
||||
/* there was an alarm() set before us, now put it back */
|
||||
long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created);
|
||||
long alarm_set;
|
||||
|
||||
/* the alarm period is counted in even number of seconds */
|
||||
alarm_set = prev_alarm - elapsed_ms/1000;
|
||||
|
||||
if(alarm_set<=0) {
|
||||
/* if it turned negative, we should fire off a SIGALRM here, but we
|
||||
won't, and zero would be to switch it off so we never set it to
|
||||
less than 1! */
|
||||
alarm(1);
|
||||
result = CURLE_OPERATION_TIMEOUTED;
|
||||
failf(data, "Previous alarm fired off!");
|
||||
}
|
||||
else
|
||||
alarm(alarm_set);
|
||||
}
|
||||
else
|
||||
alarm(0); /* just shut it off */
|
||||
}
|
||||
#endif
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/*************************************************************
|
||||
* Proxy authentication
|
||||
@@ -2072,7 +2236,12 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
struct in_addr in;
|
||||
(void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr));
|
||||
infof(data, "Connected to %s (%s)\n", conn->hostaddr->h_name,
|
||||
inet_ntoa(in));
|
||||
#if defined(HAVE_INET_NTOA_R)
|
||||
inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf))
|
||||
#else
|
||||
inet_ntoa(in)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2092,14 +2261,13 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
}
|
||||
|
||||
CURLcode Curl_connect(struct SessionHandle *data,
|
||||
struct connectdata **in_connect,
|
||||
bool allow_port)
|
||||
struct connectdata **in_connect)
|
||||
{
|
||||
CURLcode code;
|
||||
struct connectdata *conn;
|
||||
|
||||
/* call the stuff that needs to be called */
|
||||
code = CreateConnection(data, in_connect, allow_port);
|
||||
code = CreateConnection(data, in_connect);
|
||||
|
||||
if(CURLE_OK != code) {
|
||||
/* We're not allowed to return failure with memory left allocated
|
||||
@@ -2155,14 +2323,38 @@ CURLcode Curl_done(struct connectdata *conn)
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLcode Curl_do(struct connectdata *conn)
|
||||
CURLcode Curl_do(struct connectdata **connp)
|
||||
{
|
||||
CURLcode result=CURLE_OK;
|
||||
struct connectdata *conn = *connp;
|
||||
struct SessionHandle *data=conn->data;
|
||||
|
||||
if(conn->curl_do)
|
||||
if(conn->curl_do) {
|
||||
/* generic protocol-specific function pointer set in curl_connect() */
|
||||
result = conn->curl_do(conn);
|
||||
|
||||
/* This was formerly done in transfer.c, but we better do it here */
|
||||
|
||||
if((CURLE_WRITE_ERROR == result) && conn->bits.reuse) {
|
||||
/* This was a re-use of a connection and we got a write error in the
|
||||
* DO-phase. Then we DISCONNECT this connection and have another attempt
|
||||
* to CONNECT and then DO again! The retry cannot possibly find another
|
||||
* connection to re-use, since we only keep one possible connection for
|
||||
* each. */
|
||||
|
||||
infof(data, "Re-used connection seems dead, get a new one\n");
|
||||
|
||||
conn->bits.close = TRUE; /* enforce close of this connetion */
|
||||
result = Curl_done(conn); /* we are so done with this */
|
||||
if(CURLE_OK == result) {
|
||||
/* Now, redo the connect and get a new connection */
|
||||
result = Curl_connect(data, connp);
|
||||
if(CURLE_OK == result)
|
||||
/* ... finally back to actually retry the DO phase */
|
||||
result = conn->curl_do(*connp);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
10
lib/url.h
10
lib/url.h
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* In order to be useful for every potential user, curl and libcurl are
|
||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
||||
@@ -29,11 +29,9 @@
|
||||
|
||||
CURLcode Curl_open(struct SessionHandle **curl);
|
||||
CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...);
|
||||
CURLcode Curl_close(struct SessionHandle *data); /* the opposite of curl_open() */
|
||||
CURLcode Curl_connect(struct SessionHandle *,
|
||||
struct connectdata **,
|
||||
bool allow_port);
|
||||
CURLcode Curl_do(struct connectdata *);
|
||||
CURLcode Curl_close(struct SessionHandle *data); /* opposite of curl_open() */
|
||||
CURLcode Curl_connect(struct SessionHandle *, struct connectdata **);
|
||||
CURLcode Curl_do(struct connectdata **);
|
||||
CURLcode Curl_done(struct connectdata *);
|
||||
CURLcode Curl_disconnect(struct connectdata *);
|
||||
|
||||
|
114
lib/urldata.h
114
lib/urldata.h
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "setup.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
|
||||
#define PORT_FTP 21
|
||||
#define PORT_TELNET 23
|
||||
@@ -58,6 +59,9 @@
|
||||
#include "openssl/pem.h"
|
||||
#include "openssl/ssl.h"
|
||||
#include "openssl/err.h"
|
||||
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||
#include <openssl/engine.h>
|
||||
#endif
|
||||
#else
|
||||
#include "rsa.h"
|
||||
#include "crypto.h"
|
||||
@@ -79,7 +83,7 @@
|
||||
#include "http_chunks.h" /* for the structs and enum stuff */
|
||||
|
||||
/* Download buffer size, keep it fairly big for speed reasons */
|
||||
#define BUFSIZE (1024*50)
|
||||
#define BUFSIZE (1024*20)
|
||||
|
||||
/* Defaul upload buffer size, keep it smallish to get faster progress meter
|
||||
updates. This is just default, it is dynamic and adjusts to the upload
|
||||
@@ -111,6 +115,9 @@ enum protection_level {
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_OPENSSL_ENGINE_H
|
||||
typedef void ENGINE;
|
||||
#endif
|
||||
/* struct for data related to SSL and SSL connections */
|
||||
struct ssl_connect_data {
|
||||
bool use; /* use ssl encrypted communications TRUE/FALSE */
|
||||
@@ -175,6 +182,9 @@ struct FTP {
|
||||
char *file; /* decoded file */
|
||||
|
||||
char *entrypath; /* the PWD reply when we logged on */
|
||||
|
||||
char *cache; /* data cache between getresponse()-calls */
|
||||
size_t cache_size; /* size of cache in bytes */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@@ -202,6 +212,58 @@ struct ConnectBits {
|
||||
complete */
|
||||
};
|
||||
|
||||
/*
|
||||
* This struct is all the previously local variables from Curl_perform() moved
|
||||
* to struct to allow the function to return and get re-invoked better without
|
||||
* losing state.
|
||||
*/
|
||||
|
||||
struct Curl_transfer_keeper {
|
||||
int bytecount; /* total number of bytes read */
|
||||
int writebytecount; /* number of bytes written */
|
||||
long contentlength; /* size of incoming data */
|
||||
struct timeval start; /* transfer started at this time */
|
||||
struct timeval now; /* current time */
|
||||
bool header; /* incoming data has HTTP header */
|
||||
int headerline; /* counts header lines to better track the
|
||||
first one */
|
||||
char *hbufp; /* points at *end* of header line */
|
||||
int hbuflen;
|
||||
char *str; /* within buf */
|
||||
char *str_start; /* within buf */
|
||||
char *end_ptr; /* within buf */
|
||||
char *p; /* within headerbuff */
|
||||
bool content_range; /* set TRUE if Content-Range: was found */
|
||||
int 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 */
|
||||
bool write_after_100_header; /* should we enable the write after
|
||||
we received a 100-continue/timeout
|
||||
or directly */
|
||||
|
||||
/* for the low speed checks: */
|
||||
time_t timeofdoc;
|
||||
long bodywrites;
|
||||
int writetype;
|
||||
|
||||
/* the highest fd we use + 1 */
|
||||
struct SessionHandle *data;
|
||||
struct connectdata *conn;
|
||||
char *buf;
|
||||
char *uploadbuf;
|
||||
int maxfd;
|
||||
|
||||
/* the file descriptors to play with */
|
||||
fd_set readfd;
|
||||
fd_set writefd;
|
||||
fd_set rkeepfd;
|
||||
fd_set wkeepfd;
|
||||
int keepon;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* The connectdata struct contains all fields and variables that should be
|
||||
* unique for an entire connection.
|
||||
@@ -223,6 +285,7 @@ struct connectdata {
|
||||
#define PROT_LDAP (1<<7)
|
||||
#define PROT_FILE (1<<8)
|
||||
#define PROT_FTPS (1<<9)
|
||||
#define PROT_SSL (1<<10) /* protocol requires SSL */
|
||||
|
||||
Curl_addrinfo *hostaddr; /* IP-protocol independent host info pointer list */
|
||||
char *hostent_buf; /* pointer to allocated memory for name info */
|
||||
@@ -246,7 +309,7 @@ struct connectdata {
|
||||
|
||||
char *range; /* range, if used. See README for detailed specification on
|
||||
this syntax. */
|
||||
int resume_from; /* continue [ftp] transfer from here */
|
||||
ssize_t resume_from; /* continue [ftp] transfer from here */
|
||||
|
||||
char *proxyhost; /* name of the http proxy host */
|
||||
|
||||
@@ -345,6 +408,18 @@ struct connectdata {
|
||||
void *generic;
|
||||
} proto;
|
||||
|
||||
/* This struct is inited when needed */
|
||||
struct Curl_transfer_keeper keep;
|
||||
|
||||
/* 'upload_present' is used to keep a byte counter of how much data there is
|
||||
still left in the buffer, aimed for upload. */
|
||||
int upload_present;
|
||||
|
||||
/* 'upload_fromhere' is used as a read-pointer when we uploaded parts of a
|
||||
buffer, so the next read should read from where this pointer points to,
|
||||
and the 'upload_present' contains the number of bytes available at this
|
||||
position */
|
||||
char *upload_fromhere;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -374,7 +449,7 @@ struct Progress {
|
||||
int width; /* screen width at download start */
|
||||
int flags; /* see progress.h */
|
||||
|
||||
long timespent;
|
||||
double timespent;
|
||||
|
||||
double dlspeed;
|
||||
double ulspeed;
|
||||
@@ -382,6 +457,7 @@ struct Progress {
|
||||
double t_nslookup;
|
||||
double t_connect;
|
||||
double t_pretransfer;
|
||||
double t_starttransfer;
|
||||
|
||||
struct timeval start;
|
||||
struct timeval t_startsingle;
|
||||
@@ -430,8 +506,8 @@ struct UrlState {
|
||||
char *headerbuff; /* allocated buffer to store headers in */
|
||||
int headersize; /* size of the allocation */
|
||||
|
||||
char buffer[BUFSIZE+1]; /* buffer with size BUFSIZE */
|
||||
|
||||
char buffer[BUFSIZE+1]; /* download buffer */
|
||||
char uploadbuffer[BUFSIZE+1]; /* upload buffer */
|
||||
double current_speed; /* the ProgressShow() funcion sets this */
|
||||
|
||||
bool this_is_a_follow; /* this is a followed Location: request */
|
||||
@@ -449,6 +525,13 @@ struct UrlState {
|
||||
bool errorbuf; /* Set to TRUE if the error buffer is already filled in.
|
||||
This must be set to FALSE every time _easy_perform() is
|
||||
called. */
|
||||
|
||||
#ifdef HAVE_SIGNAL
|
||||
/* storage for the previous bag^H^H^HSIGPIPE signal handler :-) */
|
||||
void (*prev_signal)(int sig);
|
||||
#endif
|
||||
bool allow_port; /* Is set.use_port allowed to take effect or not. This
|
||||
is always set TRUE when curl_easy_perform() is called. */
|
||||
};
|
||||
|
||||
|
||||
@@ -520,8 +603,12 @@ struct UserDefined {
|
||||
char *cookie; /* HTTP cookie string to send */
|
||||
struct curl_slist *headers; /* linked list of extra headers */
|
||||
struct HttpPost *httppost; /* linked list of POST data */
|
||||
char *cert; /* PEM-formatted certificate */
|
||||
char *cert_passwd; /* plain text certificate password */
|
||||
char *cert; /* certificate */
|
||||
char *cert_type; /* format for certificate (default: PEM) */
|
||||
char *key; /* private key */
|
||||
char *key_type; /* format for private key (default: PEM) */
|
||||
char *key_passwd; /* plain text private key password */
|
||||
char *crypto_engine; /* name of the crypto engine to use */
|
||||
char *cookiejar; /* dump all cookies to this file */
|
||||
bool crlf; /* convert crlf on ftp upload(?) */
|
||||
struct curl_slist *quote; /* before the transfer */
|
||||
@@ -541,6 +628,8 @@ struct UserDefined {
|
||||
char *krb4_level; /* what security level */
|
||||
struct ssl_config_data ssl; /* user defined SSL stuff */
|
||||
|
||||
int dns_cache_timeout; /* DNS cache timeout */
|
||||
|
||||
/* 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. */
|
||||
@@ -554,7 +643,9 @@ struct UserDefined {
|
||||
bool hide_progress;
|
||||
bool http_fail_on_error;
|
||||
bool http_follow_location;
|
||||
bool http_include_header;
|
||||
bool include_header;
|
||||
#define http_include_header include_header /* former name */
|
||||
|
||||
bool http_set_referer;
|
||||
bool http_auto_referer; /* set "correct" referer when following location: */
|
||||
bool no_body;
|
||||
@@ -566,6 +657,9 @@ struct UserDefined {
|
||||
bool reuse_forbid; /* forbidden to be reused, close after use */
|
||||
bool reuse_fresh; /* do not re-use an existing connection */
|
||||
bool expect100header; /* TRUE if we added Expect: 100-continue */
|
||||
bool ftp_use_epsv; /* if EPSV is to be attempted or not */
|
||||
|
||||
bool global_dns_cache;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -580,6 +674,7 @@ struct UserDefined {
|
||||
* 'struct urlstate' instead. */
|
||||
|
||||
struct SessionHandle {
|
||||
curl_hash *hostcache;
|
||||
struct UserDefined set; /* values set by the libcurl user */
|
||||
struct DynamicStatic change; /* possibly modified userdefined data */
|
||||
|
||||
@@ -588,6 +683,9 @@ struct SessionHandle {
|
||||
struct UrlState state; /* struct for fields used for state info and
|
||||
other dynamic purposes */
|
||||
struct PureInfo info; /* stats, reports and info data */
|
||||
#ifdef USE_SSLEAY
|
||||
ENGINE* engine;
|
||||
#endif /* USE_SSLEAY */
|
||||
};
|
||||
|
||||
#define LIBCURL_NAME "libcurl"
|
||||
|
21
multi/Makefile.am
Normal file
21
multi/Makefile.am
Normal file
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
|
||||
bin_PROGRAMS = app single double
|
||||
|
||||
app_SOURCES = app.c
|
||||
app_LDADD = ../lib/libcurl.la
|
||||
app_DEPENDENCIES = ../lib/libcurl.la
|
||||
|
||||
single_SOURCES = single.c
|
||||
single_LDADD = ../lib/libcurl.la
|
||||
single_DEPENDENCIES = ../lib/libcurl.la
|
||||
|
||||
double_SOURCES = double.c
|
||||
double_LDADD = ../lib/libcurl.la
|
||||
double_DEPENDENCIES = ../lib/libcurl.la
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign no-dependencies
|
92
multi/app.c
Normal file
92
multi/app.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* This is an example application source code using the multi interface.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
/* To start with, we include the header from the lib directory. This should
|
||||
later of course be moved to the proper include dir. */
|
||||
#include "../lib/multi.h"
|
||||
|
||||
/*
|
||||
* Download a HTTP file and upload an FTP file simultaneously.
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CURL *http_handle;
|
||||
CURL *ftp_handle;
|
||||
CURLM *multi_handle;
|
||||
|
||||
int still_running; /* keep number of running handles */
|
||||
|
||||
http_handle = curl_easy_init();
|
||||
ftp_handle = curl_easy_init();
|
||||
|
||||
/* set the options (I left out a few, you'll get the point anyway) */
|
||||
curl_easy_setopt(http_handle, CURLOPT_URL, "http://website.com");
|
||||
|
||||
curl_easy_setopt(ftp_handle, CURLOPT_URL, "ftp://ftpsite.com");
|
||||
curl_easy_setopt(ftp_handle, CURLOPT_UPLOAD, TRUE);
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
/* add the individual transfers */
|
||||
curl_multi_add_handle(multi_handle, http_handle);
|
||||
curl_multi_add_handle(multi_handle, ftp_handle);
|
||||
|
||||
/* we start some action by calling perform right away */
|
||||
while(CURLM_CALL_MULTI_PERFORM ==
|
||||
curl_multi_perform(multi_handle, &still_running));
|
||||
|
||||
while(still_running) {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
fd_set fdexcep;
|
||||
int maxfd;
|
||||
|
||||
FD_ZERO(&fdread);
|
||||
FD_ZERO(&fdwrite);
|
||||
FD_ZERO(&fdexcep);
|
||||
|
||||
/* set a suitable timeout to play around with */
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
/* get file descriptors from the transfers */
|
||||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
switch(rc) {
|
||||
case -1:
|
||||
/* select error */
|
||||
break;
|
||||
case 0:
|
||||
/* timeout, do something else */
|
||||
break;
|
||||
default:
|
||||
/* one or more of curl's file descriptors say there's data to read
|
||||
or write */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
curl_easy_cleanup(http_handle);
|
||||
curl_easy_cleanup(ftp_handle);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
87
multi/double.c
Normal file
87
multi/double.c
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This is a simple example using the multi interface.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* To start with, we include the header from the lib directory. This should
|
||||
later of course be moved to the proper include dir. */
|
||||
#include "../lib/multi.h"
|
||||
|
||||
/*
|
||||
* Simply download two HTTP files!
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CURL *http_handle;
|
||||
CURL *http_handle2;
|
||||
CURLM *multi_handle;
|
||||
|
||||
int still_running; /* keep number of running handles */
|
||||
|
||||
http_handle = curl_easy_init();
|
||||
http_handle2 = curl_easy_init();
|
||||
|
||||
/* set options */
|
||||
curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.haxx.se/");
|
||||
|
||||
/* set options */
|
||||
curl_easy_setopt(http_handle2, CURLOPT_URL, "http://localhost/");
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
/* add the individual transfers */
|
||||
curl_multi_add_handle(multi_handle, http_handle);
|
||||
curl_multi_add_handle(multi_handle, http_handle2);
|
||||
|
||||
/* we start some action by calling perform right away */
|
||||
while(CURLM_CALL_MULTI_PERFORM ==
|
||||
curl_multi_perform(multi_handle, &still_running));
|
||||
|
||||
while(still_running) {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
fd_set fdexcep;
|
||||
int maxfd;
|
||||
|
||||
FD_ZERO(&fdread);
|
||||
FD_ZERO(&fdwrite);
|
||||
FD_ZERO(&fdexcep);
|
||||
|
||||
/* set a suitable timeout to play around with */
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
/* get file descriptors from the transfers */
|
||||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
switch(rc) {
|
||||
case -1:
|
||||
/* select error */
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
/* timeout or readable/writable sockets */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
curl_easy_cleanup(http_handle);
|
||||
curl_easy_cleanup(http_handle2);
|
||||
|
||||
return 0;
|
||||
}
|
80
multi/single.c
Normal file
80
multi/single.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This is a very simple example using the multi interface.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* To start with, we include the header from the lib directory. This should
|
||||
later of course be moved to the proper include dir. */
|
||||
#include "../lib/multi.h"
|
||||
|
||||
/*
|
||||
* Simply download a HTTP file.
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CURL *http_handle;
|
||||
CURLM *multi_handle;
|
||||
|
||||
int still_running; /* keep number of running handles */
|
||||
|
||||
http_handle = curl_easy_init();
|
||||
|
||||
/* set the options (I left out a few, you'll get the point anyway) */
|
||||
curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.haxx.se/");
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
/* add the individual transfers */
|
||||
curl_multi_add_handle(multi_handle, http_handle);
|
||||
|
||||
/* we start some action by calling perform right away */
|
||||
while(CURLM_CALL_MULTI_PERFORM ==
|
||||
curl_multi_perform(multi_handle, &still_running));
|
||||
|
||||
while(still_running) {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
fd_set fdexcep;
|
||||
int maxfd;
|
||||
|
||||
FD_ZERO(&fdread);
|
||||
FD_ZERO(&fdwrite);
|
||||
FD_ZERO(&fdexcep);
|
||||
|
||||
/* set a suitable timeout to play around with */
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
/* get file descriptors from the transfers */
|
||||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
switch(rc) {
|
||||
case -1:
|
||||
/* select error */
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
/* timeout or readable/writable sockets */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
curl_easy_cleanup(http_handle);
|
||||
|
||||
return 0;
|
||||
}
|
@@ -15,20 +15,21 @@ EXTRA_DIST = README
|
||||
CYGBUILD = 1
|
||||
|
||||
# Cygwin tarball build dir (fully-qualified name, gets deleted when done)
|
||||
cygwintmp = $(CURDIR)/cygwinbin-builddir
|
||||
cygwintmp = $(CURDIR)/tmp_binbuild
|
||||
|
||||
cygwinbin:
|
||||
rm -rf $(cygwintmp)
|
||||
$(MAKE) -C $(top_builddir) install prefix=$(cygwintmp)/usr
|
||||
$(MAKE) -C $(top_builddir) install-strip prefix=$(cygwintmp)/usr
|
||||
$(STRIP) $(cygwintmp)/usr/bin/cygcurl-?.dll
|
||||
$(mkinstalldirs) $(cygwintmp)/usr/doc/Cygwin \
|
||||
$(cygwintmp)/usr/doc/$(PACKAGE)-$(VERSION)
|
||||
cd $(top_srcdir); \
|
||||
cp packages/Win32/cygwin/README \
|
||||
cp $(srcdir)/README \
|
||||
$(cygwintmp)/usr/doc/Cygwin/$(PACKAGE)-$(VERSION)-$(CYGBUILD).README
|
||||
cd $(top_srcdir) ; \
|
||||
cp CHANGES LEGAL MPL-1.1.txt README docs/FAQ docs/FEATURES docs/TODO \
|
||||
cd $(top_srcdir) ; cp CHANGES LEGAL MPL-1.1.txt MITX.txt README \
|
||||
docs/FAQ docs/FEATURES docs/TODO \
|
||||
$(cygwintmp)/usr/doc/$(PACKAGE)-$(VERSION)
|
||||
cd $(cygwintmp) ; \
|
||||
tar cjf $(PACKAGE)-$(VERSION)-$(CYGBUILD).tar.bz2 usr
|
||||
mv $(cygwintmp)/$(PACKAGE)-$(VERSION)-$(CYGBUILD).tar.bz2 . \
|
||||
&& rm -rf $(cygwintmp)
|
||||
|
||||
|
@@ -1,35 +1,34 @@
|
||||
Curl is a tool for transferring files with URL syntax, supporting FTP, FTPS,
|
||||
HTTP, HTTPS, GOPHER, TELNET, DICT, FILE and LDAP. Curl supports HTTPS
|
||||
certificates, HTTP POST, HTTP PUT, FTP uploading, kerberos, HTTP form based
|
||||
upload, proxies, cookies, user+password authentication, file transfer resume,
|
||||
Curl is a tool for transferring files with URL syntax, supporting
|
||||
FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE and LDAP.
|
||||
Curl supports HTTPS certificates, HTTP POST, HTTP PUT,
|
||||
FTP uploading, kerberos, HTTP form based upload, proxies,
|
||||
cookies, user+password authentication, file transfer resume,
|
||||
http proxy tunneling and a busload of other useful tricks.
|
||||
|
||||
See /usr/doc/curl-<version>/FEATURES for more info.
|
||||
|
||||
cURL (as of 7.9.1) builds 100% cleanly OOTB.
|
||||
|
||||
The Cygwin specific source files (README and a Makefile for
|
||||
building binary tarballs) are not in a CYGWIN-PATCHES directory.
|
||||
They are at: <srctop>/packages/Win32/cygwin/
|
||||
|
||||
|
||||
Direct Dependencies:
|
||||
OpenSSL 0.9.6b
|
||||
Dependencies:
|
||||
- Cygwin
|
||||
- OpenSSL 0.9.6b-2+ (*)
|
||||
(*) cURL can be built without SSL support: ./configure --without-ssl
|
||||
|
||||
|
||||
Canonical Homepage:
|
||||
Canonical Homepage and Downloads:
|
||||
http://curl.haxx.se/
|
||||
|
||||
|
||||
Canonical Download:
|
||||
http://curl.haxx.se/download.html
|
||||
|
||||
|
||||
Build Instructions:
|
||||
Download the source, move it to a location of your choosing, and then:
|
||||
Cygwin specific source files (a .README template and a Makefile
|
||||
for building binary tarballs) are maintained in the upstream
|
||||
CVS at: <srctop>/packages/Win32/cygwin/
|
||||
|
||||
|
||||
Build Instructions (as distributed via cygwin's setup.exe):
|
||||
(NOTE: as of curl 7.9.1, compiles/tests 100% cleanly OOTB under cygwin)
|
||||
|
||||
Download the source, unpack it to a location of your choosing, and then:
|
||||
|
||||
$ tar xjf curl-<ver>-X-src.tar.bz2
|
||||
$ cd curl-<ver>-X
|
||||
$ ./configure --prefix=/usr
|
||||
$ make
|
||||
$ make test # optional, requires perl
|
||||
@@ -42,19 +41,45 @@ Build Instructions:
|
||||
|
||||
|
||||
Packaging Instructions:
|
||||
To create a new binary tarball for cygwin's setup.exe, the first step is to
|
||||
do a clean build (./configure and make). The 'make install' step is optional.
|
||||
Then do:
|
||||
---BINARY---
|
||||
Compile cleanly (./configure + make). Then:
|
||||
|
||||
$ cd curl-<ver>-X
|
||||
$ make cygwinbin CYGBUILD=X
|
||||
$ make cygwinbin CYGBUILD=n
|
||||
|
||||
where "X" is the cygwin release number (e.g. the "-1" in curl-7.9.3-1).
|
||||
If you leave off "CYGBUILD=X", X defaults to 1.
|
||||
where n is the cygwin release number (e.g. the "1" in curl-7.9-1).
|
||||
If you leave off "CYGBUILD=n", n defaults to 1.
|
||||
|
||||
Assuming everything worked properly, you'll find your cygwin
|
||||
binary tarball in the curl-<ver>-X/packages/Win32/cygwin/ directory.
|
||||
Assuming everything worked properly, you'll find your binary tarball
|
||||
in the packages/Win32/cygwin/ sub-directory.
|
||||
|
||||
---SOURCE---
|
||||
1. unpack the pristine source into an otherwise empty directory
|
||||
2. rename the source dir to add the "-$(REL)" suffix, e.g.:
|
||||
$ mv curl-7.9 curl-7.9-1
|
||||
3. add a CYGWIN-PATCHES directory, and add this readme to it
|
||||
$ cd curl-7.9-$(REL); mkdir CYGWIN-PATCHES
|
||||
$ cp packages/Win32/cygwin/README CYGWIN-PATCHES/curl-7.9-$(REL).README
|
||||
4. if applicable, document any changes in the README file
|
||||
5. create a patch which, when applied (patch -p1 < curl-7.9-$(REL).patch)
|
||||
will remove any patches you've applied:
|
||||
$ cd ..
|
||||
$ diff -Nrup (patched-src-dir) (pristine-src-dir) > curl-7.9-$(REL).patch
|
||||
and then move it into the CYGWIN-PATCHES directory
|
||||
6. repack
|
||||
|
||||
---SETUP.HINT---
|
||||
sdesc: "a client that groks URLs"
|
||||
ldesc: "Curl is a tool for transferring files with URL syntax,
|
||||
supporting FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE
|
||||
and LDAP. Curl supports HTTPS certificates, HTTP POST, HTTP PUT,
|
||||
FTP uploading, kerberos, HTTP form based upload, proxies,
|
||||
cookies, user+password authentication, file transfer resume,
|
||||
http proxy tunneling and a busload of other useful tricks."
|
||||
category: Web Libs
|
||||
requires: cygwin openssl
|
||||
|
||||
|
||||
Cygwin port maintained by:
|
||||
Kevin Roth <kproth at bigfoot dot com>
|
||||
Questions about cURL should be directed to curl@contactor.se.
|
||||
Questions about its cygwin package should be directed to cygwin@cygwin.com.
|
||||
|
10
perl/README
10
perl/README
@@ -10,8 +10,14 @@ Perl
|
||||
elegantly used from within it. You can either invoke external curl command
|
||||
line or use the curl interface.
|
||||
|
||||
Georg Horn's Perl interface to curl is available in the Curl_easy/
|
||||
subdirectory. Using the Curl::easy module is just straightforward and
|
||||
The latest release of Curl_easy, a Perl interface to curl is available from
|
||||
|
||||
http://curl.haxx.se/libcurl/perl/
|
||||
|
||||
(Georg Horn's original version of Curl_easy, supporting curl versions
|
||||
before 7.7 is still available from: http://www.koblenz-net.de/~horn/export/ )
|
||||
|
||||
Using the Curl::easy module is just straightforward and
|
||||
works much like using libcurl in a C programm, so please refer to the
|
||||
documentation of libcurl. Have a look at test.pl to get an idea of how
|
||||
to start.
|
||||
|
@@ -12,6 +12,7 @@ bin_PROGRAMS = curl #memtest
|
||||
|
||||
noinst_HEADERS = setup.h \
|
||||
config-win32.h \
|
||||
config-mac.h \
|
||||
urlglob.h \
|
||||
version.h \
|
||||
writeout.h
|
||||
@@ -26,8 +27,12 @@ BUILT_SOURCES = hugehelp.c
|
||||
CLEANFILES = hugehelp.c
|
||||
NROFF=@NROFF@
|
||||
|
||||
EXTRA_DIST = mkhelp.pl config-win32.h curlmsg.msg\
|
||||
Makefile.vc6 Makefile.b32 Makefile.m32 config.h.in
|
||||
EXTRA_DIST = mkhelp.pl curlmsg.msg \
|
||||
Makefile.vc6 Makefile.b32 Makefile.m32 config.h.in \
|
||||
macos/curl.mcp.xml.sit.hqx \
|
||||
macos/MACINSTALL.TXT \
|
||||
macos/src/curl_GUSIConfig.cpp \
|
||||
macos/src/macos_main.cpp
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign no-dependencies
|
||||
|
||||
|
12
src/config-mac.h
Normal file
12
src/config-mac.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#define HAVE_UNISTD_H 1
|
||||
#define HAVE_FCNTL_H 1
|
||||
#define HAVE_UTIME_H 1
|
||||
#define HAVE_SYS_UTIME_H 1
|
||||
|
||||
#define HAVE_SETVBUF 1
|
||||
#define HAVE_UTIME 1
|
||||
|
||||
#define main(x,y) curl_main(x,y)
|
||||
|
||||
/* we provide our own strdup prototype */
|
||||
char *strdup(char *s1);
|
1
src/macos/MACINSTALL.TXT
Normal file
1
src/macos/MACINSTALL.TXT
Normal file
@@ -0,0 +1 @@
|
||||
MACOS (not MACOS X)
|
1
src/macos/curl.mcp.xml.sit.hqx
Normal file
1
src/macos/curl.mcp.xml.sit.hqx
Normal file
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user