Compare commits

...

227 Commits

Author SHA1 Message Date
Daniel Stenberg
ef442d5803 release time 2007-01-29 14:53:01 +00:00
Daniel Stenberg
8680e010c2 the user-agent fix 2007-01-29 10:12:30 +00:00
Daniel Stenberg
4d8dcf7b77 the libtest source codes that use curlx_tv* functions MUST use the
lib/timeval.c source code since those functions are not in the API (and might
not be accessible)
2007-01-29 10:09:06 +00:00
Daniel Stenberg
abdbd3100f - Michael Wallner reported that when doing a CONNECT with a custom User-Agent
header, you got _two_ User-Agent headers in the CONNECT request...! Added
  test case 287 to verify the fix.
2007-01-29 09:26:36 +00:00
Gunter Knauf
ddace02efe fixed segfault when compiled with MingW32 and cmd or command shell. 2007-01-29 00:51:02 +00:00
Daniel Stenberg
1f4c8c4f09 Andreas Rieke added extra infof() for when a connection is not re-used due to
SSL conditions not being the same
2007-01-28 22:45:22 +00:00
Daniel Stenberg
8162b32bad silence compiler warnings 2007-01-28 22:36:23 +00:00
Gunter Knauf
daf527b276 enabled build with sspi. 2007-01-28 21:54:10 +00:00
Gunter Knauf
ee51c07be6 enabled build with hardcoded ca-bundle path;
added distclean target.
2007-01-28 15:31:06 +00:00
Gunter Knauf
856ba4c6c6 force to create ca-bunde.h even if it exists already. 2007-01-28 15:07:53 +00:00
Gunter Knauf
b3e23373bd use var for awk. 2007-01-28 14:43:25 +00:00
Daniel Stenberg
e5adab39b1 curl_easy_reset() now resets the CA bundle path correctly 2007-01-28 12:58:13 +00:00
Gunter Knauf
d31153584e another small fix to directory listing output; disabled CURL_LIBSSH2_DEBUG. 2007-01-28 12:35:39 +00:00
Daniel Stenberg
823d296e12 recent contributors 2007-01-28 09:59:11 +00:00
Yang Tse
e09450103b Compiler warning fix 2007-01-28 03:51:10 +00:00
Daniel Stenberg
fbc4407583 - David McCreedy fixed the Curl command line tool for HTTP on non-ASCII
platforms.
2007-01-27 23:02:17 +00:00
Gunter Knauf
a79e5d7925 fix sftp directory listing so that it works without -v and is redirectable with -o/-O. 2007-01-27 12:14:02 +00:00
Gunter Knauf
82491d5c06 tell us what we put out here... 2007-01-27 11:50:42 +00:00
Yang Tse
b6f889085d update copyright year notice 2007-01-27 03:43:05 +00:00
Yang Tse
cdbbb7d900 Compiler warning fix 2007-01-27 03:14:25 +00:00
Yang Tse
2bf4d9a22c sync with lib/setup_once.h 2007-01-27 01:56:57 +00:00
Yang Tse
f1918aa343 sync comment with reality 2007-01-27 01:56:20 +00:00
Gunter Knauf
56580fc6f8 remove the res file too with clean target. 2007-01-26 21:00:02 +00:00
Gunter Knauf
2e6600425e removed CFLAGS from linking. 2007-01-26 20:05:38 +00:00
Gunter Knauf
cc021fc200 fix redefine warning when build from CVS. 2007-01-26 20:00:55 +00:00
Dan Fandrich
e6aed92742 Fixed compiler warning. 2007-01-26 17:50:06 +00:00
Gisle Vanem
02fb4d96d1 Remove LoadLibrary() (from my private build). 2007-01-26 16:36:59 +00:00
Gisle Vanem
43e3c5e5fa Free 'config->libcurl' at exit. 2007-01-26 16:24:52 +00:00
Gisle Vanem
4f496f2f70 Use "%Od" instead of CURL_FORMAT_OFF_T for <curlx.h> functions. 2007-01-26 16:18:47 +00:00
Gisle Vanem
d681bc7520 Options of type CURLOPTTYPE_FUNCTIONPOINT are never printable. 2007-01-26 15:15:27 +00:00
Gunter Knauf
f21a2b3270 updated mingw build instructions for libssh2. 2007-01-26 13:55:18 +00:00
Gunter Knauf
5f5a28d20e added project header to lib resource file; fixed header copyright. 2007-01-26 08:53:03 +00:00
Gunter Knauf
89f9cb4041 use provided resource file for exe. 2007-01-26 08:50:06 +00:00
Daniel Stenberg
2b280bcc69 fix compiler warnings for SSL-disabled builds 2007-01-25 21:00:03 +00:00
Daniel Stenberg
1c0224be42 ugha, prevent a buffer overflow and allow very long strings in the generated
libcurl source...
2007-01-25 20:47:47 +00:00
Daniel Stenberg
dbdb7fa55a - Added the --libcurl [file] option to curl. Append this option to any
ordinary curl command line, and you will get a libcurl-using source code
  written to the file that does the equivalent operation of what your command
  line operation does!
2007-01-25 15:58:00 +00:00
Gunter Knauf
83a43bea8a removed unused define. 2007-01-25 15:00:01 +00:00
Gunter Knauf
abb4cdafe9 set proper lib extension for non-configure mingw32 builds on Win32. 2007-01-25 14:06:38 +00:00
Gunter Knauf
2b7bcf2505 fixed copyright for new year. 2007-01-25 13:17:20 +00:00
Gunter Knauf
5aefdd93cb added targets for libssh2 builds. 2007-01-25 13:15:47 +00:00
Gunter Knauf
4b27fae069 enabled build with libssh2. 2007-01-25 13:14:42 +00:00
Daniel Stenberg
10a13eba72 fix non-SSL builds again 2007-01-25 11:09:56 +00:00
Dan Fandrich
44ac2776ae Fixed a dangling pointer problem that prevented the http_proxy environment
variable from being properly used in many cases (and caused test case 63
to fail).
2007-01-25 01:35:43 +00:00
Gunter Knauf
36e3e6ed16 removed not used define. 2007-01-25 00:26:29 +00:00
Dan Fandrich
5f9cbc4209 Only shut down SSL if the CCC command succeeded. 2007-01-24 19:09:12 +00:00
Daniel Stenberg
3239f059b8 moved the SSL pending function to the proper place and name 2007-01-24 17:19:08 +00:00
Daniel Stenberg
45bac25d90 bail out on strdup() errors 2007-01-24 12:34:23 +00:00
Daniel Stenberg
354c8dcd82 - David McCreedy did NTLM changes mainly for non-ASCII platforms:
#1
  There's a compilation error in http_ntlm.c if USE_NTLM2SESSION is NOT
  defined.  I noticed this while testing various configurations.  Line 867 of
  the current http_ntlm.c is a closing bracket for an if/else pair that only
  gets compiled in if USE_NTLM2SESSION is defined.  But this closing bracket
  wasn't in an #ifdef so the code fails to compile unless USE_NTLM2SESSION was
  defined.  Lines 198 and 140 of my patch wraps that closing bracket in an
  #ifdef USE_NTLM2SESSION.

  #2
  I noticed several picky compiler warnings when DEBUG_ME is defined.  I've
  fixed them with casting.  By the way, DEBUG_ME was a huge help in
  understanding this code.

  #3
  Hopefully the last non-ASCII conversion patch for libcurl in a while.  I
  changed the "NTLMSSP" literal to hex since this signature must always be in
  ASCII.

  Conversion code was strategically added where necessary.  And the
  Curl_base64_encode calls were changed so the binary "blobs" http_ntlm.c
  creates are NOT translated on non-ASCII platforms.
2007-01-23 22:57:42 +00:00
Daniel Stenberg
b1e4cc370d recount 2007-01-23 22:13:52 +00:00
Daniel Stenberg
2293474b90 #79 is no problem to me (and no response on my mail) 2007-01-23 22:13:34 +00:00
Daniel Stenberg
9e1aef7183 very minor indent change 2007-01-23 22:13:05 +00:00
Dan Fandrich
f68323da7d Ignore XML DOCTYPEs and declarations. 2007-01-23 20:24:26 +00:00
Gisle Vanem
a61aafa325 Speed-up djgpp's stat() by avoid checking for uneeded stuff. 2007-01-23 08:57:12 +00:00
Dan Fandrich
33bea767eb Convert (most of) the test data files into genuine XML. A handful still
are not, due mainly to the lack of support for XML character entities
(e.g. & => &amp; ).  This will make it easier to validate test files using
tools like xmllint, as well as edit and view them using XML tools.
2007-01-23 02:25:56 +00:00
Gunter Knauf
9ab7cda010 enabled build with libssh2; fixed copyright for new year.. 2007-01-23 00:26:45 +00:00
Dan Fandrich
6da70628c6 Make the test script tag parser a bit more robust.
Check for the .exe extension on mingw32 builds.
2007-01-18 20:32:46 +00:00
Dan Fandrich
3bae748256 Added precheck that curl supports the 'openssl' engine in test 307. 2007-01-18 18:04:20 +00:00
Dan Fandrich
521c4b303d Fixed some tag typos in the test data files. 2007-01-17 20:36:56 +00:00
Dan Fandrich
a2effd123a Disabled test 307 for now. 2007-01-17 19:23:32 +00:00
Gisle Vanem
7b704e173c Supress "comparison between signed and unsigned" warning. 2007-01-17 15:15:21 +00:00
Daniel Stenberg
6045d051d7 two other still outstanding issues 2007-01-17 12:00:08 +00:00
Daniel Stenberg
cfe00ed4ad more reported bugs we need to address at some point, possibly before a release 2007-01-17 10:15:09 +00:00
Daniel Stenberg
0b4bdcf18f clarify the INFILESIZE option(s) 2007-01-17 08:57:20 +00:00
Daniel Stenberg
8cade952bf David McCreedy fixed a flaw from his previous non-ascii HTTP patch 2007-01-16 22:26:50 +00:00
Daniel Stenberg
385e612fa5 - Armel Asselin improved libcurl to behave a lot better when an easy handle
doing an FTP transfer is removed from a multi handle before completion. The
  fix also fixed the "alive counter" to be correct on "premature removal" for
  all protocols.
2007-01-16 22:22:10 +00:00
Daniel Stenberg
1886388791 restore previous addition to the amount of data that is returned 2007-01-16 21:28:45 +00:00
Dan Fandrich
32fe5b14ec Added simple OpenSSL crypto engine tests. 2007-01-16 18:34:58 +00:00
Dan Fandrich
bbdc483671 Fixed a small memory leak in tftp uploads discovered by curl's memory leak
detector.  Also changed tftp downloads to URL-unescape the downloaded
file name.
2007-01-16 18:33:25 +00:00
Dan Fandrich
f11d3c329c Added TFTP upload tests. 2007-01-15 21:06:12 +00:00
Dan Fandrich
b0d13fa4cb Leave the TFTPD test server running after a file upload.
Flush the protocol log data so it's immediately available to the test harness.
2007-01-15 21:03:53 +00:00
Daniel Stenberg
0fb5a65a58 - David McCreedy provided libcurl changes for doing HTTP communication on
non-ASCII platforms. It does add some complexity, most notably with more
  #ifdefs, but I want to see this supported added and I can't see how we can
  add it without the extra stuff added.
2007-01-14 14:57:51 +00:00
Daniel Stenberg
c8afb02b4c 4GB download and cookielist "ALL" fixes 2007-01-13 23:33:50 +00:00
Daniel Stenberg
869d65337e fixed bad variable use when getting the size which we should read when
attempting not to read data that might belong to the next response (if
pipelining)
2007-01-13 23:33:21 +00:00
Daniel Stenberg
277df1c6b1 make Curl_cookie_clearall() survive getting called with a NULL pointer 2007-01-13 23:32:14 +00:00
Dan Fandrich
5ec5b95f54 Added test for TFTP retrieve of boundary case 512 byte file. 2007-01-10 23:40:22 +00:00
Dan Fandrich
9e61c904ac Display crypto engine name correctly in debug message. 2007-01-10 21:21:53 +00:00
Dan Fandrich
7efb955fd0 Added test of TFTP server error reporting. 2007-01-10 03:32:19 +00:00
Daniel Stenberg
75899741b9 corrected example 2007-01-09 18:58:16 +00:00
Linus Nielsen Feltzing
d465199411 Correct error code for CCC/SSL shutdown failure 2007-01-08 11:24:11 +00:00
Linus Nielsen Feltzing
55123424c8 Removed unused variable in Curl_ossl_shutdown() 2007-01-08 10:03:19 +00:00
Daniel Stenberg
f5e4a78b59 no suprise really, but it works fine on SH4 as well... 2007-01-08 09:32:02 +00:00
Linus Nielsen Feltzing
7515a75206 Fix compilation errors when building without SSL 2007-01-06 10:49:11 +00:00
Daniel Stenberg
4750e6f3c5 - Linus Nielsen Feltzing introduced the --ftp-ssl-ccc command line option to
curl that uses the new CURLOPT_FTP_SSL_CCC option in libcurl. If enabled, it
  will make libcurl shutdown SSL/TLS after the authentication is done on a
  FTP-SSL operation.
2007-01-05 23:11:14 +00:00
Gisle Vanem
b7aaa4d907 Include <dos.h> for delay() on MSDOS. 2007-01-05 15:56:28 +00:00
Daniel Stenberg
e61e09f658 prevent compiler warning since we use base64.h from libcurl which now has
function(s) using SessionHandle pointers
2007-01-04 23:04:50 +00:00
Daniel Stenberg
058e993acb one issue less before release 2007-01-03 23:13:49 +00:00
Daniel Stenberg
359d500908 - David McCreedy made changes to allow base64 encoding/decoding to work on
non-ASCII platforms.
2007-01-03 23:04:38 +00:00
Daniel Stenberg
cb42855445 new year 2007-01-03 22:24:01 +00:00
Daniel Stenberg
d8ff0336a5 - Matt Witherspoon fixed the flaw which made libcurl 7.16.0 always store
downloaded data in two buffers, just to be able to deal with a special HTTP
  pipelining case. That is now only activated for pipelined transfers. In
  Matt's case, it showed as a considerable performance difference,
2007-01-03 22:18:38 +00:00
Daniel Stenberg
0682d25da5 - Victor Snezhko helped us fix bug report #1603712
(http://curl.haxx.se/bug/view.cgi?id=1603712) (known bug #36) --limit-rate
  (CURLOPT_MAX_SEND_SPEED_LARGE and CURLOPT_MAX_RECV_SPEED_LARGE) are broken
  on Windows (since 7.16.0, but that's when they were introduced as previous
  to that the limiting logic was made in the application only and not in the
  library). It was actually also broken on select()-based systems (as apposed
  to poll()) but we haven't had any such reports. We now use select(), Sleep()
  or delay() properly to sleep a while without waiting for anything input or
  output when the rate limiting is activated with the easy interface.
2007-01-02 22:34:56 +00:00
Daniel Stenberg
d86d14074d - Modified libcurl.pc.in to use Libs.private for the libs libcurl itself needs
to get built static. It has been mentioned before and was again brought to
  our attention by Nathanael Nerode who filed debian bug report #405226
  (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=405226).
2007-01-02 12:14:21 +00:00
Daniel Stenberg
8500397cf1 curl_easy_cleanup kills this memory too 2006-12-31 13:53:19 +00:00
Daniel Stenberg
bd600fbebe curl_easy_duphandle() sets the magic number in the new handle 2006-12-29 11:32:14 +00:00
Daniel Stenberg
064bbb999f mention the no_proxy work 2006-12-25 22:35:48 +00:00
Daniel Stenberg
bedc61ac45 - Robert Foreman provided a prime example snippet showing how libcurl would
get confused and not acknowledge the 'no_proxy' variable properly once it
  had used the proxy and you re-used the same easy handle. I made sure the
  proxy name is properly stored in the connect struct rather than the
  sessionhandle/easy struct.
2006-12-22 15:04:59 +00:00
Daniel Stenberg
61a6992559 Curl_getinfo() now checks for a NULL SessionHandle pointer 2006-12-22 13:44:10 +00:00
Daniel Stenberg
ebee2e323d - David McCreedy fixed a bad call to getsockname() that wrongly used a size_t
variable to point to when it should be a socklen_t.
2006-12-22 13:30:54 +00:00
Daniel Stenberg
b2f8de571f When setting a proxy with environment variables and (for example) running
'curl [URL]' with a URL without a protocol prefix, curl would not send a
correct request as it failed to add the protocol prefix.
2006-12-22 07:30:21 +00:00
Daniel Stenberg
cb4a5f5a2b minor indent fix 2006-12-21 15:47:19 +00:00
Daniel Stenberg
1beb7de7e0 removed unused variables 2006-12-21 10:18:15 +00:00
Daniel Stenberg
89ab5f4380 Robson Braga Araujo reported bug #1618359
(http://curl.haxx.se/bug/view.cgi?id=1618359) and subsequently provided a
patch for it: when downloading 2 zero byte files in a row, curl 7.16.0
enters an infinite loop, while curl 7.16.1-20061218 does one additional
unnecessary request.

Fix: During the "Major overhaul introducing http pipelining support and
shared connection cache within the multi handle." change, headerbytecount
was moved to live in the Curl_transfer_keeper structure. But that structure
is reset in the Transfer method, losing the information that we had about
the header size. This patch moves it back to the connectdata struct.
2006-12-21 10:15:38 +00:00
Daniel Stenberg
439b84c782 CURLOPT_CAPATH is OpenSSL-only 2006-12-21 09:36:03 +00:00
Daniel Stenberg
0e899d7728 * removed the SSH-based protocols as they are now being implemented
* added mentioning of doing the stunnel equivalent ourselves for the test suite
* spell-check
2006-12-19 14:28:01 +00:00
Daniel Stenberg
1a85fb2bd0 37. Having more than one connection to the same host when doing NTLM
authentication (with performs multiple "passes" and authenticates a
  connection rather than a HTTP request), and particularly when using the
  multi interface, there's a risk that libcurl will re-use a wrong connection
  when doing the different passes in the NTLM negotiation and thus fail to
  negotiate (in seemingly mysterious ways).

36. --limit-rate (CURLOPT_MAX_SEND_SPEED_LARGE and
  CURLOPT_MAX_RECV_SPEED_LARGE) are broken on Windows (since 7.16.0, but
  that's when they were introduced as previous to that the limiting logic was
  made in the application only and not in the library). This problem is easily
  repeated and it takes a Windows person to fire up his/hers debugger in order
  to fix. http://curl.haxx.se/bug/view.cgi?id=1603712
2006-12-19 09:09:44 +00:00
Daniel Stenberg
8d11767048 recv() doesn't take MSG_NOSIGNAL in its forth argument so let's not pass it.
Brendan Jurd pointed out.
2006-12-16 22:28:08 +00:00
Daniel Stenberg
fcccf9aa0d Brendan Jurd provided a fix that now prevents libcurl from getting a SIGPIPE
during certain conditions when GnuTLS is used.
2006-12-16 21:33:51 +00:00
Daniel Stenberg
72bd027537 Brendan Jurd pointed out these typos 2006-12-16 21:05:33 +00:00
Gisle Vanem
1d44c9ccc1 Plug more leaks. 2006-12-15 16:57:28 +00:00
Gisle Vanem
33831759b5 Fix typo. 2006-12-15 16:49:40 +00:00
Daniel Stenberg
6fe932b255 minor syntax mistake 2006-12-14 18:20:46 +00:00
Gisle Vanem
8da02df8e0 Free 'config->iface' if set. 2006-12-14 16:42:53 +00:00
Gisle Vanem
587c99351d ahost.exe needs getopt.obj. 2006-12-11 15:18:52 +00:00
Daniel Stenberg
88c8d72a21 Alexey Simak found out that when doing FTP with the multi interface and
something went wrong like it got a bad response code back from the server,
libcurl would leak memory. Added test case 538 to verify the fix.

I also noted that the connection would get cached in that case, which
doesn't make sense since it cannot be re-use when the authentication has
failed. I fixed that issue too at the same time, and also that the path
would be "remembered" in vain for cases where the connection was about to
get closed.
2006-12-11 09:32:58 +00:00
Daniel Stenberg
cf99fed17a PROT_CLOSEACTION doesn't have to be its own bit but can just as well just
include the protocol bits of such actions, which currently only means FTP
2006-12-11 09:31:08 +00:00
Daniel Stenberg
ca48b6bf35 fixed the printf formatting after I changed the type of 'excess' 2006-12-07 15:33:06 +00:00
Daniel Stenberg
4dcd606b47 7.16.1 knows SFTP too 2006-12-06 10:07:12 +00:00
Daniel Stenberg
393ddd6e1f clarify --limit-rate somewhat: it might send away/receive chunks of date in
temporarily higher speeds than requested, but the given limiting is considered
"over time" and is an average
2006-12-06 09:52:04 +00:00
Daniel Stenberg
840e796aa9 Sebastien Willemijns reported bug #1603712
(http://curl.haxx.se/bug/view.cgi?id=1603712) which is about connections
getting cut off prematurely when --limit-rate is used. While I found no such
problems in my tests nor in my reading of the code, I found that the
--limit-rate code was severly flawed (since it was moved into the lib, since
7.15.5) when used with the easy interface and it didn't work as documented so
I reworked it somewhat and now it works for my tests.
2006-12-06 09:37:40 +00:00
Daniel Stenberg
5fd096da8d Stefan Krause pointed out a compiler warning with a picky MSCV compiler when
passing a curl_off_t argument to the Curl_read_rewind() function which takes
an size_t argument. Curl_read_rewind() also had debug code left in it and it
was put in a different source file with no good reason when only used from
one single spot.
2006-12-05 21:40:14 +00:00
Daniel Stenberg
eb29c5c285 removed the final traces of the closepolicy option 2006-12-05 21:39:24 +00:00
Daniel Stenberg
1eb286e43e update after today's work 2006-12-05 16:04:46 +00:00
Daniel Stenberg
ae76ebe2d1 Sh Diao reported that CURLOPT_CLOSEPOLICY doesn't work, and indeed, there is
no code present in the library that receives the option. Since it was not
possible to use, we know that no current users exist and thus we simply
removed it from the docs and made the code always use the default path of
the code.
2006-12-05 16:04:01 +00:00
Daniel Stenberg
e4505aefd9 Jared Lundell filed bug report #1604956
(http://curl.haxx.se/bug/view.cgi?id=1604956) which identified setting
CURLOPT_MAXCONNECTS to zero caused libcurl to SIGSEGV. Starting now, libcurl
will always internally use no less than 1 entry in the connection cache.
2006-12-05 15:36:26 +00:00
Daniel Stenberg
d6b0612882 better preprocessor check for recent MSVC versions 2006-12-05 15:24:18 +00:00
Daniel Stenberg
4c65eb0af8 CURLOPT_FORBID_REUSE works again with a cleaned up order of doing things in
Curl_done()
2006-12-05 15:17:32 +00:00
Daniel Stenberg
318a8258fd oops, fix belonging to the previous curl_getdate() fix since it makes MSVC
use gmtime_r
2006-12-05 15:00:14 +00:00
Daniel Stenberg
17ae28e0fe Martin Skinner brought back bug report #1230118 to haunt us once again.
(http://curl.haxx.se/bug/view.cgi?id=1230118) curl_getdate() did not work
properly for all input dates on Windows. It was mostly seen on some TZ time
zones using DST. Luckily, Martin also provided a fix.
2006-12-05 14:57:43 +00:00
Daniel Stenberg
3c4f622479 Alexey Simak filed bug report #1600447
(http://curl.haxx.se/bug/view.cgi?id=1600447) in which he noted that active
FTP connections don't work with the multi interface. The problem is here that
the multi interface state machine has a state during which it can wait for the
data connection to connect, but the active connection is not done in the same
step in the sequence as the passive one is so it doesn't quite work for
active. The active FTP code still use a blocking function to allow the remote
server to connect.

The fix (work-around is a better word) for this problem is to set the
boolean prematurely that the data connection is completed, so that the "wait
for connect" phase ends at once.
2006-12-05 13:49:29 +00:00
Daniel Stenberg
3ce43764be Matt Witherspoon fixed a problem case when the CPU load went to 100% when a
HTTP upload was disconnected:

"What appears to be happening is that my system (Linux 2.6.17 and 2.6.13) is
setting *only* POLLHUP on poll() when the conditions in my previous mail
occur. As you can see, select.c:Curl_select() does not check for POLLHUP. So
basically what was happening, is poll() was returning immediately (with
POLLHUP set), but when Curl_select() looked at the bits, neither POLLERR or
POLLOUT was set. This still caused Curl_readwrite() to be called, which
quickly returned. Then the transfer() loop kept continuing at full speed
forever."
2006-12-05 13:37:05 +00:00
Daniel Stenberg
b555c60e49 curl.dsmirror.nl is another mirror 2006-12-05 13:21:55 +00:00
Daniel Stenberg
2336d010ef fixed in CVS 2006-12-05 13:20:28 +00:00
Daniel Stenberg
b9af0d89d5 fix the libssh2 include path somewhat when --with-libssh2 is used and added
a warning output if no OpenSSL was found
2006-12-03 09:19:23 +00:00
Daniel Stenberg
6f2afe0c30 CURLOPT_CLOSEPOLICY can't be set 2006-12-01 11:54:00 +00:00
Daniel Stenberg
d8c61d459e Toon Verwaest reported that there are servers that send the Content-Range:
header in a third, not suppported by libcurl, format and we agreed that we
could make the parser more forgiving to accept all the three found
variations.
2006-12-01 07:49:22 +00:00
Daniel Stenberg
7ae5ebbeb2 the extra copy of downloads should be fixed too 2006-11-30 09:21:21 +00:00
Daniel Stenberg
7335b71dfb two more 2006-11-29 21:47:22 +00:00
Daniel Stenberg
9583b03074 Is CURLOPT_FORBID_REUSE broken? 2006-11-29 14:39:50 +00:00
Daniel Stenberg
3c81d5f125 adding notes of what to work on and fix before next release 2006-11-27 22:07:56 +00:00
Daniel Stenberg
688699a046 no need to access it with conn->data since data is already a local variable
holding the conn->data value
2006-11-27 13:38:32 +00:00
Daniel Stenberg
090f5a9a45 added the new test 282 2006-11-25 13:32:48 +00:00
Daniel Stenberg
da58d03ff7 Venkat Akella found out that libcurl did not like HTTP responses that simply
responded with a single status line and no headers nor body. Starting now, a
HTTP response on a persistent connection (i.e not set to be closed after the
response has been taken care of) must have Content-Length or chunked
encoding set, or libcurl will simply assume that there is no body.

To my horror I learned that we had no less than 57(!) test cases that did bad
HTTP responses like this, and even the test http server (sws) responded badly
when queried by the test system if it is the test system. So although the
actual fix for the problem was tiny, going through all the newly failing test
cases got really painful and boring.
2006-11-25 13:32:04 +00:00
Daniel Stenberg
9ea3831c08 James Housley fixed SCP downloading by setting the maxdownload. 2006-11-25 09:49:29 +00:00
Yang Tse
a46f55b9de Make sure RETSIGTYPE is properly defined 2006-11-25 01:02:52 +00:00
Daniel Stenberg
a634f64400 James Housley did lots of work and introduced SFTP downloads. 2006-11-24 22:14:39 +00:00
Yang Tse
bcd8a3b240 Define HAVE_SIGNAL_H, HAVE_SIG_ATOMIC_T and HAVE_SIG_ATOMIC_T_VOLATILE
as appropriate for platforms that don't have autotools support
2006-11-24 16:38:58 +00:00
Daniel Stenberg
04d5d1895c Michael Wallner fixed this problem: When I set domains in the options
struct, and there are domain/search entries in /etc/resolv.conf, the domains
of the options struct will be overridden.
2006-11-22 22:54:41 +00:00
Daniel Stenberg
abd2775a70 Install ares_dns.h too 2006-11-22 22:51:01 +00:00
Yang Tse
73226415fc Added a check in configure that verifies if <signal.h> is available,
defining HAVE_SIGNAL_H if the header is available.

Added a check in configure that tests if the sig_atomic_t type is
available, defining HAVE_SIG_ATOMIC_T if it is available. Providing
a suitable default in setup_once.h if not available.

Added a check in configure that tests if the sig_atomic_t type is
already defined as volatile, defining HAVE_SIG_ATOMIC_T_VOLATILE
if it is available and already defined as volatile.
2006-11-22 18:41:34 +00:00
Daniel Stenberg
ab160ef445 new french mirror 2006-11-21 07:45:49 +00:00
Yang Tse
268fe09322 Revert ftpserver.pl back to revision 1.74 Adding change done in 1.76
This is done to back out changes done in revisions 1.77 and 1.75
2006-11-20 16:58:41 +00:00
Yang Tse
7a557e984a Revert runtests.pl back to revision 1.212
This is done to back out changes done from revisions 1.213 to 1.217
2006-11-20 16:58:04 +00:00
Yang Tse
f1a55cbe6d Revert ftp.pm back to revision 1.5 Adding copyright notice.
This is done to back out changes done from revisions 1.6 to 1.10
2006-11-20 16:57:01 +00:00
Yang Tse
1e35d95df8 Add some message logging 2006-11-20 10:35:25 +00:00
Yang Tse
d8387b418d stop slaves before stopping servers 2006-11-20 06:22:51 +00:00
Yang Tse
adea16a294 Revert to KILL test servers until all test servers
have proper TERM and INT signal handlers implemented.
2006-11-20 03:25:17 +00:00
Daniel Stenberg
7f2d5cab2d log the sleep, like when done in test 190 2006-11-19 22:48:40 +00:00
Daniel Stenberg
c6ff612f6e Frank Teo provided an updated, mostly docs changed 2006-11-19 21:55:34 +00:00
Yang Tse
8db353e1d7 Avoid passing child pid and test server pid, using the running
servers hash, and adjust message arguments accordingly.
2006-11-19 03:47:56 +00:00
Yang Tse
e6978117a7 Comment out the use of the "warnings" module now that ftp.pm seems to
be clear of warnings. Uncomment it if this module is further modified.

The "warnings" module requires perl 5.006 or later. Previous perl
versions don't have it and die on missing modules.
2006-11-19 03:47:11 +00:00
Daniel Stenberg
5dcb055077 new ruby binding, new tclcurl release 2006-11-18 14:46:33 +00:00
Yang Tse
0b5e1a9b2f Avoid keeping dupe pids When forked pid and test server pid is the same one. 2006-11-18 04:07:01 +00:00
Yang Tse
2e17a97474 Fix warning "Use of uninitialized value in ...".
If the list has only one item avoid sort subroutine.
2006-11-18 04:05:42 +00:00
Yang Tse
74ddbd8a3b The hash of running servers is now a hash of hashes which for each running
server holds not only its two main pids, but also the pidfile of the test
server and the 'slavepidfiles' for ftp* servers. This allows a better control
when stopping servers.

Now from runtests.pl when test servers are stopped they are signalled in
sequence TERM, INT and KILL allowing time in between for them to die. This
will give us a chance of gracefully stopping test servers, which we didn't
have when we were killing them in first instance.
2006-11-17 16:44:22 +00:00
Gisle Vanem
b8039a821b Call libssh2_session_free() to release memory allocated during
libssh2 startup.
2006-11-15 05:35:35 +00:00
Gisle Vanem
438312f00e Free 'scp->path' in case of libssh2 setup failure. 2006-11-14 20:26:13 +00:00
Daniel Stenberg
381ccaa391 Ron in bug #1595348 (http://curl.haxx.se/bug/view.cgi?id=1595348) pointed
out a stack overwrite (and the corresponding fix) on 64bit Windows when
dealing with HTTP chunked encoding.
2006-11-13 17:29:07 +00:00
Daniel Stenberg
3204494883 bug #1595348 by Ron pointed out this flaw and fix 2006-11-13 17:26:43 +00:00
Daniel Stenberg
e264f699d4 Tor Arntsen spotted this mistake 2006-11-13 13:48:55 +00:00
Daniel Stenberg
68d4b77d44 we did 1.3.2 and are now on the 1.3.3 track! 2006-11-11 22:23:48 +00:00
Daniel Stenberg
e1ac99af1f fix header to match actual proto 2006-11-11 22:05:33 +00:00
Daniel Stenberg
be0d17e812 cleaned up Curl_write() and the sub functions it uses for various protocols.
They all now return ssize_t to Curl_write().

Unfortunately, Curl_read() is in a sorrier state but it too would benefit from
a similar cleanup.
2006-11-11 21:34:43 +00:00
Daniel Stenberg
4eb35406f4 Nir Soffer updated libcurl.framework.make: fix symlinks, should link to
Versions, not to ./Versions and indentation improvments
2006-11-09 21:58:28 +00:00
Daniel Stenberg
624745ab20 Dmitriy Sergeyev found a SIGSEGV with his test04.c example posted on 7 Nov
2006. It turned out we wrongly assumed that the connection cache was present
when tearing down a connection.
2006-11-09 21:54:33 +00:00
Daniel Stenberg
9354822e09 Ciprian Badescu found a SIGSEGV when doing multiple TFTP transfers using the
multi interface, but I could also repeat it doing multiple sequential ones
with the easy interface. Using Ciprian's test case, I could fix it.
2006-11-09 21:36:18 +00:00
Yang Tse
17d4f9513e Remove showing stderr log files unconditionally for tests 518 and 537.
Add failure checking for servers when fork()ed.

Use same code path in 'stopserver' when called with a single or multiple pids.
2006-11-09 13:20:42 +00:00
Daniel Stenberg
f830d77307 Bradford Bruce reported that when setting CURLOPT_DEBUGFUNCTION without
CURLOPT_VERBOSE set to non-zero, you still got a few debug messages from the
SSL handshake. This is now stopped.
2006-11-08 21:49:14 +00:00
Daniel Stenberg
a03c76b228 ok stop using old and deprecated options 2006-11-08 08:49:27 +00:00
Daniel Stenberg
35ad61429d add missing names 2006-11-07 15:21:11 +00:00
Daniel Stenberg
b5b3d9e5c7 Olaf fixed a leftover problem with the CONNECT fix of his that would leave a
wrong error message in the error message buffer.
2006-11-07 14:07:02 +00:00
Gisle Vanem
6e682c2b01 Moved select_s() to Makefile.dj since select() is used in applications. 2006-11-07 13:29:15 +00:00
Gisle Vanem
7e2ea2ece0 Update copyright year. 2006-11-07 13:20:01 +00:00
Yang Tse
01926d66d7 add TODO note 2006-11-06 18:28:34 +00:00
Yang Tse
69f7d0a0ce compiler warning fix 2006-11-06 18:27:25 +00:00
Yang Tse
d1c84705ec remove redundant check for Win32 2006-11-06 18:26:36 +00:00
Yang Tse
3274908551 avoid a couple of potential zero size memory allocations 2006-11-06 13:56:51 +00:00
Daniel Stenberg
c730934498 mention the areslib.dsp fix 2006-11-05 23:11:22 +00:00
Daniel Stenberg
471a8b223b add the recent crowd of contributors 2006-11-05 23:11:07 +00:00
Daniel Stenberg
47ee9202c3 Andreas Rieke fixed back the correct line endings! 2006-11-05 23:08:11 +00:00
Yang Tse
1bcbe89802 Prevent multiple initialization of memdebug configuration variables.
This was possible on debug c-ares enabled builds when both CURL_MEMDEBUG
and CARES_MEMDEBUG environment variables were set. Leading to a file handle
leak even when both variables had the same value, and wierd test suite
results when different.
2006-11-05 12:42:50 +00:00
Gisle Vanem
bf57e9bb12 Ifdef around S_IRGRP and S_IROTH (meaningless on Win32). 2006-11-03 15:52:21 +00:00
Yang Tse
318a7584f3 add a couple more of debugging messages 2006-11-03 14:13:25 +00:00
Daniel Stenberg
961ec228d4 SCP support added 2006-11-03 13:45:52 +00:00
Daniel Stenberg
a777eb3d81 Olaf Stueben provided a patch that I edited slightly. It fixes the notorious
KNOWN_BUGS #25, which happens when a proxy closes the connection when
libcurl has sent CONNECT, as part of an authentication negotiation. Starting
now, libcurl will re-connect accordingly and continue the authentication as
it should.
2006-11-03 12:43:55 +00:00
Daniel Stenberg
7f79b52dae initial SCP support is now added 2006-11-03 12:22:13 +00:00
Daniel Stenberg
db680edc26 Update the information about what c-ares version that's required. 1.3.1 had
a fatal bug so we must require 1.3.2 to get flawless functionality with c-ares.
2006-11-03 10:56:37 +00:00
Daniel Stenberg
e6ce80458f stand clear for release 1.3.2 2006-11-03 10:47:35 +00:00
Daniel Stenberg
cdcb123aa8 Andreas Rieke added missing file and changed line endings 2006-11-03 10:41:33 +00:00
Yang Tse
78081a1652 reduce max size of dinamically allocated arrays to minimize the nasty
behaviour some versions of IRIX exhibit of committing suicide on big
mallocs instead of just returning a friendly null pointer
2006-11-03 10:05:21 +00:00
Yang Tse
7408976b15 fix missing '$' for var OPT_LIBSSH2 2006-11-03 03:05:15 +00:00
Yang Tse
763bb73cc3 update copyright year 2006-11-03 02:36:32 +00:00
Yang Tse
1dee2cd55e fix comments and renumber rlimit return codes
fix closing of fd's when limit is reached
2006-11-03 01:57:25 +00:00
Yang Tse
426ecfd136 fix comments and renumber rlimit return codes 2006-11-03 01:56:55 +00:00
Daniel Stenberg
4913baed16 update the counter 2006-11-02 22:11:38 +00:00
Daniel Stenberg
675f6a8901 mention the new options 2006-11-02 22:10:18 +00:00
Daniel Stenberg
2147284cad James Housley brought support for SCP transfers 2006-11-02 21:56:40 +00:00
Yang Tse
7f1870da5f remove leftover comment 2006-11-02 20:56:40 +00:00
Yang Tse
2149a095f7 update and split test cases 518 and 537 into its own source code file 2006-11-02 20:50:18 +00:00
Yang Tse
e8d21adbaa code cleanup 2006-11-02 15:47:24 +00:00
Yang Tse
fa28531322 use our internal string functions and replace sprintf with snprintf 2006-11-02 03:45:07 +00:00
Yang Tse
deef85ca9a Update protocol verification end of lines 2006-11-02 01:21:28 +00:00
Yang Tse
4f4427ff41 check symbol HAVE_UNISTD_H instead of UNISTD_H to include unistd.h 2006-11-02 00:34:21 +00:00
Yang Tse
0ed285e84d prototype for gethostname is in unistd.h 2006-11-02 00:33:43 +00:00
Yang Tse
905ca77c9e test 518 is all about testing libcurl functionality
when more than FD_SETSIZE file descriptors are open.
This means that if for any reason we are not able to
open more than FD_SETSIZE file descriptors then test
518 should not be run.

test 537 is all about testing libcurl functionality
when the system has nearly exhausted the number of
free file descriptors. Test 537 will try to run with
very few free file descriptors.
2006-11-01 18:33:50 +00:00
Gisle Vanem
61043c7e74 Updated dependency output. 2006-10-31 20:45:17 +00:00
Gisle Vanem
4545c9f22f Updated dependencies to not include config.h. 2006-10-31 20:44:36 +00:00
Gisle Vanem
ad772d7b48 Removed unneeded stuff. 2006-10-31 18:01:07 +00:00
Gisle Vanem
a56ef92729 Added Watt-32 section to fix things for Watt32+Win32 targets. 2006-10-31 17:54:51 +00:00
Gisle Vanem
561d01c450 Don't include "nameser.h" for Watt32. Use the normal BSD-socket headers. 2006-10-31 17:51:54 +00:00
Gisle Vanem
c6c8a30da1 Added definition of select() for Watt32. 2006-10-31 17:25:48 +00:00
Gisle Vanem
914dbeb12c Rewritten to use ../packages/DOS/common.dj. 2006-10-31 17:24:25 +00:00
Gisle Vanem
56dc90eaab Change 'FILETYPE' to ' VFT_APP'. 2006-10-31 16:25:30 +00:00
Yang Tse
f51c567de3 Show stderr log file for test 518 unconditionally.
In this way we'll be able to sort out problems that might
arise in the prechek phase of the 518 test.

Once that 518 has been verified this change will be undone.
2006-10-31 01:30:42 +00:00
Yang Tse
9b2acca63e Sync comment with code and add three messages more 2006-10-31 01:24:03 +00:00
Yang Tse
afcd9f1b1c Address some pitfalls in the rlimit() function check that were
preventing execution of this test on many platforms
2006-10-30 17:24:31 +00:00
Gisle Vanem
755ccbc468 Allow 'curl_*printf()' to be used in C++ programs. 2006-10-30 16:26:24 +00:00
Daniel Stenberg
0af7aec211 add contributors from the 7.16.0 release 2006-10-30 09:03:34 +00:00
Daniel Stenberg
ee085ad6bd start working on 7.16.1 2006-10-30 08:52:12 +00:00
448 changed files with 6496 additions and 1357 deletions

287
CHANGES
View File

@@ -6,6 +6,293 @@
Changelog
Version 7.16.1 (29 January 2007)
Daniel (29 January 2007)
- Michael Wallner reported that when doing a CONNECT with a custom User-Agent
header, you got _two_ User-Agent headers in the CONNECT request...! Added
test case 287 to verify the fix.
Daniel (28 January 2007)
- curl_easy_reset() now resets the CA bundle path correctly.
- David McCreedy fixed the Curl command line tool for HTTP on non-ASCII
platforms.
Daniel (25 January 2007)
- Added the --libcurl [file] option to curl. Append this option to any
ordinary curl command line, and you will get a libcurl-using source code
written to the file that does the equivalent operation of what your command
line operation does!
Dan F (24 January 2007)
- Fixed a dangling pointer problem that prevented the http_proxy environment
variable from being properly used in many cases (and caused test case 63
to fail).
Daniel (23 January 2007)
- David McCreedy did NTLM changes mainly for non-ASCII platforms:
#1
There's a compilation error in http_ntlm.c if USE_NTLM2SESSION is NOT
defined. I noticed this while testing various configurations. Line 867 of
the current http_ntlm.c is a closing bracket for an if/else pair that only
gets compiled in if USE_NTLM2SESSION is defined. But this closing bracket
wasn't in an #ifdef so the code fails to compile unless USE_NTLM2SESSION was
defined. Lines 198 and 140 of my patch wraps that closing bracket in an
#ifdef USE_NTLM2SESSION.
#2
I noticed several picky compiler warnings when DEBUG_ME is defined. I've
fixed them with casting. By the way, DEBUG_ME was a huge help in
understanding this code.
#3
Hopefully the last non-ASCII conversion patch for libcurl in a while. I
changed the "NTLMSSP" literal to hex since this signature must always be in
ASCII.
Conversion code was strategically added where necessary. And the
Curl_base64_encode calls were changed so the binary "blobs" http_ntlm.c
creates are NOT translated on non-ASCII platforms.
Dan F (22 January 2007)
- Converted (most of) the test data files into genuine XML. A handful still
are not, due mainly to the lack of support for XML character entities
(e.g. & => &amp; ). This will make it easier to validate test files using
tools like xmllint, as well as to edit and view them using XML tools.
Daniel (16 January 2007)
- Armel Asselin improved libcurl to behave a lot better when an easy handle
doing an FTP transfer is removed from a multi handle before completion. The
fix also fixed the "alive counter" to be correct on "premature removal" for
all protocols.
Dan F (16 January 2007)
- Fixed a small memory leak in tftp uploads discovered by curl's memory leak
detector. Also changed tftp downloads to URL-unescape the downloaded
file name.
Daniel (14 January 2007)
- David McCreedy provided libcurl changes for doing HTTP communication on
non-ASCII platforms. It does add some complexity, most notably with more
#ifdefs, but I want to see this supported added and I can't see how we can
add it without the extra stuff added.
- Setting CURLOPT_COOKIELIST to "ALL" when no cookies at all was present,
libcurl would crash when trying to read a NULL pointer.
Daniel (12 January 2007)
- Toby Peterson found a nasty bug that prevented (lib)curl from properly
downloading (most) things that were larger than 4GB on 32 bit systems. Matt
Witherspoon helped as narrow down the problem.
Daniel (5 January 2007)
- Linus Nielsen Feltzing introduced the --ftp-ssl-ccc command line option to
curl that uses the new CURLOPT_FTP_SSL_CCC option in libcurl. If enabled, it
will make libcurl shutdown SSL/TLS after the authentication is done on a
FTP-SSL operation.
Daniel (4 January 2007)
- David McCreedy made changes to allow base64 encoding/decoding to work on
non-ASCII platforms.
Daniel (3 January 2007)
- Matt Witherspoon fixed the flaw which made libcurl 7.16.0 always store
downloaded data in two buffers, just to be able to deal with a special HTTP
pipelining case. That is now only activated for pipelined transfers. In
Matt's case, it showed as a considerable performance difference,
Daniel (2 January 2007)
- Victor Snezhko helped us fix bug report #1603712
(http://curl.haxx.se/bug/view.cgi?id=1603712) (known bug #36) --limit-rate
(CURLOPT_MAX_SEND_SPEED_LARGE and CURLOPT_MAX_RECV_SPEED_LARGE) are broken
on Windows (since 7.16.0, but that's when they were introduced as previous
to that the limiting logic was made in the application only and not in the
library). It was actually also broken on select()-based systems (as apposed
to poll()) but we haven't had any such reports. We now use select(), Sleep()
or delay() properly to sleep a while without waiting for anything input or
output when the rate limiting is activated with the easy interface.
- Modified libcurl.pc.in to use Libs.private for the libs libcurl itself needs
to get built static. It has been mentioned before and was again brought to
our attention by Nathanael Nerode who filed debian bug report #405226
(http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=405226).
Daniel (29 December 2006)
- Make curl_easy_duphandle() set the magic number in the new handle.
Daniel (22 December 2006)
- Robert Foreman provided a prime example snippet showing how libcurl would
get confused and not acknowledge the 'no_proxy' variable properly once it
had used the proxy and you re-used the same easy handle. I made sure the
proxy name is properly stored in the connect struct rather than the
sessionhandle/easy struct.
- David McCreedy fixed a bad call to getsockname() that wrongly used a size_t
variable to point to when it should be a socklen_t.
- When setting a proxy with environment variables and (for example) running
'curl [URL]' with a URL without a protocol prefix, curl would not send a
correct request as it failed to add the protocol prefix.
Daniel (21 December 2006)
- Robson Braga Araujo reported bug #1618359
(http://curl.haxx.se/bug/view.cgi?id=1618359) and subsequently provided a
patch for it: when downloading 2 zero byte files in a row, curl 7.16.0
enters an infinite loop, while curl 7.16.1-20061218 does one additional
unnecessary request.
Fix: During the "Major overhaul introducing http pipelining support and
shared connection cache within the multi handle." change, headerbytecount
was moved to live in the Curl_transfer_keeper structure. But that structure
is reset in the Transfer method, losing the information that we had about
the header size. This patch moves it back to the connectdata struct.
Daniel (16 December 2006)
- Brendan Jurd provided a fix that now prevents libcurl from getting a SIGPIPE
during certain conditions when GnuTLS is used.
Daniel (11 December 2006)
- Alexey Simak found out that when doing FTP with the multi interface and
something went wrong like it got a bad response code back from the server,
libcurl would leak memory. Added test case 538 to verify the fix.
I also noted that the connection would get cached in that case, which
doesn't make sense since it cannot be re-use when the authentication has
failed. I fixed that issue too at the same time, and also that the path
would be "remembered" in vain for cases where the connection was about to
get closed.
Daniel (6 December 2006)
- Sebastien Willemijns reported bug #1603712
(http://curl.haxx.se/bug/view.cgi?id=1603712) which is about connections
getting cut off prematurely when --limit-rate is used. While I found no such
problems in my tests nor in my reading of the code, I found that the
--limit-rate code was severly flawed (since it was moved into the lib, since
7.15.5) when used with the easy interface and it didn't work as documented
so I reworked it somewhat and now it works for my tests.
Daniel (5 December 2006)
- Stefan Krause pointed out a compiler warning with a picky MSCV compiler when
passing a curl_off_t argument to the Curl_read_rewind() function which takes
an size_t argument. Curl_read_rewind() also had debug code left in it and it
was put in a different source file with no good reason when only used from
one single spot.
- Sh Diao reported that CURLOPT_CLOSEPOLICY doesn't work, and indeed, there is
no code present in the library that receives the option. Since it was not
possible to use, we know that no current users exist and thus we simply
removed it from the docs and made the code always use the default path of
the code.
- Jared Lundell filed bug report #1604956
(http://curl.haxx.se/bug/view.cgi?id=1604956) which identified setting
CURLOPT_MAXCONNECTS to zero caused libcurl to SIGSEGV. Starting now, libcurl
will always internally use no less than 1 entry in the connection cache.
- Sh Diao reported that CURLOPT_FORBID_REUSE no works, and indeed it broke in
the 7.16.0 release.
- Martin Skinner brought back bug report #1230118 to haunt us once again.
(http://curl.haxx.se/bug/view.cgi?id=1230118) curl_getdate() did not work
properly for all input dates on Windows. It was mostly seen on some TZ time
zones using DST. Luckily, Martin also provided a fix.
- Alexey Simak filed bug report #1600447
(http://curl.haxx.se/bug/view.cgi?id=1600447) in which he noted that active
FTP connections don't work with the multi interface. The problem is here
that the multi interface state machine has a state during which it can wait
for the data connection to connect, but the active connection is not done in
the same step in the sequence as the passive one is so it doesn't quite work
for active. The active FTP code still use a blocking function to allow the
remote server to connect.
The fix (work-around is a better word) for this problem is to set the
boolean prematurely that the data connection is completed, so that the "wait
for connect" phase ends at once.
The proper fix, left for the future, is of course to make the active FTP
case to act in a non-blocking way too.
- Matt Witherspoon fixed a problem case when the CPU load went to 100% when a
HTTP upload was disconnected:
"What appears to be happening is that my system (Linux 2.6.17 and 2.6.13) is
setting *only* POLLHUP on poll() when the conditions in my previous mail
occur. As you can see, select.c:Curl_select() does not check for POLLHUP. So
basically what was happening, is poll() was returning immediately (with
POLLHUP set), but when Curl_select() looked at the bits, neither POLLERR or
POLLOUT was set. This still caused Curl_readwrite() to be called, which
quickly returned. Then the transfer() loop kept continuing at full speed
forever."
Daniel (1 December 2006)
- Toon Verwaest reported that there are servers that send the Content-Range:
header in a third, not suppported by libcurl, format and we agreed that we
could make the parser more forgiving to accept all the three found
variations.
Daniel (25 November 2006)
- Venkat Akella found out that libcurl did not like HTTP responses that simply
responded with a single status line and no headers nor body. Starting now, a
HTTP response on a persistent connection (i.e not set to be closed after the
response has been taken care of) must have Content-Length or chunked
encoding set, or libcurl will simply assume that there is no body.
To my horror I learned that we had no less than 57(!) test cases that did bad
HTTP responses like this, and even the test http server (sws) responded badly
when queried by the test system if it is the test system. So although the
actual fix for the problem was tiny, going through all the newly failing test
cases got really painful and boring.
Daniel (24 November 2006)
- James Housley did lots of work and introduced SFTP downloads.
Daniel (13 November 2006)
- Ron in bug #1595348 (http://curl.haxx.se/bug/view.cgi?id=1595348) pointed
out a stack overwrite (and the corresponding fix) on 64bit Windows when
dealing with HTTP chunked encoding.
Daniel (9 November 2006)
- Nir Soffer updated libcurl.framework.make:
o fix symlinks, should link to Versions, not to ./Versions
o indentation improvments
- Dmitriy Sergeyev found a SIGSEGV with his test04.c example posted on 7 Nov
2006. It turned out we wrongly assumed that the connection cache was present
when tearing down a connection.
- Ciprian Badescu found a SIGSEGV when doing multiple TFTP transfers using the
multi interface, but I could also repeat it doing multiple sequential ones
with the easy interface. Using Ciprian's test case, I could fix it.
Daniel (8 November 2006)
- Bradford Bruce reported that when setting CURLOPT_DEBUGFUNCTION without
CURLOPT_VERBOSE set to non-zero, you still got a few debug messages from the
SSL handshake. This is now stopped.
Daniel (7 November 2006)
- Olaf fixed a leftover problem with the CONNECT fix of his that would leave a
wrong error message in the error message buffer.
Daniel (3 November 2006)
- Olaf Stueben provided a patch that I edited slightly. It fixes the notorious
KNOWN_BUGS #25, which happens when a proxy closes the connection when
libcurl has sent CONNECT, as part of an authentication negotiation. Starting
now, libcurl will re-connect accordingly and continue the authentication as
it should.
Daniel (2 November 2006)
- James Housley brought support for SCP transfers, based on the libssh2 library
for the actual network protocol stuff.
Added these new curl_easy_setopt() options:
CURLOPT_SSH_AUTH_TYPES
CURLOPT_SSH_PUBLIC_KEYFILE
CURLOPT_SSH_PRIVATE_KEYFILE
Version 7.16.0 (30 October 2006)
Daniel (25 October 2006)

View File

@@ -1,6 +1,6 @@
COPYRIGHT AND PERMISSION NOTICE
Copyright (c) 1996 - 2006, Daniel Stenberg, <daniel@haxx.se>.
Copyright (c) 1996 - 2007, Daniel Stenberg, <daniel@haxx.se>.
All rights reserved.

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
# Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -73,6 +73,14 @@ mingw32-ssl:
$(MAKE) -C lib -f Makefile.m32 SSL=1 ZLIB=1
$(MAKE) -C src -f Makefile.m32 SSL=1 ZLIB=1
mingw32-ssh2-ssl:
$(MAKE) -C lib -f Makefile.m32 SSH2=1 SSL=1 ZLIB=1
$(MAKE) -C src -f Makefile.m32 SSH2=1 SSL=1 ZLIB=1
mingw32-ssh2-ssl-sspi:
$(MAKE) -C lib -f Makefile.m32 SSH2=1 SSL=1 SSPI=1 ZLIB=1
$(MAKE) -C src -f Makefile.m32 SSH2=1 SSL=1 SSPI=1 ZLIB=1
mingw32-clean:
$(MAKE) -C lib -f Makefile.m32 clean
$(MAKE) -C src -f Makefile.m32 clean
@@ -212,6 +220,10 @@ netware-ssl-zlib:
$(MAKE) -C lib -f Makefile.netware WITH_SSL=1 WITH_ZLIB=1
$(MAKE) -C src -f Makefile.netware WITH_SSL=1 WITH_ZLIB=1
netware-ssh2-ssl-zlib:
$(MAKE) -C lib -f Makefile.netware WITH_SSH2=1 WITH_SSL=1 WITH_ZLIB=1
$(MAKE) -C src -f Makefile.netware WITH_SSH2=1 WITH_SSL=1 WITH_ZLIB=1
netware-zlib:
$(MAKE) -C lib -f Makefile.netware WITH_ZLIB=1
$(MAKE) -C src -f Makefile.netware WITH_ZLIB=1

View File

@@ -1,80 +1,86 @@
Curl and libcurl 7.16.0
Curl and libcurl 7.16.1
Public curl release number: 96
Releases counted from the very beginning: 123
Available command line options: 112
Available curl_easy_setopt() options: 133
Public curl release number: 97
Releases counted from the very beginning: 124
Available command line options: 115
Available curl_easy_setopt() options: 137
Number of public functions in libcurl: 54
Amount of public web site mirrors: 37
Amount of public web site mirrors: 39
Number of known libcurl bindings: 35
Number of contributors: 515
Number of contributors: 539
This release includes the following changes:
o Added CURLE_SSL_CACERT_BADFILE
o Added CURLMOPT_TIMERFUNCTION and CURLMOPT_TIMERDATA
o (FTP) the CURLOPT_SOURCE_* options are removed and so are the --3p* command
line options
o curl_multi_socket() and family are suitable to start using
o uses WSAPoll() on Windows Vista
o (FTP) --ftp-ssl-control was added
o CURLOPT_SSL_SESSIONID_CACHE and --no-sessionid added
o CURLMOPT_PIPELINING added for enabling HTTP pipelined transfers
o multi handles now have a shared connection cache
o Added support for other MS-DOS compilers (besides djgpp)
o CURLOPT_SOCKOPTFUNCTION and CURLOPT_SOCKOPTDATA were added
o (FTP) libcurl avoids sending TYPE if the desired type was already set
o (FTP) CURLOPT_PREQUOTE works even when CURLOPT_NOBODY is set true
o Support for SCP and SFTP were added (powered by libssh2)
o CURLOPT_CLOSEPOLICY is now deprecated
o --ftp-ssl-ccc and CURLOPT_FTP_SSL_CCC were added
o HTTP support for non-ASCII platforms
o --libcurl was added
This release includes the following bugfixes:
o (HTTP) CURLOPT_FAILONERROR (curl -f) covers a few more reponse cases
o curl_multi_socket() and the LOW_SPEED options
o curl_multi_socket() expire timer during c-ares name resolves
o curl_multi_add_handle on an already added handle now fails gracefully
o multi interface crash if bad function call order was used for cleanup
o put a new URL in saved cookie jar files
o configure --with-gssapi-libs
o SOCKS proxy connection fixes
o (FTP) a failed upload does not invalidate the control connection
o proxy URL with user name and empty password or no password at all now work
o fixed a socket state problem with *multi_socket()
o (HTTP) NTLM hostname fix
o getsockname usage fixes
o SOCKS5 proxy connects can now time-out
o SOCKS5 connects that require auth no longer segfaults when auth not given
o multi interface using asynch resolves could get stuck in wrong state
o the 'running_handles' counter wasn't always updated properly when
curl_multi_remove_handle() was used
o (FTP) EPRT transfers with IPv6 didn't work properly
o (FTP) SINGLECWD mode and using files in the root dir
o (HTTP) Expect: header disabling work better
o (HTTP) "Expect: 100-continue" disable on second POST on re-used connection
o src/config.h.in is fixed
o (HTTP) POST data logged to the debug callback function is now correctly
tagged as data, not header
o proxy close during CONNECT authentication is now dealt with nicely
o the CURLOPT_DEBUGFUNCTION was sometimes called even when CURLOPT_VERBOSE
was not enabled
o multiple TFTP transfers on the same (easy or multi) handle could cause a
crash
o SIGSEGV when disconnecting on a transfer on a re-used handle when the
host name didn't resolve
o stack overwrite on 64bit Windows in the chunked decoding department
o HTTP responses on persistent connections without Content-Length nor chunked
encoding are now considered to be without response body
o Content-Range: header parsing improved
o CPU 100% load when HTTP upload connection broke
o active FTP didn't work with multi interface
o curl_getdate() could be off one hour for TZ time zones with DST, on windows
o CURLOPT_FORBID_REUSE works again
o CURLOPT_MAXCONNECTS set to zero caused libcurl to SIGSEGV
o rate limiting works better
o getting FTP response code errors when using the multi-interface caused
libcurl to leak memory
o no more SIGPIPE when GnuTLS is used
o FTP downloading 2 zero byte files in a row
o using proxy and URLs without protocol prefixes
o first using a proxy and then accessing a site that 'no_proxy' matched,
would still make libcurl use the proxy...
o curl_easy_duphandle() now makes a handle that is valid for the multi
interface since the magic number is set fine
o libcurl.pc now uses Libs.private for "private" libs
o --limit-rate (CURLOPT_MAX_SEND_SPEED_LARGE and CURLOPT_MAX_RECV_SPEED_LARGE)
now work on windows again
o improved download performance by avoiding the unconditional "double copying"
o base64 encoding/decoding works on non-ASCII platforms
o large file downloads
o CURLOPT_COOKIELIST set to "ALL" crash
o easy handle removal from multi handle before completion
o TFTP upload memory leak
o curl_easy_reset() now resets the CA bundle path correctly
o two User-Agent headers in CONNECT requests with custom User-Agent
This release includes the following known bugs:
o see docs/KNOWN_BUGS (http://curl.haxx.se/docs/knownbugs.html)
Other curl-related news:
o a Smalltalk binding: http://curl.haxx.se/libcurl/smalltalk/
o pycurl-7.15.5 was released: http://pycurl.sf.net
o TclCurl 7.16.0 was released:
http://personal1.iddeo.es/andresgarci/tclcurl/english/
o Curb - Libcurl bindings for Ruby: http://curb.rubyforge.org/
New curl mirrors:
o http://curl.geosdreams.info/ is a new Polish mirror
o http://curl.gfiles.org/ is a new Russian mirror
o http://curl.online-mirror.de/ is a new German mirror
o http://curl.blogvoid.com/ is a new Canadian mirror
o http://curl.internet.bs/ is a new United Kingdom mirror
o http://curl2.haxx.se/ is a new Swedish mirror
o curl.miroir-francais.fr is a new French web mirror
o curl.dsmirror.nl is a new Dutch web mirror
This release would not have looked like this without help, code, reports and
advice from friends like these:
Domenico Andreoli, Armel Asselin, Gisle Vanem, Yang Tse, Andrew Biggs,
Peter Sylvester, David McCreedy, Dmitriy Sergeyev, Dmitry Rechkin,
Jari Sundell, Ravi Pratap, Michele Bini, Jeff Pohlmeyer, Michael Wallner,
Mike Protts, Cory Nelson, Bernard Leak, Bogdan Nicula, Dan Fandrich,
Nir Soffer
James Housley, Olaf Stueben, Yang Tse, Gisle Vanem, Bradford Bruce,
Ciprian Badescu, Dmitriy Sergeyev, Nir Soffer, Venkat Akella, Toon Verwaest,
Matt Witherspoon, Alexey Simak, Martin Skinner, Sh Diao, Jared Lundell,
Stefan Krause, Sebastien Willemijns, Alexey Simak, Brendan Jurd,
Robson Braga Araujo, David McCreedy, Robert Foreman, Nathanael Nerode,
Victor Snezhko, Linus Nielsen Feltzing, Toby Peterson, Dan Fandrich,
Armel Asselin, Michael Wallner, Guenter Knauf
Thanks! (and sorry if I forgot to mention someone)

View File

@@ -1,6 +1,4 @@
To get fixed in 7.16.0 (planned release: October 2006)
To get fixed in 7.16.1 (planned release: January 2007)
======================
67 - Jeff Pohlmeyer's crashing pipelining test case
69 -
82 -

View File

@@ -1035,6 +1035,48 @@ AC_DEFUN([CURL_CHECK_STRUCT_TIMEVAL], [
]) # AC_DEFUN
dnl TYPE_SIG_ATOMIC_T
dnl -------------------------------------------------
dnl Check if the sig_atomic_t type is available, and
dnl verify if it is already defined as volatile.
AC_DEFUN([TYPE_SIG_ATOMIC_T], [
AC_CHECK_HEADERS(signal.h)
AC_CHECK_TYPE([sig_atomic_t],[
AC_DEFINE(HAVE_SIG_ATOMIC_T, 1,
[Define to 1 if sig_atomic_t is an available typedef.])
], ,[
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
])
case "$ac_cv_type_sig_atomic_t" in
yes)
#
AC_MSG_CHECKING([if sig_atomic_t is already defined as volatile])
AC_TRY_LINK([
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
],[
static volatile sig_atomic_t dummy = 0;
],[
AC_MSG_RESULT([no])
ac_cv_sig_atomic_t_volatile="no"
],[
AC_MSG_RESULT([yes])
ac_cv_sig_atomic_t_volatile="yes"
])
#
if test "$ac_cv_sig_atomic_t_volatile" = "yes"; then
AC_DEFINE(HAVE_SIG_ATOMIC_T_VOLATILE, 1,
[Define to 1 if sig_atomic_t is already defined as volatile.])
fi
;;
esac
]) # AC_DEFUN
dnl CURL_CHECK_NONBLOCKING_SOCKET
dnl -------------------------------------------------
dnl Check for how to set a socket to non-blocking state. There seems to exist

View File

@@ -14,3 +14,9 @@ Henrik Stoerner
Yang Tse
Nick Mathewson
Alexander Lazic
Andreas Rieke
Guilherme Balena Versiani
Brad Spencer
Ravi Pratap
William Ahern
Bram Matthys

View File

@@ -1,5 +1,23 @@
Changelog for the c-ares project
* November 22
- Install ares_dns.h too
- Michael Wallner fixed this problem: When I set domains in the options
struct, and there are domain/search entries in /etc/resolv.conf, the domains
of the options struct will be overridden.
* November 6
- Yang Tse removed a couple of potential zero size memory allocations.
- Andreas Rieke fixed the line endings in the areslib.dsp file that I (Daniel)
broke in the 1.3.2 release. We should switch to a system where that file is
auto-generated. We could rip some code for that from curl...
Version 1.3.2 (November 3, 2006)
* October 12 2006
- Prevent ares_getsock() to overflow if more than 16 sockets are used.

View File

@@ -59,7 +59,7 @@ libcares_la_SOURCES = $(CSOURCES) $(HHEADERS)
# where to install the c-ares headers
libcares_ladir = $(includedir)
# what headers to install on 'make install':
libcares_la_HEADERS = ares.h ares_version.h
libcares_la_HEADERS = ares.h ares_version.h ares_dns.h
# Make files named *.dist replace the file without .dist extension
dist-hook:

View File

@@ -2,34 +2,50 @@
# c-ares Makefile for djgpp/gcc/Watt-32.
# By Gisle Vanem <giva@bgnett.no> 2004.
#
.SUFFIXES: .exe
# $Id$
include ../packages/DOS/common.dj
include Makefile.inc
WATT32_ROOT = $(subst \,/,$(WATT_ROOT))
CC = gcc
CFLAGS = -O2 -Wall -DWATT32 -Dselect=select_s -DHAVE_AF_INET6 \
-DHAVE_PF_INET6 -DHAVE_IOCTLSOCKET -DHAVE_STRUCT_IN6_ADDR \
-DHAVE_STRUCT_SOCKADDR_IN6 -DHAVE_STRUCT_ADDRINFO \
-DHAVE_ARPA_NAMESER_H -DNS_INADDRSZ=4 \
-DHAVE_SYS_TIME_H -DHAVE_TIME_H \
-DTIME_WITH_SYS_TIME -DHAVE_STRUCT_TIMEVAL \
-DHAVE_SOCKADDR_IN6_SIN6_SCOPE_ID -I$(WATT32_ROOT)/inc
CFLAGS += -DWATT32 -DHAVE_AF_INET6 -DHAVE_PF_INET6 -DHAVE_FIONBIO \
-DHAVE_STRUCT_IN6_ADDR -DHAVE_SOCKADDR_IN6_SIN6_SCOPE_ID \
-DHAVE_SYS_TIME_H -DHAVE_STRUCT_SOCKADDR_IN6 -DHAVE_STRUCT_ADDRINFO \
-DHAVE_SIGNAL_H -DHAVE_SIG_ATOMIC_T -DRETSIGTYPE='void' \
-DHAVE_ARPA_NAMESER_H -DNS_INADDRSZ=4 -DHAVE_RECV -DHAVE_SEND \
-DSEND_TYPE_ARG1='int' -DSEND_QUAL_ARG2='const' \
-DSEND_TYPE_ARG2='void*' -DSEND_TYPE_ARG3='int' \
-DSEND_TYPE_ARG4='int' -DSEND_TYPE_RETV='int' \
-DRECV_TYPE_ARG1='int' -DRECV_TYPE_ARG2='void*' \
-DRECV_TYPE_ARG3='int' -DRECV_TYPE_ARG4='int' \
-DRECV_TYPE_RETV='int' -UHAVE_CONFIG_H -Dselect=select_s
LDFLAGS = -s
EX_LIBS = $(WATT32_ROOT)/lib/libwatt.a
OBJ_DIR = djgpp
ifeq ($(USE_DEBUG),1)
EX_LIBS = ../lib/libcurl.a
endif
ifeq ($(USE_SSL),1)
EX_LIBS += $(OPENSSL_ROOT)/lib/libssl.a $(OPENSSL_ROOT)/lib/libcrypt.a
endif
ifeq ($(USE_ZLIB),1)
EX_LIBS += $(ZLIB_ROOT)/libz.a
CFLAGS += -DUSE_MANUAL
endif
ifeq ($(USE_IDNA),1)
EX_LIBS += $(LIBIDN_ROOT)/lib/dj_obj/libidn.a -liconv
endif
EX_LIBS += $(WATT32_ROOT)/lib/libwatt.a
OBJECTS = $(addprefix $(OBJ_DIR)/, $(CSOURCES:.c=.o))
all: $(OBJ_DIR) libcares.a ahost.exe adig.exe
@echo Welcome to c-ares.
$(OBJ_DIR):
- mkdir $(OBJ_DIR)
libcares.a: $(OBJECTS)
ar rs $@ $?
@@ -46,12 +62,132 @@ vclean realclean: clean
rm -f ahost.exe adig.exe depend.dj
- rmdir $(OBJ_DIR)
$(OBJ_DIR)/%.o: %.c
$(CC) $(CFLAGS) -o $@ -c $<
@echo
depend:
$(CC) -MM $(CFLAGS) $(CSOURCES) | \
sed -e 's/^\([a-zA-Z0-9_-]*\.o:\)/$$(OBJ_DIR)\/\1/' > depend.dj
-include depend.dj
# DO NOT DELETE THIS LINE
$(OBJ_DIR)/ares_fds.o: ares_fds.c setup.h setup_once.h ares.h ares_private.h \
ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares_getsock.o: ares_getsock.c setup.h setup_once.h ares.h ares_private.h \
ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares_process.o: ares_process.c setup.h setup_once.h ares.h ares_dns.h \
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares_free_hostent.o: ares_free_hostent.c setup.h setup_once.h ares.h \
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares_query.o: ares_query.c setup.h setup_once.h ares.h ares_dns.h \
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares__close_sockets.o: ares__close_sockets.c setup.h setup_once.h ares.h \
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares_free_string.o: ares_free_string.c setup.h setup_once.h ares.h \
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares_search.o: ares_search.c setup.h setup_once.h ares.h ares_private.h \
ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares__get_hostent.o: ares__get_hostent.c setup.h setup_once.h ares.h \
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h inet_net_pton.h
$(OBJ_DIR)/ares_gethostbyaddr.o: ares_gethostbyaddr.c setup.h setup_once.h ares.h \
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h inet_net_pton.h
$(OBJ_DIR)/ares_send.o: ares_send.c setup.h setup_once.h ares.h ares_dns.h \
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares__read_line.o: ares__read_line.c setup.h setup_once.h ares.h \
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares_gethostbyname.o: ares_gethostbyname.c setup.h setup_once.h ares.h \
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h inet_net_pton.h \
bitncmp.h
$(OBJ_DIR)/ares_strerror.o: ares_strerror.c setup.h setup_once.h ares.h
$(OBJ_DIR)/ares_cancel.o: ares_cancel.c setup.h setup_once.h ares.h ares_private.h \
ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares_init.o: ares_init.c setup.h setup_once.h ares.h ares_private.h \
ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h inet_net_pton.h
$(OBJ_DIR)/ares_timeout.o: ares_timeout.c setup.h setup_once.h ares.h ares_private.h \
ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares_destroy.o: ares_destroy.c setup.h setup_once.h ares.h ares_private.h \
ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares_mkquery.o: ares_mkquery.c setup.h setup_once.h ares.h ares_dns.h \
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares_version.o: ares_version.c setup.h setup_once.h ares_version.h
$(OBJ_DIR)/ares_expand_name.o: ares_expand_name.c setup.h setup_once.h ares.h \
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares_parse_a_reply.o: ares_parse_a_reply.c setup.h setup_once.h ares.h \
ares_dns.h ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/windows_port.o: windows_port.c setup.h setup_once.h
$(OBJ_DIR)/ares_expand_string.o: ares_expand_string.c setup.h setup_once.h ares.h \
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares_parse_ptr_reply.o: ares_parse_ptr_reply.c setup.h setup_once.h \
ares.h ares_dns.h ares_private.h ares_ipv6.h ../lib/memdebug.h \
../lib/setup.h ../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares_parse_aaaa_reply.o: ares_parse_aaaa_reply.c setup.h setup_once.h \
ares.h ares_dns.h inet_net_pton.h ares_private.h ares_ipv6.h \
../lib/memdebug.h ../lib/setup.h ../include/curl/stdcheaders.h \
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h
$(OBJ_DIR)/ares_getnameinfo.o: ares_getnameinfo.c setup.h setup_once.h ares.h \
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
../include/curl/stdcheaders.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/curl.h inet_ntop.h
$(OBJ_DIR)/inet_net_pton.o: inet_net_pton.c setup.h setup_once.h ares_ipv6.h \
inet_net_pton.h
$(OBJ_DIR)/bitncmp.o: bitncmp.c bitncmp.h
$(OBJ_DIR)/inet_ntop.o: inet_ntop.c setup.h setup_once.h ares_ipv6.h inet_ntop.h

View File

@@ -20,7 +20,7 @@ endif
TARGETS = adig.nlm ahost.nlm
LTARGET = libcares.lib
VERSION = $(LIBCARES_VERSION)
COPYR = Copyright (C) 1996 - 2006, Daniel Stenberg, <daniel@haxx.se>
COPYR = Copyright (C) 1996 - 2007, Daniel Stenberg, <daniel@haxx.se>
DESCR = cURL $(subst .def,,$(notdir $@)) $(LIBCARES_VERSION_STR) - http://curl.haxx.se
MTSAFE = YES
STACK = 64000
@@ -281,6 +281,8 @@ config.h: Makefile.netware
@echo $(DL)#define HAVE_SEND 1$(DL) >> $@
@echo $(DL)#define HAVE_SETJMP_H 1$(DL) >> $@
@echo $(DL)#define HAVE_SIGNAL 1$(DL) >> $@
@echo $(DL)#define HAVE_SIGNAL_H 1$(DL) >> $@
@echo $(DL)#define HAVE_SIG_ATOMIC_T 1$(DL) >> $@
@echo $(DL)#define HAVE_SOCKET 1$(DL) >> $@
@echo $(DL)#define HAVE_STDINT_H 1$(DL) >> $@
@echo $(DL)#define HAVE_STDLIB_H 1$(DL) >> $@

View File

@@ -121,8 +121,8 @@ $(DEF_FILE): $(OBJECTS) Makefile.VC6
@echo ares_gettimeofday >> $@
@echo ares_parse_aaaa_reply >> $@
ahost.exe: $(OBJ_DIR) $(OBJ_DIR)\ahost.obj cares_imp.lib
link $(LDFLAGS) -out:$@ $(OBJ_DIR)\ahost.obj cares_imp.lib $(EX_LIBS)
ahost.exe: $(OBJ_DIR) $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\getopt.obj cares_imp.lib
link $(LDFLAGS) -out:$@ $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\getopt.obj cares_imp.lib $(EX_LIBS)
adig.exe: $(OBJ_DIR) $(OBJ_DIR)\adig.obj $(OBJ_DIR)\getopt.obj cares_imp.lib
link $(LDFLAGS) -out:$@ $(OBJ_DIR)\adig.obj $(OBJ_DIR)\getopt.obj cares_imp.lib $(EX_LIBS)

View File

@@ -1013,6 +1013,48 @@ AC_DEFUN([CURL_CHECK_STRUCT_TIMEVAL], [
]) # AC_DEFUN
dnl TYPE_SIG_ATOMIC_T
dnl -------------------------------------------------
dnl Check if the sig_atomic_t type is available, and
dnl verify if it is already defined as volatile.
AC_DEFUN([TYPE_SIG_ATOMIC_T], [
AC_CHECK_HEADERS(signal.h)
AC_CHECK_TYPE([sig_atomic_t],[
AC_DEFINE(HAVE_SIG_ATOMIC_T, 1,
[Define to 1 if sig_atomic_t is an available typedef.])
], ,[
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
])
case "$ac_cv_type_sig_atomic_t" in
yes)
#
AC_MSG_CHECKING([if sig_atomic_t is already defined as volatile])
AC_TRY_LINK([
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
],[
static volatile sig_atomic_t dummy = 0;
],[
AC_MSG_RESULT([no])
ac_cv_sig_atomic_t_volatile="no"
],[
AC_MSG_RESULT([yes])
ac_cv_sig_atomic_t_volatile="yes"
])
#
if test "$ac_cv_sig_atomic_t_volatile" = "yes"; then
AC_DEFINE(HAVE_SIG_ATOMIC_T_VOLATILE, 1,
[Define to 1 if sig_atomic_t is already defined as volatile.])
fi
;;
esac
]) # AC_DEFUN
dnl CURL_CHECK_NONBLOCKING_SOCKET
dnl -------------------------------------------------
dnl Check for how to set a socket to non-blocking state. There seems to exist

View File

@@ -18,7 +18,7 @@
#include "setup.h"
#include <sys/types.h>
#ifdef WIN32
#if defined(WIN32) && !defined(WATT32)
#include "nameser.h"
#else
#include <sys/time.h>

View File

@@ -18,8 +18,7 @@
#include "setup.h"
#include <sys/types.h>
#ifdef WIN32
#else
#if !defined(WIN32) || defined(WATT32)
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>

View File

@@ -39,7 +39,10 @@ void ares_cancel(ares_channel channel)
channel->queries = NULL;
if (!(channel->flags & ARES_FLAG_STAYOPEN))
{
for (i = 0; i < channel->nservers; i++)
ares__close_sockets(channel, &channel->servers[i]);
if (channel->servers)
{
for (i = 0; i < channel->nservers; i++)
ares__close_sockets(channel, &channel->servers[i]);
}
}
}

View File

@@ -25,23 +25,37 @@ void ares_destroy(ares_channel channel)
int i;
struct query *query;
for (i = 0; i < channel->nservers; i++)
ares__close_sockets(channel, &channel->servers[i]);
free(channel->servers);
for (i = 0; i < channel->ndomains; i++)
free(channel->domains[i]);
free(channel->domains);
if (!channel)
return;
if (channel->servers) {
for (i = 0; i < channel->nservers; i++)
ares__close_sockets(channel, &channel->servers[i]);
free(channel->servers);
}
if (channel->domains) {
for (i = 0; i < channel->ndomains; i++)
free(channel->domains[i]);
free(channel->domains);
}
if(channel->sortlist)
free(channel->sortlist);
free(channel->lookups);
while (channel->queries)
{
query = channel->queries;
channel->queries = query->next;
query->callback(query->arg, ARES_EDESTRUCTION, NULL, 0);
if (channel->lookups)
free(channel->lookups);
while (channel->queries) {
query = channel->queries;
channel->queries = query->next;
query->callback(query->arg, ARES_EDESTRUCTION, NULL, 0);
if (query->tcpbuf)
free(query->tcpbuf);
if (query->skip_server)
free(query->skip_server);
free(query);
}
free(query);
}
free(channel);
}

View File

@@ -125,7 +125,9 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
channel->queries = NULL;
channel->domains = NULL;
channel->sortlist = NULL;
channel->servers = NULL;
channel->sock_state_cb = NULL;
channel->sock_state_cb_data = NULL;
/* Initialize configuration by each of the four sources, from highest
* precedence to lowest.
@@ -140,7 +142,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
if (status != ARES_SUCCESS)
{
/* Something failed; clean up memory we may have allocated. */
if (channel->nservers != -1)
if (channel->servers)
free(channel->servers);
if (channel->domains)
{
@@ -214,12 +216,16 @@ static int init_by_options(ares_channel channel, struct ares_options *options,
/* Copy the servers, if given. */
if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
{
channel->servers =
malloc(options->nservers * sizeof(struct server_state));
if (!channel->servers && options->nservers != 0)
return ARES_ENOMEM;
for (i = 0; i < options->nservers; i++)
channel->servers[i].addr = options->servers[i];
/* Avoid zero size allocations at any cost */
if (options->nservers > 0)
{
channel->servers =
malloc(options->nservers * sizeof(struct server_state));
if (!channel->servers)
return ARES_ENOMEM;
for (i = 0; i < options->nservers; i++)
channel->servers[i].addr = options->servers[i];
}
channel->nservers = options->nservers;
}
@@ -228,16 +234,20 @@ static int init_by_options(ares_channel channel, struct ares_options *options,
*/
if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
{
channel->domains = malloc(options->ndomains * sizeof(char *));
if (!channel->domains && options->ndomains != 0)
return ARES_ENOMEM;
for (i = 0; i < options->ndomains; i++)
{
channel->ndomains = i;
channel->domains[i] = strdup(options->domains[i]);
if (!channel->domains[i])
return ARES_ENOMEM;
}
/* Avoid zero size allocations at any cost */
if (options->ndomains > 0)
{
channel->domains = malloc(options->ndomains * sizeof(char *));
if (!channel->domains)
return ARES_ENOMEM;
for (i = 0; i < options->ndomains; i++)
{
channel->ndomains = i;
channel->domains[i] = strdup(options->domains[i]);
if (!channel->domains[i])
return ARES_ENOMEM;
}
}
channel->ndomains = options->ndomains;
}
@@ -582,11 +592,11 @@ DhcpNameServer
return (errno == ENOENT) ? ARES_SUCCESS : ARES_EFILE;
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
{
if ((p = try_config(line, "domain")))
if ((p = try_config(line, "domain")) && channel->ndomains == -1)
status = config_domain(channel, p);
else if ((p = try_config(line, "lookup")) && !channel->lookups)
status = config_lookup(channel, p, "bind", "file");
else if ((p = try_config(line, "search")))
else if ((p = try_config(line, "search")) && channel->ndomains == -1)
status = set_search(channel, p);
else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
status = config_nameserver(&servers, &nservers, p);
@@ -711,7 +721,6 @@ static int init_by_defaults(ares_channel channel)
if (gethostname(hostname, sizeof(hostname)) == -1
|| !strchr(hostname, '.'))
{
channel->domains = malloc(0);
channel->ndomains = 0;
}
else
@@ -940,6 +949,7 @@ static int set_search(ares_channel channel, const char *str)
for(n=0; n < channel->ndomains; n++)
free(channel->domains[n]);
free(channel->domains);
channel->domains = NULL;
channel->ndomains = -1;
}
@@ -955,8 +965,14 @@ static int set_search(ares_channel channel, const char *str)
n++;
}
if (!n)
{
channel->ndomains = 0;
return ARES_SUCCESS;
}
channel->domains = malloc(n * sizeof(char *));
if (!channel->domains && n)
if (!channel->domains)
return ARES_ENOMEM;
/* Now copy the domains. */

View File

@@ -5,11 +5,11 @@
#define ARES_VERSION_MAJOR 1
#define ARES_VERSION_MINOR 3
#define ARES_VERSION_PATCH 1
#define ARES_VERSION_PATCH 3
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
(ARES_VERSION_MINOR<<8)|\
(ARES_VERSION_PATCH))
#define ARES_VERSION_STR "1.3.1"
#define ARES_VERSION_STR "1.3.3-CVS"
#ifdef __cplusplus
extern "C" {

View File

@@ -3,7 +3,7 @@
/* $Id$ */
/* Copyright (C) 2004 - 2005 by Daniel Stenberg et al
/* Copyright (C) 2004 - 2006 by Daniel Stenberg et al
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
@@ -17,7 +17,7 @@
*/
/* ================================================================ */
/* ares/config-win32.h - Hand crafted config file for windows */
/* ares/config-win32.h - Hand crafted config file for Windows */
/* ================================================================ */
/* ---------------------------------------------------------------- */
@@ -29,6 +29,9 @@
#define HAVE_GETOPT_H 1
#endif
/* Define if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
/* Define if you have the <sys/time.h> header file */
/* #define HAVE_SYS_TIME_H 1 */
@@ -57,6 +60,9 @@
/* OTHER HEADER INFO */
/* ---------------------------------------------------------------- */
/* Define if sig_atomic_t is an available typedef. */
#define HAVE_SIG_ATOMIC_T 1
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1
@@ -70,24 +76,6 @@
/* Define if you have the ioctlsocket function. */
#define HAVE_IOCTLSOCKET 1
/* Define if you have the getnameinfo function. */
#define HAVE_GETNAMEINFO 1
/* Define to the type qualifier of arg 1 for getnameinfo. */
#define GETNAMEINFO_QUAL_ARG1 const
/* Define to the type of arg 1 for getnameinfo. */
#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
/* Define to the type of arg 2 for getnameinfo. */
#define GETNAMEINFO_TYPE_ARG2 socklen_t
/* Define to the type of args 4 and 6 for getnameinfo. */
#define GETNAMEINFO_TYPE_ARG46 DWORD
/* Define to the type of arg 7 for getnameinfo. */
#define GETNAMEINFO_TYPE_ARG7 int
/* Define if you have the recv function. */
#define HAVE_RECV 1
@@ -127,6 +115,39 @@
/* Define to the function return type for send. */
#define SEND_TYPE_RETV int
/* Specifics for the Watt-32 tcp/ip stack */
#ifdef WATT32
#define SOCKET int
#define NS_INADDRSZ 4
#define HAVE_ARPA_NAMESER_H 1
#undef HAVE_WINSOCK_H
#undef HAVE_WINSOCK2_H
#undef HAVE_WS2TCPIP_H
#endif
/* ---------------------------------------------------------------- */
/* TYPEDEF REPLACEMENTS */
/* ---------------------------------------------------------------- */
/* Define this if in_addr_t is not an available 'typedefed' type */
#define in_addr_t unsigned long
/* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void
/* Define ssize_t if it is not an available 'typedefed' type */
#if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || defined(__POCC__)
#elif defined(_WIN64)
#define ssize_t __int64
#else
#define ssize_t int
#endif
/* Define to 'int' if socklen_t is not an available 'typedefed' type */
#ifndef HAVE_WS2TCPIP_H
#define socklen_t int
#endif
/* ---------------------------------------------------------------- */
/* STRUCT RELATED */
/* ---------------------------------------------------------------- */

View File

@@ -297,6 +297,10 @@ TYPE_IN_ADDR_T
TYPE_SOCKADDR_STORAGE
TYPE_SIG_ATOMIC_T
AC_TYPE_SIGNAL
CURL_CHECK_FUNC_RECV
CURL_CHECK_FUNC_SEND

View File

@@ -3,7 +3,7 @@
/* $Id$ */
/* Copyright (C) 2004 - 2006 by Daniel Stenberg et al
/* Copyright (C) 2004 - 2007 by Daniel Stenberg et al
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
@@ -29,7 +29,7 @@
/*
* If we have the MSG_NOSIGNAL define, make sure we use
* it as the fourth argument of send() and recv()
* it as the fourth argument of function send()
*/
#ifdef HAVE_MSG_NOSIGNAL
@@ -74,7 +74,7 @@
#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \
(RECV_TYPE_ARG2)(y), \
(RECV_TYPE_ARG3)(z), \
(RECV_TYPE_ARG4)(SEND_4TH_ARG))
(RECV_TYPE_ARG4)(0))
#endif
#else /* HAVE_RECV */
#ifndef sread
@@ -123,5 +123,24 @@
#define ISPRINT(x) (isprint((int) ((unsigned char)x)))
/*
* Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type.
*/
#ifndef HAVE_SIG_ATOMIC_T
typedef int sig_atomic_t;
#define HAVE_SIG_ATOMIC_T
#endif
/*
* Default return type for signal handlers.
*/
#ifndef RETSIGTYPE
#define RETSIGTYPE void
#endif
#endif /* __SETUP_ONCE_H */

View File

@@ -129,6 +129,10 @@ SOURCE=..\..\ares_gethostbyname.c
# End Source File
# Begin Source File
SOURCE=..\..\ares_getsock.c
# End Source File
# Begin Source File
SOURCE=..\..\ares_init.c
# End Source File
# Begin Source File

View File

@@ -5,7 +5,6 @@ REM $Date$
REM create ca-bundle.h
echo /* This file is generated automatically */ >lib\ca-bundle.h
echo #define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE") >>lib\ca-bundle.h
REM create hugehelp.c
copy src\hugehelp.c.cvs src\hugehelp.c

View File

@@ -78,6 +78,7 @@ AC_SUBST(PKGADD_VENDOR)
dnl
dnl initialize all the info variables
curl_ssl_msg="no (--with-ssl / --with-gnutls)"
curl_ssh_msg="no (--with-libssh2)"
curl_zlib_msg="no (--with-zlib)"
curl_krb4_msg="no (--with-krb4*)"
curl_gss_msg="no (--with-gssapi)"
@@ -1043,6 +1044,74 @@ if test X"$OPT_SSL" != Xno; then
fi
dnl **********************************************************************
dnl Check for the presence of LIBSSH2 libraries and headers
dnl **********************************************************************
dnl Default to compiler & linker defaults for LIBSSH2 files & libraries.
OPT_LIBSSH2=off
AC_ARG_WITH(libssh2,dnl
AC_HELP_STRING([--with-libssh2=PATH],[Where to look for libssh2, PATH points to the LIBSSH2 installation (default: /usr/local/lib); when possible, set the PKG_CONFIG_PATH environment variable instead of using this option])
AC_HELP_STRING([--without-libssh2], [disable LIBSSH2]),
OPT_LIBSSH2=$withval)
if test X"$OPT_LIBSSH2" != Xno; then
dnl backup the pre-libssh2 variables
CLEANLDFLAGS="$LDFLAGS"
CLEANCPPFLAGS="$CPPFLAGS"
CLEANLIBS="$LIBS"
case "$OPT_LIBSSH2" in
yes)
dnl --with-libssh2 (without path) used
PREFIX_LIBSSH2=/usr/local/lib
LIB_LIBSSH2="$PREFIX_LIBSSH2/lib$libsuff"
;;
off)
dnl no --with-libssh2 option given, just check default places
PREFIX_LIBSSH2=
;;
*)
dnl use the given --with-libssh2 spot
PREFIX_LIBSSH2=$OPT_LIBSSH2
LIB_LIBSSH2="$PREFIX_LIBSSH2/lib$libsuff"
LDFLAGS="$LDFLAGS -L$LIB_LIBSSH2"
CPPFLAGS="$CPPFLAGS -I$PREFIX_LIBSSH2/include"
;;
esac
if test X"$HAVECRYPTO" = X"yes"; then
dnl This is only reasonable to do if crypto actually is there: check for
dnl LIBSSH2 libs NOTE: it is important to do this AFTER the crypto lib
AC_CHECK_LIB(ssh2, libssh2_channel_open_ex)
AC_CHECK_HEADERS(libssh2.h,
curl_ssh_msg="enabled (libSSH2)"
LIBSSH2_ENABLED=1
AC_DEFINE(USE_LIBSSH2, 1, [if libSSH2 is in use]))
if test X"$OPT_LIBSSH2" != Xoff &&
test "$LIBSSH2_ENABLED" != "1"; then
AC_MSG_ERROR([libSSH2 libs and/or directories were not found where specified!])
fi
else
AC_MSG_WARN([without the use of OpenSSL libs, libssh2 cannot work])
fi
if test "$LIBSSH2_ENABLED" = "1"; then
if test -n "$LIB_LIBSSH2"; then
dnl when the libssh2 shared libs were found in a path that the run-time
dnl linker doesn't search through, we need to add it to LD_LIBRARY_PATH
dnl to prevent further configure tests to fail due to this
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$LIB_LIBSSH2"
export LD_LIBRARY_PATH
AC_MSG_NOTICE([Added $LIB_LIBSSH2 to LD_LIBRARY_PATH])
fi
fi
fi
dnl **********************************************************************
dnl Check for the random seed preferences
dnl **********************************************************************
@@ -1564,6 +1633,10 @@ TYPE_IN_ADDR_T
TYPE_SOCKADDR_STORAGE
TYPE_SIG_ATOMIC_T
AC_TYPE_SIGNAL
AC_FUNC_SELECT_ARGTYPES
CURL_CHECK_FUNC_RECV
@@ -1574,7 +1647,7 @@ CURL_CHECK_MSG_NOSIGNAL
dnl Checks for library functions.
dnl AC_PROG_GCC_TRADITIONAL
AC_TYPE_SIGNAL
dnl AC_FUNC_VPRINTF
case $host in
*msdosdjgpp)
@@ -2076,6 +2149,7 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
Install prefix: ${prefix}
Compiler: ${CC}
SSL support: ${curl_ssl_msg}
SSH support: ${curl_ssh_msg}
zlib support: ${curl_zlib_msg}
krb4 support: ${curl_krb4_msg}
GSSAPI support: ${curl_gss_msg}

View File

@@ -142,8 +142,8 @@ Rexx
Ruby
Written by Hirotaka Matsuyuki
http://www.d1.dion.ne.jp/~matuyuki/ruby.html
Written by Ross Bamford
http://curb.rubyforge.org/
Scheme

View File

@@ -51,12 +51,12 @@ UNIX
path for your compiler/linker, you don't need to do anything special. If
you have OpenSSL installed in /usr/local/ssl, you can run configure like:
./configure --with-ssl
./configure --with-ssl
If you have OpenSSL installed somewhere else (for example, /opt/OpenSSL,)
you can run configure like this:
./configure --with-ssl=/opt/OpenSSL
./configure --with-ssl=/opt/OpenSSL
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:
@@ -148,12 +148,21 @@ Win32
-------
Run the 'mingw32.bat' file to get the proper environment variables set,
then run 'make mingw32' in the root dir. Use 'make mingw32-ssl' to build
then run 'make mingw32' in the root dir. Use 'make mingw32-ssl' to build
curl SSL enabled.
If you have any problems linking libraries or finding header files, be sure
to verify that the provided "Makefile.m32" files use the proper paths, and
adjust as necessary.
adjust as necessary. It is also possible to override these paths with
environment variables, for example:
set ZLIB_PATH=c:\zlib-1.2.3
set OPENSSL_PATH=c:\openssl-0.9.8d
set LIBSSH2_PATH=c:\libssh2-0.15
ATTENTION: if you want to build with libssh2 support you have to use latest
sources fetched from CVS - the current 0.14 release will NOT work!
Use 'make mingw32-ssh2-ssl' to build curl with SSH2 and SSL enabled.
Cygwin
------
@@ -184,7 +193,7 @@ Win32
documentation on how to compile zlib. Define the ZLIB_PATH environment
variable to the location of zlib.h and zlib.lib, for example:
set ZLIB_PATH=c:\zlib-1.2.1
set ZLIB_PATH=c:\zlib-1.2.3
Then run 'nmake vc-zlib' in curl's root directory.
@@ -198,7 +207,7 @@ Win32
Before running nmake define the OPENSSL_PATH environment variable with
the root/base directory of OpenSSL, for example:
set OPENSSL_PATH=c:\openssl-0.9.7d
set OPENSSL_PATH=c:\openssl-0.9.8d
Then run 'nmake vc-ssl' or 'nmake vc-ssl-dll' in curl's root
directory. 'nmake vc-ssl' will create a libcurl static and dynamic
@@ -676,6 +685,7 @@ PORTS
- PowerPC Linux
- PowerPC Mac OS 9
- PowerPC Mac OS X
- SuperH4 Linux 2.6.X
- SINIX-Z v5
- Sparc Linux
- Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7, 8, 9, 10
@@ -717,3 +727,6 @@ OpenSSL http://www.openssl.org
MingW http://www.mingw.org
OpenLDAP http://www.openldap.org
Zlib http://www.gzip.org/zlib/
libssh2 http://www.libssh2.org

View File

@@ -3,6 +3,25 @@ join in and help us correct one or more of these! Also be sure to check the
changelog of the current development status, as one or more of these problems
may have been fixed since this was written!
41. Jeff Pohlmeyer's curl_multi_socket crashing case. Recipe and instructions
here: http://curl.haxx.se/mail/lib-2007-01/0022.html
40. HTTP Pipelining, NULL content
http://curl.haxx.se/bug/view.cgi?id=1631566
39. Steffen Rumler's Race Condition in Curl_proxyCONNECT:
http://curl.haxx.se/mail/lib-2007-01/0045.html
38. Kumar Swamy Bhatt's problem in ftp/ssl "LIST" operation:
http://curl.haxx.se/mail/lib-2007-01/0103.html
37. Having more than one connection to the same host when doing NTLM
authentication (with performs multiple "passes" and authenticates a
connection rather than a HTTP request), and particularly when using the
multi interface, there's a risk that libcurl will re-use a wrong connection
when doing the different passes in the NTLM negotiation and thus fail to
negotiate (in seemingly mysterious ways).
35. Both SOCKS5 and SOCKS4 proxy connections are done blocking, which is very
bad when used with the multi interface.
@@ -44,11 +63,6 @@ may have been fixed since this was written!
"system context" will make it use wrong(?) user name - at least when compared
to what winhttp does. See http://curl.haxx.se/bug/view.cgi?id=1281867
25. When doing a CONNECT request with curl it doesn't properly handle if the
proxy closes the connection within the authentication "negotiation phase".
Like if you do HTTPS or similar over a proxy and you use perhaps
--proxy-anyauth.
23. We don't support SOCKS for IPv6. We don't support FTPS over a SOCKS proxy.
We don't have any test cases for SOCKS proxy. We probably have even more
bugs and lack of features when a SOCKS proxy is used. And there seem to be a

View File

@@ -17,6 +17,7 @@ Alexander Kourakos
Alexander Krasnostavsky
Alexander Lazic
Alexander Zhuravlev
Alexey Simak
Alexis Carvalho
Amol Pattekar
Andi Jahja
@@ -26,6 +27,7 @@ Andreas Olsson
Andreas Rieke
Andres Garcia
Andrew Benham
Andrew Biggs
Andrew Bushnell
Andrew Francis
Andrew Fuller
@@ -36,6 +38,7 @@ Angus Mackay
Antoine Calando
Anton Kalmykov
Arkadiusz Miskiewicz
Armel Asselin
Arve Knudsen
Ates Goral
Augustus Saunders
@@ -43,12 +46,15 @@ Avery Fay
Ben Greear
Ben Madsen
Benjamin Gerard
Bernard Leak
Bertrand Demiddelaer
Bjorn Reese
Bj<EFBFBD>rn Stenberg
Bob Schader
Bogdan Nicula
Brad Burdick
Bradford Bruce
Brendan Jurd
Brent Beardsley
Brian Akins
Brian Dessent
@@ -68,6 +74,7 @@ Christian Robottom Reis
Christophe Demory
Christophe Legry
Christopher R. Palmer
Ciprian Badescu
Clarence Gardner
Clifford Wolf
Cody Jones
@@ -116,7 +123,9 @@ Dimitris Sarris
Dinar
Dirk Eddelbuettel
Dirk Manske
Dmitriy Sergeyev
Dmitry Bartsevich
Dmitry Rechkin
Dolbneff A.V
Domenico Andreoli
Dominick Meglio
@@ -206,11 +215,13 @@ James Clancy
James Cone
James Gallagher
James Griffiths
James Housley
James MacMillan
Jamie Lokier
Jamie Newton
Jamie Wilkinson
Jan Kunder
Jared Lundell
Jari Sundell
Jason S. Priebe
Jaz Fresh
@@ -313,12 +324,14 @@ Markus Oberhumer
Martijn Koster
Martin C. Martin
Martin Hedenfalk
Martin Skinner
Marty Kuhrt
Maruko
Massimiliano Ziccardi
Mathias Axelsson
Mats Lidell
Matt Veenstra
Matt Witherspoon
Matthew Blain
Matthew Clarke
Maurice Barnum
@@ -337,12 +350,14 @@ Mihai Ionescu
Mikael Sennerholm
Mike Bytnar
Mike Dobbs
Mike Protts
Miklos Nemeth
Mitz Wark
Mohamed Lrhazi
Mohun Biswas
Moonesamy
Nathan O'Sullivan
Nathanael Nerode
Naveen Noel
Neil Dunbar
Neil Spring
@@ -355,10 +370,12 @@ Nicolas Croiset
Nicolas Fran<61>ois
Niels van Tongeren
Nikita Schmidt
Nir Soffer
Nis Jorgensen
Nodak Sodak
Norbert Novotny
Ofer
Olaf Stueben
Olaf St<53>ben
Oren Tirosh
P R Schaffner
@@ -398,6 +415,7 @@ Ralph Beckmann
Ralph Mitchell
Ramana Mokkapati
Randy McMurchy
Ravi Pratap
Reinout van Schouwen
Renaud Chaillat
Renaud Duhaut
@@ -416,6 +434,7 @@ Rick Jones
Rick Richardson
Rob Stanzel
Robert D. Young
Robert Foreman
Robert Olson
Robert Weaver
Robin Kay
@@ -442,6 +461,7 @@ Scott Davis
Sebastien Willemijns
Sergio Ballestrero
Seshubabu Pasam
Sh Diao
Shard
Shawn Poulson
Shmulik Regev
@@ -452,6 +472,7 @@ Simon Liu
Spiridonoff A.V
Stadler Stephan
Stefan Esser
Stefan Krause
Stefan Ulrich
Stephan Bergmann
Stephen Kick
@@ -489,6 +510,7 @@ Tomas Szepe
Tomasz Lacki
Tommy Tam
Ton Voon
Toon Verwaest
Tor Arntsen
Torsten Foertsch
Toshiyuki Maezawa
@@ -498,6 +520,8 @@ Troy Engel
Tupone Alfredo
Ulf H<>rnhammar
Ulrich Zadow
Venkat Akella
Victor Snezhko
Vilmos Nebehaj
Vincent Bronner
Vincent Penquerc'h

View File

@@ -43,10 +43,6 @@ TODO
powered libcurl the default build (which of course would require that we'd
bundle the c-ares source code in the libcurl source code releases).
* Support CONNECT 407 responses that kill the connection and expect the
client to reconnect to complete the authentication. Currently libcurl
assumes that a proxy connection will be kept alive.
* Make the curl/*.h headers include the proper system includes based on what
was present at the time when configure was run. Currently, the sys/select.h
header is for example included by curl/multi.h only on specific platforms
@@ -188,8 +184,8 @@ TODO
* Fix the connection phase to be non-blocking when multi interface is used
* Add a way to check if the connection seems to be alive, to corrspond to the
SSL_peak() way we use with OpenSSL.
* Add a way to check if the connection seems to be alive, to correspond to
the SSL_peak() way we use with OpenSSL.
LDAP
@@ -201,10 +197,6 @@ TODO
* RTSP - RFC2326 (protocol - very HTTP-like, also contains URL description)
* SFTP/SCP/SSH (no RFCs for protocol nor URI/URL format). An implementation
should most probably use an existing ssh library, such as OpenSSH. or
libssh2.org
* RSYNC (no RFCs for protocol nor URI/URL format). An implementation should
most probably use an existing rsync library, such as librsync.
@@ -273,6 +265,10 @@ TODO
TEST SUITE
* Make our own version of stunnel for simple port forwarding to enable HTTPS
and FTP-SSL tests without the stunnel dependency, and it could allow us to
provide test tools built with either OpenSSL or GnuTLS
* Make the test servers able to serve multiple running test suites. Like if
two users run 'make test' at once.

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -21,7 +21,7 @@
.\" * $Id$
.\" **************************************************************************
.\"
.TH curl 1 "23 Sep 2006" "Curl 7.16.0" "Curl Manual"
.TH curl 1 "3 Nov 2006" "Curl 7.16.1" "Curl Manual"
.SH NAME
curl \- transfer a URL
.SH SYNOPSIS
@@ -30,8 +30,8 @@ curl \- transfer a URL
.SH DESCRIPTION
.B curl
is a tool to transfer data from or to a server, using one of the supported
protocols (HTTP, HTTPS, FTP, FTPS, TFTP, DICT, TELNET, LDAP or FILE).
The command is designed to work without user interaction.
protocols (HTTP, HTTPS, FTP, FTPS, SCP, SFTP, TFTP, DICT, TELNET, LDAP or
FILE). The command is designed to work without user interaction.
curl offers a busload of useful tricks like proxy support, user
authentication, ftp upload, HTTP post, SSL connections, cookies, file transfer
@@ -320,7 +320,7 @@ is used to seed the random engine for SSL connections. See also the
with HTTPS or FTPS. The certificate must be in PEM format. If the optional
password isn't specified, it will be queried for on the terminal. Note that
this option assumes a \&"certificate" file that is the private key and the
private certificate concatenated! See \fI--cert\P and \fI--key\fP to specify
private certificate concatenated! See \fI--cert\fP and \fI--key\fP to specify
them independently.
If this option is used several times, the last one will be used.
@@ -432,6 +432,14 @@ If this option is used twice, the second will again disable this.
Terminates the connection if the server doesn't support SSL/TLS.
(Added in 7.15.5)
If this option is used twice, the second will again disable this.
.IP "--ftp-ssl-ccc"
(FTP) Use CCC (Clear Command Channel)
Shuts down the SSL/TLS layer after authenticating. The rest of the
control channel communication will be unencrypted. This allows
NAT routers to follow the FTP transaction.
(Added in 7.16.1)
If this option is used twice, the second will again disable this.
.IP "-F/--form <name=content>"
(HTTP) This lets curl emulate a filled in form in which a user has pressed the
@@ -591,7 +599,7 @@ line. So, it could look similar to this:
url = "http://curl.haxx.se/docs/"
This option can be used multiple times.
This option can be used multiple times to load multiple config files.
When curl is invoked, it always (unless \fI-q\fP is used) checks for a default
config file and uses it if found. The default config file is checked for in
@@ -606,6 +614,12 @@ resort the '%USERPROFILE%\Application Data'.
2) On windows, if there is no _curlrc file in the home dir, it checks for one
in the same dir the executable curl is placed. On unix-like systems, it will
simply try to load .curlrc from the determined home dir.
.IP "--libcurl <file>"
Append this option to any ordinary curl command line, and you will get a
libcurl-using source code written to the file that does the equivalent
operation of what your command line operation does!
If this option is used several times, the last given file name will be used.
.IP "--limit-rate <speed>"
Specify the maximum transfer rate you want curl to use. This feature is useful
if you have a limited pipe and you'd like your transfer not use your entire
@@ -615,6 +629,10 @@ The given speed is measured in bytes/second, unless a suffix is appended.
Appending 'k' or 'K' will count the number as kilobytes, 'm' or M' makes it
megabytes while 'g' or 'G' makes it gigabytes. Examples: 200K, 3m and 1G.
The given rate is the average speed, counted during the entire transfer. It
means that curl might use higher transfer speeds in short bursts, but over
time it uses no more than the given rate.
If you are also using the \fI-Y/--speed-limit\fP option, that option will take
precedence and might cripple the rate-limiting slightly, to help keeping the
speed-limit logic working.

View File

@@ -1,8 +1,8 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
@@ -41,9 +41,6 @@ int main(int argc, char **argv)
/* no progress meter please */
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1);
/* shut up completely */
curl_easy_setopt(curl_handle, CURLOPT_MUTE, 1);
/* send all data to this function */
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);

View File

@@ -9,6 +9,18 @@
*
* This example code only builds as-is on Windows.
*
* While Unix/Linux user, you do not need this software.
* You can achieve the same result as synctime using curl, awk and date.
* Set proxy as according to your network, but beware of proxy Cache-Control.
*
* To set your system clock, root access is required.
* # date -s "`curl -sI http://nist.time.gov/timezone.cgi?UTC/s/0 \
* | awk -F': ' '/Date: / {print $2}'`"
*
* To view remote webserver date and time.
* $ curl -sI http://nist.time.gov/timezone.cgi?UTC/s/0 \
* | awk -F': ' '/Date: / {print $2}'
*
* Synchronising your computer clock via Internet time server usually relies
* on DAYTIME, TIME, or NTP protocols. These protocols provide good accurate
* time synchronisation but it does not work very well through a
@@ -300,10 +312,11 @@ int main(int argc, char *argv[])
MthStr[LOCALTime.wMonth-1], LOCALTime.wYear,
LOCALTime.wHour, LOCALTime.wMinute, LOCALTime.wSecond,
LOCALTime.wMilliseconds);
fprintf(stderr, "\nBefore HTTP. Date: %s%s\n\n", timeBuf, tzoneBuf);
fprintf(stderr, "Fetch: %s\n\n", conf->timeserver);
fprintf(stderr, "Before HTTP. Date: %s%s\n\n", timeBuf, tzoneBuf);
/* HTTP HEAD command to the Webserver */
fprintf(stderr, "Fetch: %s\n", conf->timeserver);
SyncTime_CURL_Fetch(curl, conf->timeserver, "index.htm",
HTTP_COMMAND_HEAD);

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -21,7 +21,7 @@
.\" * $Id$
.\" **************************************************************************
.\"
.TH curl_easy_setopt 3 "19 Apr 2006" "libcurl 7.15.4" "libcurl Manual"
.TH curl_easy_setopt 3 "2 Nov 2006" "libcurl 7.16.1" "libcurl Manual"
.SH NAME
curl_easy_setopt \- set options for a curl easy handle
.SH SYNOPSIS
@@ -925,6 +925,12 @@ Try "AUTH SSL" first, and only if that fails try "AUTH TLS"
.IP CURLFTPAUTH_TLS
Try "AUTH TLS" first, and only if that fails try "AUTH SSL"
.RE
.IP CURLOPT_FTP_SSL_CCC
Pass a long that is set to 0 to disable and 1 to enable. If enabled, this
option makes libcurl use CCC (Clear Command Channel). It shuts down the
SSL/TLS layer after authenticating. The rest of the control channel
communication will be unencrypted. This allows NAT routers to follow the FTP
transaction. (Added in 7.16.1)
.IP CURLOPT_FTP_ACCOUNT
Pass a pointer to a zero-terminated string (or NULL to disable). When an FTP
server asks for "account data" after user name and password has been provided,
@@ -1008,10 +1014,16 @@ to POST with \fICURLOPT_POST\fP etc.
When uploading a file to a remote site, this option should be used to tell
libcurl what the expected size of the infile is. This value should be passed
as a long. See also \fICURLOPT_INFILESIZE_LARGE\fP.
Note that this option does not limit how much data libcurl will actually send,
as that is controlled entirely by what the read callback returns.
.IP CURLOPT_INFILESIZE_LARGE
When uploading a file to a remote site, this option should be used to tell
libcurl what the expected size of the infile is. This value should be passed
as a curl_off_t. (Added in 7.11.0)
Note that this option does not limit how much data libcurl will actually send,
as that is controlled entirely by what the read callback returns.
.IP CURLOPT_UPLOAD
A non-zero parameter tells the library to prepare for an upload. The
\fICURLOPT_READDATA\fP and \fICURLOPT_INFILESIZE\fP or
@@ -1092,23 +1104,14 @@ value unless you are perfectly aware of how this work and changes libcurl's
behaviour. This concerns connection using any of the protocols that support
persistent connections.
When reaching the maximum limit, curl uses the \fICURLOPT_CLOSEPOLICY\fP to
figure out which of the existing connections to close to prevent the number of
open connections to increase.
When reaching the maximum limit, curl closes the oldest one in the cache to
prevent the number of open connections to increase.
If you already have performed transfers with this curl handle, setting a
smaller MAXCONNECTS than before may cause open connections to get closed
unnecessarily.
.IP CURLOPT_CLOSEPOLICY
Pass a long. This option sets what policy libcurl should use when the
connection cache is filled and one of the open connections has to be closed to
make room for a new connection. This must be one of the CURLCLOSEPOLICY_*
defines. Use \fICURLCLOSEPOLICY_LEAST_RECENTLY_USED\fP to make libcurl close
the connection that was least recently used, that connection is also least
likely to be capable of re-use. Use \fICURLCLOSEPOLICY_OLDEST\fP to make
libcurl close the oldest connection, the one that was created first among the
ones in the connection cache. The other close policies are not support
yet.
(Obsolete) This option does nothing.
.IP CURLOPT_FRESH_CONNECT
Pass a long. Set to non-zero to make the next transfer use a new (fresh)
connection by force. If the connection cache is full before this connection,
@@ -1246,14 +1249,14 @@ even indicate an accessible file.
Note that option is by default set to the system path where libcurl's cacert
bundle is assumed to be stored, as established at build time.
.IP CURLOPT_CAPATH
Pass a char * to a zero terminated string naming a directory holding
multiple CA certificates to verify the peer with. The certificate
directory must be prepared using the openssl c_rehash utility. This
makes sense only when used in combination with the
\fICURLOPT_SSL_VERIFYPEER\fP option. If \fICURLOPT_SSL_VERIFYPEER\fP
is zero, \fICURLOPT_CAPATH\fP need not even indicate an accessible
path. The \fICURLOPT_CAPATH\fP function apparently does not work in
Windows due to some limitation in openssl. (Added in 7.9.8)
Pass a char * to a zero terminated string naming a directory holding multiple
CA certificates to verify the peer with. The certificate directory must be
prepared using the openssl c_rehash utility. This makes sense only when used
in combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. If
\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_CAPATH\fP need not even
indicate an accessible path. The \fICURLOPT_CAPATH\fP function apparently
does not work in Windows due to some limitation in openssl. This option is
OpenSSL-specific and does nothing if libcurl is built to use GnuTLS.
.IP CURLOPT_RANDOM_FILE
Pass a char * to a zero terminated file name. The file will be used to read
from to seed the random engine for SSL. The more random the specified file is,
@@ -1312,6 +1315,17 @@ krb4 awareness. This is a string, 'clear', 'safe', 'confidential' or
\&'private'. If the string is set but doesn't match one of these, 'private'
will be used. Set the string to NULL to disable kerberos4. The kerberos
support only works for FTP.
.SH SSH OPTIONS
.IP CURLOPT_SSH_AUTH_TYPES
Pass a long set to a bitmask consisting of one or more of
CURLSSH_AUTH_PUBLICKEY, CURLSSH_AUTH_PASSWORD, CURLSSH_AUTH_HOST,
CURLSSH_AUTH_KEYBOARD. Set CURLSSH_AUTH_ANY to let libcurl pick one.
.IP CURLOPT_SSH_PUBLIC_KEYFILE
Pass a char * pointing to a file name for your public key. If not used,
libcurl defaults to using \fB~/.ssh/id_dsa.pub\fP.
.IP CURLOPT_SSH_PRIVATE_KEYFILE
Pass a char * pointing to a file name for your private key. If not used,
libcurl defaults to using \fB~/.ssh/id_dsa\fP.
.SH OTHER OPTIONS
.IP CURLOPT_PRIVATE
Pass a char * as parameter, pointing to data that should be associated with

View File

@@ -26,7 +26,8 @@ again. It will instead return new messages at each new invoke until the queue
is emptied.
The data the returned pointer points to will not survive calling
\fIcurl_multi_cleanup(3)\fP or \fIcurl_multi_remove_handle(3)\fP.
\fIcurl_multi_cleanup(3)\fP, \fIcurl_multi_remove_handle(3)\fP or
\fIcurl_easy_cleanup(3)\fP.
The 'CURLMsg' struct is very simple and only contain very basic information.
If more involved information is wanted, the particular "easy handle" in

View File

@@ -24,8 +24,9 @@ The list should be freed again (after usage) with
A null pointer is returned if anything went wrong, otherwise the new list
pointer is returned.
.SH EXAMPLE
.nf
CURL handle;
curl_slist *slist=NULL;
struct curl_slist *slist=NULL;
slist = curl_slist_append(slist, "pragma:");
curl_easy_setopt(handle, CURLOPT_HTTPHEADER, slist);
@@ -33,5 +34,6 @@ pointer is returned.
curl_easy_perform(handle);
curl_slist_free_all(slist); /* free the list again */
.fi
.SH "SEE ALSO"
.BR curl_slist_free_all "(3), "

View File

@@ -21,7 +21,7 @@
.\" * $Id$
.\" **************************************************************************
.\"
.TH curl_version_info 3 "19 Apr 2006" "libcurl 7.15.4" "libcurl Manual"
.TH curl_version_info 3 "2 Nov 2006" "libcurl 7.16.1" "libcurl Manual"
.SH NAME
curl_version_info - returns run-time libcurl version info
.SH SYNOPSIS
@@ -66,6 +66,11 @@ typedef struct {
/* when 'age' is 2 or higher, the member below also exists: */
const char *libidn; /* human readable string */
/* when 'age' is 3 or higher, the members below also exist: */
int iconv_ver_num; /* '_libiconv_version' if iconv support enabled */
const char *libssh_version; /* human readable string */
} curl_version_info_data;
.fi

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -392,6 +392,13 @@ typedef enum {
CURLOPT_CONV_FROM_UTF8_FUNCTION */
CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing
or wrong format */
CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */
CURLE_SSH, /* 79 - error from the SSH layer, somewhat
generic so the error message will be of
interest when this has happened */
CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL
connection */
CURL_LAST /* never use! */
} CURLcode;
@@ -427,6 +434,14 @@ typedef enum {
#define CURLAUTH_ANY ~0 /* all types set */
#define CURLAUTH_ANYSAFE (~CURLAUTH_BASIC)
#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */
#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */
#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */
#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */
#define CURLSSH_AUTH_HOST (1<<2) /* host key files */
#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */
#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
the obsolete stuff removed! */
/* this was the error code 50 in 7.7.3 and a few earlier versions, this
@@ -1029,6 +1044,16 @@ typedef enum {
enabled (== 1) */
CINIT(SSL_SESSIONID_CACHE, LONG, 150),
/* allowed SSH authentication methods */
CINIT(SSH_AUTH_TYPES, LONG, 151),
/* Used by scp/sftp to do public/private key authentication */
CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152),
CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153),
/* Send CCC (Clear Command Channel) after authentication */
CINIT(FTP_SSL_CCC, LONG, 154),
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
@@ -1506,6 +1531,7 @@ typedef enum {
CURLVERSION_FIRST,
CURLVERSION_SECOND,
CURLVERSION_THIRD,
CURLVERSION_FOURTH,
CURLVERSION_LAST /* never actually use this */
} CURLversion;
@@ -1514,7 +1540,7 @@ typedef enum {
meant to be a built-in version number for what kind of struct the caller
expects. If the struct ever changes, we redefine the NOW to another enum
from above. */
#define CURLVERSION_NOW CURLVERSION_THIRD
#define CURLVERSION_NOW CURLVERSION_FOURTH
typedef struct {
CURLversion age; /* age of the returned struct */
@@ -1535,8 +1561,13 @@ typedef struct {
/* This field was added in CURLVERSION_THIRD */
const char *libidn;
/* These field were added in CURLVERSION_FOURTH */
/* Same as '_libiconv_version' if built with HAVE_ICONV */
int iconv_ver_num;
const char *libssh_version; /* human readable string */
} curl_version_info_data;
#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */

View File

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

View File

@@ -28,6 +28,10 @@
#include "curl.h"
#ifdef __cplusplus
extern "C" {
#endif
CURL_EXTERN int curl_mprintf(const char *format, ...);
CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...);
CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...);
@@ -59,4 +63,8 @@ CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
# define vaprintf curl_mvaprintf
#endif
#ifdef __cplusplus
}
#endif
#endif /* __CURL_MPRINTF_H */

View File

@@ -8,7 +8,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
content_encoding.c share.c http_digest.c md5.c http_negotiate.c \
http_ntlm.c inet_pton.c strtoofft.c strerror.c hostares.c hostasyn.c \
hostip4.c hostip6.c hostsyn.c hostthre.c inet_ntop.c parsedate.c \
select.c gtls.c sslgen.c tftp.c splay.c strdup.c socks.c
select.c gtls.c sslgen.c tftp.c splay.c strdup.c socks.c ssh.c
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
@@ -18,6 +18,6 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
share.h md5.h http_digest.h http_negotiate.h http_ntlm.h ca-bundle.h \
inet_pton.h strtoofft.h strerror.h inet_ntop.h curlx.h memory.h \
setup.h transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h \
gtls.h tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h
gtls.h tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h ssh.h

View File

@@ -2,18 +2,21 @@
# $Id$
#
## Makefile for building libcurl.a with MingW32 (GCC-3.2) and
## optionally OpenSSL (0.9.7)
## optionally OpenSSL (0.9.8)
##
## Use: make -f Makefile.m32
## Use: make -f Makefile.m32 [SSL=1] [SSH2=1] [DYN=1]
##
## Comments to: Troy Engel <tengel@sonic.net> or
## Joern Hartroth <hartroth@acm.org>
ifndef OPENSSL_PATH
OPENSSL_PATH = ../../openssl-0.9.7d
OPENSSL_PATH = ../../openssl-0.9.8d
endif
ifndef LIBSSH2_PATH
LIBSSH2_PATH = ../../libssh2-0.14
endif
ifndef ZLIB_PATH
ZLIB_PATH = ../../zlib-1.2.1
ZLIB_PATH = ../../zlib-1.2.3
endif
CC = gcc
@@ -26,19 +29,27 @@ STRIP = strip -g
## Nothing more to do below this line!
INCLUDES = -I. -I../include
CFLAGS = -g -O2 -DMINGW32 -DBUILDING_LIBCURL -DHAVE_LONGLONG
CFLAGS = -g -O2 -DBUILDING_LIBCURL -DHAVE_LONGLONG
ifdef SSH2
INCLUDES += -I"$(LIBSSH2_PATH)/include" -I"$(LIBSSH2_PATH)/win32"
CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H
DLL_LIBS += -L$(LIBSSH2_PATH)/win32 -lssh2
endif
ifdef SSL
INCLUDES += -I"$(OPENSSL_PATH)/outinc" -I"$(OPENSSL_PATH)/outinc/openssl"
CFLAGS += -DUSE_SSLEAY -DUSE_OPENSSL -DHAVE_OPENSSL_ENGINE_H -DHAVE_OPENSSL_PKCS12_H \
-DHAVE_ENGINE_LOAD_BUILTIN_ENGINES -DOPENSSL_NO_KRB5 \
-DCURL_CA_BUNDLE='getenv("CURL_CA_BUNDLE")'
DLL_LIBS = -L$(OPENSSL_PATH)/out -leay32 -lssl32
-DCURL_WANTS_CA_BUNDLE_ENV
DLL_LIBS += -L$(OPENSSL_PATH)/out -leay32 -lssl32
endif
ifdef ZLIB
INCLUDES += -I"$(ZLIB_PATH)"
CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H
DLL_LIBS += -L$(ZLIB_PATH) -lz
endif
ifdef SSPI
CFLAGS += -DUSE_WINDOWS_SSPI
endif
COMPILE = $(CC) $(INCLUDES) $(CFLAGS)
# Makefile.inc provides the CSOURCES and HHEADERS defines

View File

@@ -19,7 +19,12 @@ endif
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH
OPENSSL_PATH = ../../openssl-0.9.8c
OPENSSL_PATH = ../../openssl-0.9.8d
endif
# Edit the path below to point to the base of your LibSSH2 package.
ifndef LIBSSH2_PATH
LIBSSH2_PATH = ../../libssh2-0.14
endif
ifndef INSTDIR
@@ -29,7 +34,7 @@ endif
# Edit the vars below to change NLM target settings.
TARGET = libcurl
VERSION = $(LIBCURL_VERSION)
COPYR = Copyright (C) 1996 - 2006, Daniel Stenberg, <daniel@haxx.se>
COPYR = Copyright (C) 1996 - 2007, Daniel Stenberg, <daniel@haxx.se>
DESCR = cURL libcurl $(LIBCURL_VERSION_STR) - http://curl.haxx.se
MTSAFE = YES
STACK = 64000
@@ -63,6 +68,7 @@ ifdef METROWERKS
else
CC = gcc
endif
AWK = awk
YACC = bison -y
CP = cp -afv
# RM = rm -f
@@ -121,6 +127,15 @@ ifdef WITH_SSL
LDLIBS += $(OPENSSL_PATH)/out_nw_libc/crypto.lib $(OPENSSL_PATH)/out_nw_libc/ssl.lib
IMPORTS += GetProcessSwitchCount RunningProcess
endif
ifdef WITH_SSH2
INCLUDES += -I$(LIBSSH2_PATH)/include
ifdef LINK_STATIC
LDLIBS += $(LIBSSH2_PATH)/nw/libssh2.lib
else
IMPORTS += @$(LIBSSH2_PATH)/nw/libssh2.imp
MODULES += libssh2.nlm
endif
endif
ifdef WITH_ZLIB
INCLUDES += -I$(ZLIB_PATH)
ifdef LINK_STATIC
@@ -184,7 +199,7 @@ $(OBJDIR)/%.o: %.c
$(OBJDIR)/version.inc: ../include/curl/curlver.h $(OBJDIR)
@echo Creating $@
@awk -f ../packages/NetWare/get_ver.awk $< > $@
@$(AWK) -f ../packages/NetWare/get_ver.awk $< > $@
dist: all
-$(RM) $(OBJDIR)/*.o $(OBJDIR)/$(TARGET).map $(OBJDIR)/$(TARGET).ncv
@@ -205,6 +220,9 @@ clean:
-$(RM) config.h ca-bundle.h
-$(RM) -r $(OBJDIR)
distclean: clean
-$(RM) -r $(TARGET).lib $(TARGET).nlm
$(INSTDIR):
@mkdir $(INSTDIR)
@@ -324,6 +342,8 @@ config.h: Makefile.netware
@echo $(DL)#define HAVE_SEND 1$(DL) >> $@
@echo $(DL)#define HAVE_SETJMP_H 1$(DL) >> $@
@echo $(DL)#define HAVE_SIGNAL 1$(DL) >> $@
@echo $(DL)#define HAVE_SIGNAL_H 1$(DL) >> $@
@echo $(DL)#define HAVE_SIG_ATOMIC_T 1$(DL) >> $@
@echo $(DL)#define HAVE_SOCKET 1$(DL) >> $@
@echo $(DL)#define HAVE_STDINT_H 1$(DL) >> $@
@echo $(DL)#define HAVE_STDLIB_H 1$(DL) >> $@
@@ -402,28 +422,44 @@ ifdef WITH_SSL
@echo $(DL)#define HAVE_LIBCRYPTO 1$(DL) >> $@
@echo $(DL)#define OPENSSL_NO_KRB5 1$(DL) >> $@
endif
ifdef WITH_SSH2
@echo $(DL)#define USE_LIBSSH2 1$(DL) >> $@
@echo $(DL)#define HAVE_LIBSSH2_H 1$(DL) >> $@
endif
ifdef OLD_NOVELLSDK
@echo $(DL)#define socklen_t int$(DL) >> $@
endif
ca-bundle.h: Makefile.netware
FORCE: ;
ca-bundle.h: FORCE Makefile.netware
@echo Creating $@
@echo $(DL)/* Do not edit this file - it is created by make!$(DL) > $@
@echo $(DL)** All your changes will be lost!!$(DL) >> $@
@echo $(DL)*/$(DL) >> $@
ifdef CABUNDLE
@echo $(DL)#define CURL_CA_BUNDLE "$(CABUNDLE)"$(DL) >> $@
else
@echo $(DL)#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")$(DL) >> $@
url.c: ca-bundle.h
endif
info: $(OBJDIR)/version.inc
@echo Configured to build $(TARGET) with these options:
@echo curl version: $(LIBCURL_VERSION_STR)
@echo compiler/linker: $(CC) / $(LD)
ifdef CABUNDLE
@echo ca-bundle path: $(CABUNDLE)
endif
ifdef WITH_SSL
@echo SSL support: enabled (OpenSSL)
else
@echo SSL support: no
endif
ifdef WITH_SSH2
@echo SSH2 support: enabled (libssh2)
else
@echo SSH2 support: no
endif
ifdef WITH_ZLIB
@echo zlib support: enabled
else

View File

@@ -12,11 +12,11 @@ c-ares:
http://daniel.haxx.se/projects/c-ares/
NOTE
libcurl 7.11.1 builds with c-ares 1.1.0, but 7.11.2 and later require c-ares
1.2.0 or alter.
The latest libcurl version requires c-ares 1.3.2 or later to work
flawlessly.
Once upon the time libcurl built fine with the "original" ares. That is no
longer true. You need to use c-ares. c-ares is based on ares but improved.
longer true. You need to use c-ares.
Build c-ares
============

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -40,28 +40,27 @@
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "urldata.h" /* for the SessionHandle definition */
#include "easyif.h" /* for Curl_convert_... prototypes */
#include "base64.h"
#include "memory.h"
/* include memdebug.h last */
#include "memdebug.h"
/* ---- Base64 Encoding/Decoding Table --- */
static const char table64[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static void decodeQuantum(unsigned char *dest, const char *src)
{
unsigned int x = 0;
int i;
char *found;
for(i = 0; i < 4; i++) {
if(src[i] >= 'A' && src[i] <= 'Z')
x = (x << 6) + (unsigned int)(src[i] - 'A' + 0);
else if(src[i] >= 'a' && src[i] <= 'z')
x = (x << 6) + (unsigned int)(src[i] - 'a' + 26);
else if(src[i] >= '0' && src[i] <= '9')
x = (x << 6) + (unsigned int)(src[i] - '0' + 52);
else if(src[i] == '+')
x = (x << 6) + 62;
else if(src[i] == '/')
x = (x << 6) + 63;
if((found = strchr(table64, src[i])))
x = (x << 6) + (unsigned int)(found - table64);
else if(src[i] == '=')
x = (x << 6);
}
@@ -133,10 +132,6 @@ size_t Curl_base64_decode(const char *src, unsigned char **outptr)
return rawlen;
}
/* ---- Base64 Encoding --- */
static const char table64[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/*
* Curl_base64_encode()
*
@@ -145,7 +140,8 @@ static const char table64[]=
* went wrong, -1 is returned.
*
*/
size_t Curl_base64_encode(const char *inp, size_t insize, char **outptr)
size_t Curl_base64_encode(struct SessionHandle *data,
const char *inp, size_t insize, char **outptr)
{
unsigned char ibuf[3];
unsigned char obuf[4];
@@ -153,6 +149,9 @@ size_t Curl_base64_encode(const char *inp, size_t insize, char **outptr)
int inputparts;
char *output;
char *base64data;
#ifdef CURL_DOES_CONVERSIONS
char *convbuf;
#endif
char *indata = (char *)inp;
@@ -165,6 +164,28 @@ size_t Curl_base64_encode(const char *inp, size_t insize, char **outptr)
if(NULL == output)
return 0;
#ifdef CURL_DOES_CONVERSIONS
/*
* The base64 data needs to be created using the network encoding
* not the host encoding. And we can't change the actual input
* so we copy it to a buffer, translate it, and use that instead.
*/
if(data) {
convbuf = (char*)malloc(insize);
if(!convbuf) {
return 0;
}
memcpy(convbuf, indata, insize);
if(CURLE_OK != Curl_convert_to_network(data, convbuf, insize)) {
free(convbuf);
return 0;
}
indata = convbuf; /* switch to the converted buffer */
}
#else
(void)data;
#endif
while(insize > 0) {
for (i = inputparts = 0; i < 3; i++) {
if(insize > 0) {
@@ -209,6 +230,10 @@ size_t Curl_base64_encode(const char *inp, size_t insize, char **outptr)
*output=0;
*outptr = base64data; /* make it return the actual data memory */
#ifdef CURL_DOES_CONVERSIONS
if(data)
free(convbuf);
#endif
return strlen(base64data); /* return the length of the new data */
}
/* ---- End of Base64 Encoding ---- */
@@ -231,14 +256,26 @@ int main(int argc, char **argv, char **envp)
size_t base64Len;
unsigned char *data;
int dataLen;
struct SessionHandle *handle = NULL;
#ifdef CURL_DOES_CONVERSIONS
/* get a Curl handle so Curl_base64_encode can translate properly */
handle = curl_easy_init();
if(handle == NULL) {
fprintf(stderr, "Error: curl_easy_init failed\n");
return 0;
}
#endif
data = (unsigned char *)suck(&dataLen);
base64Len = Curl_base64_encode(data, dataLen, &base64);
base64Len = Curl_base64_encode(handle, data, dataLen, &base64);
fprintf(stderr, "%d\n", base64Len);
fprintf(stdout, "%s", base64);
fprintf(stdout, "%s\n", base64);
free(base64); free(data);
#ifdef CURL_DOES_CONVERSIONS
curl_easy_cleanup(handle);
#endif
return 0;
}
#endif
@@ -261,10 +298,17 @@ int main(int argc, char **argv, char **envp)
unsigned char *data;
int dataLen;
int i, j;
#ifdef CURL_DOES_CONVERSIONS
/* get a Curl handle so main can translate properly */
struct SessionHandle *handle = curl_easy_init();
if(handle == NULL) {
fprintf(stderr, "Error: curl_easy_init failed\n");
return 0;
}
#endif
base64 = (char *)suck(&base64Len);
data = (unsigned char *)malloc(base64Len * 3/4 + 8);
dataLen = Curl_base64_decode(base64, data);
dataLen = Curl_base64_decode(base64, &data);
fprintf(stderr, "%d\n", dataLen);
@@ -279,13 +323,21 @@ int main(int argc, char **argv, char **envp)
printf(" | ");
for(j=0; j < 0x10; j++)
if((j+i) < dataLen)
if((j+i) < dataLen) {
#ifdef CURL_DOES_CONVERSIONS
if(CURLE_OK !=
Curl_convert_from_network(handle, &data[i+j], (size_t)1))
data[i+j] = '.';
#endif /* CURL_DOES_CONVERSIONS */
printf("%c", ISGRAPH(data[i+j])?data[i+j]:'.');
else
} else
break;
puts("");
}
#ifdef CURL_DOES_CONVERSIONS
curl_easy_cleanup(handle);
#endif
free(base64); free(data);
return 0;
}

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -22,6 +22,7 @@
*
* $Id$
***************************************************************************/
size_t Curl_base64_encode(const char *input, size_t size, char **str);
size_t Curl_base64_encode(struct SessionHandle *data,
const char *input, size_t size, char **str);
size_t Curl_base64_decode(const char *source, unsigned char **outptr);
#endif

View File

@@ -31,6 +31,8 @@
#define HAVE_SETJMP_H 1
#define HAVE_SGTTY_H 1
#define HAVE_SIGNAL 1
#define HAVE_SIGNAL_H 1
#define HAVE_SIG_ATOMIC_T 1
#define HAVE_SOCKET 1
#define HAVE_STRCASECMP 1
#define HAVE_STRDUP 1

View File

@@ -32,6 +32,8 @@
//#define HAVE_STRICMP 1
#define HAVE_SIGACTION 1
#define HAVE_SIGNAL_H 1
#define HAVE_SIG_ATOMIC_T 1
#ifdef MACOS_SSL_SUPPORT
# define USE_SSLEAY 1
@@ -45,6 +47,8 @@
#define HAVE_FIONBIO 1
#define RETSIGTYPE void
#define HAVE_GETNAMEINFO 1
#define GETNAMEINFO_QUAL_ARG1 const
#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *

View File

@@ -245,6 +245,15 @@
/* Define if you have the `signal' function. */
#define HAVE_SIGNAL
/* Define if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H
/* Define if sig_atomic_t is an available typedef. */
#define HAVE_SIG_ATOMIC_T
/* Define if sig_atomic_t is already defined as volatile. */
#undef HAVE_SIG_ATOMIC_T_VOLATILE
/* Define if you have the `socket' function. */
#define HAVE_SOCKET

View File

@@ -413,6 +413,15 @@
/* Define to 1 if you have the `signal' function. */
#define HAVE_SIGNAL 1
/* Define to 1 if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
/* Define to 1 if sig_atomic_t is an available typedef. */
#define HAVE_SIG_ATOMIC_T 1
/* Define to 1 if sig_atomic_t is already defined as volatile. */
/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */
/* If you have sigsetjmp */
/* #undef HAVE_SIGSETJMP */

View File

@@ -57,6 +57,9 @@
#define HAVE_PROCESS_H 1
#endif
/* Define if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
/* Define if you have the <sgtty.h> header file. */
/* #define HAVE_SGTTY_H 1 */
@@ -125,6 +128,9 @@
/* OTHER HEADER INFO */
/* ---------------------------------------------------------------- */
/* Define if sig_atomic_t is an available typedef. */
#define HAVE_SIG_ATOMIC_T 1
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1
@@ -288,13 +294,11 @@
#define in_addr_t unsigned long
/* Define as the return type of signal handlers (int or void). */
/* #define RETSIGTYPE void */
#define RETSIGTYPE void
/* Define to `unsigned' if size_t is not an available 'typedefed' type */
/* #define size_t unsigned */
/* Define to 'int' if ssize_t is not an available 'typedefed' type */
#if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || defined(__POCC__)
#elif defined(_WIN64)
#define ssize_t __int64
#else
#define ssize_t int
#endif
@@ -348,6 +352,11 @@
/* Undef keyword 'const' if it does not work. */
/* #undef const */
#if defined(_MSC_VER) && (_MSC_VER > 1310)
/* MSVC 2003 has gmtime_r */
#define HAVE_GMTIME_R
#endif
/* ---------------------------------------------------------------- */
/* LDAP LIBRARY FILES */
/* ---------------------------------------------------------------- */

View File

@@ -48,6 +48,9 @@
/* Define if you have the <netinet/in.h> header file. */
/* #define HAVE_NETINET_IN_H 1 */
/* Define if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
/* Define if you have the <sgtty.h> header file. */
/* #define HAVE_SGTTY_H 1 */
@@ -114,6 +117,9 @@
/* OTHER HEADER INFO */
/* ---------------------------------------------------------------- */
/* Define if sig_atomic_t is an available typedef. */
#define HAVE_SIG_ATOMIC_T 1
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1
@@ -272,13 +278,15 @@
#define in_addr_t unsigned long
/* Define as the return type of signal handlers (int or void). */
/* #define RETSIGTYPE void */
#define RETSIGTYPE void
/* Define to `unsigned' if size_t is not an available 'typedefed' type */
/* #define size_t unsigned */
/* Define to 'int' if ssize_t is not an available 'typedefed' type */
/* Define ssize_t if it is not an available 'typedefed' type */
#if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || defined(__POCC__)
#elif defined(_WIN64)
#define ssize_t __int64
#else
#define ssize_t int
#endif
/* Define to 'int' if socklen_t is not an available 'typedefed' type */
#ifndef HAVE_WS2TCPIP_H

View File

@@ -51,6 +51,8 @@
#define HAVE_SETLOCALE 1
#define HAVE_SETVBUF 1
#define HAVE_SIGNAL 1
#define HAVE_SIGNAL_H 1
#define HAVE_SIG_ATOMIC_T 1
#define HAVE_SOCKET 1
#define HAVE_SPNEGO 1
#define HAVE_STRDUP 1

View File

@@ -384,11 +384,10 @@ static CURLcode bindlocal(struct connectdata *conn,
if( bind(sockfd, sock, socksize) >= 0) {
/* we succeeded to bind */
struct Curl_sockaddr_storage add;
size_t size;
socklen_t size;
size = sizeof(add);
if(getsockname(sockfd, (struct sockaddr *) &add,
(socklen_t *)&size)<0) {
if(getsockname(sockfd, (struct sockaddr *) &add, &size) < 0) {
failf(data, "getsockname() failed");
return CURLE_HTTP_PORT_FAILED;
}

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -806,9 +806,11 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
****************************************************************************/
void Curl_cookie_clearall(struct CookieInfo *cookies)
{
Curl_cookie_freelist(cookies->cookies);
cookies->cookies = NULL;
cookies->numcookies = 0;
if(cookies) {
Curl_cookie_freelist(cookies->cookies);
cookies->cookies = NULL;
cookies->numcookies = 0;
}
}
/*****************************************************************************

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -87,6 +87,7 @@
#include "progress.h"
#include "easyif.h"
#include "sendf.h" /* for failf function prototype */
#include <ca-bundle.h>
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -471,7 +472,7 @@ CURLcode curl_easy_perform(CURL *curl)
if(!data->state.connc) {
/* oops, no connection cache, make one up */
data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE);
data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, -1);
if(!data->state.connc)
return CURLE_OUT_OF_MEMORY;
}
@@ -561,7 +562,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
if(data->state.used_interface == Curl_if_multi)
outcurl->state.connc = data->state.connc;
else
outcurl->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE);
outcurl->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, -1);
if(!outcurl->state.connc)
break;
@@ -593,12 +594,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
break;
outcurl->change.url_alloc = TRUE;
}
if(data->change.proxy) {
outcurl->change.proxy = strdup(data->change.proxy);
if(!outcurl->change.proxy)
break;
outcurl->change.proxy_alloc = TRUE;
}
if(data->change.referer) {
outcurl->change.referer = strdup(data->change.referer);
if(!outcurl->change.referer)
@@ -623,6 +619,8 @@ CURL *curl_easy_duphandle(CURL *incurl)
Curl_easy_initHandleData(outcurl);
outcurl->magic = CURLEASY_MAGIC_NUMBER;
fail = FALSE; /* we reach this point and thus we are OK */
} while(0);
@@ -633,8 +631,6 @@ CURL *curl_easy_duphandle(CURL *incurl)
Curl_rm_connc(outcurl->state.connc);
if(outcurl->state.headerbuff)
free(outcurl->state.headerbuff);
if(outcurl->change.proxy)
free(outcurl->change.proxy);
if(outcurl->change.url)
free(outcurl->change.url);
if(outcurl->change.referer)
@@ -715,6 +711,9 @@ void curl_easy_reset(CURL *curl)
/* This is our prefered CA cert bundle since install time */
data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
#endif
data->set.ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
type */
}
#ifdef CURL_DOES_CONVERSIONS

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -165,7 +165,7 @@ CURLcode Curl_file_connect(struct connectdata *conn)
file->fd = fd;
if(!conn->data->set.upload && (fd == -1)) {
failf(conn->data, "Couldn't open file %s", conn->data->reqdata.path);
Curl_file_done(conn, CURLE_FILE_COULDNT_READ_FILE);
Curl_file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE);
return CURLE_FILE_COULDNT_READ_FILE;
}
@@ -173,10 +173,11 @@ CURLcode Curl_file_connect(struct connectdata *conn)
}
CURLcode Curl_file_done(struct connectdata *conn,
CURLcode status)
CURLcode status, bool premature)
{
struct FILEPROTO *file = conn->data->reqdata.proto.file;
(void)status; /* not used */
(void)premature; /* not used */
Curl_safefree(file->freepath);
if(file->fd != -1)

View File

@@ -8,7 +8,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -25,7 +25,7 @@
***************************************************************************/
#ifndef CURL_DISABLE_FILE
CURLcode Curl_file(struct connectdata *, bool *done);
CURLcode Curl_file_done(struct connectdata *, CURLcode);
CURLcode Curl_file_done(struct connectdata *, CURLcode, bool premature);
CURLcode Curl_file_connect(struct connectdata *);
#endif
#endif

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -24,7 +24,7 @@
/*
Debug the form generator stand-alone by compiling this source file with:
gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -o formdata -I../include formdata.c strequal.c
gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -DCURLDEBUG -o formdata -I../include formdata.c strequal.c memdebug.c mprintf.c strerror.c
run the 'formdata' executable the output should end with:
All Tests seem to have worked ...
@@ -63,7 +63,7 @@ Content-Type: multipart/mixed, boundary=curlz1s0dkticx49MV1KGcYP5cvfSsz
Content-Disposition: attachment; filename="inet_ntoa_r.h"
Content-Type: text/plain
...
Content-Disposition: attachment; filename="Makefile.b32.resp"
Content-Disposition: attachment; filename="Makefile.b32"
Content-Type: text/plain
...
@@ -73,7 +73,7 @@ Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1
Content-Disposition: attachment; filename="inet_ntoa_r.h"
Content-Type: text/plain
...
Content-Disposition: attachment; filename="Makefile.b32.resp"
Content-Disposition: attachment; filename="Makefile.b32"
Content-Type: text/plain
...
Content-Disposition: attachment; filename="inet_ntoa_r.h"
@@ -87,7 +87,7 @@ Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1
Content-Disposition: attachment; filename="inet_ntoa_r.h"
Content-Type: text/plain
...
Content-Disposition: attachment; filename="Makefile.b32.resp"
Content-Disposition: attachment; filename="Makefile.b32"
Content-Type: text/plain
...
Content-Disposition: attachment; filename="inet_ntoa_r.h"
@@ -118,6 +118,8 @@ Content-Disposition: form-data; name="FILECONTENT"
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
#include <libgen.h>
#endif
#include "urldata.h" /* for struct SessionHandle */
#include "easyif.h" /* for Curl_convert_... prototypes */
#include "formdata.h"
#include "strequal.h"
#include "memory.h"
@@ -452,7 +454,12 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
* Set the Name property.
*/
case CURLFORM_PTRNAME:
#ifdef CURL_DOES_CONVERSIONS
/* treat CURLFORM_PTR like CURLFORM_COPYNAME so we'll
have safe memory for the eventual conversion */
#else
current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
#endif
case CURLFORM_COPYNAME:
if (current_form->name)
return_value = CURL_FORMADD_OPTION_TWICE;
@@ -835,7 +842,7 @@ static CURLcode AddFormData(struct FormData **formp,
*formp = newform;
if (size) {
if(type == FORM_DATA)
if((type == FORM_DATA) || (type == FORM_CONTENT))
*size += length;
else {
/* Since this is a file to be uploaded here, add the size of the actual
@@ -872,10 +879,11 @@ static CURLcode AddFormDataf(struct FormData **formp,
* Curl_formclean() is used from http.c, this cleans a built FormData linked
* list
*/
void Curl_formclean(struct FormData *form)
void Curl_formclean(struct FormData **form_ptr)
{
struct FormData *next;
struct FormData *next, *form;
form = *form_ptr;
if(!form)
return;
@@ -885,8 +893,40 @@ void Curl_formclean(struct FormData *form)
free(form); /* free the struct */
} while ((form = next) != NULL); /* continue */
*form_ptr = NULL;
}
#ifdef CURL_DOES_CONVERSIONS
/*
* Curl_formcovert() is used from http.c, this converts any
form items that need to be sent in the network encoding.
Returns CURLE_OK on success.
*/
CURLcode Curl_formconvert(struct SessionHandle *data, struct FormData *form)
{
struct FormData *next;
CURLcode rc;
if(!form)
return CURLE_OK;
if(!data)
return CURLE_BAD_FUNCTION_ARGUMENT;
do {
next=form->next; /* the following form line */
if (form->type == FORM_DATA) {
rc = Curl_convert_to_network(data, form->line, form->length);
/* Curl_convert_to_network calls failf if unsuccessful */
if (rc != CURLE_OK)
return rc;
}
} while ((form = next) != NULL); /* continue */
return CURLE_OK;
}
#endif /* CURL_DOES_CONVERSIONS */
/*
* curl_formget()
* Serialize a curl_httppost struct.
@@ -917,18 +957,18 @@ int curl_formget(struct curl_httppost *form, void *arg,
if (temp.fp) {
fclose(temp.fp);
}
Curl_formclean(data);
Curl_formclean(&data);
return -1;
}
} while (read == sizeof(buffer));
} else {
if (ptr->length != append(arg, ptr->line, ptr->length)) {
Curl_formclean(data);
Curl_formclean(&data);
return -1;
}
}
}
Curl_formclean(data);
Curl_formclean(&data);
return 0;
}
@@ -1179,7 +1219,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
curList = curList->next;
}
if (result) {
Curl_formclean(firstform);
Curl_formclean(&firstform);
free(boundary);
return result;
}
@@ -1194,7 +1234,10 @@ CURLcode Curl_getFormData(struct FormData **finalform,
if(file->contenttype &&
!checkprefix("text/", file->contenttype)) {
/* this is not a text content, mention our binary encoding */
size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0);
result = AddFormDataf(&form, &size,
"\r\nContent-Transfer-Encoding: binary");
if (result)
break;
}
#endif
@@ -1232,21 +1275,26 @@ CURLcode Curl_getFormData(struct FormData **finalform,
size_t nread;
char buffer[512];
while ((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) {
result = AddFormData(&form, FORM_DATA, buffer, nread, &size);
result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size);
if (result)
break;
}
}
if (result) {
Curl_formclean(firstform);
Curl_formclean(&firstform);
free(boundary);
return result;
}
}
else {
Curl_formclean(firstform);
#ifdef _FORM_DEBUG
fprintf(stderr,
"\n==> Curl_getFormData couldn't open/read \"%s\"\n",
file->contents);
#endif
Curl_formclean(&firstform);
free(boundary);
*finalform = NULL;
return CURLE_READ_ERROR;
@@ -1255,7 +1303,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
}
else if (post->flags & HTTPPOST_BUFFER) {
/* include contents of buffer */
result = AddFormData(&form, FORM_DATA, post->buffer,
result = AddFormData(&form, FORM_CONTENT, post->buffer,
post->bufferlength, &size);
if (result)
break;
@@ -1263,14 +1311,14 @@ CURLcode Curl_getFormData(struct FormData **finalform,
else {
/* include the contents we got */
result = AddFormData(&form, FORM_DATA, post->contents,
result = AddFormData(&form, FORM_CONTENT, post->contents,
post->contentslength, &size);
if (result)
break;
}
} while ((file = file->more) != NULL); /* for each specified file for this field */
if (result) {
Curl_formclean(firstform);
Curl_formclean(&firstform);
free(boundary);
return result;
}
@@ -1288,7 +1336,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
} while ((post = post->next) != NULL); /* for each field */
if (result) {
Curl_formclean(firstform);
Curl_formclean(&firstform);
free(boundary);
return result;
}
@@ -1298,7 +1346,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
"\r\n--%s--\r\n",
boundary);
if (result) {
Curl_formclean(firstform);
Curl_formclean(&firstform);
free(boundary);
return result;
}
@@ -1397,7 +1445,7 @@ size_t Curl_FormReader(char *buffer,
form->data = form->data->next; /* advance */
} while(form->data && (form->data->type == FORM_DATA));
} while(form->data && (form->data->type != FORM_FILE));
/* If we got an empty line and we have more data, we proceed to the next
line immediately to avoid returning zero before we've reached the end.
This is the bug reported November 22 1999 on curl 6.3. (Daniel) */
@@ -1464,7 +1512,7 @@ int main()
char value5[] = "value for PTRCONTENTS + CONTENTSLENGTH";
char value6[] = "value for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE";
char value7[] = "inet_ntoa_r.h";
char value8[] = "Makefile.b32.resp";
char value8[] = "Makefile.b32";
char type2[] = "image/gif";
char type6[] = "text/plain";
char type7[] = "text/html";
@@ -1473,7 +1521,8 @@ int main()
int value5length = strlen(value4);
int value6length = strlen(value5);
int errors = 0;
int size;
CURLcode rc;
size_t size;
size_t nread;
char buffer[4096];
struct curl_httppost *httppost=NULL;
@@ -1549,7 +1598,14 @@ int main()
CURLFORM_END))
++errors;
form=Curl_getFormData(httppost, &size);
rc = Curl_getFormData(&form, httppost, NULL, &size);
if(rc != CURLE_OK) {
if(rc != CURLE_READ_ERROR) {
const char *errortext = curl_easy_strerror(rc);
fprintf(stdout, "\n==> Curl_getFormData error: %s\n", errortext);
}
return 0;
}
Curl_FormInit(&formread, form);
@@ -1557,7 +1613,7 @@ int main()
nread = Curl_FormReader(buffer, 1, sizeof(buffer),
(FILE *)&formread);
if(-1 == nread)
if(nread < 1)
break;
fwrite(buffer, nread, 1, stdout);
} while(1);

View File

@@ -8,7 +8,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -25,8 +25,10 @@
***************************************************************************/
enum formtype {
FORM_DATA, /* regular data */
FORM_FILE /* 'line' points to a file name we should read from */
FORM_DATA, /* form metadata (convert to network encoding if necessary) */
FORM_CONTENT, /* form content (never convert) */
FORM_FILE /* 'line' points to a file name we should read from
to create the form data (never convert) */
};
/* plain and simple linked list with lines to send */
@@ -87,7 +89,9 @@ char *Curl_formpostheader(void *formp, size_t *len);
char *Curl_FormBoundary(void);
void Curl_formclean(struct FormData *);
void Curl_formclean(struct FormData **);
CURLcode Curl_formconvert(struct SessionHandle *, struct FormData *);
#endif

104
lib/ftp.c
View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -265,7 +265,6 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
ssize_t gotbytes;
char *ptr;
struct SessionHandle *data = conn->data;
struct Curl_transfer_keeper *k = &data->reqdata.keep;
char *buf = data->state.buffer;
CURLcode result = CURLE_OK;
struct ftp_conn *ftpc = &conn->proto.ftpc;
@@ -329,7 +328,7 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
* line */
int i;
k->headerbytecount += gotbytes;
conn->headerbytecount += gotbytes;
ftpc->nread_resp += gotbytes;
for(i = 0; i < gotbytes; ptr++, i++) {
@@ -448,7 +447,6 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
long timeout; /* timeout in seconds */
int interval_ms;
struct SessionHandle *data = conn->data;
struct Curl_transfer_keeper *k = &data->reqdata.keep;
char *line_start;
int code=0; /* default ftp "error code" to return */
char *buf = data->state.buffer;
@@ -562,7 +560,7 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
* line */
int i;
k->headerbytecount += gotbytes;
conn->headerbytecount += gotbytes;
*nreadp += gotbytes;
for(i = 0; i < gotbytes; ptr++, i++) {
@@ -573,7 +571,7 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
/* output debug output if that is requested */
if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN,
Curl_debug(data, CURLINFO_HEADER_IN,
line_start, (size_t)perline, conn);
/*
@@ -668,6 +666,7 @@ static void state(struct connectdata *conn,
"ACCT",
"PBSZ",
"PROT",
"CCC",
"PWD",
"QUOTE",
"RETR_PREQUOTE",
@@ -1168,6 +1167,15 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
#endif /* end of ipv4-specific code */
/* this tcpconnect assignment below is a hackish work-around to make the
multi interface with active FTP work - as it will not wait for a
(passive) connect in Curl_is_connected().
The *proper* fix is to make sure that the active connection from the
server is done in a non-blocking way. Currently, it is still BLOCKING.
*/
conn->bits.tcpconnect = TRUE;
state(conn, FTP_PORT);
return result;
}
@@ -1661,7 +1669,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
return CURLE_FTP_WEIRD_PASV_REPLY;
}
if(data->change.proxy && *data->change.proxy) {
if(data->set.proxy && *data->set.proxy) {
/*
* This is a tunnel through a http proxy and we need to connect to the
* proxy again here.
@@ -2538,6 +2546,31 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
/* we failed and bails out */
return CURLE_FTP_SSL_FAILED;
if(data->set.ftp_use_ccc) {
/* CCC - Clear Command Channel
*/
NBFTPSENDF(conn, "CCC", NULL);
state(conn, FTP_CCC);
}
else {
result = ftp_state_pwd(conn);
if(result)
return result;
}
break;
case FTP_CCC:
if (ftpcode < 500) {
/* First shut down the SSL layer (note: this call will block) */
result = Curl_ssl_shutdown(conn, FIRSTSOCKET);
if(result) {
failf(conn->data, "Failed to clear the command channel (CCC)");
return result;
}
}
/* Then continue as normal */
result = ftp_state_pwd(conn);
if(result)
return result;
@@ -2933,7 +2966,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn,
*
* Input argument is already checked for validity.
*/
CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status, bool premature)
{
struct SessionHandle *data = conn->data;
struct FTP *ftp = data->reqdata.proto.ftp;
@@ -2956,6 +2989,32 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
*/
return CURLE_OK;
switch(status) {
case CURLE_BAD_DOWNLOAD_RESUME:
case CURLE_FTP_WEIRD_PASV_REPLY:
case CURLE_FTP_PORT_FAILED:
case CURLE_FTP_COULDNT_SET_BINARY:
case CURLE_FTP_COULDNT_RETR_FILE:
case CURLE_FTP_COULDNT_STOR_FILE:
case CURLE_FTP_ACCESS_DENIED:
/* the connection stays alive fine even though this happened */
/* fall-through */
case CURLE_OK: /* doesn't affect the control connection's status */
if (!premature) {
ftpc->ctl_valid = was_ctl_valid;
break;
}
/* until we cope better with prematurely ended requests, let them
* fallback as if in complete failure */
default: /* by default, an error means the control connection is
wedged and should not be used anymore */
ftpc->ctl_valid = FALSE;
ftpc->cwdfail = TRUE; /* set this TRUE to prevent us to remember the
current path, as this connection is going */
conn->bits.close = TRUE; /* marked for closure */
break;
}
/* now store a copy of the directory we are in */
if(ftpc->prevpath)
free(ftpc->prevpath);
@@ -2981,25 +3040,6 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
/* free the dir tree and file parts */
freedirs(conn);
switch(status) {
case CURLE_BAD_DOWNLOAD_RESUME:
case CURLE_FTP_WEIRD_PASV_REPLY:
case CURLE_FTP_PORT_FAILED:
case CURLE_FTP_COULDNT_SET_BINARY:
case CURLE_FTP_COULDNT_RETR_FILE:
case CURLE_FTP_COULDNT_STOR_FILE:
case CURLE_FTP_ACCESS_DENIED:
/* the connection stays alive fine even though this happened */
/* fall-through */
case CURLE_OK: /* doesn't affect the control connection's status */
ftpc->ctl_valid = was_ctl_valid;
break;
default: /* by default, an error means the control connection is
wedged and should not be used anymore */
ftpc->ctl_valid = FALSE;
break;
}
#ifdef HAVE_KRB4
Curl_sec_fflush_fd(conn, conn->sock[SECONDARYSOCKET]);
#endif
@@ -3014,7 +3054,7 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
if(!ftp->no_transfer && !status) {
if(!ftp->no_transfer && !status && !premature) {
/*
* Let's see what the server says about the transfer we just performed,
* but lower the timeout as sometimes this connection has died while the
@@ -3047,7 +3087,7 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
}
}
if(result)
if(result || premature)
/* the response code from the transfer showed an error already so no
use checking further */
;
@@ -3089,7 +3129,7 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
ftpc->dont_check = FALSE;
/* Send any post-transfer QUOTE strings? */
if(!status && !result && data->set.postquote)
if(!status && !result && !premature && data->set.postquote)
result = ftp_sendquote(conn, data->set.postquote);
return result;
@@ -3433,7 +3473,7 @@ CURLcode Curl_nbftpsendf(struct connectdata *conn,
return res;
if(conn->data->set.verbose)
Curl_debug(conn->data, CURLINFO_HEADER_OUT,
Curl_debug(conn->data, CURLINFO_HEADER_OUT,
sptr, (size_t)bytes_written, conn);
if(bytes_written != (ssize_t)write_len) {
@@ -3491,7 +3531,7 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
break;
if(conn->data->set.verbose)
Curl_debug(conn->data, CURLINFO_HEADER_OUT,
Curl_debug(conn->data, CURLINFO_HEADER_OUT,
sptr, (size_t)bytes_written, conn);
if(bytes_written != (ssize_t)write_len) {

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -25,7 +25,7 @@
#ifndef CURL_DISABLE_FTP
CURLcode Curl_ftp(struct connectdata *conn, bool *done);
CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode);
CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode, bool premature);
CURLcode Curl_ftp_connect(struct connectdata *conn, bool *done);
CURLcode Curl_ftp_disconnect(struct connectdata *conn);
CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);

View File

@@ -77,6 +77,9 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
struct curl_slist **param_slistp=NULL;
char buf;
if(!data)
return CURLE_BAD_FUNCTION_ARGUMENT;
va_start(arg, info);
switch(info&CURLINFO_TYPEMASK) {

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -67,6 +67,23 @@ static void tls_log_func(int level, const char *str)
}
#endif
/*
* Custom push and pull callback functions used by GNU TLS to read and write
* to the socket. These functions are simple wrappers to send() and recv()
* (although here using the sread/swrite macros as defined by setup_once.h).
* We use custom functions rather than the GNU TLS defaults because it allows
* us to get specific about the fourth "flags" argument, and to use arbitrary
* private data with gnutls_transport_set_ptr if we wish.
*/
static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len)
{
return swrite(s, buf, len);
}
static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len)
{
return sread(s, buf, len);
}
/* Global GnuTLS init, called from Curl_ssl_init() */
int Curl_gtls_init(void)
@@ -285,6 +302,13 @@ Curl_gtls_connect(struct connectdata *conn,
gnutls_transport_set_ptr(session,
(gnutls_transport_ptr)conn->sock[sockindex]);
/* register callback functions to send and receive data. */
gnutls_transport_set_push_function(session, Curl_gtls_push);
gnutls_transport_set_pull_function(session, Curl_gtls_pull);
/* lowat must be set to zero when using custom push and pull functions. */
gnutls_transport_set_lowat(session, 0);
/* This might be a reconnect, so we check for a session ID in the cache
to speed up things */
@@ -452,13 +476,12 @@ Curl_gtls_connect(struct connectdata *conn,
/* return number of sent (non-SSL) bytes */
int Curl_gtls_send(struct connectdata *conn,
ssize_t Curl_gtls_send(struct connectdata *conn,
int sockindex,
void *mem,
size_t len)
{
int rc;
rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
ssize_t rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
if(rc < 0 ) {
if(rc == GNUTLS_E_AGAIN)
@@ -493,6 +516,72 @@ void Curl_gtls_close(struct connectdata *conn)
close_one(conn, 1);
}
/*
* This function is called to shut down the SSL layer but keep the
* socket open (CCC - Clear Command Channel)
*/
int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
{
int result;
int retval = 0;
struct SessionHandle *data = conn->data;
int done = 0;
ssize_t nread;
char buf[120];
/* This has only been tested on the proftpd server, and the mod_tls code
sends a close notify alert without waiting for a close notify alert in
response. Thus we wait for a close notify alert from the server, but
we do not send one. Let's hope other servers do the same... */
if(conn->ssl[sockindex].session) {
while(!done) {
int what = Curl_select(conn->sock[sockindex],
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
if(what > 0) {
/* Something to read, let's do it and hope that it is the close
notify alert from the server */
result = gnutls_record_recv(conn->ssl[sockindex].session,
buf, sizeof(buf));
switch(result) {
case 0:
/* This is the expected response. There was no data but only
the close notify alert */
done = 1;
break;
case GNUTLS_E_AGAIN:
case GNUTLS_E_INTERRUPTED:
infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n");
break;
default:
retval = -1;
done = 1;
break;
}
}
else if(0 == what) {
/* timeout */
failf(data, "SSL shutdown timeout");
done = 1;
break;
}
else {
/* anything that gets here is fatally bad */
failf(data, "select on SSL socket, errno: %d", Curl_sockerrno());
retval = -1;
done = 1;
}
}
gnutls_deinit(conn->ssl[sockindex].session);
}
gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);
conn->ssl[sockindex].session = NULL;
conn->ssl[sockindex].use = FALSE;
return retval;
}
/*
* If the read would block we return -1 and set 'wouldblock' to TRUE.
* Otherwise we return the amount of data read. Other errors should return -1

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -32,8 +32,8 @@ void Curl_gtls_close_all(struct SessionHandle *data);
void Curl_gtls_close(struct connectdata *conn); /* close a SSL connection */
/* return number of sent (non-SSL) bytes */
int Curl_gtls_send(struct connectdata *conn, int sockindex,
void *mem, size_t len);
ssize_t Curl_gtls_send(struct connectdata *conn, int sockindex,
void *mem, size_t len);
ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
int num, /* socketindex */
char *buf, /* store read data here */
@@ -41,5 +41,6 @@ ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
bool *wouldblock);
void Curl_gtls_session_free(void *ptr);
size_t Curl_gtls_version(char *buffer, size_t size);
int Curl_gtls_shutdown(struct connectdata *conn, int sockindex);
#endif

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -80,6 +80,7 @@
#include <curl/curl.h>
#include "transfer.h"
#include "sendf.h"
#include "easyif.h" /* for Curl_convert_... prototypes */
#include "formdata.h"
#include "progress.h"
#include "base64.h"
@@ -149,12 +150,12 @@ static CURLcode Curl_output_basic(struct connectdata *conn, bool proxy)
}
snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
if(Curl_base64_encode(data->state.buffer,
if(Curl_base64_encode(data, data->state.buffer,
strlen(data->state.buffer),
&authorization) > 0) {
if(*userp)
free(*userp);
*userp = aprintf( "%sAuthorization: Basic %s\015\012",
*userp = aprintf( "%sAuthorization: Basic %s\r\n",
proxy?"Proxy-":"",
authorization);
free(authorization);
@@ -873,6 +874,20 @@ CURLcode add_buffer_send(send_buffer *in,
ptr = in->buffer;
size = in->size_used;
#ifdef CURL_DOES_CONVERSIONS
if(size - included_body_bytes > 0) {
res = Curl_convert_to_network(conn->data, ptr, size - included_body_bytes);
/* Curl_convert_to_network calls failf if unsuccessful */
if(res != CURLE_OK) {
/* conversion failed, free memory and return to the caller */
if(in->buffer)
free(in->buffer);
free(in);
return res;
}
}
#endif /* CURL_DOES_CONVERSIONS */
if(conn->protocol & PROT_HTTPS) {
/* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
when we speak HTTPS, as if only a fraction of it is sent now, this data
@@ -903,8 +918,8 @@ CURLcode add_buffer_send(send_buffer *in,
Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr,
(size_t)(amount-included_body_bytes), conn);
if (included_body_bytes)
Curl_debug(conn->data, CURLINFO_DATA_OUT,
ptr+amount-included_body_bytes,
Curl_debug(conn->data, CURLINFO_DATA_OUT,
ptr+amount-included_body_bytes,
(size_t)included_body_bytes, conn);
}
@@ -1086,6 +1101,8 @@ Curl_compareheader(char *headerline, /* line to check */
* like any ordinary HTTP request, and not specially crafted like this. This
* function only remains here like this for now since the rewrite is a bit too
* much work to do at the moment.
*
* This function is BLOCKING which is nasty for all multi interface using apps.
*/
CURLcode Curl_proxyCONNECT(struct connectdata *conn,
@@ -1110,6 +1127,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
curl_socket_t tunnelsocket = conn->sock[sockindex];
send_buffer *req_buffer;
curl_off_t cl=0;
bool closeConnection = FALSE;
#define SELECT_OK 0
#define SELECT_ERROR 1
@@ -1117,6 +1135,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
int error = SELECT_OK;
infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
conn->bits.proxy_connect_closed = FALSE;
do {
if(data->reqdata.newurl) {
@@ -1143,15 +1162,18 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
if(CURLE_OK == result) {
char *host=(char *)"";
const char *proxyconn="";
const char *useragent="";
if(!checkheaders(data, "Host:")) {
host = aprintf("Host: %s\r\n", host_port);
if(!host)
result = CURLE_OUT_OF_MEMORY;
}
if(!checkheaders(data, "Proxy-Connection:")) {
if(!checkheaders(data, "Proxy-Connection:"))
proxyconn = "Proxy-Connection: Keep-Alive\r\n";
}
if(!checkheaders(data, "User-Agent:") && data->set.useragent)
useragent = conn->allocptr.uagent;
if(CURLE_OK == result) {
/* Send the connect request to the proxy */
@@ -1167,7 +1189,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
host,
conn->allocptr.proxyuserpwd?
conn->allocptr.proxyuserpwd:"",
data->set.useragent?conn->allocptr.uagent:"",
useragent,
proxyconn);
if(CURLE_OK == result)
@@ -1258,7 +1280,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
/* output debug if that is requested */
if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN,
Curl_debug(data, CURLINFO_HEADER_IN,
line_start, (size_t)perline, conn);
/* send the header to the callback */
@@ -1310,6 +1332,9 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
cl = curlx_strtoofft(line_start + strlen("Content-Length:"),
NULL, 10);
}
else if(Curl_compareheader(line_start,
"Connection:", "close"))
closeConnection = TRUE;
else if(2 == sscanf(line_start, "HTTP/1.%d %d",
&subversion,
&k->httpcode)) {
@@ -1336,11 +1361,21 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
headers. 'newurl' is set to a new URL if we must loop. */
Curl_http_auth_act(conn);
if (closeConnection && data->reqdata.newurl) {
/* Connection closed by server. Don't use it anymore */
sclose(conn->sock[sockindex]);
conn->sock[sockindex] = CURL_SOCKET_BAD;
break;
}
} while(data->reqdata.newurl);
if(200 != k->httpcode) {
failf(data, "Received HTTP code %d from proxy after CONNECT",
k->httpcode);
if (closeConnection && data->reqdata.newurl)
conn->bits.proxy_connect_closed = TRUE;
return CURLE_RECV_ERROR;
}
@@ -1390,6 +1425,8 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
free(data->state.first_host);
data->state.first_host = strdup(conn->host.name);
if(!data->state.first_host)
return CURLE_OUT_OF_MEMORY;
}
if(conn->protocol & PROT_HTTPS) {
@@ -1473,11 +1510,12 @@ int Curl_https_getsock(struct connectdata *conn,
*/
CURLcode Curl_http_done(struct connectdata *conn,
CURLcode status)
CURLcode status, bool premature)
{
struct SessionHandle *data = conn->data;
struct HTTP *http =data->reqdata.proto.http;
struct Curl_transfer_keeper *k = &data->reqdata.keep;
(void)premature; /* not used */
/* set the proper values (possibly modified on POST) */
conn->fread = data->set.fread; /* restore */
@@ -1497,7 +1535,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
if(HTTPREQ_POST_FORM == data->set.httpreq) {
k->bytecount = http->readbytecount + http->writebytecount;
Curl_formclean(http->sendit); /* Now free that whole lot */
Curl_formclean(&http->sendit); /* Now free that whole lot */
if(http->form.fp) {
/* a file being uploaded was left opened, close it! */
fclose(http->form.fp);
@@ -1512,8 +1550,8 @@ CURLcode Curl_http_done(struct connectdata *conn,
if(!conn->bits.retry &&
((http->readbytecount +
k->headerbytecount -
k->deductheadercount)) <= 0) {
conn->headerbytecount -
conn->deductheadercount)) <= 0) {
/* If this connection isn't simply closed to be retried, AND nothing was
read from the HTTP server (that counts), this can't be right so we
return an error here */
@@ -1599,7 +1637,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
struct HTTP *http;
char *ppath = data->reqdata.path;
char *host = conn->host.name;
const char *te = ""; /* tranfer-encoding */
const char *te = ""; /* transfer-encoding */
char *ptr;
char *request;
Curl_HttpReq httpreq = data->set.httpreq;
@@ -1684,7 +1722,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
Curl_safefree(conn->allocptr.ref);
if(data->change.referer && !checkheaders(data, "Referer:"))
conn->allocptr.ref = aprintf("Referer: %s\015\012", data->change.referer);
conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
else
conn->allocptr.ref = NULL;
@@ -1695,7 +1733,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
data->set.encoding) {
Curl_safefree(conn->allocptr.accept_encoding);
conn->allocptr.accept_encoding =
aprintf("Accept-Encoding: %s\015\012", data->set.encoding);
aprintf("Accept-Encoding: %s\r\n", data->set.encoding);
if(!conn->allocptr.accept_encoding)
return CURLE_OUT_OF_MEMORY;
}
@@ -2179,10 +2217,19 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
&http->readbytecount,
FIRSTSOCKET,
&http->writebytecount);
if(result) {
Curl_formclean(http->sendit); /* free that whole lot */
Curl_formclean(&http->sendit); /* free that whole lot */
return result;
}
#ifdef CURL_DOES_CONVERSIONS
/* time to convert the form data... */
result = Curl_formconvert(data, http->sendit);
if(result) {
Curl_formclean(&http->sendit); /* free that whole lot */
return result;
}
#endif /* CURL_DOES_CONVERSIONS */
break;
case HTTPREQ_PUT: /* Let's PUT the data to the server! */
@@ -2301,8 +2348,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
(size_t)postsize);
if(CURLE_OK == result)
result = add_buffer(req_buffer,
"\r\n0\r\n\r\n", 7); /* end of a chunked
transfer stream */
"\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
/* CR LF 0 CR LF CR LF */
included_body = postsize + 7;
}
if(result)

View File

@@ -8,7 +8,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -35,7 +35,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
/* protocol-specific functions set up to be called by the main engine */
CURLcode Curl_http(struct connectdata *conn, bool *done);
CURLcode Curl_http_done(struct connectdata *, CURLcode);
CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature);
CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
CURLcode Curl_https_connecting(struct connectdata *conn, bool *done);
int Curl_https_getsock(struct connectdata *conn,

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -36,6 +36,7 @@
#include "content_encoding.h"
#include "http.h"
#include "memory.h"
#include "easyif.h" /* for Curl_convert_to_network prototype */
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -96,6 +97,9 @@ void Curl_httpchunk_init(struct connectdata *conn)
* client (for byte-counting and whatever).
*
* The states and the state-machine is further explained in the header file.
*
* This function always uses ASCII hex values to accommodate non-ASCII hosts.
* For example, 0x0d and 0x0a are used instead of '\r' and '\n'.
*/
CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
char *datap,
@@ -115,7 +119,11 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
while(length) {
switch(ch->state) {
case CHUNK_HEX:
if(ISXDIGIT(*datap)) {
/* Check for an ASCII hex digit.
We avoid the use of isxdigit to accommodate non-ASCII hosts. */
if((*datap >= 0x30 && *datap <= 0x39) /* 0-9 */
|| (*datap >= 0x41 && *datap <= 0x46) /* A-F */
|| (*datap >= 0x61 && *datap <= 0x66)) { /* a-f */
if(ch->hexindex < MAXNUM_SIZE) {
ch->hexbuffer[ch->hexindex] = *datap;
datap++;
@@ -134,6 +142,17 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
}
/* length and datap are unmodified */
ch->hexbuffer[ch->hexindex]=0;
#ifdef CURL_DOES_CONVERSIONS
/* convert to host encoding before calling strtoul */
result = Curl_convert_from_network(conn->data,
ch->hexbuffer,
ch->hexindex);
if(result != CURLE_OK) {
/* Curl_convert_from_network calls failf if unsuccessful */
/* Treat it as a bad hex character */
return(CHUNKE_ILLEGAL_HEX);
}
#endif /* CURL_DOES_CONVERSIONS */
ch->datasize=strtoul(ch->hexbuffer, NULL, 16);
ch->state = CHUNK_POSTHEX;
}
@@ -143,7 +162,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
/* In this state, we're waiting for CRLF to arrive. We support
this to allow so called chunk-extensions to show up here
before the CRLF comes. */
if(*datap == '\r')
if(*datap == 0x0d)
ch->state = CHUNK_CR;
length--;
datap++;
@@ -151,7 +170,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
case CHUNK_CR:
/* waiting for the LF */
if(*datap == '\n') {
if(*datap == 0x0a) {
/* we're now expecting data to come, unless size was zero! */
if(0 == ch->datasize) {
if (conn->bits.trailerHdrPresent!=TRUE) {
@@ -235,7 +254,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
break;
case CHUNK_POSTCR:
if(*datap == '\r') {
if(*datap == 0x0d) {
ch->state = CHUNK_POSTLF;
datap++;
length--;
@@ -245,7 +264,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
break;
case CHUNK_POSTLF:
if(*datap == '\n') {
if(*datap == 0x0a) {
/*
* The last one before we go back to hex state and start all
* over.
@@ -277,7 +296,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
}
conn->trailer[conn->trlPos++]=*datap;
if(*datap == '\r')
if(*datap == 0x0d)
ch->state = CHUNK_TRAILER_CR;
else {
datap++;
@@ -286,7 +305,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
break;
case CHUNK_TRAILER_CR:
if(*datap == '\r') {
if(*datap == 0x0d) {
ch->state = CHUNK_TRAILER_POSTCR;
datap++;
length--;
@@ -296,14 +315,25 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
break;
case CHUNK_TRAILER_POSTCR:
if (*datap == '\n') {
conn->trailer[conn->trlPos++]='\n';
if (*datap == 0x0a) {
conn->trailer[conn->trlPos++]=0x0a;
conn->trailer[conn->trlPos]=0;
if (conn->trlPos==2) {
ch->state = CHUNK_STOP;
return CHUNKE_STOP;
}
else {
#ifdef CURL_DOES_CONVERSIONS
/* Convert to host encoding before calling Curl_client_write */
result = Curl_convert_from_network(conn->data,
conn->trailer,
conn->trlPos);
if(result != CURLE_OK) {
/* Curl_convert_from_network calls failf if unsuccessful */
/* Treat it as a bad chunk */
return(CHUNKE_BAD_CHUNK);
}
#endif /* CURL_DOES_CONVERSIONS */
Curl_client_write(conn, CLIENTWRITE_HEADER,
conn->trailer, conn->trlPos);
}

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -39,6 +39,7 @@
#include "strtok.h"
#include "url.h" /* for Curl_safefree() */
#include "memory.h"
#include "easyif.h" /* included for Curl_convert_... prototypes */
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -234,6 +235,21 @@ CURLcode Curl_output_digest(struct connectdata *conn,
struct SessionHandle *data = conn->data;
struct digestdata *d;
#ifdef CURL_DOES_CONVERSIONS
CURLcode rc;
/* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines.
It converts digest text to ASCII so the MD5 will be correct for
what ultimately goes over the network.
*/
#define CURL_OUTPUT_DIGEST_CONV(a, b) \
rc = Curl_convert_to_network(a, (char *)b, strlen((const char*)b)); \
if (rc != CURLE_OK) { \
free(b); \
return rc; \
}
#else
#define CURL_OUTPUT_DIGEST_CONV(a, b)
#endif /* CURL_DOES_CONVERSIONS */
if(proxy) {
d = &data->state.proxydigest;
@@ -270,7 +286,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
/* Generate a cnonce */
now = Curl_tvnow();
snprintf(cnoncebuf, sizeof(cnoncebuf), "%06ld", now.tv_sec);
if(Curl_base64_encode(cnoncebuf, strlen(cnoncebuf), &cnonce))
if(Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf), &cnonce))
d->cnonce = cnonce;
else
return CURLE_OUT_OF_MEMORY;
@@ -291,6 +307,8 @@ CURLcode Curl_output_digest(struct connectdata *conn,
aprintf("%s:%s:%s", userp, d->realm, passwdp);
if(!md5this)
return CURLE_OUT_OF_MEMORY;
CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
Curl_md5it(md5buf, md5this);
free(md5this); /* free this again */
@@ -305,6 +323,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
tmp = aprintf("%s:%s:%s", ha1, d->nonce, d->cnonce);
if(!tmp)
return CURLE_OUT_OF_MEMORY;
CURL_OUTPUT_DIGEST_CONV(data, tmp); /* convert on non-ASCII machines */
Curl_md5it(md5buf, (unsigned char *)tmp);
free(tmp); /* free this again */
md5_to_ascii(md5buf, ha1);
@@ -334,6 +353,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
entity-body here */
/* TODO: Append H(entity-body)*/
}
CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
Curl_md5it(md5buf, md5this);
free(md5this); /* free this again */
md5_to_ascii(md5buf, ha2);
@@ -357,6 +377,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
if(!md5this)
return CURLE_OUT_OF_MEMORY;
CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
Curl_md5it(md5buf, md5this);
free(md5this); /* free this again */
md5_to_ascii(md5buf, request_digest);

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -290,7 +290,8 @@ CURLcode Curl_output_negotiate(struct connectdata *conn)
}
}
#endif
len = Curl_base64_encode(neg_ctx->output_token.value,
len = Curl_base64_encode(conn->data,
neg_ctx->output_token.value,
neg_ctx->output_token.length,
&encoded);

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -44,7 +44,12 @@
#include <stdlib.h>
#include <ctype.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "urldata.h"
#include "easyif.h" /* for Curl_convert_... prototypes */
#include "sendf.h"
#include "strequal.h"
#include "base64.h"
@@ -56,6 +61,9 @@
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
/* "NTLMSSP" signature is always in ASCII regardless of the platform */
#define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50"
#ifndef USE_WINDOWS_SSPI
#include <openssl/des.h>
@@ -261,7 +269,7 @@ CURLntlm Curl_input_ntlm(struct connectdata *conn,
ntlm->flags = 0;
if((size < 32) ||
(memcmp(buffer, "NTLMSSP", 8) != 0) ||
(memcmp(buffer, NTLMSSP_SIGNATURE, 8) != 0) ||
(memcmp(buffer+8, type2_marker, sizeof(type2_marker)) != 0)) {
/* This was not a good enough type-2 message */
free(buffer);
@@ -275,7 +283,7 @@ CURLntlm Curl_input_ntlm(struct connectdata *conn,
fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags);
print_flags(stderr, ntlm->flags);
fprintf(stderr, "\n nonce=");
print_hex(stderr, ntlm->nonce, 8);
print_hex(stderr, (char *)ntlm->nonce, 8);
fprintf(stderr, "\n****\n");
fprintf(stderr, "**** Header %s\n ", header);
});
@@ -345,7 +353,9 @@ static void lm_resp(unsigned char *keys,
/*
* Set up lanmanager hashed password
*/
static void mk_lm_hash(char *password, unsigned char *lmbuffer /* 21 bytes */)
static void mk_lm_hash(struct SessionHandle *data,
char *password,
unsigned char *lmbuffer /* 21 bytes */)
{
unsigned char pw[14];
static const unsigned char magic[] = {
@@ -363,6 +373,17 @@ static void mk_lm_hash(char *password, unsigned char *lmbuffer /* 21 bytes */)
for (; i<14; i++)
pw[i] = 0;
#ifdef CURL_DOES_CONVERSIONS
/*
* The LanManager hashed password needs to be created using the
* password in the network encoding not the host encoding.
*/
if(data)
Curl_convert_to_network(data, (char *)pw, 14);
#else
(void)data;
#endif
{
/* Create LanManager hashed password. */
@@ -394,13 +415,26 @@ static void utf8_to_unicode_le(unsigned char *dest, const char *src,
/*
* Set up nt hashed passwords
*/
static void mk_nt_hash(char *password, unsigned char *ntbuffer /* 21 bytes */)
static void mk_nt_hash(struct SessionHandle *data,
char *password,
unsigned char *ntbuffer /* 21 bytes */)
{
size_t len = strlen(password);
unsigned char *pw = malloc(len*2);
utf8_to_unicode_le(pw, password, len);
#ifdef CURL_DOES_CONVERSIONS
/*
* The NT hashed password needs to be created using the
* password in the network encoding not the host encoding.
*/
if(data)
Curl_convert_to_network(data, (char *)pw, len*2);
#else
(void)data;
#endif
{
/* Create NT hashed password. */
MD4_CTX MD4;
@@ -643,7 +677,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
#else
#define NTLM2FLAG 0
#endif
snprintf((char *)ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c"
snprintf((char *)ntlmbuf, sizeof(ntlmbuf), NTLMSSP_SIGNATURE "%c"
"\x01%c%c%c" /* 32-bit type = 1 */
"%c%c%c%c" /* 32-bit NTLM flag field */
"%c%c" /* domain length */
@@ -702,7 +736,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
});
/* now size is the size of the base64 encoded package size */
size = Curl_base64_encode((char *)ntlmbuf, size, &base64);
size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
if(size >0 ) {
Curl_safefree(*allocuserpwd);
@@ -837,7 +871,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
MD5_Final(md5sum, &MD5);
/* We shall only use the first 8 bytes of md5sum,
but the des code in lm_resp only encrypt the first 8 bytes */
mk_nt_hash(passwdp, ntbuffer);
mk_nt_hash(conn->data, passwdp, ntbuffer);
lm_resp(ntbuffer, md5sum, ntresp);
/* End of NTLM2 Session code */
@@ -851,16 +885,18 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
unsigned char lmbuffer[0x18];
#if USE_NTRESPONSES
mk_nt_hash(passwdp, ntbuffer);
mk_nt_hash(conn->data, passwdp, ntbuffer);
lm_resp(ntbuffer, &ntlm->nonce[0], ntresp);
#endif
mk_lm_hash(passwdp, lmbuffer);
mk_lm_hash(conn->data, passwdp, lmbuffer);
lm_resp(lmbuffer, &ntlm->nonce[0], lmresp);
/* A safer but less compatible alternative is:
* lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
* See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
#if USE_NTLM2SESSION
}
#endif
lmrespoff = 64; /* size of the message header */
#if USE_NTRESPONSES
@@ -874,7 +910,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
/* Create the big type-3 message binary blob */
size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf),
"NTLMSSP%c"
NTLMSSP_SIGNATURE "%c"
"\x03%c%c%c" /* type-3, 32 bits */
"%c%c" /* LanManager length */
@@ -966,7 +1002,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
DEBUG_OUT({
fprintf(stderr, "**** TYPE3 header lmresp=");
print_hex(stderr, &ntlmbuf[lmrespoff], 0x18);
print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18);
});
#if USE_NTRESPONSES
@@ -978,7 +1014,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
DEBUG_OUT({
fprintf(stderr, "\n ntresp=");
print_hex(stderr, &ntlmbuf[ntrespoff], 0x18);
print_hex(stderr, (char *)&ntlmbuf[ntrespoff], 0x18);
});
#endif
@@ -1010,10 +1046,19 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
memcpy(&ntlmbuf[size], host, hostlen);
size += hostlen;
#ifdef CURL_DOES_CONVERSIONS
/* convert domain, user, and host to ASCII but leave the rest as-is */
if(CURLE_OK != Curl_convert_to_network(conn->data,
(char *)&ntlmbuf[domoff],
size-domoff)) {
return CURLE_CONV_FAILED;
}
#endif /* CURL_DOES_CONVERSIONS */
#endif
/* convert the binary blob into base64 */
size = Curl_base64_encode((char *)ntlmbuf, size, &base64);
size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
if(size >0 ) {
Curl_safefree(*allocuserpwd);

View File

@@ -7,7 +7,7 @@
*
* Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* Copyright (c) 2004 - 2006 Daniel Stenberg
* Copyright (c) 2004 - 2007 Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -252,7 +252,7 @@ krb4_auth(void *app_data, struct connectdata *conn)
}
#endif
if(Curl_base64_encode((char *)adat.dat, adat.length, &p) < 1) {
if(Curl_base64_encode(conn->data, (char *)adat.dat, adat.length, &p) < 1) {
Curl_failf(data, "Out of memory base64-encoding");
return AUTH_CONTINUE;
}
@@ -400,7 +400,8 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
memset(key, 0, sizeof(key));
memset(schedule, 0, sizeof(schedule));
memset(passwd, 0, sizeof(passwd));
if(Curl_base64_encode((char *)tktcopy.dat, tktcopy.length, &p) < 1) {
if(Curl_base64_encode(conn->data, (char *)tktcopy.dat, tktcopy.length, &p)
< 1) {
failf(conn->data, "Out of memory base64-encoding.");
Curl_set_command_prot(conn, save);
return CURLE_OUT_OF_MEMORY;

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -53,7 +53,8 @@ int Curl_sec_read_msg (struct connectdata *conn, char *, int);
int Curl_sec_vfprintf(struct connectdata *, FILE *, const char *, va_list);
int Curl_sec_fprintf2(struct connectdata *conn, FILE *f, const char *fmt, ...);
int Curl_sec_vfprintf2(struct connectdata *conn, FILE *, const char *, va_list);
int Curl_sec_write (struct connectdata *conn, int, char *, int);
ssize_t Curl_sec_send(struct connectdata *conn, int, char *, int);
int Curl_sec_write(struct connectdata *conn, int, char *, int);
void Curl_sec_end (struct connectdata *);
int Curl_sec_login (struct connectdata *);

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -402,7 +402,9 @@ CURLcode Curl_ldap(struct connectdata *conn, bool *done)
(char *)attribute +
(strlen((char *)attribute) - 7)) == 0)) {
/* Binary attribute, encode to base64. */
val_b64_sz = Curl_base64_encode(vals[i]->bv_val, vals[i]->bv_len,
val_b64_sz = Curl_base64_encode(conn->data,
vals[i]->bv_val,
vals[i]->bv_len,
&val_b64);
if (val_b64_sz > 0) {
Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, val_b64_sz);

View File

@@ -120,11 +120,11 @@ $(LIB_DIR)/libcurl.framework: $(OBJECTS) $(LIB_DIR)/libcurl.plist
mkdir -p $(LIB_DIR)/libcurl.framework/Versions/A/Headers
cp $(LIB_DIR)/../include/curl/*.h $(LIB_DIR)/libcurl.framework/Versions/A/Headers
cd $(LIB_DIR)/libcurl.framework; \
ln -fs ./Versions/A/libcurl libcurl; \
ln -fs ./Versions/A/Resources Resources; \
ln -fs ./Versions/A/Headers Headers
ln -fs Versions/A/libcurl libcurl; \
ln -fs Versions/A/Resources Resources; \
ln -fs Versions/A/Headers Headers
cd $(LIB_DIR)/libcurl.framework/Versions; \
ln -fs ./A Current
ln -fs A Current
$(OBJECTS) : $(TMP_DIR)/%.o: $(LIB_DIR)/%.c
$(CC) $(C_OPTIONS) -c $< -o $@

View File

@@ -1,3 +1,25 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#include <winver.h>
#include "../include/curl/curlver.h"
@@ -30,7 +52,7 @@ BEGIN
VALUE "OriginalFilename", "libcurl.dll\0"
VALUE "ProductName", "The cURL library\0"
VALUE "ProductVersion", LIBCURL_VERSION "\0"
VALUE "LegalCopyright", "Copyright 1996-2005 by Daniel Stenberg. http://curl.haxx.se/docs/copyright.html\0"
VALUE "LegalCopyright", "Copyright 1996-2007 by Daniel Stenberg. http://curl.haxx.se/docs/copyright.html\0"
END
END

View File

@@ -61,25 +61,29 @@ struct memdebug {
*/
#define logfile curl_debuglogfile
FILE *curl_debuglogfile;
static bool memlimit; /* enable memory limit */
static long memsize; /* set number of mallocs allowed */
FILE *curl_debuglogfile = NULL;
static bool memlimit = FALSE; /* enable memory limit */
static long memsize = 0; /* set number of mallocs allowed */
/* this sets the log file name */
void curl_memdebug(const char *logname)
{
if(logname)
logfile = fopen(logname, "w");
else
logfile = stderr;
if (!logfile) {
if(logname)
logfile = fopen(logname, "w");
else
logfile = stderr;
}
}
/* This function sets the number of malloc() calls that should return
successfully! */
void curl_memlimit(long limit)
{
memlimit = TRUE;
memsize = limit;
if (!memlimit) {
memlimit = TRUE;
memsize = limit;
}
}
/* returns TRUE if this isn't allowed! */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -347,7 +347,7 @@ CURLM *curl_multi_init(void)
return NULL;
}
multi->connc = Curl_mk_connc(CONNCACHE_MULTI);
multi->connc = Curl_mk_connc(CONNCACHE_MULTI, -1);
if(!multi->connc) {
Curl_hash_destroy(multi->hostcache);
free(multi);
@@ -512,9 +512,11 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
}
if(easy) {
bool premature = (bool)(easy->state != CURLM_STATE_COMPLETED);
/* 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. */
if(easy->state != CURLM_STATE_COMPLETED)
if(premature)
/* this handle is "alive" so we need to count down the total number of
alive connections when this is removed */
multi->num_alive--;
@@ -547,7 +549,7 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
/* Curl_done() clears the conn->data field to lose the association
between the easy handle and the connection */
Curl_done(&easy->easy_conn, easy->result);
Curl_done(&easy->easy_conn, easy->result, premature);
if(easy->easy_conn)
/* the connection is still alive, set back the association to enable
@@ -802,7 +804,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
char *gotourl;
Curl_posttransfer(easy->easy_handle);
easy->result = Curl_done(&easy->easy_conn, CURLE_OK);
easy->result = Curl_done(&easy->easy_conn, CURLE_OK, FALSE);
/* We make sure that the pipe broken flag is reset
because in this case, it isn't an actual break */
easy->easy_handle->state.pipe_broke = FALSE;
@@ -950,7 +952,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
else if(easy->result) {
/* failure detected */
Curl_posttransfer(easy->easy_handle);
Curl_done(&easy->easy_conn, easy->result);
Curl_done(&easy->easy_conn, easy->result, FALSE);
Curl_disconnect(easy->easy_conn); /* close the connection */
easy->easy_conn = NULL; /* no more connection */
}
@@ -1017,7 +1019,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
else {
/* failure detected */
Curl_posttransfer(easy->easy_handle);
Curl_done(&easy->easy_conn, easy->result);
Curl_done(&easy->easy_conn, easy->result, FALSE);
Curl_disconnect(easy->easy_conn); /* close the connection */
easy->easy_conn = NULL; /* no more connection */
}
@@ -1050,7 +1052,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
else {
/* failure detected */
Curl_posttransfer(easy->easy_handle);
Curl_done(&easy->easy_conn, easy->result);
Curl_done(&easy->easy_conn, easy->result, FALSE);
Curl_disconnect(easy->easy_conn); /* close the connection */
easy->easy_conn = NULL; /* no more connection */
}
@@ -1169,7 +1171,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
easy->easy_conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
}
Curl_posttransfer(easy->easy_handle);
Curl_done(&easy->easy_conn, easy->result);
Curl_done(&easy->easy_conn, easy->result, FALSE);
}
else if(TRUE == done) {
char *newurl;
@@ -1188,7 +1190,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
newurl = easy->easy_handle->reqdata.newurl;
easy->easy_handle->reqdata.newurl = NULL;
}
easy->result = Curl_done(&easy->easy_conn, CURLE_OK);
easy->result = Curl_done(&easy->easy_conn, CURLE_OK, FALSE);
if(easy->result == CURLE_OK)
easy->result = Curl_follow(easy->easy_handle, newurl, retry);
if(CURLE_OK == easy->result) {
@@ -1224,7 +1226,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
if (!easy->easy_handle->state.cancelled) {
/* post-transfer command */
easy->result = Curl_done(&easy->easy_conn, CURLE_OK);
easy->result = Curl_done(&easy->easy_conn, CURLE_OK, FALSE);
/* after we have DONE what we're supposed to do, go COMPLETED, and
it doesn't matter what the Curl_done() returned! */

View File

@@ -239,18 +239,6 @@ static time_t Curl_parsedate(const char *date)
const char *indate = date; /* save the original pointer */
int part = 0; /* max 6 parts */
#ifdef WIN32
/*
* On Windows, we need an odd work-around for the case when no TZ variable
* is set. If it isn't set and "automatic DST adjustment" is enabled, the
* time functions below will return values one hour off! As reported and
* investigated in bug report #1230118.
*/
const char *env = getenv("TZ");
if(!env)
putenv("TZ=GMT");
#endif
while(*date && (part < 6)) {
bool found=FALSE;
@@ -400,13 +388,22 @@ static time_t Curl_parsedate(const char *date)
/* thread-safe version */
struct tm keeptime2;
gmt = (struct tm *)gmtime_r(&t, &keeptime2);
#else
gmt = gmtime(&t); /* use gmtime_r() if available */
#endif
if(!gmt)
return -1; /* illegal date/time */
t2 = mktime(gmt);
#else
/* It seems that at least the MSVC version of mktime() doesn't work
properly if it gets the 'gmt' pointer passed in (which is a pointer
returned from gmtime() pointing to static memory), so instead we copy
the tm struct to a local struct and pass a pointer to that struct as
input to mktime(). */
struct tm gmt2;
gmt = gmtime(&t); /* use gmtime_r() if available */
if(!gmt)
return -1; /* illegal date/time */
gmt2 = *gmt;
t2 = mktime(&gmt2);
#endif
/* Add the time zone diff (between the given timezone and GMT) and the
diff between the local time zone and GMT. */

View File

@@ -278,6 +278,13 @@ Curl_sec_write(struct connectdata *conn, int fd, char *buffer, int length)
return tx;
}
ssize_t
Curl_sec_send(struct connectdata *conn, int num, char *buffer, int length)
{
curl_socket_t fd = conn->sock[num];
return (ssize_t)Curl_sec_write(conn, fd, buffer, length);
}
int
Curl_sec_putc(struct connectdata *conn, int c, FILE *F)
{

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -44,6 +44,10 @@
#include <socket.h>
#endif
#ifdef __MSDOS__
#include <dos.h> /* delay() */
#endif
#include <curl/curl.h>
#include "urldata.h"
@@ -111,7 +115,7 @@ int Curl_select(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms)
if (pfd[num].revents & (POLLIN|POLLHUP))
ret |= CSELECT_IN;
if (pfd[num].revents & POLLERR) {
#ifdef __CYGWIN__
#ifdef __CYGWIN__
/* Cygwin 1.5.21 needs this hack to pass test 160 */
if (errno == EINPROGRESS)
ret |= CSELECT_IN;
@@ -124,7 +128,7 @@ int Curl_select(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms)
if (writefd != CURL_SOCKET_BAD) {
if (pfd[num].revents & POLLOUT)
ret |= CSELECT_OUT;
if (pfd[num].revents & POLLERR)
if (pfd[num].revents & (POLLERR|POLLHUP))
ret |= CSELECT_ERR;
}
@@ -141,6 +145,21 @@ int Curl_select(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms)
timeout.tv_sec = timeout_ms / 1000;
timeout.tv_usec = (timeout_ms % 1000) * 1000;
if((readfd == CURL_SOCKET_BAD) && (writefd == CURL_SOCKET_BAD)) {
/* According to POSIX we should pass in NULL pointers if we don't want to
wait for anything in particular but just use the timeout function.
Windows however returns immediately if done so. I copied the MSDOS
delay() use from src/main.c that already had this work-around. */
#ifdef WIN32
Sleep(timeout_ms);
#elif defined(__MSDOS__)
delay(timeout_ms);
#else
select(0, NULL, NULL, NULL, &timeout);
#endif
return 0;
}
FD_ZERO(&fds_err);
maxfd = (curl_socket_t)-1;

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -45,6 +45,8 @@
#include "sendf.h"
#include "connect.h" /* for the Curl_sockerrno() proto */
#include "sslgen.h"
#include "ssh.h"
#include "multiif.h"
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
#include <curl/mprintf.h>
@@ -52,7 +54,7 @@
#ifdef HAVE_KRB4
#include "krb4.h"
#else
#define Curl_sec_write(a,b,c,d) -1
#define Curl_sec_send(a,b,c,d) -1
#define Curl_sec_read(a,b,c,d) -1
#endif
@@ -312,9 +314,40 @@ CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
return res;
}
static ssize_t Curl_plain_send(struct connectdata *conn,
int num,
void *mem,
size_t len)
{
curl_socket_t sockfd = conn->sock[num];
ssize_t bytes_written = swrite(sockfd, mem, len);
if(-1 == bytes_written) {
int err = Curl_sockerrno();
if(
#ifdef WSAEWOULDBLOCK
/* This is how Windows does it */
(WSAEWOULDBLOCK == err)
#else
/* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
due to its inability to send off data without blocking. We therefor
treat both error codes the same here */
(EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
#endif
)
/* this is just a case of EWOULDBLOCK */
bytes_written=0;
else
failf(conn->data, "Send failure: %s",
Curl_strerror(conn, err));
}
return bytes_written;
}
/*
* Curl_write() is an internal write function that sends plain (binary) data
* to the server. Works with plain sockets, SSL or kerberos.
* Curl_write() is an internal write function that sends data to the
* server. Works with plain sockets, SCP, SSL or kerberos.
*/
CURLcode Curl_write(struct connectdata *conn,
curl_socket_t sockfd,
@@ -329,35 +362,18 @@ CURLcode Curl_write(struct connectdata *conn,
if (conn->ssl[num].use)
/* only TRUE if SSL enabled */
bytes_written = Curl_ssl_send(conn, num, mem, len);
else {
if(conn->sec_complete)
/* only TRUE if krb4 enabled */
bytes_written = Curl_sec_write(conn, sockfd, mem, len);
else
bytes_written = swrite(sockfd, mem, len);
#ifdef USE_LIBSSH2
else if (conn->protocol & PROT_SCP)
bytes_written = Curl_scp_send(conn, num, mem, len);
else if (conn->protocol & PROT_SFTP)
bytes_written = Curl_sftp_send(conn, num, mem, len);
#endif /* !USE_LIBSSH2 */
else if(conn->sec_complete)
/* only TRUE if krb4 enabled */
bytes_written = Curl_sec_send(conn, num, mem, len);
else
bytes_written = Curl_plain_send(conn, num, mem, len);
if(-1 == bytes_written) {
int err = Curl_sockerrno();
if(
#ifdef WSAEWOULDBLOCK
/* This is how Windows does it */
(WSAEWOULDBLOCK == err)
#else
/* As pointed out by Christophe Demory on March 11 2003, errno
may be EWOULDBLOCK or on some systems EAGAIN when it returned
due to its inability to send off data without blocking. We
therefor treat both error codes the same here */
(EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
#endif
)
/* this is just a case of EWOULDBLOCK */
bytes_written=0;
else
failf(conn->data, "Send failure: %s",
Curl_strerror(conn, err));
}
}
*written = bytes_written;
retcode = (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
@@ -438,25 +454,9 @@ CURLcode Curl_client_write(struct connectdata *conn,
return CURLE_OK;
}
#define MIN(a,b) (a < b ? a : b)
void Curl_read_rewind(struct connectdata *conn,
size_t extraBytesRead)
{
char buf[512 + 1];
size_t bytesToShow;
conn->read_pos -= extraBytesRead;
conn->bits.stream_was_rewound = TRUE;
bytesToShow = MIN(conn->buf_len - conn->read_pos, sizeof(buf)-1);
memcpy(buf, conn->master_buffer + conn->read_pos, bytesToShow);
buf[bytesToShow] = '\0';
DEBUGF(infof(conn->data,
"Buffer after stream rewind (read_pos = %d): [%s]",
conn->read_pos, buf));
}
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
/*
* Internal read-from-socket function. This is meant to deal with plain
@@ -472,8 +472,10 @@ int Curl_read(struct connectdata *conn, /* connection data */
ssize_t *n) /* amount bytes read */
{
ssize_t nread;
size_t bytestocopy = MIN(conn->buf_len - conn->read_pos, sizerequested);
size_t bytesfromsocket = 0;
char *buffertofill = NULL;
bool pipelining = (bool)(conn->data->multi &&
Curl_multi_canPipeline(conn->data->multi));
/* Set 'num' to 0 or 1, depending on which socket that has been sent here.
If it is the second socket, we set num to 1. Otherwise to 0. This lets
@@ -482,32 +484,53 @@ int Curl_read(struct connectdata *conn, /* connection data */
*n=0; /* reset amount to zero */
/* Copy from our master buffer first if we have some unread data there*/
if (bytestocopy > 0) {
memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
conn->read_pos += bytestocopy;
conn->bits.stream_was_rewound = FALSE;
/* If session can pipeline, check connection buffer */
if(pipelining) {
size_t bytestocopy = MIN(conn->buf_len - conn->read_pos, sizerequested);
*n = (ssize_t)bytestocopy;
return CURLE_OK;
}
/* Copy from our master buffer first if we have some unread data there*/
if (bytestocopy > 0) {
memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
conn->read_pos += bytestocopy;
conn->bits.stream_was_rewound = FALSE;
/* If we come here, it means that there is no data to read from the buffer,
* so we read from the socket */
bytesfromsocket = MIN(sizerequested, sizeof(conn->master_buffer));
if(conn->ssl[num].use) {
nread = Curl_ssl_recv(conn, num, conn->master_buffer, bytesfromsocket);
if(nread == -1)
return -1; /* -1 from Curl_ssl_recv() means EWOULDBLOCK */
*n = (ssize_t)bytestocopy;
return CURLE_OK;
}
/* If we come here, it means that there is no data to read from the buffer,
* so we read from the socket */
bytesfromsocket = MIN(sizerequested, sizeof(conn->master_buffer));
buffertofill = conn->master_buffer;
}
else {
bytesfromsocket = MIN((long)sizerequested, conn->data->set.buffer_size ?
conn->data->set.buffer_size : BUFSIZE);
buffertofill = buf;
}
if(conn->ssl[num].use) {
nread = Curl_ssl_recv(conn, num, buffertofill, bytesfromsocket);
if(nread == -1) {
return -1; /* -1 from Curl_ssl_recv() means EWOULDBLOCK */
}
}
#ifdef USE_LIBSSH2
else if (conn->protocol & PROT_SCP) {
nread = Curl_scp_recv(conn, num, buffertofill, bytesfromsocket);
/* TODO: return CURLE_OK also for nread <= 0
read failures and timeouts ? */
}
else if (conn->protocol & PROT_SFTP) {
nread = Curl_sftp_recv(conn, num, buffertofill, bytesfromsocket);
}
#endif /* !USE_LIBSSH2 */
else {
if(conn->sec_complete)
nread = Curl_sec_read(conn, sockfd, conn->master_buffer,
nread = Curl_sec_read(conn, sockfd, buffertofill,
bytesfromsocket);
else
nread = sread(sockfd, conn->master_buffer, bytesfromsocket);
nread = sread(sockfd, buffertofill, bytesfromsocket);
if(-1 == nread) {
int err = Curl_sockerrno();
@@ -521,11 +544,13 @@ int Curl_read(struct connectdata *conn, /* connection data */
}
if (nread >= 0) {
memcpy(buf, conn->master_buffer, nread);
if(pipelining) {
memcpy(buf, conn->master_buffer, nread);
conn->buf_len = nread;
conn->read_pos = nread;
}
conn->buf_len = nread;
conn->read_pos = nread;
*n = nread;
*n += nread;
}
return CURLE_OK;
@@ -540,6 +565,7 @@ static int showit(struct SessionHandle *data, curl_infotype type,
#ifdef CURL_DOES_CONVERSIONS
char buf[BUFSIZE+1];
size_t conv_size = 0;
switch(type) {
case CURLINFO_HEADER_OUT:
@@ -549,8 +575,24 @@ static int showit(struct SessionHandle *data, curl_infotype type,
size = BUFSIZE; /* truncate if necessary */
buf[BUFSIZE] = '\0';
}
conv_size = size;
memcpy(buf, ptr, size);
Curl_convert_from_network(data, buf, size);
/* Special processing is needed for this block if it
* contains both headers and data (separated by CRLFCRLF).
* We want to convert just the headers, leaving the data as-is.
*/
if(size > 4) {
size_t i;
for(i = 0; i < size-4; i++) {
if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
/* convert everthing through this CRLFCRLF but no further */
conv_size = i + 4;
break;
}
}
}
Curl_convert_from_network(data, buf, conv_size);
/* Curl_convert_from_network calls failf if unsuccessful */
/* we might as well continue even if it fails... */
ptr = buf; /* switch pointer to use my buffer instead */
@@ -571,6 +613,12 @@ static int showit(struct SessionHandle *data, curl_infotype type,
case CURLINFO_HEADER_IN:
fwrite(s_infotype[type], 2, 1, data->set.err);
fwrite(ptr, size, 1, data->set.err);
#ifdef CURL_DOES_CONVERSIONS
if(size != conv_size) {
/* we had untranslated data so we need an explicit newline */
fwrite("\n", 1, 1, data->set.err);
}
#endif
break;
default: /* nada */
break;

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -364,6 +364,11 @@ int fileno( FILE *stream);
#define DEBUGF(x)
#endif
/* non-configure builds may define CURL_WANTS_CA_BUNDLE_ENV */
#if defined(CURL_WANTS_CA_BUNDLE_ENV) && !defined(CURL_CA_BUNDLE)
#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")
#endif
/*
* Include macros and defines that should only be processed once.
*/

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -36,7 +36,7 @@
/*
* If we have the MSG_NOSIGNAL define, make sure we use
* it as the fourth argument of send() and recv()
* it as the fourth argument of function send()
*/
#ifdef HAVE_MSG_NOSIGNAL
@@ -81,7 +81,7 @@
#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \
(RECV_TYPE_ARG2)(y), \
(RECV_TYPE_ARG3)(z), \
(RECV_TYPE_ARG4)(SEND_4TH_ARG))
(RECV_TYPE_ARG4)(0))
#endif
#else /* HAVE_RECV */
#ifndef sread
@@ -130,5 +130,24 @@
#define ISPRINT(x) (isprint((int) ((unsigned char)x)))
/*
* Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type.
*/
#ifndef HAVE_SIG_ATOMIC_T
typedef int sig_atomic_t;
#define HAVE_SIG_ATOMIC_T
#endif
/*
* Default return type for signal handlers.
*/
#ifndef RETSIGTYPE
#define RETSIGTYPE void
#endif
#endif /* __SETUP_ONCE_H */

979
lib/ssh.c Normal file
View File

@@ -0,0 +1,979 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
/* #define CURL_LIBSSH2_DEBUG */
#include "setup.h"
#ifdef USE_LIBSSH2
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <limits.h>
#include <libssh2.h>
#include <libssh2_sftp.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#ifdef WIN32
#else /* probably some kind of unix */
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#include <sys/types.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_UTSNAME_H
#include <sys/utsname.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef VMS
#include <in.h>
#include <inet.h>
#endif
#endif
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
#undef in_addr_t
#define in_addr_t unsigned long
#endif
#include <curl/curl.h>
#include "urldata.h"
#include "sendf.h"
#include "easyif.h" /* for Curl_convert_... prototypes */
#include "if2ip.h"
#include "hostip.h"
#include "progress.h"
#include "transfer.h"
#include "escape.h"
#include "http.h" /* for HTTP proxy tunnel stuff */
#include "ssh.h"
#include "url.h"
#include "speedcheck.h"
#include "getinfo.h"
#include "strtoofft.h"
#include "strequal.h"
#include "sslgen.h"
#include "connect.h"
#include "strerror.h"
#include "memory.h"
#include "inet_ntop.h"
#include "select.h"
#include "parsedate.h" /* for the week day and month names */
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
#include "multiif.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>
#if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
#define DIRSEP '\\'
#else
#define DIRSEP '/'
#endif
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
/* The last #include file should be: */
#ifdef CURLDEBUG
#include "memdebug.h"
#endif
#ifndef LIBSSH2_SFTP_S_IRUSR
/* Here's a work-around for those of you who happend to run a libssh2 version
that is 0.14 or older. We should remove this kludge as soon as we can
require a more recent libssh2 release. */
#ifndef S_IRGRP
#define S_IRGRP 0
#endif
#ifndef S_IROTH
#define S_IROTH 0
#endif
#define LIBSSH2_SFTP_S_IRUSR S_IRUSR
#define LIBSSH2_SFTP_S_IWUSR S_IWUSR
#define LIBSSH2_SFTP_S_IRGRP S_IRGRP
#define LIBSSH2_SFTP_S_IROTH S_IROTH
#define LIBSSH2_SFTP_S_IRUSR S_IRUSR
#define LIBSSH2_SFTP_S_IWUSR S_IWUSR
#define LIBSSH2_SFTP_S_IRGRP S_IRGRP
#define LIBSSH2_SFTP_S_IROTH S_IROTH
#define LIBSSH2_SFTP_S_IFMT S_IFMT
#define LIBSSH2_SFTP_S_IFDIR S_IFDIR
#define LIBSSH2_SFTP_S_IFLNK S_IFLNK
#define LIBSSH2_SFTP_S_IFSOCK S_IFSOCK
#define LIBSSH2_SFTP_S_IFCHR S_IFCHR
#define LIBSSH2_SFTP_S_IFBLK S_IFBLK
#define LIBSSH2_SFTP_S_IXUSR S_IXUSR
#define LIBSSH2_SFTP_S_IWGRP S_IWGRP
#define LIBSSH2_SFTP_S_IXGRP S_IXGRP
#define LIBSSH2_SFTP_S_IWOTH S_IWOTH
#define LIBSSH2_SFTP_S_IXOTH S_IXOTH
#endif
static LIBSSH2_ALLOC_FUNC(libssh2_malloc);
static LIBSSH2_REALLOC_FUNC(libssh2_realloc);
static LIBSSH2_FREE_FUNC(libssh2_free);
static void
kbd_callback(const char *name, int name_len, const char *instruction,
int instruction_len, int num_prompts,
const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
void **abstract)
{
struct SSHPROTO *ssh = (struct SSHPROTO *)*abstract;
#ifdef CURL_LIBSSH2_DEBUG
fprintf(stderr, "name=%s\n", name);
fprintf(stderr, "name_len=%d\n", name_len);
fprintf(stderr, "instruction=%s\n", instruction);
fprintf(stderr, "instruction_len=%d\n", instruction_len);
fprintf(stderr, "num_prompts=%d\n", num_prompts);
#else
(void)name;
(void)name_len;
(void)instruction;
(void)instruction_len;
#endif /* CURL_LIBSSH2_DEBUG */
if (num_prompts == 1) {
responses[0].text = strdup(ssh->passwd);
responses[0].length = strlen(ssh->passwd);
}
(void)prompts;
(void)abstract;
} /* kbd_callback */
static CURLcode libssh2_error_to_CURLE(struct connectdata *conn)
{
int errorcode;
struct SSHPROTO *scp = conn->data->reqdata.proto.ssh;
/* Get the libssh2 error code and string */
errorcode = libssh2_session_last_error(scp->ssh_session, &scp->errorstr,
NULL, 0);
if (errorcode == LIBSSH2_FX_OK)
return CURLE_OK;
infof(conn->data, "libssh2 error %d, '%s'\n", errorcode, scp->errorstr);
/* TODO: map some of the libssh2 errors to the more appropriate CURLcode
error code, and possibly add a few new SSH-related one. We must however
not return or even depend on libssh2 errors in the public libcurl API */
return CURLE_SSH;
}
static LIBSSH2_ALLOC_FUNC(libssh2_malloc)
{
return malloc(count);
(void)abstract;
}
static LIBSSH2_REALLOC_FUNC(libssh2_realloc)
{
return realloc(ptr, count);
(void)abstract;
}
static LIBSSH2_FREE_FUNC(libssh2_free)
{
free(ptr);
(void)abstract;
}
static CURLcode ssh_init(struct connectdata *conn)
{
struct SessionHandle *data = conn->data;
struct SSHPROTO *ssh;
if (data->reqdata.proto.ssh)
return CURLE_OK;
ssh = (struct SSHPROTO *)calloc(sizeof(struct SSHPROTO), 1);
if (!ssh)
return CURLE_OUT_OF_MEMORY;
data->reqdata.proto.ssh = ssh;
/* get some initial data into the ssh struct */
ssh->bytecountp = &data->reqdata.keep.bytecount;
/* no need to duplicate them, this connectdata struct won't change */
ssh->user = conn->user;
ssh->passwd = conn->passwd;
ssh->errorstr = NULL;
ssh->ssh_session = NULL;
ssh->ssh_channel = NULL;
ssh->sftp_session = NULL;
ssh->sftp_handle = NULL;
return CURLE_OK;
}
/*
* Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
* do protocol-specific actions at connect-time.
*/
CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
{
int i;
struct SSHPROTO *ssh;
const char *fingerprint;
const char *authlist;
char *home;
char rsa_pub[PATH_MAX];
char rsa[PATH_MAX];
char tempHome[PATH_MAX];
curl_socket_t sock;
char *real_path;
char *working_path;
int working_path_len;
bool authed = FALSE;
CURLcode result;
struct SessionHandle *data = conn->data;
rsa_pub[0] = rsa[0] = '\0';
result = ssh_init(conn);
if (result)
return result;
ssh = data->reqdata.proto.ssh;
working_path = curl_easy_unescape(data, data->reqdata.path, 0,
&working_path_len);
if (!working_path)
return CURLE_OUT_OF_MEMORY;
#ifdef CURL_LIBSSH2_DEBUG
if (ssh->user) {
infof(data, "User: %s\n", ssh->user);
}
if (ssh->passwd) {
infof(data, "Password: %s\n", ssh->passwd);
}
#endif /* CURL_LIBSSH2_DEBUG */
sock = conn->sock[FIRSTSOCKET];
ssh->ssh_session = libssh2_session_init_ex(libssh2_malloc, libssh2_free,
libssh2_realloc, ssh);
if (ssh->ssh_session == NULL) {
failf(data, "Failure initialising ssh session\n");
Curl_safefree(ssh->path);
return CURLE_FAILED_INIT;
}
#ifdef CURL_LIBSSH2_DEBUG
infof(data, "SSH socket: %d\n", sock);
#endif /* CURL_LIBSSH2_DEBUG */
if (libssh2_session_startup(ssh->ssh_session, sock)) {
failf(data, "Failure establishing ssh session\n");
libssh2_session_free(ssh->ssh_session);
ssh->ssh_session = NULL;
Curl_safefree(ssh->path);
return CURLE_FAILED_INIT;
}
/*
* Before we authenticate we should check the hostkey's fingerprint against
* our known hosts. How that is handled (reading from file, whatever) is
* up to us. As for know not much is implemented, besides showing how to
* get the fingerprint.
*/
fingerprint = libssh2_hostkey_hash(ssh->ssh_session,
LIBSSH2_HOSTKEY_HASH_MD5);
#ifdef CURL_LIBSSH2_DEBUG
/* The fingerprint points to static storage (!), don't free() it. */
infof(data, "Fingerprint: ");
for (i = 0; i < 16; i++) {
infof(data, "%02X ", (unsigned char) fingerprint[i]);
}
infof(data, "\n");
#endif /* CURL_LIBSSH2_DEBUG */
/* TBD - methods to check the host keys need to be done */
/*
* Figure out authentication methods
* NB: As soon as we have provided a username to an openssh server we must
* never change it later. Thus, always specify the correct username here,
* even though the libssh2 docs kind of indicate that it should be possible
* to get a 'generic' list (not user-specific) of authentication methods,
* presumably with a blank username. That won't work in my experience.
* So always specify it here.
*/
authlist = libssh2_userauth_list(ssh->ssh_session, ssh->user,
strlen(ssh->user));
/*
* Check the supported auth types in the order I feel is most secure with the
* requested type of authentication
*/
if ((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
(strstr(authlist, "publickey") != NULL)) {
/* To ponder about: should really the lib be messing about with the HOME
environment variable etc? */
home = curl_getenv("HOME");
if (data->set.ssh_public_key)
snprintf(rsa_pub, sizeof(rsa_pub), "%s", data->set.ssh_public_key);
else if (home)
snprintf(rsa_pub, sizeof(rsa_pub), "%s/.ssh/id_dsa.pub", home);
if (data->set.ssh_private_key)
snprintf(rsa, sizeof(rsa), "%s", data->set.ssh_private_key);
else if (home)
snprintf(rsa, sizeof(rsa), "%s/.ssh/id_dsa", home);
curl_free(home);
if (rsa_pub[0]) {
/* The function below checks if the files exists, no need to stat() here.
*/
if (libssh2_userauth_publickey_fromfile(ssh->ssh_session, ssh->user,
rsa_pub, rsa, "") == 0) {
authed = TRUE;
}
}
}
if (!authed &&
(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
(strstr(authlist, "password") != NULL)) {
if (!libssh2_userauth_password(ssh->ssh_session, ssh->user, ssh->passwd))
authed = TRUE;
}
if (!authed && (data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
(strstr(authlist, "hostbased") != NULL)) {
}
if (!authed && (data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
&& (strstr(authlist, "keyboard-interactive") != NULL)) {
/* Authentication failed. Continue with keyboard-interactive now. */
if (libssh2_userauth_keyboard_interactive_ex(ssh->ssh_session, ssh->user,
strlen(ssh->user),
&kbd_callback) == 0) {
authed = TRUE;
}
}
if (!authed) {
failf(data, "Authentication failure\n");
libssh2_session_free(ssh->ssh_session);
ssh->ssh_session = NULL;
Curl_safefree(ssh->path);
return CURLE_FAILED_INIT;
}
/*
* At this point we have an authenticated ssh session.
*/
conn->sockfd = sock;
conn->writesockfd = CURL_SOCKET_BAD;
if (conn->protocol == PROT_SFTP) {
/*
* Start the libssh2 sftp session
*/
ssh->sftp_session = libssh2_sftp_init(ssh->ssh_session);
if (ssh->sftp_session == NULL) {
failf(data, "Failure initialising sftp session\n");
libssh2_sftp_shutdown(ssh->sftp_session);
ssh->sftp_session = NULL;
libssh2_session_free(ssh->ssh_session);
ssh->ssh_session = NULL;
return CURLE_FAILED_INIT;
}
/*
* Get the "home" directory
*/
i = libssh2_sftp_realpath(ssh->sftp_session, ".", tempHome, PATH_MAX-1);
if (i > 0) {
/* It seems that this string is not always NULL terminated */
tempHome[i] = '\0';
ssh->homedir = (char *)strdup(tempHome);
if (!ssh->homedir) {
libssh2_sftp_shutdown(ssh->sftp_session);
ssh->sftp_session = NULL;
libssh2_session_free(ssh->ssh_session);
ssh->ssh_session = NULL;
return CURLE_OUT_OF_MEMORY;
}
}
else {
/* Return the error type */
i = libssh2_sftp_last_error(ssh->sftp_session);
DEBUGF(infof(data, "error = %d\n", i));
}
}
/* Check for /~/ , indicating realative to the users home directory */
if (conn->protocol == PROT_SCP) {
real_path = (char *)malloc(working_path_len+1);
if (real_path == NULL) {
Curl_safefree(working_path);
libssh2_session_free(ssh->ssh_session);
ssh->ssh_session = NULL;
return CURLE_OUT_OF_MEMORY;
}
if (working_path[1] == '~')
/* It is referenced to the home directory, so strip the leading '/' */
memcpy(real_path, working_path+1, 1 + working_path_len-1);
else
memcpy(real_path, working_path, 1 + working_path_len);
}
else if (conn->protocol == PROT_SFTP) {
if (working_path[1] == '~') {
real_path = (char *)malloc(strlen(ssh->homedir) +
working_path_len + 1);
if (real_path == NULL) {
libssh2_sftp_shutdown(ssh->sftp_session);
ssh->sftp_session = NULL;
libssh2_session_free(ssh->ssh_session);
ssh->ssh_session = NULL;
Curl_safefree(working_path);
return CURLE_OUT_OF_MEMORY;
}
/* It is referenced to the home directory, so strip the leading '/' */
memcpy(real_path, ssh->homedir, strlen(ssh->homedir));
real_path[strlen(ssh->homedir)] = '/';
real_path[strlen(ssh->homedir)+1] = '\0';
if (working_path_len > 3) {
memcpy(real_path+strlen(ssh->homedir)+1, working_path + 3,
1 + working_path_len -3);
}
}
else {
real_path = (char *)malloc(working_path_len+1);
if (real_path == NULL) {
libssh2_session_free(ssh->ssh_session);
ssh->ssh_session = NULL;
Curl_safefree(working_path);
return CURLE_OUT_OF_MEMORY;
}
memcpy(real_path, working_path, 1+working_path_len);
}
}
else
return CURLE_FAILED_INIT;
Curl_safefree(working_path);
ssh->path = real_path;
*done = TRUE;
return CURLE_OK;
}
CURLcode Curl_scp_do(struct connectdata *conn, bool *done)
{
struct stat sb;
struct SSHPROTO *scp = conn->data->reqdata.proto.ssh;
CURLcode res = CURLE_OK;
*done = TRUE; /* unconditionally */
if (conn->data->set.upload) {
/*
* NOTE!!! libssh2 requires that the destination path is a full path
* that includes the destination file and name OR ends in a "/" .
* If this is not done the destination file will be named the
* same name as the last directory in the path.
*/
scp->ssh_channel = libssh2_scp_send_ex(scp->ssh_session, scp->path,
LIBSSH2_SFTP_S_IRUSR|
LIBSSH2_SFTP_S_IWUSR|
LIBSSH2_SFTP_S_IRGRP|
LIBSSH2_SFTP_S_IROTH,
conn->data->set.infilesize, 0, 0);
if (!scp->ssh_channel)
return CURLE_FAILED_INIT;
/* upload data */
res = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
}
else {
/*
* We must check the remote file, if it is a directory no vaules will
* be set in sb
*/
curl_off_t bytecount;
memset(&sb, 0, sizeof(struct stat));
scp->ssh_channel = libssh2_scp_recv(scp->ssh_session, scp->path, &sb);
if (!scp->ssh_channel) {
if ((sb.st_mode == 0) && (sb.st_atime == 0) && (sb.st_mtime == 0) &&
(sb.st_size == 0)) {
/* Since sb is still empty, it is likely the file was not found */
return CURLE_REMOTE_FILE_NOT_FOUND;
}
return libssh2_error_to_CURLE(conn);
}
/* download data */
bytecount = (curl_off_t) sb.st_size;
conn->data->reqdata.maxdownload = (curl_off_t) sb.st_size;
res = Curl_setup_transfer(conn, FIRSTSOCKET,
bytecount, FALSE, NULL, -1, NULL);
}
return res;
}
CURLcode Curl_scp_done(struct connectdata *conn, CURLcode status,
bool premature)
{
struct SSHPROTO *scp = conn->data->reqdata.proto.ssh;
(void)premature; /* not used */
Curl_safefree(scp->path);
scp->path = NULL;
if (scp->ssh_channel) {
if (libssh2_channel_close(scp->ssh_channel) < 0) {
infof(conn->data, "Failed to stop libssh2 channel subsystem\n");
}
}
if (scp->ssh_session) {
libssh2_session_disconnect(scp->ssh_session, "Shutdown");
libssh2_session_free(scp->ssh_session);
scp->ssh_session = NULL;
}
free(conn->data->reqdata.proto.ssh);
conn->data->reqdata.proto.ssh = NULL;
Curl_pgrsDone(conn);
(void)status; /* unused */
return CURLE_OK;
}
/* return number of received (decrypted) bytes */
ssize_t Curl_scp_send(struct connectdata *conn, int sockindex,
void *mem, size_t len)
{
ssize_t nwrite;
/* libssh2_channel_write() returns int
*
* NOTE: we should not store nor rely on connection-related data to be
* in the SessionHandle struct
*/
nwrite = (ssize_t)
libssh2_channel_write(conn->data->reqdata.proto.ssh->ssh_channel,
mem, len);
(void)sockindex;
return nwrite;
}
/*
* If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
* a regular CURLcode value.
*/
ssize_t Curl_scp_recv(struct connectdata *conn, int sockindex,
char *mem, size_t len)
{
ssize_t nread;
/* libssh2_channel_read() returns int
*
* NOTE: we should not store nor rely on connection-related data to be
* in the SessionHandle struct
*/
nread = (ssize_t)
libssh2_channel_read(conn->data->reqdata.proto.ssh->ssh_channel,
mem, len);
(void)sockindex;
return nread;
}
/*
* =============== SFTP ===============
*/
CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
{
LIBSSH2_SFTP_ATTRIBUTES attrs;
struct SSHPROTO *sftp = conn->data->reqdata.proto.ssh;
CURLcode res = CURLE_OK;
struct SessionHandle *data = conn->data;
curl_off_t bytecount = 0;
char *buf = data->state.buffer;
*done = TRUE; /* unconditionally */
if (data->set.upload) {
/*
* NOTE!!! libssh2 requires that the destination path is a full path
* that includes the destination file and name OR ends in a "/" .
* If this is not done the destination file will be named the
* same name as the last directory in the path.
*/
sftp->sftp_handle =
libssh2_sftp_open(sftp->sftp_session, sftp->path,
LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT,
LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
if (!sftp->sftp_handle)
return CURLE_FAILED_INIT;
/* upload data */
res = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
}
else {
if (sftp->path[strlen(sftp->path)-1] == '/') {
/*
* This is a directory that we are trying to get, so produce a
* directory listing
*
* **BLOCKING behaviour** This should be made into a state machine and
* get a separate function called from Curl_sftp_recv() when there is
* data to read from the network, instead of "hanging" here.
*/
char filename[PATH_MAX+1];
int len, totalLen, currLen;
char *line;
sftp->sftp_handle =
libssh2_sftp_opendir(sftp->sftp_session, sftp->path);
if (!sftp->sftp_handle)
return CURLE_SSH;
while ((len = libssh2_sftp_readdir(sftp->sftp_handle, filename,
PATH_MAX, &attrs)) > 0) {
filename[len] = '\0';
if (data->set.ftp_list_only) {
if ((attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
LIBSSH2_SFTP_S_IFDIR)) {
infof(data, "%s\n", filename);
}
}
else {
totalLen = 80 + len;
line = (char *)malloc(totalLen);
if (!line)
return CURLE_OUT_OF_MEMORY;
if (!(attrs.flags & LIBSSH2_SFTP_ATTR_UIDGID))
attrs.uid = attrs.gid =0;
currLen = snprintf(line, totalLen, "---------- 1 %5d %5d",
attrs.uid, attrs.gid);
if (attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) {
if ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
LIBSSH2_SFTP_S_IFDIR) {
line[0] = 'd';
}
else if ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
LIBSSH2_SFTP_S_IFLNK) {
line[0] = 'l';
}
else if ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
LIBSSH2_SFTP_S_IFSOCK) {
line[0] = 's';
}
else if ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
LIBSSH2_SFTP_S_IFCHR) {
line[0] = 'c';
}
else if ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
LIBSSH2_SFTP_S_IFBLK) {
line[0] = 'b';
}
if (attrs.permissions & LIBSSH2_SFTP_S_IRUSR) {
line[1] = 'r';
}
if (attrs.permissions & LIBSSH2_SFTP_S_IWUSR) {
line[2] = 'w';
}
if (attrs.permissions & LIBSSH2_SFTP_S_IXUSR) {
line[3] = 'x';
}
if (attrs.permissions & LIBSSH2_SFTP_S_IRGRP) {
line[4] = 'r';
}
if (attrs.permissions & LIBSSH2_SFTP_S_IWGRP) {
line[5] = 'w';
}
if (attrs.permissions & LIBSSH2_SFTP_S_IXGRP) {
line[6] = 'x';
}
if (attrs.permissions & LIBSSH2_SFTP_S_IROTH) {
line[7] = 'r';
}
if (attrs.permissions & LIBSSH2_SFTP_S_IWOTH) {
line[8] = 'w';
}
if (attrs.permissions & LIBSSH2_SFTP_S_IXOTH) {
line[9] = 'x';
}
}
if (attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) {
currLen += snprintf(line+currLen, totalLen-currLen, "%11lld",
attrs.filesize);
}
if (attrs.flags & LIBSSH2_SFTP_ATTR_ACMODTIME) {
const char *months[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
struct tm *nowParts;
time_t now, remoteTime;
now = time(NULL);
remoteTime = (time_t)attrs.mtime;
nowParts = localtime(&remoteTime);
if ((time_t)attrs.mtime > (now - (3600 * 24 * 180))) {
currLen += snprintf(line+currLen, totalLen-currLen,
" %s %2d %2d:%02d", months[nowParts->tm_mon],
nowParts->tm_mday, nowParts->tm_hour,
nowParts->tm_min);
}
else {
currLen += snprintf(line+currLen, totalLen-currLen,
" %s %2d %5d", months[nowParts->tm_mon],
nowParts->tm_mday, 1900+nowParts->tm_year);
}
}
currLen += snprintf(line+currLen, totalLen-currLen, " %s", filename);
if ((attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
LIBSSH2_SFTP_S_IFLNK)) {
char linkPath[PATH_MAX + 1];
snprintf(linkPath, PATH_MAX, "%s%s", sftp->path, filename);
len = libssh2_sftp_readlink(sftp->sftp_session, linkPath, filename,
PATH_MAX);
line = realloc(line, totalLen + 4 + len);
if (!line)
return CURLE_OUT_OF_MEMORY;
currLen += snprintf(line+currLen, totalLen-currLen, " -> %s",
filename);
}
currLen += snprintf(line+currLen, totalLen-currLen, "\n");
res = Curl_client_write(conn, CLIENTWRITE_BODY, line, 0);
free(line);
}
}
libssh2_sftp_closedir(sftp->sftp_handle);
sftp->sftp_handle = NULL;
/* no data to transfer */
res = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
}
else {
/*
* Work on getting the specified file
*/
sftp->sftp_handle =
libssh2_sftp_open(sftp->sftp_session, sftp->path, LIBSSH2_FXF_READ,
LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
if (!sftp->sftp_handle)
return CURLE_SSH;
if (libssh2_sftp_stat(sftp->sftp_session, sftp->path, &attrs)) {
/*
* libssh2_sftp_open() didn't return an error, so maybe the server
* just doesn't support stat()
*/
data->reqdata.size = -1;
data->reqdata.maxdownload = -1;
}
else {
data->reqdata.size = attrs.filesize;
data->reqdata.maxdownload = attrs.filesize;
Curl_pgrsSetDownloadSize(data, attrs.filesize);
}
Curl_pgrsTime(data, TIMER_STARTTRANSFER);
/* Now download data. The libssh2 0.14 doesn't offer any way to do this
without using this BLOCKING approach, so here's room for improvement
once libssh2 can return EWOULDBLOCK to us. */
#if 0
/* code left here just because this is what this function will use the
day libssh2 is improved */
res = Curl_setup_transfer(conn, FIRSTSOCKET,
bytecount, FALSE, NULL, -1, NULL);
#endif
while (res == CURLE_OK) {
size_t nread;
/* NOTE: most *read() functions return ssize_t but this returns size_t
which normally is unsigned! */
nread = libssh2_sftp_read(data->reqdata.proto.ssh->sftp_handle,
buf, BUFSIZE-1);
if (nread > 0)
buf[nread] = 0;
/* this check can be changed to a <= 0 when nread is changed to a
signed variable type */
if ((nread == 0) || (nread == (size_t)~0))
break;
bytecount += nread;
res = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
if(res)
return res;
Curl_pgrsSetDownloadCounter(data, bytecount);
if(Curl_pgrsUpdate(conn))
res = CURLE_ABORTED_BY_CALLBACK;
else {
struct timeval now = Curl_tvnow();
res = Curl_speedcheck(data, now);
}
}
if(Curl_pgrsUpdate(conn))
res = CURLE_ABORTED_BY_CALLBACK;
/* no (more) data to transfer */
res = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
}
}
return res;
}
CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode status,
bool premature)
{
struct SSHPROTO *sftp = conn->data->reqdata.proto.ssh;
(void)premature; /* not used */
Curl_safefree(sftp->path);
sftp->path = NULL;
Curl_safefree(sftp->homedir);
sftp->homedir = NULL;
if (sftp->sftp_handle) {
if (libssh2_sftp_close(sftp->sftp_handle) < 0) {
infof(conn->data, "Failed to close libssh2 file\n");
}
}
if (sftp->sftp_session) {
if (libssh2_sftp_shutdown(sftp->sftp_session) < 0) {
infof(conn->data, "Failed to stop libssh2 sftp subsystem\n");
}
}
if (sftp->ssh_channel) {
if (libssh2_channel_close(sftp->ssh_channel) < 0) {
infof(conn->data, "Failed to stop libssh2 channel subsystem\n");
}
}
if (sftp->ssh_session) {
libssh2_session_disconnect(sftp->ssh_session, "Shutdown");
libssh2_session_free(sftp->ssh_session);
sftp->ssh_session = NULL;
}
free(conn->data->reqdata.proto.ssh);
conn->data->reqdata.proto.ssh = NULL;
Curl_pgrsDone(conn);
(void)status; /* unused */
return CURLE_OK;
}
/* return number of received (decrypted) bytes */
ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex,
void *mem, size_t len)
{
ssize_t nwrite;
/* libssh2_sftp_write() returns size_t !*/
nwrite = (ssize_t)
libssh2_sftp_write(conn->data->reqdata.proto.ssh->sftp_handle, mem, len);
(void)sockindex;
return nwrite;
}
/*
* If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
* a regular CURLcode value.
*/
ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
char *mem, size_t len)
{
ssize_t nread;
/* libssh2_sftp_read() returns size_t !*/
nread = (ssize_t)
libssh2_sftp_read(conn->data->reqdata.proto.ssh->sftp_handle, mem, len);
(void)sockindex;
return nread;
}
#endif /* USE_LIBSSH2 */

49
lib/ssh.h Normal file
View File

@@ -0,0 +1,49 @@
#ifndef __SSH_H
#define __SSH_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#ifdef USE_LIBSSH2
CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done);
CURLcode Curl_scp_do(struct connectdata *conn, bool *done);
CURLcode Curl_scp_done(struct connectdata *conn, CURLcode, bool premature);
ssize_t Curl_scp_send(struct connectdata *conn, int sockindex,
void *mem, size_t len);
ssize_t Curl_scp_recv(struct connectdata *conn, int sockindex,
char *mem, size_t len);
CURLcode Curl_sftp_do(struct connectdata *conn, bool *done);
CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode, bool premature);
ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex,
void *mem, size_t len);
ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
char *mem, size_t len);
#endif /* USE_LIBSSH2 */
#endif /* __SSH_H */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -23,7 +23,7 @@
/* This file is for "generic" SSL functions that all libcurl internals should
use. It is responsible for calling the proper 'ossl' function in ssluse.c
(OpenSSL based) or the 'gtsl' function in gtsl.c (GnuTLS based).
(OpenSSL based) or the 'gtls' function in gtls.c (GnuTLS based).
SSL-functions in libcurl should call functions in this source file, and not
to any specific SSL-layer.
@@ -397,6 +397,25 @@ void Curl_ssl_close(struct connectdata *conn)
}
}
CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex)
{
if(conn->ssl[sockindex].use) {
#ifdef USE_SSLEAY
if(Curl_ossl_shutdown(conn, sockindex))
return CURLE_SSL_SHUTDOWN_FAILED;
#else
#ifdef USE_GNUTLS
if(Curl_gtls_shutdown(conn, sockindex))
return CURLE_SSL_SHUTDOWN_FAILED;
#else
(void)conn;
(void)sockindex;
#endif /* USE_GNUTLS */
#endif /* USE_SSLEAY */
}
return CURLE_OK;
}
/* Selects an (Open)SSL crypto engine
*/
CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine)
@@ -455,10 +474,10 @@ struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data)
}
/* return number of sent (non-SSL) bytes */
int Curl_ssl_send(struct connectdata *conn,
int sockindex,
void *mem,
size_t len)
ssize_t Curl_ssl_send(struct connectdata *conn,
int sockindex,
void *mem,
size_t len)
{
#ifdef USE_SSLEAY
return Curl_ossl_send(conn, sockindex, mem, len);
@@ -481,10 +500,10 @@ int Curl_ssl_send(struct connectdata *conn,
* If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
* a regular CURLcode value.
*/
int Curl_ssl_recv(struct connectdata *conn, /* connection data */
int sockindex, /* socketindex */
char *mem, /* store read data here */
size_t len) /* max amount to read */
ssize_t Curl_ssl_recv(struct connectdata *conn, /* connection data */
int sockindex, /* socketindex */
char *mem, /* store read data here */
size_t len) /* max amount to read */
{
#ifdef USE_SSL
ssize_t nread;
@@ -581,3 +600,19 @@ int Curl_ssl_check_cxn(struct connectdata *conn)
return -1; /* connection status unknown */
#endif /* USE_SSLEAY */
}
bool Curl_ssl_data_pending(struct connectdata *conn,
int connindex)
{
#ifdef USE_SSLEAY
/* OpenSSL-specific */
if(conn->ssl[connindex].handle)
/* SSL is in use */
return SSL_pending(conn->ssl[connindex].handle);
#else
(void)conn;
(void)connindex;
#endif
return FALSE; /* nothing pending */
}

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -32,7 +32,7 @@ void Curl_free_ssl_config(struct ssl_config_data* sslc);
int Curl_ssl_init(void);
void Curl_ssl_cleanup(void);
CURLcode Curl_ssl_connect(struct connectdata *conn, int sockindex);
CURLcode Curl_ssl_connect_nonblocking(struct connectdata *conn,
CURLcode Curl_ssl_connect_nonblocking(struct connectdata *conn,
int sockindex,
bool *done);
void Curl_ssl_close(struct connectdata *conn);
@@ -42,14 +42,14 @@ void Curl_ssl_close_all(struct SessionHandle *data);
CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine);
/* Sets engine as default for all SSL operations */
CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data);
int Curl_ssl_send(struct connectdata *conn,
int sockindex,
void *mem,
size_t len);
int Curl_ssl_recv(struct connectdata *conn, /* connection data */
int sockindex, /* socketindex */
char *mem, /* store read data here */
size_t len); /* max amount to read */
ssize_t Curl_ssl_send(struct connectdata *conn,
int sockindex,
void *mem,
size_t len);
ssize_t Curl_ssl_recv(struct connectdata *conn, /* connection data */
int sockindex, /* socketindex */
char *mem, /* store read data here */
size_t len); /* max amount to read */
/* init the SSL session ID cache */
CURLcode Curl_ssl_initsessions(struct SessionHandle *, long);
@@ -69,9 +69,16 @@ size_t Curl_ssl_version(char *buffer, size_t size);
int Curl_ssl_check_cxn(struct connectdata *conn);
CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex);
bool Curl_ssl_data_pending(struct connectdata *conn,
int connindex);
#if !defined(USE_SSL) && !defined(SSLGEN_C)
/* set up blank macros for none-SSL builds */
#define Curl_ssl_close_all(x)
#endif
#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */
#endif

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -634,8 +634,8 @@ CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine)
if (data->state.engine) {
ENGINE_finish(data->state.engine);
ENGINE_free(data->state.engine);
data->state.engine = NULL;
}
data->state.engine = NULL;
if (!ENGINE_init(e)) {
char buf[256];
@@ -661,10 +661,10 @@ CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data)
#ifdef HAVE_OPENSSL_ENGINE_H
if (data->state.engine) {
if (ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) {
infof(data,"set default crypto engine %s\n", data->state.engine);
infof(data,"set default crypto engine '%s'\n", ENGINE_get_id(data->state.engine));
}
else {
failf(data, "set default crypto engine %s failed", data->state.engine);
failf(data, "set default crypto engine '%s' failed", ENGINE_get_id(data->state.engine));
return CURLE_SSL_ENGINE_SETFAILED;
}
}
@@ -728,6 +728,101 @@ void Curl_ossl_close(struct connectdata *conn)
}
}
/*
* This function is called to shut down the SSL layer but keep the
* socket open (CCC - Clear Command Channel)
*/
int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
{
int retval = 0;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct SessionHandle *data = conn->data;
char buf[120]; /* We will use this for the OpenSSL error buffer, so it has
to be at least 120 bytes long. */
unsigned long sslerror;
ssize_t nread;
int err;
int done = 0;
/* This has only been tested on the proftpd server, and the mod_tls code
sends a close notify alert without waiting for a close notify alert in
response. Thus we wait for a close notify alert from the server, but
we do not send one. Let's hope other servers do the same... */
if(connssl->handle) {
while(!done) {
int what = Curl_select(conn->sock[sockindex],
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
if(what > 0) {
/* Something to read, let's do it and hope that it is the close
notify alert from the server */
nread = (ssize_t)SSL_read(conn->ssl[sockindex].handle, buf,
sizeof(buf));
err = SSL_get_error(conn->ssl[sockindex].handle, (int)nread);
switch(err) {
case SSL_ERROR_NONE: /* this is not an error */
case SSL_ERROR_ZERO_RETURN: /* no more data */
/* This is the expected response. There was no data but only
the close notify alert */
done = 1;
break;
case SSL_ERROR_WANT_READ:
/* there's data pending, re-invoke SSL_read() */
infof(data, "SSL_ERROR_WANT_READ\n");
break;
case SSL_ERROR_WANT_WRITE:
/* SSL wants a write. Really odd. Let's bail out. */
infof(data, "SSL_ERROR_WANT_WRITE\n");
done = 1;
break;
default:
/* openssl/ssl.h says "look at error stack/return value/errno" */
sslerror = ERR_get_error();
failf(conn->data, "SSL read: %s, errno %d",
ERR_error_string(sslerror, buf),
Curl_sockerrno() );
done = 1;
break;
}
}
else if(0 == what) {
/* timeout */
failf(data, "SSL shutdown timeout");
done = 1;
break;
}
else {
/* anything that gets here is fatally bad */
failf(data, "select on SSL socket, errno: %d", Curl_sockerrno());
retval = -1;
done = 1;
}
} /* while()-loop for the select() */
if(data->set.verbose) {
switch(SSL_get_shutdown(connssl->handle)) {
case SSL_SENT_SHUTDOWN:
infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n");
break;
case SSL_RECEIVED_SHUTDOWN:
infof(data, "SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\n");
break;
case SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN:
infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|"
"SSL_RECEIVED__SHUTDOWN\n");
break;
}
}
connssl->use = FALSE; /* get back to ordinary socket usage */
SSL_free (connssl->handle);
connssl->handle = NULL;
}
return retval;
}
void Curl_ossl_session_free(void *ptr)
{
/* free the ID */
@@ -1207,7 +1302,7 @@ Curl_ossl_connect_step1(struct connectdata *conn,
}
#ifdef SSL_CTRL_SET_MSG_CALLBACK
if (data->set.fdebug) {
if (data->set.fdebug && data->set.verbose) {
/* the SSL trace callback is only used for verbose logging so we only
inform about failures of setting it */
if (!SSL_CTX_callback_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK,
@@ -1629,7 +1724,7 @@ Curl_ossl_connect_common(struct connectdata *conn,
while(1) {
int what = Curl_select(readfd, writefd, nonblocking?0:(int)timeout_ms);
if(what > 0)
/* reabable or writable, go loop in the outer loop */
/* readable or writable, go loop in the outer loop */
break;
else if(0 == what) {
if (nonblocking) {
@@ -1702,10 +1797,10 @@ Curl_ossl_connect(struct connectdata *conn,
}
/* return number of sent (non-SSL) bytes */
int Curl_ossl_send(struct connectdata *conn,
int sockindex,
void *mem,
size_t len)
ssize_t Curl_ossl_send(struct connectdata *conn,
int sockindex,
void *mem,
size_t len)
{
/* SSL_write() is said to return 'int' while write() and send() returns
'size_t' */
@@ -1741,7 +1836,7 @@ int Curl_ossl_send(struct connectdata *conn,
failf(conn->data, "SSL_write() return error %d\n", err);
return -1;
}
return rc; /* number of bytes */
return (ssize_t)rc; /* number of bytes */
}
/*

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -29,8 +29,8 @@
#include "urldata.h"
CURLcode Curl_ossl_connect(struct connectdata *conn, int sockindex);
CURLcode Curl_ossl_connect_nonblocking(struct connectdata *conn,
int sockindex,
CURLcode Curl_ossl_connect_nonblocking(struct connectdata *conn,
int sockindex,
bool *done);
void Curl_ossl_close(struct connectdata *conn); /* close a SSL connection */
/* tell OpenSSL to close down all open information regarding connections (and
@@ -52,10 +52,10 @@ struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data);
int Curl_ossl_init(void);
void Curl_ossl_cleanup(void);
int Curl_ossl_send(struct connectdata *conn,
int sockindex,
void *mem,
size_t len);
ssize_t Curl_ossl_send(struct connectdata *conn,
int sockindex,
void *mem,
size_t len);
ssize_t Curl_ossl_recv(struct connectdata *conn, /* connection data */
int num, /* socketindex */
char *buf, /* store read data here */
@@ -66,4 +66,6 @@ size_t Curl_ossl_version(char *buffer, size_t size);
int Curl_ossl_check_cxn(struct connectdata *cxn);
int Curl_ossl_seed(struct SessionHandle *data);
int Curl_ossl_shutdown(struct connectdata *conn, int sockindex);
#endif

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2004 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2004 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -244,6 +244,9 @@ curl_easy_strerror(CURLcode error)
case CURLE_FTP_SSL_FAILED:
return "Requested FTP SSL level failed";
case CURLE_SSL_SHUTDOWN_FAILED:
return "Failed to shut down the SSL connection";
case CURLE_SEND_FAIL_REWIND:
return "Send failed since rewinding of the data stream failed";
@@ -277,6 +280,12 @@ curl_easy_strerror(CURLcode error)
case CURLE_CONV_REQD:
return "caller must register CURLOPT_CONV_ callback options";
case CURLE_REMOTE_FILE_NOT_FOUND:
return "Remote file not found";
case CURLE_SSH:
return "Error in the SSH layer";
/* error codes not used by current libcurl */
case CURLE_URL_MALFORMAT_USER:
case CURLE_FTP_USER_PASSWORD_INCORRECT:

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -1073,10 +1073,11 @@ void telrcv(struct connectdata *conn,
}
}
CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode status)
CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode status, bool premature)
{
struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
(void)status; /* unused */
(void)premature; /* not used */
curl_slist_free_all(tn->telnet_vars);

View File

@@ -8,7 +8,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -25,6 +25,6 @@
***************************************************************************/
#ifndef CURL_DISABLE_TELNET
CURLcode Curl_telnet(struct connectdata *conn, bool *done);
CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode);
CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode, bool premature);
#endif
#endif

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -77,6 +77,7 @@
#include "connect.h"
#include "strerror.h"
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
#include "url.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -255,10 +256,7 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
{
int sbytes;
const char *mode = "octet";
/* As RFC3617 describes the separator slash is not actually part of the file
name so we skip the always-present first letter of the path string. */
char *filename = &state->conn->data->reqdata.path[1];
char *filename;
struct SessionHandle *data = state->conn->data;
CURLcode res = CURLE_OK;
@@ -281,7 +279,6 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
if(data->set.upload) {
/* If we are uploading, send an WRQ */
setpacketevent(&state->spacket, TFTP_EVENT_WRQ);
filename = curl_easy_unescape(data, filename, 0, NULL);
state->conn->data->reqdata.upload_fromhere = (char *)&state->spacket.data[4];
if(data->set.infilesize != -1)
Curl_pgrsSetUploadSize(data, data->set.infilesize);
@@ -290,6 +287,10 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
/* If we are downloading, send an RRQ */
setpacketevent(&state->spacket, TFTP_EVENT_RRQ);
}
/* As RFC3617 describes the separator slash is not actually part of the
file name so we skip the always-present first letter of the path string. */
filename = curl_easy_unescape(data, &state->conn->data->reqdata.path[1], 0,
NULL);
snprintf((char *)&state->spacket.data[2],
TFTP_BLOCKSIZE,
"%s%c%s%c", filename, '\0', mode, '\0');
@@ -301,6 +302,7 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
if(sbytes < 0) {
failf(data, "%s\n", Curl_strerror(state->conn, Curl_sockerrno()));
}
Curl_safefree(filename);
break;
case TFTP_EVENT_ACK: /* Connected for transmit */
@@ -569,10 +571,13 @@ CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done)
tftp_state_data_t *state;
int rc;
state = conn->data->reqdata.proto.tftp = calloc(sizeof(tftp_state_data_t), 1);
state = conn->data->reqdata.proto.tftp = calloc(sizeof(tftp_state_data_t),
1);
if(!state)
return CURLE_OUT_OF_MEMORY;
conn->bits.close = FALSE; /* keep it open if possible */
state->conn = conn;
state->sockfd = state->conn->sock[FIRSTSOCKET];
state->state = TFTP_STATE_START;
@@ -582,24 +587,27 @@ CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done)
tftp_set_timeouts(state);
/* Bind to any interface, random UDP port.
*
* We once used the size of the local_addr struct as the third argument for
* bind() to better work with IPv6 or whatever size the struct could have,
* but we learned that at least Tru64, AIX and IRIX *requires* the size of
* that argument to match the exact size of a 'sockaddr_in' struct when
* running IPv4-only.
*
* Therefore we use the size from the address we connected to, which we
* assume uses the same IP version and thus hopefully this works for both
* IPv4 and IPv6...
*/
rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
conn->ip_addr->ai_addrlen);
if(rc) {
failf(conn->data, "bind() failed; %s\n",
Curl_strerror(conn, Curl_sockerrno()));
return CURLE_COULDNT_CONNECT;
if(!conn->bits.reuse) {
/* If not reused, bind to any interface, random UDP port. If it is reused,
* this has already been done!
*
* We once used the size of the local_addr struct as the third argument for
* bind() to better work with IPv6 or whatever size the struct could have,
* but we learned that at least Tru64, AIX and IRIX *requires* the size of
* that argument to match the exact size of a 'sockaddr_in' struct when
* running IPv4-only.
*
* Therefore we use the size from the address we connected to, which we
* assume uses the same IP version and thus hopefully this works for both
* IPv4 and IPv6...
*/
rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
conn->ip_addr->ai_addrlen);
if(rc) {
failf(conn->data, "bind() failed; %s\n",
Curl_strerror(conn, Curl_sockerrno()));
return CURLE_COULDNT_CONNECT;
}
}
Curl_pgrsStartNow(conn->data);
@@ -616,12 +624,16 @@ CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done)
* The done callback
*
**********************************************************/
CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode status)
CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode status,
bool premature)
{
(void)status; /* unused */
(void)premature; /* not used */
#if 0
free(conn->data->reqdata.proto.tftp);
conn->data->reqdata.proto.tftp = NULL;
#endif
Curl_pgrsDone(conn);
return CURLE_OK;
@@ -641,7 +653,8 @@ CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode status)
CURLcode Curl_tftp(struct connectdata *conn, bool *done)
{
struct SessionHandle *data = conn->data;
tftp_state_data_t *state = (tftp_state_data_t *)(conn->data->reqdata.proto.tftp);
tftp_state_data_t *state =
(tftp_state_data_t *) conn->data->reqdata.proto.tftp;
tftp_event_t event;
CURLcode code;
int rc;
@@ -649,7 +662,20 @@ CURLcode Curl_tftp(struct connectdata *conn, bool *done)
socklen_t fromlen;
int check_time = 0;
(void)done; /* prevent compiler warning */
*done = TRUE;
/*
Since connections can be re-used between SessionHandles, this might be a
connection already existing but on a fresh SessionHandle struct so we must
make sure we have a good 'struct TFTP' to play with. For new connections,
the struct TFTP is allocated and setup in the Curl_tftp_connect() function.
*/
if(!state) {
code = Curl_tftp_connect(conn, done);
if(code)
return code;
state = (tftp_state_data_t *)conn->data->reqdata.proto.tftp;
}
/* Run the TFTP State Machine */
for(tftp_state_machine(state, TFTP_EVENT_INIT);

View File

@@ -8,7 +8,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -26,6 +26,6 @@
#ifndef CURL_DISABLE_TFTP
CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done);
CURLcode Curl_tftp(struct connectdata *conn, bool *done);
CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode);
CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode, bool premature);
#endif
#endif

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -189,17 +189,39 @@ checkhttpprefix(struct SessionHandle *data,
const char *s)
{
struct curl_slist *head = data->set.http200aliases;
bool rc = FALSE;
#ifdef CURL_DOES_CONVERSIONS
/* convert from the network encoding using a scratch area */
char *scratch = calloc(1, strlen(s)+1);
if (NULL == scratch) {
failf (data, "Failed to calloc memory for conversion!");
return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
}
strcpy(scratch, s);
if (CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
/* Curl_convert_from_network calls failf if unsuccessful */
free(scratch);
return FALSE; /* can't return CURLE_foobar so return FALSE */
}
s = scratch;
#endif /* CURL_DOES_CONVERSIONS */
while (head) {
if (checkprefix(head->data, s))
return TRUE;
if (checkprefix(head->data, s)) {
rc = TRUE;
break;
}
head = head->next;
}
if(checkprefix("HTTP/", s))
return TRUE;
if ((rc != TRUE) && (checkprefix("HTTP/", s))) {
rc = TRUE;
}
return FALSE;
#ifdef CURL_DOES_CONVERSIONS
free(scratch);
#endif /* CURL_DOES_CONVERSIONS */
return rc;
}
/*
@@ -251,21 +273,37 @@ CURLcode Curl_readrewind(struct connectdata *conn)
return CURLE_OK;
}
#ifdef USE_SSLEAY
/* FIX: this is nasty OpenSSL-specific code that really shouldn't be here */
static int data_pending(struct connectdata *conn)
{
if(conn->ssl[FIRSTSOCKET].handle)
/* SSL is in use */
return SSL_pending(conn->ssl[FIRSTSOCKET].handle);
return 0; /* nothing */
return Curl_ssl_data_pending(conn, FIRSTSOCKET);
}
#else
/* non-SSL never have pending data */
#define data_pending(x) 0
#ifndef MIN
#define MIN(a,b) (a < b ? a : b)
#endif
static void read_rewind(struct connectdata *conn,
size_t thismuch)
{
conn->read_pos -= thismuch;
conn->bits.stream_was_rewound = TRUE;
#ifdef CURLDEBUG
{
char buf[512 + 1];
size_t show;
show = MIN(conn->buf_len - conn->read_pos, sizeof(buf)-1);
memcpy(buf, conn->master_buffer + conn->read_pos, show);
buf[show] = '\0';
DEBUGF(infof(conn->data,
"Buffer after stream rewind (read_pos = %d): [%s]",
conn->read_pos, buf));
}
#endif
}
/*
* Curl_readwrite() is the low-level function to be called when data is to
* be read and written to/from the connection.
@@ -285,12 +323,15 @@ CURLcode Curl_readwrite(struct connectdata *conn,
curl_off_t contentlength;
if(k->keepon & KEEP_READ)
/* only use the proper socket if the *_HOLD bit is not set simultaneously as
then we are in rate limiting state in that transfer direction */
if((k->keepon & (KEEP_READ|KEEP_READ_HOLD)) == KEEP_READ)
fd_read = conn->sockfd;
else
fd_read = CURL_SOCKET_BAD;
if(k->keepon & KEEP_WRITE)
if((k->keepon & (KEEP_WRITE|KEEP_WRITE_HOLD)) == KEEP_WRITE)
fd_write = conn->writesockfd;
else
fd_write = CURL_SOCKET_BAD;
@@ -318,8 +359,14 @@ CURLcode Curl_readwrite(struct connectdata *conn,
size_t bytestoread = buffersize;
int readrc;
if (k->size != -1 && !k->header)
bytestoread = (size_t)(k->size - k->bytecount);
if (k->size != -1 && !k->header) {
/* make sure we don't read "too much" if we can help it since we
might be pipelining and then someone else might want to read what
follows! */
curl_off_t totalleft = k->size - k->bytecount;
if(totalleft < (curl_off_t)bytestoread)
bytestoread = (size_t)totalleft;
}
/* receive data from the network! */
readrc = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread);
@@ -377,7 +424,8 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* str_start is start of line within buf */
k->str_start = k->str;
k->end_ptr = memchr(k->str_start, '\n', nread);
/* data is in network encoding so use 0x0a instead of '\n' */
k->end_ptr = memchr(k->str_start, 0x0a, nread);
if (!k->end_ptr) {
/* Not a complete header line within buffer, append the data to
@@ -475,14 +523,27 @@ CURLcode Curl_readwrite(struct connectdata *conn,
}
}
if (('\n' == *k->p) || ('\r' == *k->p)) {
/* headers are in network encoding so
use 0x0a and 0x0d instead of '\n' and '\r' */
if ((0x0a == *k->p) || (0x0d == *k->p)) {
size_t headerlen;
/* Zero-length header line means end of headers! */
#ifdef CURL_DOES_CONVERSIONS
if (0x0d == *k->p) {
*k->p = '\r'; /* replace with CR in host encoding */
k->p++; /* pass the CR byte */
}
if (0x0a == *k->p) {
*k->p = '\n'; /* replace with LF in host encoding */
k->p++; /* pass the LF byte */
}
#else
if ('\r' == *k->p)
k->p++; /* pass the \r byte */
if ('\n' == *k->p)
k->p++; /* pass the \n byte */
#endif /* CURL_DOES_CONVERSIONS */
if(100 == k->httpcode) {
/*
@@ -501,9 +562,19 @@ CURLcode Curl_readwrite(struct connectdata *conn,
k->keepon |= KEEP_WRITE;
}
}
else
else {
k->header = FALSE; /* no more header to parse! */
if((k->size == -1) && !conn->bits.chunk && !conn->bits.close)
/* When connection is not to get closed, but no
Content-Length nor Content-Encoding chunked have been
received, there is no body in this response. We don't set
stop_reading TRUE since that would also prevent necessary
authentication actions to take place. */
conn->bits.no_body = TRUE;
}
if (417 == k->httpcode) {
/*
* we got: "417 Expectation Failed" this means:
@@ -542,10 +613,10 @@ CURLcode Curl_readwrite(struct connectdata *conn,
return result;
data->info.header_size += (long)headerlen;
k->headerbytecount += (long)headerlen;
conn->headerbytecount += (long)headerlen;
k->deductheadercount =
(100 == k->httpcode)?k->headerbytecount:0;
conn->deductheadercount =
(100 == k->httpcode)?conn->headerbytecount:0;
if (data->reqdata.resume_from &&
(data->set.httpreq==HTTPREQ_GET) &&
@@ -634,12 +705,37 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if (!k->headerline++) {
/* This is the first header, it MUST be the error code line
or else we consiser this to be the body right away! */
or else we consider this to be the body right away! */
int httpversion_major;
int nc=sscanf(k->p, " HTTP/%d.%d %3d",
&httpversion_major,
&k->httpversion,
&k->httpcode);
int nc;
#ifdef CURL_DOES_CONVERSIONS
#define HEADER1 scratch
#define SCRATCHSIZE 21
CURLcode res;
char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
/* We can't really convert this yet because we
don't know if it's the 1st header line or the body.
So we do a partial conversion into a scratch area,
leaving the data at k->p as-is.
*/
strncpy(&scratch[0], k->p, SCRATCHSIZE);
scratch[SCRATCHSIZE] = 0; /* null terminate */
res = Curl_convert_from_network(data,
&scratch[0],
SCRATCHSIZE);
if (CURLE_OK != res) {
/* Curl_convert_from_network calls failf if unsuccessful */
return res;
}
#else
#define HEADER1 k->p /* no conversion needed, just use k->p */
#endif /* CURL_DOES_CONVERSIONS */
nc = sscanf(HEADER1,
" HTTP/%d.%d %3d",
&httpversion_major,
&k->httpversion,
&k->httpcode);
if (nc==3) {
k->httpversion += 10 * httpversion_major;
}
@@ -647,7 +743,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* this is the real world, not a Nirvana
NCSA 1.5.x returns this crap when asked for HTTP/1.1
*/
nc=sscanf(k->p, " HTTP %3d", &k->httpcode);
nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
k->httpversion = 10;
/* If user has set option HTTP200ALIASES,
@@ -730,6 +826,15 @@ CURLcode Curl_readwrite(struct connectdata *conn,
}
}
#ifdef CURL_DOES_CONVERSIONS
/* convert from the network encoding */
result = Curl_convert_from_network(data, k->p, strlen(k->p));
if (CURLE_OK != result) {
return(result);
}
/* Curl_convert_from_network calls failf if unsuccessful */
#endif /* CURL_DOES_CONVERSIONS */
/* Check for Content-Length: header lines to get size. Ignore
the header completely if we get a 416 response as then we're
resuming a document that we don't get, and this header contains
@@ -767,6 +872,8 @@ CURLcode Curl_readwrite(struct connectdata *conn,
start++)
; /* empty loop */
/* data is now in the host encoding so
use '\r' and '\n' instead of 0x0d and 0x0a */
end = strchr(start, '\r');
if(!end)
end = strchr(start, '\n');
@@ -894,19 +1001,20 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|| checkprefix("x-compress", start))
k->content_encoding = COMPRESS;
}
else if (Curl_compareheader(k->p, "Content-Range:", "bytes")) {
else if (checkprefix("Content-Range:", k->p)) {
/* Content-Range: bytes [num]-
Content-Range: bytes: [num]-
Content-Range: [num]-
The second format was added since Sun's webserver
JavaWebServer/1.1.1 obviously sends the header this way!
The third added since some servers use that!
*/
char *ptr = Curl_strcasestr(k->p, "bytes");
ptr+=5;
char *ptr = k->p + 14;
if(*ptr == ':')
/* stupid colon skip */
/* Move forward until first digit */
while(*ptr && !ISDIGIT(*ptr))
ptr++;
k->offset = curlx_strtoofft(ptr, NULL, 10);
@@ -1000,7 +1108,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
return result;
data->info.header_size += (long)k->hbuflen;
k->headerbytecount += (long)k->hbuflen;
conn->headerbytecount += (long)k->hbuflen;
/* reset hbufp pointer && hbuflen */
k->hbufp = data->state.headerbuff;
@@ -1134,17 +1242,18 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if((-1 != k->maxdownload) &&
(k->bytecount + nread >= k->maxdownload)) {
curl_off_t excess = k->bytecount +
((curl_off_t) nread) - k->maxdownload;
/* The 'excess' amount below can't be more than BUFSIZE which
always will fit in a size_t */
size_t excess = k->bytecount + nread - k->maxdownload;
if (excess > 0 && !k->ignorebody) {
infof(data,
"Rewinding stream by : %" FORMAT_OFF_T
"Rewinding stream by : %d"
" bytes on url %s (size = %" FORMAT_OFF_T
", maxdownload = %" FORMAT_OFF_T
", bytecount = %" FORMAT_OFF_T ", nread = %d)\n",
excess, conn->data->reqdata.path,
k->size, k->maxdownload, k->bytecount, nread);
Curl_read_rewind(conn, excess);
read_rewind(conn, excess);
}
nread = (ssize_t) (k->maxdownload - k->bytecount);
@@ -1492,7 +1601,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
}
/* Now update the "done" boolean we return */
*done = (bool)(0 == k->keepon);
*done = (bool)(0 == (k->keepon&(KEEP_READ|KEEP_WRITE)));
return CURLE_OK;
}
@@ -1523,7 +1632,6 @@ CURLcode Curl_readwrite_init(struct connectdata *conn)
k->writebytecountp = data->reqdata.writebytecountp;
k->bytecount = 0;
k->headerbytecount = 0;
k->buf = data->state.buffer;
k->uploadbuf = data->state.uploadbuffer;
@@ -1661,37 +1769,40 @@ Transfer(struct connectdata *conn)
while (!done) {
curl_socket_t fd_read;
curl_socket_t fd_write;
int interval_ms;
interval_ms = 1 * 1000;
/* limit-rate logic: if speed exceeds threshold, then do not include fd in
select set */
if ( (conn->data->set.max_send_speed > 0) &&
(conn->data->progress.ulspeed > conn->data->set.max_send_speed) ) {
select set. The current speed is recalculated in each Curl_readwrite()
call */
if ((k->keepon & KEEP_WRITE) &&
(!data->set.max_send_speed ||
(data->progress.ulspeed < data->set.max_send_speed) )) {
fd_write = conn->writesockfd;
k->keepon &= ~KEEP_WRITE_HOLD;
}
else {
fd_write = CURL_SOCKET_BAD;
Curl_pgrsUpdate(conn);
}
else {
if(k->keepon & KEEP_WRITE)
fd_write = conn->writesockfd;
else
fd_write = CURL_SOCKET_BAD;
k->keepon |= KEEP_WRITE_HOLD; /* hold it */
}
if ( (conn->data->set.max_recv_speed > 0) &&
(conn->data->progress.dlspeed > conn->data->set.max_recv_speed) ) {
fd_read = CURL_SOCKET_BAD;
Curl_pgrsUpdate(conn);
if ((k->keepon & KEEP_READ) &&
(!data->set.max_recv_speed ||
(data->progress.dlspeed < data->set.max_recv_speed)) ) {
fd_read = conn->sockfd;
k->keepon &= ~KEEP_READ_HOLD;
}
else {
fd_read = CURL_SOCKET_BAD;
if(k->keepon & KEEP_READ)
fd_read = conn->sockfd;
else
fd_read = CURL_SOCKET_BAD;
k->keepon |= KEEP_READ_HOLD; /* hold it */
}
switch (Curl_select(fd_read, fd_write, interval_ms)) {
/* The *_HOLD logic is necessary since even though there might be no
traffic during the select interval, we still call Curl_readwrite() for
the timeout case and if we limit transfer speed we must make sure that
this function doesn't transfer anything while in HOLD status. */
switch (Curl_select(fd_read, fd_write, 1000)) {
case -1: /* select() error, stop reading */
#ifdef EINTR
/* The EINTR is not serious, and it seems you might get this more
@@ -2182,7 +2293,7 @@ Curl_connect_host(struct SessionHandle *data,
to the new URL */
urlchanged = data->change.url_changed;
if ((CURLE_OK == res) && urlchanged) {
res = Curl_done(conn, res);
res = Curl_done(conn, res, FALSE);
if(CURLE_OK == res) {
char *gotourl = strdup(data->change.url);
res = Curl_follow(data, gotourl, FALSE);
@@ -2201,9 +2312,8 @@ bool Curl_retry_request(struct connectdata *conn,
{
bool retry = FALSE;
struct SessionHandle *data = conn->data;
struct Curl_transfer_keeper *k = &data->reqdata.keep;
if((data->reqdata.keep.bytecount+k->headerbytecount == 0) &&
if((data->reqdata.keep.bytecount+conn->headerbytecount == 0) &&
conn->bits.reuse &&
!conn->bits.no_body) {
/* We got no data, we attempted to re-use a connection and yet we want a
@@ -2259,7 +2369,7 @@ CURLcode Curl_perform(struct SessionHandle *data)
if(data->set.connect_only) {
/* keep connection open for application to use the socket */
conn->bits.close = FALSE;
res = Curl_done(&conn, CURLE_OK);
res = Curl_done(&conn, CURLE_OK, FALSE);
break;
}
res = Curl_do(&conn, &do_done);
@@ -2292,14 +2402,14 @@ CURLcode Curl_perform(struct SessionHandle *data)
/* Always run Curl_done(), even if some of the previous calls
failed, but return the previous (original) error code */
res2 = Curl_done(&conn, res);
res2 = Curl_done(&conn, res, FALSE);
if(CURLE_OK == res)
res = res2;
}
else
/* Curl_do() failed, clean up left-overs in the done-call */
res2 = Curl_done(&conn, res);
res2 = Curl_done(&conn, res, FALSE);
/*
* Important: 'conn' cannot be used here, since it may have been closed
@@ -2344,8 +2454,8 @@ CURLcode Curl_perform(struct SessionHandle *data)
}
/*
* Curl_setup_transfer() is called to setup some basic properties for the upcoming
* transfer.
* Curl_setup_transfer() is called to setup some basic properties for the
* upcoming transfer.
*/
CURLcode
Curl_setup_transfer(

270
lib/url.c
View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -128,6 +128,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by
#include "http.h"
#include "file.h"
#include "ldap.h"
#include "ssh.h"
#include "url.h"
#include "connect.h"
#include "inet_ntop.h"
@@ -165,7 +166,7 @@ static void signalPipeClose(struct curl_llist *pipe);
#define MAX_PIPELINE_LENGTH 5
/*
/*
* We use this ZERO_NULL to avoid picky compiler warnings,
* when assigning a NULL pointer to a function pointer var.
*/
@@ -178,9 +179,6 @@ static void signalPipeClose(struct curl_llist *pipe);
#ifndef WIN32
/* not for WIN32 builds */
#ifndef RETSIGTYPE
#define RETSIGTYPE void
#endif
#ifdef HAVE_SIGSETJMP
extern sigjmp_buf curl_jmpenv;
#endif
@@ -312,9 +310,6 @@ CURLcode Curl_close(struct SessionHandle *data)
Curl_safefree(data->state.first_host);
Curl_safefree(data->state.scratch);
if(data->change.proxy_alloc)
free(data->change.proxy);
if(data->change.referer_alloc)
free(data->change.referer);
@@ -379,11 +374,13 @@ CURLcode Curl_close(struct SessionHandle *data)
}
/* create a connection cache of a private or multi type */
struct conncache *Curl_mk_connc(int type)
struct conncache *Curl_mk_connc(int type,
int amount) /* set -1 to use default */
{
/* It is subject for debate how many default connections to have for a multi
connection cache... */
int default_amount = (type == CONNCACHE_PRIVATE)?5:10;
int default_amount = amount == -1?
((type == CONNCACHE_PRIVATE)?5:10):amount;
struct conncache *c;
c= calloc(sizeof(struct conncache), 1);
@@ -409,6 +406,20 @@ CURLcode Curl_ch_connc(struct SessionHandle *data,
long i;
struct connectdata **newptr;
if(newamount < 1)
newamount = 1; /* we better have at least one entry */
if(!c) {
/* we get a NULL pointer passed in as connection cache, which means that
there is no cache created for this SessionHandle just yet, we create a
brand new with the requested size.
*/
data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, newamount);
if(!data->state.connc)
return CURLE_OUT_OF_MEMORY;
return CURLE_OK;
}
if(newamount < c->num) {
/* Since this number is *decreased* from the existing number, we must
close the possibly open connections that live on the indexes that
@@ -546,6 +557,9 @@ CURLcode Curl_open(struct SessionHandle **curl)
the first call to curl_easy_perform() or when the handle is added to a
multi stack. */
data->set.ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
type */
/* most recent connection is not yet defined */
data->state.lastconnect = -1;
@@ -1088,15 +1102,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* Setting it to NULL, means no proxy but allows the environment variables
* to decide for us.
*/
if(data->change.proxy_alloc) {
/*
* The already set string is allocated, free that first
*/
data->change.proxy_alloc = FALSE;
free(data->change.proxy);
}
data->set.set_proxy = va_arg(param, char *);
data->change.proxy = data->set.set_proxy;
data->set.proxy = va_arg(param, char *);
break;
case CURLOPT_WRITEHEADER:
@@ -1134,6 +1140,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
data->set.ftp_use_epsv = (bool)(0 != va_arg(param, long));
break;
case CURLOPT_FTP_SSL_CCC:
data->set.ftp_use_ccc = (bool)(0 != va_arg(param, long));
break;
case CURLOPT_FTP_SKIP_PASV_IP:
/*
* Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
@@ -1673,6 +1683,24 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
data->set.ssl.sessionid = (bool)(0 != va_arg(param, long));
break;
case CURLOPT_SSH_AUTH_TYPES:
data->set.ssh_auth_types = va_arg(param, long);
break;
case CURLOPT_SSH_PUBLIC_KEYFILE:
/*
* Use this file instead of the $HOME/.ssh/id_dsa.pub file
*/
data->set.ssh_public_key = va_arg(param, char *);
break;
case CURLOPT_SSH_PRIVATE_KEYFILE:
/*
* Use this file instead of the $HOME/.ssh/id_dsa file
*/
data->set.ssh_private_key = va_arg(param, char *);
break;
default:
/* unknown tag and its companion, just ignore: */
result = CURLE_FAILED_INIT; /* correct this */
@@ -1782,7 +1810,10 @@ CURLcode Curl_disconnect(struct connectdata *conn)
if(-1 != conn->connectindex) {
/* unlink ourselves! */
infof(data, "Closing connection #%ld\n", conn->connectindex);
data->state.connc->connects[conn->connectindex] = NULL;
if(data->state.connc)
/* only clear the table entry if we still know in which cache we
used to be in */
data->state.connc->connects[conn->connectindex] = NULL;
}
#ifdef USE_LIBIDN
@@ -1877,7 +1908,7 @@ int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
return 0;
}
#if 0
#if 0 /* this code is saved here as it is useful for debugging purposes */
static void Curl_printPipeline(struct curl_llist *pipe)
{
struct curl_llist_element *curr;
@@ -2016,6 +2047,10 @@ ConnectionExists(struct SessionHandle *data,
ssl options as well */
if(!Curl_ssl_config_matches(&needle->ssl_config,
&check->ssl_config)) {
infof(data,
"Connection #%ld has different SSL parameters, "
"can't reuse\n",
check->connectindex );
continue;
}
}
@@ -2044,7 +2079,6 @@ ConnectionExists(struct SessionHandle *data,
}
if(match) {
#if 1
if (!IsPipeliningEnabled(data)) {
/* The check for a dead socket makes sense only in the
non-pipelining case */
@@ -2059,7 +2093,6 @@ ConnectionExists(struct SessionHandle *data,
return FALSE;
}
}
#endif
check->inuse = TRUE; /* mark this as being in use so that no other
handle in a multi stack may nick it */
@@ -2105,26 +2138,8 @@ ConnectionKillOne(struct SessionHandle *data)
if(!conn || conn->inuse)
continue;
/*
* By using the set policy, we score each connection.
*/
switch(data->set.closepolicy) {
case CURLCLOSEPOLICY_LEAST_RECENTLY_USED:
default:
/*
* Set higher score for the age passed since the connection
* was used.
*/
score = Curl_tvdiff(now, conn->now);
break;
case CURLCLOSEPOLICY_OLDEST:
/*
* Set higher score for the age passed since the connection
* was created.
*/
score = Curl_tvdiff(now, conn->created);
break;
}
/* Set higher score for the age passed since the connection was used */
score = Curl_tvdiff(now, conn->now);
if(score > highscore) {
highscore = score;
@@ -2151,10 +2166,7 @@ static void
ConnectionDone(struct connectdata *conn)
{
conn->inuse = FALSE;
conn->data = NULL;
if (conn->send_pipe == 0 &&
conn->recv_pipe == 0)
if (!conn->send_pipe && !conn->recv_pipe)
conn->is_in_pipeline = FALSE;
}
@@ -2213,10 +2225,10 @@ static CURLcode ConnectPlease(struct SessionHandle *data,
{
CURLcode result;
Curl_addrinfo *addr;
char *hostname = data->change.proxy?conn->proxy.name:conn->host.name;
char *hostname = conn->bits.httpproxy?conn->proxy.name:conn->host.name;
infof(data, "About to connect() to %s%s port %d (#%d)\n",
data->change.proxy?"proxy ":"",
conn->bits.httpproxy?"proxy ":"",
hostname, conn->port, conn->connectindex);
/*************************************************************
@@ -2372,7 +2384,8 @@ CURLcode Curl_protocol_connect(struct connectdata *conn,
/* it has started, possibly even completed but that knowledge isn't stored
in this bit! */
conn->bits.protoconnstart = TRUE;
if (!result)
conn->bits.protoconnstart = TRUE;
}
return result; /* pass back status */
@@ -2688,6 +2701,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
char passwd[MAX_CURL_PASSWORD_LENGTH];
int rc;
bool reuse;
char *proxy;
bool proxy_alloc = FALSE;
#ifndef USE_ARES
#ifdef SIGALRM
@@ -2736,9 +2751,10 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
conn->connectindex = -1; /* no index */
conn->bits.httpproxy = (bool)(data->change.proxy /* http proxy or not */
&& *data->change.proxy
&& (data->set.proxytype == CURLPROXY_HTTP));
conn->bits.httpproxy = (bool)(data->set.proxy /* http proxy or not */
&& *data->set.proxy
&& (data->set.proxytype == CURLPROXY_HTTP));
proxy = data->set.proxy; /* if global proxy is set, this is it */
/* Default protocol-independent behavior doesn't support persistent
connections, so we set this to force-close. Protocols that support
@@ -2838,7 +2854,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
/*************************************************************
* Detect what (if any) proxy to use
*************************************************************/
if(!data->change.proxy) {
if(!conn->bits.httpproxy) {
/* If proxy was not specified, we check for default proxy environment
* variables, to enable i.e Lynx compliance:
*
@@ -2858,7 +2874,6 @@ static CURLcode CreateConnection(struct SessionHandle *data,
*/
char *no_proxy=NULL;
char *no_proxy_tok_buf;
char *proxy=NULL;
char proxy_env[128];
no_proxy=curl_getenv("no_proxy");
@@ -2933,13 +2948,12 @@ static CURLcode CreateConnection(struct SessionHandle *data,
}
if(proxy && *proxy) {
long bits = conn->protocol & (PROT_HTTPS|PROT_SSL);
data->change.proxy = proxy;
data->change.proxy_alloc=TRUE; /* this needs to be freed later */
conn->bits.httpproxy = TRUE;
long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING);
/* force this to become HTTP */
conn->protocol = PROT_HTTP | bits;
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 '*' */
@@ -3023,7 +3037,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->curl_connecting = Curl_https_connecting;
conn->curl_proto_getsock = Curl_https_getsock;
#else /* USE_SS */
#else /* USE_SSL */
failf(data, LIBCURL_NAME
" was built with SSL disabled, https: not supported!");
return CURLE_UNSUPPORTED_PROTOCOL;
@@ -3050,11 +3064,9 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->port = port;
conn->remote_port = (unsigned short)port;
conn->protocol |= PROT_FTP|PROT_CLOSEACTION;
conn->protocol |= PROT_FTP;
if(data->change.proxy &&
*data->change.proxy &&
!data->set.tunnel_thru_httpproxy) {
if(proxy && *proxy && !data->set.tunnel_thru_httpproxy) {
/* Unless we have asked to tunnel ftp operations through the proxy, we
switch and use HTTP operations only */
#ifndef CURL_DISABLE_HTTP
@@ -3215,14 +3227,44 @@ static CURLcode CreateConnection(struct SessionHandle *data,
" was built with TFTP disabled!");
#endif
}
else {
else if (strequal(conn->protostr, "SCP")) {
#ifdef USE_LIBSSH2
conn->port = PORT_SSH;
conn->remote_port = PORT_SSH;
conn->protocol = PROT_SCP;
conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */
conn->curl_do = Curl_scp_do;
conn->curl_done = Curl_scp_done;
conn->curl_do_more = (Curl_do_more_func)ZERO_NULL;
#else
failf(data, LIBCURL_NAME
" was built without LIBSSH2, scp: not supported!");
return CURLE_UNSUPPORTED_PROTOCOL;
#endif
}
else if (strequal(conn->protostr, "SFTP")) {
#ifdef USE_LIBSSH2
conn->port = PORT_SSH;
conn->remote_port = PORT_SSH;
conn->protocol = PROT_SFTP;
conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */
conn->curl_do = Curl_sftp_do;
conn->curl_done = Curl_sftp_done;
conn->curl_do_more = (Curl_do_more_func)NULL;
#else
failf(data, LIBCURL_NAME
" was built without LIBSSH2, scp: not supported!");
return CURLE_UNSUPPORTED_PROTOCOL;
#endif
}
else {
/* We fell through all checks and thus we don't support the specified
protocol */
failf(data, "Unsupported protocol: %s", conn->protostr);
return CURLE_UNSUPPORTED_PROTOCOL;
}
if(data->change.proxy && *data->change.proxy) {
if(proxy && *proxy) {
/* If this is supposed to use a proxy, we need to figure out the proxy
host name name, so that we can re-use an existing connection
that may exist registered to the same proxy host. */
@@ -3231,8 +3273,9 @@ static CURLcode CreateConnection(struct SessionHandle *data,
char *endofprot;
/* We need to make a duplicate of the proxy so that we can modify the
string safely. */
char *proxydup=strdup(data->change.proxy);
string safely. If 'proxy_alloc' is TRUE, the string is already
allocated and we can treat it as duplicated. */
char *proxydup=proxy_alloc?proxy:strdup(proxy);
/* We use 'proxyptr' to point to the proxy name from now on... */
char *proxyptr=proxydup;
@@ -3341,12 +3384,13 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->proxy.name = conn->proxy.rawalloc;
free(proxydup); /* free the duplicate pointer and not the modified */
proxy = NULL; /* this may have just been freed */
if(!conn->proxy.rawalloc)
return CURLE_OUT_OF_MEMORY;
}
/*************************************************************
* If the protcol is using SSL and HTTP proxy is used, we set
* If the protocol is using SSL and HTTP proxy is used, we set
* the tunnel_proxy bit.
*************************************************************/
if((conn->protocol&PROT_SSL) && conn->bits.httpproxy)
@@ -3381,9 +3425,9 @@ static CURLcode CreateConnection(struct SessionHandle *data,
user[0] =0; /* to make everything well-defined */
passwd[0]=0;
if (conn->protocol & (PROT_FTP|PROT_HTTP)) {
/* This is a FTP or HTTP URL, we will now try to extract the possible
* user+password pair in a string like:
if (conn->protocol & (PROT_FTP|PROT_HTTP|PROT_SCP|PROT_SFTP)) {
/* This is a FTP, HTTP, SCP or SFTP URL, we will now try to extract the
* possible user+password pair in a string like:
* ftp://user:password@ftp.my.site:8021/README */
char *ptr=strchr(conn->host.name, '@');
char *userpass = conn->host.name;
@@ -3792,7 +3836,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
/* set a pointer to the hostname we display */
fix_hostname(data, conn, &conn->host);
if(!data->change.proxy || !*data->change.proxy) {
if(!conn->proxy.name || !*conn->proxy.name) {
/* If not connecting via a proxy, extract the port from the URL, if it is
* there, thus overriding any defaults that might have been set above. */
conn->port = conn->remote_port; /* it is the same port */
@@ -3905,45 +3949,62 @@ static CURLcode SetupConnection(struct connectdata *conn,
* Send user-agent to HTTP proxies even if the target protocol
* isn't HTTP.
*************************************************************/
if((conn->protocol&PROT_HTTP) ||
(data->change.proxy && *data->change.proxy)) {
if((conn->protocol&PROT_HTTP) || conn->bits.httpproxy) {
if(data->set.useragent) {
Curl_safefree(conn->allocptr.uagent);
conn->allocptr.uagent =
aprintf("User-Agent: %s\015\012", data->set.useragent);
aprintf("User-Agent: %s\r\n", data->set.useragent);
if(!conn->allocptr.uagent)
return CURLE_OUT_OF_MEMORY;
}
}
conn->headerbytecount = 0;
#ifdef CURL_DO_LINEEND_CONV
data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
#endif /* CURL_DO_LINEEND_CONV */
if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
bool connected = FALSE;
for(;;) {
/* loop for CURL_SERVER_CLOSED_CONNECTION */
/* Connect only if not already connected! */
result = ConnectPlease(data, conn, hostaddr, &connected);
if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
bool connected = FALSE;
if(connected) {
result = Curl_protocol_connect(conn, protocol_done);
if(CURLE_OK == result)
conn->bits.tcpconnect = TRUE;
/* Connect only if not already connected! */
result = ConnectPlease(data, conn, hostaddr, &connected);
if(connected) {
result = Curl_protocol_connect(conn, protocol_done);
if(CURLE_OK == result)
conn->bits.tcpconnect = TRUE;
}
else
conn->bits.tcpconnect = FALSE;
/* if the connection was closed by the server while exchanging
authentication informations, retry with the new set
authentication information */
if(conn->bits.proxy_connect_closed) {
/* reset the error buffer */
if (data->set.errorbuffer)
data->set.errorbuffer[0] = '\0';
data->state.errorbuf = FALSE;
continue;
}
if(CURLE_OK != result)
return result;
}
else
conn->bits.tcpconnect = FALSE;
if(CURLE_OK != result)
return result;
}
else {
Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
conn->bits.tcpconnect = TRUE;
*protocol_done = TRUE;
if(data->set.verbose)
verboseconnect(conn);
else {
Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
conn->bits.tcpconnect = TRUE;
*protocol_done = TRUE;
if(data->set.verbose)
verboseconnect(conn);
}
/* Stop the loop now */
break;
}
conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
@@ -4031,7 +4092,7 @@ CURLcode Curl_async_resolved(struct connectdata *conn,
CURLcode Curl_done(struct connectdata **connp,
CURLcode status) /* an error if this is called after an
CURLcode status, bool premature) /* an error if this is called after an
error was detected */
{
CURLcode result;
@@ -4071,7 +4132,7 @@ CURLcode Curl_done(struct connectdata **connp,
/* this calls the protocol-specific function pointer previously set */
if(conn->curl_done)
result = conn->curl_done(conn, status);
result = conn->curl_done(conn, status, premature);
else
result = CURLE_OK;
@@ -4081,8 +4142,6 @@ CURLcode Curl_done(struct connectdata **connp,
cancelled before we proceed */
ares_cancel(data->state.areschannel);
ConnectionDone(conn); /* the connection is no longer in use */
/* if data->set.reuse_forbid is TRUE, it means the libcurl client has
forced us to close this no matter what we think.
@@ -4090,8 +4149,7 @@ CURLcode Curl_done(struct connectdata **connp,
closed in spite of all our efforts to be nice, due to protocol
restrictions in our or the server's end */
if(data->set.reuse_forbid || conn->bits.close) {
CURLcode res2;
res2 = Curl_disconnect(conn); /* close the connection */
CURLcode res2 = Curl_disconnect(conn); /* close the connection */
*connp = NULL; /* to make the caller of this function better detect that
this was actually killed here */
@@ -4102,6 +4160,8 @@ CURLcode Curl_done(struct connectdata **connp,
result = res2;
}
else {
ConnectionDone(conn); /* the connection is no longer in use */
/* remember the most recently used connection */
data->state.lastconnect = conn->connectindex;
@@ -4138,7 +4198,7 @@ CURLcode Curl_do(struct connectdata **connp, bool *done)
infof(data, "Re-used connection seems dead, get a new one\n");
conn->bits.close = TRUE; /* enforce close of this connection */
result = Curl_done(&conn, result); /* we are so done with this */
result = Curl_done(&conn, result, FALSE); /* we are so done with this */
/* conn may no longer be a good pointer */

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -39,7 +39,7 @@ CURLcode Curl_async_resolved(struct connectdata *conn,
bool *protocol_connect);
CURLcode Curl_do(struct connectdata **, bool *done);
CURLcode Curl_do_more(struct connectdata *);
CURLcode Curl_done(struct connectdata **, CURLcode);
CURLcode Curl_done(struct connectdata **, CURLcode, bool premature);
CURLcode Curl_disconnect(struct connectdata *);
CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);
@@ -47,7 +47,7 @@ CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done);
void Curl_safefree(void *ptr);
/* create a connection cache */
struct conncache *Curl_mk_connc(int type);
struct conncache *Curl_mk_connc(int type, int amount);
/* free a connection cache */
void Curl_rm_connc(struct conncache *c);
/* Change number of entries of a connection cache */

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -35,6 +35,7 @@
#define PORT_DICT 2628
#define PORT_LDAP 389
#define PORT_TFTP 69
#define PORT_SSH 22
#define DICT_MATCH "/MATCH:"
#define DICT_MATCH2 "/M:"
@@ -109,6 +110,11 @@
# endif
#endif
#ifdef HAVE_LIBSSH2_H
#include <libssh2.h>
#include <libssh2_sftp.h>
#endif /* HAVE_LIBSSH2_H */
/* Download buffer size, keep it fairly big for speed reasons */
#undef BUFSIZE
#define BUFSIZE CURL_MAX_WRITE_SIZE
@@ -296,7 +302,7 @@ struct HTTP {
***************************************************************************/
typedef enum {
FTP_STOP, /* do nothing state, stops the state machine */
FTP_WAIT220, /* waiting for the inintial 220 response immediately after
FTP_WAIT220, /* waiting for the initial 220 response immediately after
a connect */
FTP_AUTH,
FTP_USER,
@@ -304,6 +310,7 @@ typedef enum {
FTP_ACCT,
FTP_PBSZ,
FTP_PROT,
FTP_CCC,
FTP_PWD,
FTP_QUOTE, /* waiting for a response to a command sent in a quote list */
FTP_RETR_PREQUOTE,
@@ -392,6 +399,22 @@ struct ftp_conn {
ftpstate state; /* always use ftp.c:state() to change state! */
};
struct SSHPROTO {
curl_off_t *bytecountp;
char *user;
char *passwd;
char *path; /* the path we operate on */
char *homedir;
char *errorstr;
#ifdef USE_LIBSSH2
LIBSSH2_SESSION *ssh_session; /* Secure Shell session */
LIBSSH2_CHANNEL *ssh_channel; /* Secure Shell channel handle */
LIBSSH2_SFTP *sftp_session; /* SFTP handle */
LIBSSH2_SFTP_HANDLE *sftp_handle;
#endif /* USE_LIBSSH2 */
};
/****************************************************************************
* FILE unique setup
***************************************************************************/
@@ -463,8 +486,12 @@ struct ConnectBits {
when Curl_done() is called, to prevent Curl_done() to
get invoked twice when the multi interface is
used. */
bool stream_was_rewound; /* Indicates that the stream was rewound after a request
read past the end of its response byte boundary */
bool stream_was_rewound; /* Indicates that the stream was rewound after a
request read past the end of its response byte
boundary */
bool proxy_connect_closed; /* set true if a proxy disconnected the
connection in a CONNECT request with auth, so
that libcurl should reconnect and continue. */
};
struct hostname {
@@ -477,12 +504,14 @@ struct hostname {
/*
* Flags on the keepon member of the Curl_transfer_keeper
*/
enum {
KEEP_NONE,
KEEP_READ,
KEEP_WRITE
};
#define KEEP_NONE 0
#define KEEP_READ 1 /* there is or may be data to read */
#define KEEP_WRITE 2 /* there is or may be data to write */
#define KEEP_READ_HOLD 4 /* when set, no reading should be done but there
might still be data to read */
#define KEEP_WRITE_HOLD 8 /* when set, no writing should be done but there
might still be data to write */
/*
* This struct is all the previously local variables from Curl_perform() moved
@@ -506,13 +535,6 @@ struct Curl_transfer_keeper {
curl_off_t bytecount; /* total number of bytes read */
curl_off_t writebytecount; /* number of bytes written */
long headerbytecount; /* only count received headers */
long deductheadercount; /* this amount of bytes doesn't count when we check
if anything has been transfered at the end of
a connection. We use this counter to make only
a 100 reply (without a following second response
code) result in a CURLE_GOT_NOTHING error code */
struct timeval start; /* transfer started at this time */
struct timeval now; /* current time */
bool header; /* incoming data has HTTP header */
@@ -592,7 +614,7 @@ struct Curl_async {
within the source when we need to cast between data pointers (such as NULL)
and function pointers. */
typedef CURLcode (*Curl_do_more_func)(struct connectdata *);
typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode);
typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode, bool);
/*
@@ -647,6 +669,7 @@ struct HandleData {
struct FILEPROTO *file;
void *telnet; /* private for telnet.c-eyes only */
void *generic;
struct SSHPROTO *ssh;
} proto;
};
@@ -670,7 +693,6 @@ struct connectdata {
particular struct has */
long protocol; /* PROT_* flags concerning the protocol set */
#define PROT_MISSING (1<<0)
#define PROT_CLOSEACTION (1<<1) /* needs action before socket close */
#define PROT_HTTP (1<<2)
#define PROT_HTTPS (1<<3)
#define PROT_FTP (1<<4)
@@ -681,6 +703,11 @@ struct connectdata {
#define PROT_FTPS (1<<9)
#define PROT_SSL (1<<10) /* protocol requires SSL */
#define PROT_TFTP (1<<11)
#define PROT_SCP (1<<12)
#define PROT_SFTP (1<<13)
#define PROT_CLOSEACTION PROT_FTP /* these ones need action before socket
close */
/* 'dns_entry' is the particular host we use. This points to an entry in the
DNS cache and it will not get pruned while locked. It gets unlocked in
@@ -709,6 +736,13 @@ struct connectdata {
unsigned short remote_port; /* what remote port to connect to,
not the proxy port! */
long headerbytecount; /* only count received headers */
long deductheadercount; /* this amount of bytes doesn't count when we check
if anything has been transfered at the end of
a connection. We use this counter to make only
a 100 reply (without a following second response
code) result in a CURLE_GOT_NOTHING error code */
char *user; /* user name string, allocated */
char *passwd; /* password string, allocated */
@@ -802,8 +836,10 @@ struct connectdata {
struct sockaddr_in local_addr;
#endif
bool readchannel_inuse; /* whether the read channel is in use by an easy handle */
bool writechannel_inuse; /* whether the write channel is in use by an easy handle */
bool readchannel_inuse; /* whether the read channel is in use by an easy
handle */
bool writechannel_inuse; /* whether the write channel is in use by an easy
handle */
bool is_in_pipeline; /* TRUE if this connection is in a pipeline */
struct curl_llist *send_pipe; /* List of handles waiting to
@@ -1067,8 +1103,6 @@ struct DynamicStatic {
changed after the connect phase, as we allow callback
to change it and if so, we reconnect to use the new
URL instead */
char *proxy; /* work proxy, copied from UserDefined */
bool proxy_alloc; /* http proxy string is malloc()'ed */
char *referer; /* referer string */
bool referer_alloc; /* referer sting is malloc()ed */
struct curl_slist *cookielist; /* list of cookie files set by
@@ -1097,7 +1131,7 @@ struct UserDefined {
void *in; /* the uploaded file is read from here */
void *writeheader; /* write the header to this if non-NULL */
char *set_url; /* what original URL to work on */
char *set_proxy; /* proxy to use */
char *proxy; /* proxy to use */
long use_port; /* which port to use (when not using default) */
char *userpwd; /* <user:password>, if used */
long httpauth; /* what kind of HTTP authentication to use (bitmask) */
@@ -1173,7 +1207,6 @@ struct UserDefined {
struct curl_slist *telnet_options; /* linked list of telnet options */
curl_TimeCond timecondition; /* kind of time/date comparison */
time_t timevalue; /* what time to compare with */
curl_closepolicy closepolicy; /* connection cache close concept */
Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */
char *customrequest; /* HTTP/FTP request to use */
long httpversion; /* when non-zero, a specific HTTP version requested to
@@ -1241,6 +1274,8 @@ struct UserDefined {
bool reuse_fresh; /* do not re-use an existing connection */
bool ftp_use_epsv; /* if EPSV is to be attempted or not */
bool ftp_use_eprt; /* if EPRT is to be attempted or not */
bool ftp_use_ccc; /* if CCC is to be attempted or not */
curl_ftpssl ftp_ssl; /* if AUTH TLS is to be attempted etc */
curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */
bool no_signal; /* do not use any signal/alarm handler */
@@ -1250,6 +1285,11 @@ struct UserDefined {
bool ftp_skip_ip; /* skip the IP address the FTP server passes on to
us */
bool connect_only; /* make connection, let application use the socket */
long ssh_auth_types; /* allowed SSH auth types */
char *ssh_public_key; /* the path to the public key file for
authentication */
char *ssh_private_key; /* the path to the private key file for
authentication */
};
struct Names {

View File

@@ -45,6 +45,11 @@
#include <iconv.h>
#endif
#ifdef USE_LIBSSH2
#include <libssh2.h>
#endif
char *curl_version(void)
{
static char version[200];
@@ -88,6 +93,11 @@ char *curl_version(void)
left -= len;
ptr += len;
#endif
#ifdef USE_LIBSSH2
len = snprintf(ptr, left, " libssh2/%s", LIBSSH2_VERSION);
left -= len;
ptr += len;
#endif
return version;
}
@@ -125,6 +135,12 @@ static const char * const protocols[] = {
"ftps",
#endif
#endif
#ifdef USE_LIBSSH2
"scp",
"sftp",
#endif
NULL
};
@@ -179,10 +195,15 @@ static curl_version_info_data version_info = {
0, /* c-ares version numerical */
NULL, /* libidn version */
0, /* iconv version */
NULL, /* ssh lib version */
};
curl_version_info_data *curl_version_info(CURLversion stamp)
{
#ifdef USE_LIBSSH2
static char ssh_buffer[80];
#endif
#ifdef USE_SSL
static char ssl_buffer[80];
Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer));
@@ -217,6 +238,11 @@ curl_version_info_data *curl_version_info(CURLversion stamp)
#endif /* _LIBICONV_VERSION */
#endif
#ifdef USE_LIBSSH2
snprintf(ssh_buffer, sizeof(ssh_buffer), "libssh2/%s", LIBSSH2_VERSION);
version_info.libssh_version = ssh_buffer;
#endif
(void)stamp; /* avoid compiler warnings, we don't use this */
return &version_info;

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