Compare commits

...

207 Commits

Author SHA1 Message Date
Daniel Stenberg
b8d006b9d7 7.16.3 2007-06-25 09:18:16 +00:00
Daniel Stenberg
af4edf10f5 As reported by "Tro" in http://curl.haxx.se/mail/lib-2007-06/0161.html and
http://curl.haxx.se/mail/lib-2007-06/0238.html, libcurl didn't properly do
no-body requests on FTP files on re-used connections properly, or at least
it didn't provide the info back in the header callback properly in the
subsequent requests.
2007-06-24 19:32:33 +00:00
Gunter Knauf
0f9e209534 added netware install target 2007-06-22 21:10:41 +00:00
Gunter Knauf
2aed8946b0 made debug flag settable from outside; add allways debug stuff when DB != NDEBUG 2007-06-22 21:10:17 +00:00
Daniel Stenberg
03b03f7b60 remove annoying debug output 2007-06-22 20:24:11 +00:00
Daniel Stenberg
a1b650ad7b Gerrit Bruchhuser pointed out a warning that the Intel(R) Thread Checker
tool reports and it was indeed a legitimate one and it is one fixed. It was
a use of a share without doing the proper locking first.
2007-06-21 14:23:38 +00:00
Daniel Stenberg
d978f85d55 Adam Piggott filed bug report #1740263
(http://curl.haxx.se/bug/view.cgi?id=1740263). Adam discovered that when
getting a large amount of URLs with curl, they were fetched slower and
slower... which turned out to be because the --libcurl data collecting which
wrongly always was enabled, but no longer is...
2007-06-20 21:57:28 +00:00
James Housley
6e7f47da5b If the creation of rsa and rsa_pub fail due to memory, don't try
other authentication methods.  Terminate with a memory error.
2007-06-20 11:30:35 +00:00
James Housley
277bab0c7b Check both variables, not the same one twice. Pointed out by Colin Hogben 2007-06-19 13:23:21 +00:00
Daniel Stenberg
fc3c5dae87 and fix another flaw in the singlecwd case when we get ftp://site.com/, also
from the #1739100 bug report
2007-06-19 12:33:28 +00:00
Daniel Stenberg
891dffb528 extra precaution to make PATH_MAX always be defined 2007-06-19 11:50:08 +00:00
James Housley
f0b361ecc1 Change rsa and rsa_pub from static arrays in ssh_conn to be dynamically
allocated when needed
2007-06-19 11:31:33 +00:00
James Housley
df7eed16dd If LIBSSH2DEBUG was defined "i" was undefined 2007-06-18 22:28:40 +00:00
Daniel Stenberg
61db4f3e2a Robson Braga Araujo filed bug report #1739100
(http://curl.haxx.se/bug/view.cgi?id=1739100) that mentioned that libcurl
could not actually list the contents of the root directory of a given FTP
server if the login directory isn't root. I fixed the problem and added three
test cases (one is disabled for now since I identified KNOWN_BUGS #44, we
cannot use --ftp-method nocwd and list ftp directories).
2007-06-18 21:09:32 +00:00
Daniel Stenberg
fe85ae15f3 make the ftp-method multicwd case possible to LIST the root directory of a
server!
2007-06-18 21:04:45 +00:00
Daniel Stenberg
cc26cc5dcd Test listing of root dir with the three ftp-methods. KNOWN_BUGS #44 make me
disable test 351 by default by I add the test case anyway to make it easier
to work on this problem in the future.
2007-06-18 21:04:05 +00:00
Daniel Stenberg
eb965e2a13 44. --ftp-method nocwd does not handle URLs ending with a slash properly (it
should list the contents of that directory). See test case 351.
2007-06-18 21:03:14 +00:00
Daniel Stenberg
4e35395d0e Daniel Johnson reported the tests now run fine on OS X! 2007-06-18 08:57:13 +00:00
James Housley
b61b420cb8 Curl_ssh_connect() was using an uninitialized variable in one location.
Caught by the auto-builds
2007-06-16 16:58:02 +00:00
Daniel Stenberg
b0aa11fde7 Tom Regner added /usr/lib/misc to the path to scan for sftp to make the
sftp tests run fine on gentoo
2007-06-14 21:16:08 +00:00
Daniel Stenberg
b691102ec7 Shmulik Regev fixed a flaw in the multi interface that occurred when doing
HTTP CONNECT over a proxy
2007-06-14 14:42:21 +00:00
Daniel Stenberg
2785fe7f61 s/HAVE_POLL/HAVE_SYS_POLL_H 2007-06-14 14:15:21 +00:00
James Housley
db5d4bd811 Remove duplicate code that was left in as part of 1.35. This code
only affected sftp_sendquote() for the "chgrp/chmod/chown" commands.

This also fixed failure of test 614 on a system that previously failed.
2007-06-14 13:22:00 +00:00
Daniel Stenberg
dc3b3c6916 Make our own definitions of the POLL* defiens and the pollfd struct only get
done if the sys/poll.h file is missing, as we have seen machines with poll()
present but without the header file and machines that don't get HAVE_POLL
defined but that do have the sys/poll.h header file...
2007-06-14 11:21:48 +00:00
James Housley
82d3f97659 BUG FIX: When reading a directory listing that contains symlinks
with the latest libssh2, the listing would be truncated at the symlink.
Fix by looping on LIBSSH2_ERROR_EAGAIN, like the rest of the calls.
2007-06-14 10:36:53 +00:00
Daniel Stenberg
235632ed2c Tom Regner provided a patch and worked together with James Housley, so now
CURLOPT_FTP_CREATE_MISSING_DIRS works for SFTP connections as well as FTP
ones.
2007-06-13 20:17:35 +00:00
Daniel Stenberg
68330c86e7 Rich Rauenzahn filed bug report #1733119
(http://curl.haxx.se/bug/view.cgi?id=1733119) and we collaborated on the fix.
The problem is that for 64bit HPUX builds, several socket-related functions
would still assume int (32 bit) arguments and not socklen_t (64 bit) ones.
2007-06-13 20:08:19 +00:00
James Housley
f37dc9168a Restore functionality mistakenly removed in the previous commit 2007-06-13 17:13:44 +00:00
James Housley
17798ed740 Update documentation to reflect SFTP's ability to create directories on
upload.  Some text provieded by Tom Regner
2007-06-13 15:02:34 +00:00
Gisle Vanem
05ba9f9fcd libssh2_session_free() returns void. Fix "#endif". 2007-06-13 14:01:48 +00:00
James Housley
96f4af4db9 Commit Tom Regner's code for SFTP create missing directories. This patch
uses the --ftp-create-dirs flag to control if cURL will try and create
directories that are specified in an upload path, but don't exist.
2007-06-13 12:15:23 +00:00
James Housley
3ec7f8a25a Add a define to protect the state machine from older versions of libssh2,
ie 0.14, that don't know about newer constants used in the state machine.
2007-06-13 11:27:41 +00:00
Daniel Stenberg
375cdf89ad With lots of help from Rich Rauenza(?) in bug #1733119, we introduce a fairly
complicated work-around for 64bit HPUX compiles. We do the fix using inline
static functions to make them follow the header file properly and thus get
used fine in the test suite too etc.
2007-06-12 21:39:21 +00:00
James Housley
ab7e7144ef * Updates for the latest version of libssh2, specifically
libssh2_sftp_shutdown() and libssh2_session_free() can now return
  LIBSSH2_ERROR_EAGAIN.

* Fix the _send() and _recv() return values so non-blocking works
2007-06-12 21:32:45 +00:00
James Housley
6f59e19b91 While connect and transfer works fine in non-blocking mode for the test
suite, transfer fails in the real world.  So after connect set to blocking
as full non-blocking is migrated out.
2007-06-12 16:15:20 +00:00
Daniel Stenberg
7800b56dc8 mention James current work on ssh 2007-06-12 13:51:57 +00:00
James Housley
73c13220ee Prevent the state machine from getting stuck in SSH_AUTH_HOST_INIT 2007-06-12 13:47:32 +00:00
James Housley
99e0597c7b Convert Curl_ssh_connect() to run in a state machine for
LIBSSH2_APINO >= 200706012030.  More to come...
2007-06-12 12:31:10 +00:00
Daniel Stenberg
3247ac1918 remove unused field in the state struct 2007-06-12 08:15:02 +00:00
Dan Fandrich
c45d44fee9 Wait longer for servers to start up since the ssh server needs to generate
keys the first time (which can take a while on a slow or loaded host).
Enforce a longer startup wait time for the ssh client SOCKS server, too.
Check for an error code from startnew() when starting any server.
2007-06-11 17:53:10 +00:00
Dan Fandrich
1e718a515a We do not use RSA keys in the test suite. 2007-06-11 17:49:25 +00:00
Daniel Stenberg
d23d686de2 restore the correct timeout time that my previous commit broke 2007-06-11 13:35:33 +00:00
Daniel Stenberg
c8677e9d3f Properly wait for the c-ares resolve to complete, hopefully the cure for
bug #1733955
2007-06-11 13:32:49 +00:00
Daniel Stenberg
a32eaffa77 Daniel Black's clarfication about the NTLM support 2007-06-11 07:27:02 +00:00
Gisle Vanem
1dcb99f0f7 constify 'hostname' in init_thread_sync_data(). Simply clear
the whole 'tsd' structure on exit in destroy_thread_sync_data().
2007-06-11 04:33:21 +00:00
Gisle Vanem
03bc2d34da Squelsh some warnings for libssh older than 0.1.5. 2007-06-11 04:07:51 +00:00
Dan Fandrich
477e27f99d Fixed the test harness so that it actually kills the ssh being used as
the SOCKS server.
2007-06-08 18:56:05 +00:00
Dan Fandrich
6a84d492f1 Improved compatibility with perl 5.0 on the 'open' calls. 2007-06-08 17:32:24 +00:00
Dan Fandrich
873d95a34c Incorporated Daniel Black's test706 and test707 SOCKS test cases. 2007-06-08 17:21:40 +00:00
Dan Fandrich
1500e95839 Improved compatibility with perl 5.0 on the 'open' calls. 2007-06-08 17:03:50 +00:00
James Housley
4f8ebd1673 Curl_scp_done() needs to call libssh2_channel_free() to prevent a
memory leak, and it is the right thing to do.
2007-06-08 16:19:21 +00:00
James Housley
cd4e6fbcac Fix to work with the latest CVS version of libssh2
* As of (LIBSSH2_APINO >= 200706012030) there are not *nb() functions
* As of (LIBSSH2_APINO >= 200706012030) most libssh2_*() functions
  can return LIBSSH2_ERROR_EAGAIN to indicate that the call would block.

To make the code work as previously, blocking, all the code has been
updated so that when (LIBSSH2_APINO >= 200706012030) it loops simulating
blocking.  This allows the existing code to function and not hold up
the upcoming release.
2007-06-08 16:02:57 +00:00
Daniel Stenberg
2fd2ca9dac start working on 1.4.1 2007-06-08 09:01:33 +00:00
Daniel Stenberg
82d6240e7d 1.4.0 preps 2007-06-08 08:46:28 +00:00
Dan Fandrich
ad80490711 Changed the opens to work on older versions of perl.
Redirect ssh output to ssh.log
2007-06-07 22:42:26 +00:00
Dan Fandrich
38b490a310 Fixed a compiler warning on uClibc. 2007-06-07 22:24:53 +00:00
Daniel Stenberg
2ea052336f bug #1720605, There seems to be a problem when connecting to the Microsoft telnet server 2007-06-07 21:56:03 +00:00
Daniel Stenberg
3b9eefca89 Daniel S (6 June 2007)
- -s/--silent can now be used to toggle off the silence again if used a second
  time.

Daniel S (5 June 2007)
- Added Daniel Black's work that adds the first few SOCKS test cases. I also
  fixed two minor SOCKS problems to make the test cases run fine.
2007-06-07 21:47:29 +00:00
Dan Fandrich
073a6cea45 Renamed the sshd log file to sshd.log.
Added more options to the ssh config file to improve the consistency of
the test environment.
Force a rewrite of the ssh config files on every invocation.
Changed the opens to work on older versions of perl.
2007-06-07 21:42:33 +00:00
Dan Fandrich
345ffd1163 Cleaned up SOCKS tests. Use a magic port number instead of killserver
to do nonlistening server tests, like other tests.
2007-06-07 20:14:00 +00:00
Dan Fandrich
f0ffb35d55 Fixed some problems in starting SSH for use in SOCKS. 2007-06-07 19:49:09 +00:00
Daniel Stenberg
b4d2fbae6d make -s/--silent properly toggle as it is documented 2007-06-06 20:08:40 +00:00
Daniel Stenberg
42a2138d11 the revert 2007-06-05 13:53:10 +00:00
Daniel Stenberg
e86dfd9688 added 703: a socks5 version of 702 2007-06-05 13:52:34 +00:00
Daniel Stenberg
a466b31574 Daniel Black's test suite fixes and initial test cases for SOCKS4/5 using
openssh
2007-06-05 13:50:59 +00:00
Daniel Stenberg
48064f8dee if we read zero bytes from the proxy, the connection is broken and we need
to bail out
2007-06-05 13:42:23 +00:00
Daniel Stenberg
e71378d3c8 mark connect failures as non-connected when ConnectPlease() fails, like when
a connection through a socks proxy doesn't work
2007-06-05 13:41:50 +00:00
Daniel Stenberg
90d40aff72 Revered Ashish Sharma's multiple entries patch, as it caused memory madness 2007-06-04 21:33:02 +00:00
Daniel Stenberg
30808dca40 minor edit since getting an ID seems pointless when failure happens 2007-06-04 21:26:30 +00:00
Daniel Stenberg
8629620b1c fix the bad bad bad mess this caused on name resolves returning more than
one name... Reported by James Bursa
2007-06-04 21:04:14 +00:00
Daniel Stenberg
25d2a27c64 Brad Spencer found and fixed three flaws in the code, found with the new
gcc 4.2.0 warning: -Waddress
2007-06-02 20:09:23 +00:00
Daniel Stenberg
b084dc8760 Brad House fixed VS2005 compiler warnings due to time_t being 64bit.
He also made recent Microsoft compilers use _strdup() instead of strdup().
2007-06-02 19:48:29 +00:00
Daniel Stenberg
2ae9536d32 Ashish Sharma provided a patch for supporting multiple entries in the
/etc/hosts file. Patch edited for coding style and functionality by me
(Daniel).
2007-06-02 19:42:25 +00:00
Daniel Stenberg
f5713dbb2e ares_destroy_options() and ares_save_options() man pages by Brad House 2007-06-02 19:32:30 +00:00
Daniel Stenberg
b10ff9791b ouch, two conditionals were turned backwards! 2007-06-01 21:24:34 +00:00
Daniel Stenberg
86a25239ec do the update timer stuff even when CURLM_CALL_MULTI_PERFORM is returned 2007-06-01 21:01:57 +00:00
Daniel Stenberg
4c663ba9a8 When transferring 500 downloads in parallel with a c-ares enabled build only
to find that it crashed miserably, and this was due to some select()isms left
in the code. This was due to API restrictions in c-ares 1.3.x, but with the
upcoming c-ares 1.4.0 this is no longer the case so now libcurl runs much
better with c-ares and the multi interface with > 1024 file descriptors in
use.
2007-05-31 11:34:32 +00:00
Daniel Stenberg
713c9f8602 Feng Tu made (lib)curl support "upload" resuming work for file:// URLs. 2007-05-31 08:59:44 +00:00
Daniel Stenberg
14b9b823e6 make next version 1.4.0 2007-05-30 21:45:56 +00:00
Daniel Stenberg
6a674ded0e first take at detecting a random device and seeding the random key using data
from it in randomize_key()
2007-05-30 21:37:17 +00:00
Daniel Stenberg
2faba57c85 Shmulik Regev brought cryptographically secure transaction IDs 2007-05-30 21:11:10 +00:00
Daniel Stenberg
79d59ec97b Brad House added ares_save_options() and ares_destroy_options() that can be
used to keep options for later re-usal when ares_init_options() is used.
2007-05-30 20:49:14 +00:00
Daniel Stenberg
a49e78d9b7 Added CURLMOPT_MAXCONNECTS which is a curl_multi_setopt() option for setting
the maximum size of the connection cache maximum size of the multi handle.
2007-05-30 20:04:44 +00:00
Yang Tse
9583b51d80 In case of test failure, try not to show log files of other tests 2007-05-30 17:15:05 +00:00
Daniel Stenberg
670273968c added ares_process_fd() to allow applications to ask for processing on
specific sockets and thus avoiding select() and associated functions/macros.
This function will be used by upcoming libcurl releases for this very
reason. It also made me export the ares_socket_t type in the public ares.h
header file, since ares_process_fd() uses that type for two of the arguments.
2007-05-30 12:58:47 +00:00
Daniel Stenberg
b6820b2674 remove really annoying debug output that makes life miserable when you do
hundreds of parallel transfers...
2007-05-30 09:24:06 +00:00
Daniel Stenberg
b9a6dfab03 When working with a problem Stefan Becker had, I found an off-by-one buffer
overwrite in Curl_select(). While fixing it, I also improved its performance
somewhat by changing calloc to malloc and breaking out of a loop earlier
(when possible).
2007-05-26 22:09:08 +00:00
Daniel Stenberg
8bd7197a8f Primarily this fixes an off-by-one buffer overwrite (rare but still existing).
I also switched from calloc() to malloc() as a minor performance boost since
the rest of the code fills in the structs fine anyway - and they must for the
case when we use the stack-based auto variable array instead of the allocated
one.

I made the loop filling in poll_fds[] break when poll_nfds is reached as a
minor speed improvement.
2007-05-26 22:02:29 +00:00
Daniel Stenberg
ebb5e1db4b Clarify a bit about the fact that easy handles remain in the multi stack when
transfers are done and need to be removed and closed or re-added.
2007-05-26 20:50:00 +00:00
Daniel Stenberg
4702807da8 make it a WARNING since this hits people hard in their faces 2007-05-26 20:47:33 +00:00
Daniel Stenberg
fe1fe64fd4 Rob Crittenden fixed bug #1705802
(http://curl.haxx.se/bug/view.cgi?id=1705802), which was filed by Daniel
Black identifying several FTP-SSL test cases fail when we build libcurl with
NSS for TLS/SSL. Listed as #42 in KNOWN_BUGS.
2007-05-25 21:56:27 +00:00
Daniel Stenberg
9d904ee41b updated 2007-05-25 21:20:39 +00:00
Daniel Stenberg
fcc3e2ca34 Ravi Pratap fixed a flaw in the init_by_resolv_conf() function for windows
that could cause it to return a bad return code.
2007-05-25 21:11:28 +00:00
Daniel Stenberg
c25da51913 Song Ma filed bug report #1724016
(http://curl.haxx.se/bug/view.cgi?id=1724016) noticing that downloading
glob-ranges for TFTP was broken in CVS.
2007-05-24 21:11:18 +00:00
Daniel Stenberg
05ab8d291c stay within 80 cols 2007-05-24 21:11:00 +00:00
Daniel Stenberg
70b1900dd1 'mytx' in bug report #1723194 (http://curl.haxx.se/bug/view.cgi?id=1723194)
pointed out that the warnf() function in the curl tool didn't properly deal
with the cases when excessively long words were used in the string to chop
up.
2007-05-24 20:58:25 +00:00
Daniel Stenberg
380e132da3 TFTP transfers are also blocking 2007-05-23 12:59:12 +00:00
Daniel Stenberg
f2eb3c1f79 fix the formatting of the trailing list 2007-05-23 12:51:52 +00:00
Daniel Stenberg
96c093f27c Andre Guibert de Bruet fixed a memory leak when PKCS #12 parsing failed 2007-05-22 20:46:51 +00:00
Daniel Stenberg
a9d49769ff Andre Guibert de Bruet fixed a memory leak in the function that verifies the
peer's name in the SSL certificate when built for OpenSSL. The leak happens
for libcurls with CURL_DOES_CONVERSIONS enabled that fail to convert the CN
name from UTF8.
2007-05-22 19:51:44 +00:00
Daniel Stenberg
d7616d8a0a WaitForSingleObject() uses a millisecond timeout and CURL_TIMEOUT_RESOLVE is
counted in seconds...
2007-05-20 22:11:47 +00:00
Daniel Stenberg
826bbfc01c better fix for the dl/ul counters 2007-05-18 10:40:43 +00:00
Daniel Stenberg
250f9670b7 Feng Tu reported that curl -w did wrong on TFTP transfers in
bug report #1715394 (http://curl.haxx.se/bug/view.cgi?id=1715394), and the
transfer-related info "variables" were indeed overwritten with zeroes wrongly
and have now been adjusted. The upload size still isn't accurate.
2007-05-18 10:32:48 +00:00
Daniel Stenberg
ed4936fd30 bail out with error codes on failures 2007-05-18 10:12:57 +00:00
Daniel Stenberg
4dd2628093 they spell five with a v... 2007-05-17 21:41:02 +00:00
Daniel Stenberg
8479785620 Feng Tu pointed out a division by zero error in the TFTP connect timeout
code for timeouts less than fice seconds, and also provided a fix for it.
2007-05-17 21:40:08 +00:00
Dan Fandrich
0427e94465 Added support for compiling under Minix 3.1.3 using ACK. 2007-05-17 06:04:44 +00:00
Dan Fandrich
09fd3b4935 Match file times occurring in the morning. 2007-05-16 17:45:53 +00:00
Dan Fandrich
3fef839f75 Added call to setvbuf (disabled by default for speed) to flush the
memdebug log file after every line and avoid losing the last few log
entries if curl crashes.
2007-05-15 00:36:56 +00:00
Dan Fandrich
ea43bb013b Added support for quote commands before a transfer using SFTP and test
case 614.
Allow SFTP quote commands chmod, chown, chgrp to set a value of 0.
2007-05-15 00:28:50 +00:00
Dan Fandrich
b0a4c992e7 Added SFTP directory listing test case 613. 2007-05-14 22:03:42 +00:00
Dan Fandrich
85707460e5 Added FTPS upload tests 408 and 409. 2007-05-10 20:03:20 +00:00
Dan Fandrich
41ba7666f0 Kristian Gunstone fixed a problem where overwriting an uploaded file with
sftp didn't truncate it first, which would corrupt the file if the new
file was shorter than the old.
2007-05-09 18:24:27 +00:00
Dan Fandrich
4367e0513a Added the list of SFTP post-quote commands, and fixed a few typos. 2007-05-09 18:05:14 +00:00
Dan Fandrich
ed998270aa Added FTPS test cases 406 and 407 2007-05-08 22:14:30 +00:00
Daniel Stenberg
1b7f00b2a6 CURLE_FTP_COULDNT_STOR_FILE is now known as CURLE_UPLOAD_FAILED. This is
because I just made SCP uploads return this value if the file size of
the upload file isn't given with CURLOPT_INFILESIZE*. Docs updated to
reflect this news, and a define for the old name was added to the public
header file.
2007-05-08 11:34:31 +00:00
Daniel Stenberg
ad19f95f15 James Bursa fixed a bug in the multi handle code that made the connection
cache grow a bit too much, beyond the normal 4 * easy_handles.
2007-05-07 07:07:55 +00:00
Daniel Stenberg
bcfe3cb231 extended the description for the curl_multi_socket_action() change 2007-05-06 08:14:42 +00:00
Daniel Stenberg
805a5dcac8 42. Daniel Black filed bug report #1705802 where he accurately mentions that
several FTP-SSL test cases fail when we build libcurl with NSS for TLS/SSL:
  http://curl.haxx.se/bug/view.cgi?id=1705802
2007-05-03 20:50:07 +00:00
Dan Fandrich
0b67ee7bad Fixed a few typos. 2007-05-03 19:12:45 +00:00
Daniel Stenberg
9298037639 document the new 200alias behaviour 2007-05-03 12:30:33 +00:00
Daniel Stenberg
f7472075d7 Anders Gustafsson remarked that requiring CURLOPT_HTTP_VERSION set to 1.0
when CURLOPT_HTTP200ALIASES is used to avoid the problem mentioned below is
not very nice if the client wants to be able to use _either_ a HTTP 1.1
server or one within the aliases list... so starting now, libcurl will
simply consider 200-alias matches the to be HTTP 1.0 compliant.
2007-05-02 20:42:02 +00:00
Dan Fandrich
9f72db13c4 Fixed an out of memory handling issue with HTTP pipelines. 2007-05-02 19:13:56 +00:00
Daniel Stenberg
acc4868b78 Tobias Rundstrom reported a problem they experienced with xmms2 and recent
libcurls, which turned out to be the 25-nov-2006 change which treats HTTP
responses without Content-Length or chunked encoding as without bodies. We
now added the conditional that the above mentioned response is only without
body if the response is HTTP 1.1.
2007-05-02 17:35:47 +00:00
Daniel Stenberg
1afb67e31b - Jeff Pohlmeyer improved the hiperfifo.c example to use the
CURLMOPT_TIMERFUNCTION callback option.
2007-05-02 13:52:38 +00:00
Daniel Stenberg
2f0539d880 - Set the timeout for easy handles to expire really soon after addition or
when CURLM_CALL_MULTI_PERFORM is returned from curl_multi_socket*/perform,
  to make applications using only curl_multi_socket() to properly function
  when adding easy handles "on the fly". Bug report and test app provided by
  Michael Wallner.
2007-05-02 13:47:56 +00:00
Daniel Stenberg
6f7d0a7cbd Merged _all_ old changelogs into the single CHANGES.0 file. Having a new one
for every year is giving us too many files! I also split out the changes
from 2006 from CHANGES to CHANGES.0 now.
2007-05-02 13:14:56 +00:00
Daniel Stenberg
3d513f7ab1 spell and language fix 2007-05-02 11:14:55 +00:00
Dan Fandrich
6c8e6549d0 Check the return code from curl_multi_add_handle() 2007-05-02 06:02:13 +00:00
Dan Fandrich
eec105daba Fixed a logic error in the last patch and another out of memory issue.
Reduce the scope of some variables.
2007-05-02 00:50:06 +00:00
Dan Fandrich
19a80add95 Improved behaviour in out of memory conditions. 2007-05-01 20:52:05 +00:00
Dan Fandrich
93844f64ef Use memcpy instead of strcpy to improve performance. 2007-05-01 20:50:50 +00:00
Daniel Stenberg
60588b2455 brlcad on #curl provided this patch (edited by me) since "configure will fail
looking for a C++ preprocessor on libtool-using projects" with the factory-
installed libtool version on Mac OS X.
2007-04-30 21:47:58 +00:00
Dan Fandrich
5187faeeb9 Improved the test harness to allow running test servers on other than
the default port numbers, allowing more than one test suite to run
simultaneously on the same host.
2007-04-30 20:15:33 +00:00
Dan Fandrich
1228ec9fbb Fixed some tests to stop hard-coding the port number. 2007-04-30 19:05:48 +00:00
Dan Fandrich
717adfeb96 Rearranged some allocs so they will be freed correctly in the error path. 2007-04-29 07:04:29 +00:00
Daniel Stenberg
503557e5ce Peter O'Gorman fixed libcurl to not init GnuTLS as early as we did before,
since it then inits libgcrypt and libgcrypt is being evil and EXITS the
application if it fails to get a fine random seed. That's really not a nice
thing to do by a library.
2007-04-28 21:01:30 +00:00
Daniel Stenberg
f611f42dcf Frank Hempel fixed a curl_easy_duphandle() crash on a handle that had
been removed from a multi handle, and then fixed another flaw that prevented
curl_easy_duphandle() to work even after the first fix - the handle was
still marked as using the multi interface.
2007-04-28 20:27:07 +00:00
Daniel Stenberg
7a0e0c36c5 Move the explictit free of the range string to Curl_close() from Curl_disconnect()
since it easy-handle related and not connection-related.
2007-04-27 08:30:48 +00:00
Daniel Stenberg
61edee979f oops, this was supposed to be properly removed 2007-04-27 08:19:48 +00:00
Daniel Stenberg
7a343a3f60 As a follow-up to the removal of the free of the range data in Curl_done() - this
moves and re-arranges how range/resume is setup and freed.
2007-04-27 08:18:47 +00:00
Daniel Stenberg
b4d3c4a76c Peter O'Gorman found a problem with SCP downloads when the downloaded file
was 16385 bytes (16K+1) and it turned out we didn't properly always "suck
out" all data from libssh2. The effect being that libcurl would hang on the
socket waiting for data when libssh2 had in fact already read it all...
2007-04-26 21:30:29 +00:00
Dan Fandrich
f213d0db98 Added support in runtests.pl for "!n" test numbers to disable individual tests. 2007-04-25 23:18:52 +00:00
Dan Fandrich
6e835ef3aa Fixed an out of memory handling issue. 2007-04-25 20:54:02 +00:00
Daniel Stenberg
ed8cb57151 Sonia Subramanian brought our attention to a problem that happens if you set
the CURLOPT_RESUME_FROM or CURLOPT_RANGE options and an existing connection
in the connection cache is closed to make room for the new one when you call
curl_easy_perform(). It would then wrongly free range-related data in the
connection close funtion.
2007-04-25 20:20:15 +00:00
Dan Fandrich
9bdb05b4d6 When displaying log files, truncate the really longs ones such as you
would get from a torture test.
2007-04-25 20:09:32 +00:00
Yang Tse
94b253fde7 Steve Little's fixes to allow compilation on VMS 64-bit mode 2007-04-25 03:00:10 +00:00
Dan Fandrich
61d7e720a5 Treat log files and -k the same when running torture tests as when not. 2007-04-24 23:28:57 +00:00
Dan Fandrich
17507eac85 Clear out FTP server options before each new client.
Wait for child processes to die to avoid creating zombies.
2007-04-24 21:30:39 +00:00
Daniel Stenberg
bc1ae973da Robert Iakobashvili made the 'master_buffer' get allocated first once it is
can/will be used as it then makes the common cases save 16KB of data for each
easy handle that isn't used for pipelining.
2007-04-24 10:18:06 +00:00
Dan Fandrich
6a35841b2e Added tests 610-612 to test more SFTP post-quote commands. 2007-04-23 23:00:38 +00:00
Dan Fandrich
28dde78dde Added <postcheck> support to the test harness. 2007-04-23 22:58:45 +00:00
Dan Fandrich
37171809f6 Mention NSS, <postcmd> commands 2007-04-23 21:18:30 +00:00
Dan Fandrich
3398eca7c3 Changed another nonexistent host name to be under the haxx.se domain
to guarantee against it ever being valid.
2007-04-23 01:51:02 +00:00
Yang Tse
3616912d22 Avoid an unnecessary call to gettimeofday() when
using custom timeout values.
2007-04-22 18:17:46 +00:00
Daniel Stenberg
0abccc676d --without-ssl disables OpenSSL only 2007-04-22 09:37:05 +00:00
Daniel Stenberg
a93af43974 - Song Ma's warning if -r/--range is given with a "bad" range, also noted in
the man page now.
2007-04-22 09:31:27 +00:00
Daniel Stenberg
0bbc759c0c configure fix and new mirror 2007-04-22 08:51:11 +00:00
Daniel Stenberg
56a5c49ac0 clarify a bit on the follow-redirect logic and when curl switches from POST
to GET on redirect
2007-04-22 08:05:40 +00:00
Daniel Stenberg
02267eba4c shell script assigns should not have spaces, hopefully fixes bug #1705177 2007-04-22 07:36:12 +00:00
Daniel Stenberg
cea9695bcf Daniel Black filed bug #1704675 (http://curl.haxx.se/bug/view.cgi?id=1704675)
identifying a double-free problem in the SSL-dealing layer, telling GnuTLS to
free NULL credentials on closedown after a failure and a bad #ifdef for NSS
when closing down SSL.
2007-04-21 21:32:31 +00:00
Daniel Stenberg
92039629c7 Curl_ssl_close(): mark the connection as not using SSL anymore, to better
survive getting called twice
2007-04-21 21:24:53 +00:00
Gunter Knauf
c8d3327e92 fixed ARFLAGS for CodeWarrior build. 2007-04-21 15:32:35 +00:00
Dan Fandrich
043070f90e Changed an error message slightly so it can be caught easier by the
autobuild logs scanner.
2007-04-20 17:16:32 +00:00
Daniel Stenberg
36626c4b6e ifndef check the CURL_MAX_WRITE_SIZE define to allow this value to easier be
changed at build time (from command line or similar)
2007-04-20 07:19:36 +00:00
Yang Tse
7f33aae067 initialize pending_ms to zero to avoid compiler warning:
'pending_ms' may be used uninitialized in this function
2007-04-20 01:58:15 +00:00
Yang Tse
61022f3817 - Save one call to curlx_tvnow(), which calls gettimeofday(), in each of
Curl_socket_ready(), Curl_poll() and Curl_select() when these are called
  with a zero timeout or a timeout value indicating a blocking call should
  be performed.

  These unnecessary calls to gettimeofday() got introduced in 7.16.2 when
  fixing 'timeout would restart when signal caught while awaiting socket
  events' on 20 March 2007.

- Move some loop breaking logic from the while clause into the loop,
  avoiding compiler warning 'assignment within conditional expression'
2007-04-20 00:07:19 +00:00
Daniel Stenberg
bf648fcfc3 keep lines < 80 columns 2007-04-19 20:20:48 +00:00
Yang Tse
b0e909329e fix comment and line spacing 2007-04-19 20:16:28 +00:00
Dan Fandrich
ae3d5949b8 Various test file cleanups, including using <servercmd> instead of writing
directly to ftpserver.cmd and removing unneeded empty sections.
2007-04-18 20:22:01 +00:00
Daniel Stenberg
c234b9d04b clarify the comment about libssh2_sftp_write's return type 2007-04-18 20:15:22 +00:00
Daniel Stenberg
7a86740afd - James Housley made SFTP uploads use libssh2's non-blocking API (if available) 2007-04-18 20:11:47 +00:00
Daniel Stenberg
8e719e3ef5 - Prevent the internal progress meter from updating more frequently than once
per second.
2007-04-18 20:02:41 +00:00
Dan Fandrich
66fc5498d2 Added test cases 296, 297 and 298 to test --ftp-method handling 2007-04-18 06:30:28 +00:00
Gunter Knauf
f30ae93a1f added ranlib when library is created with ar. 2007-04-16 20:54:56 +00:00
Gisle Vanem
365e8eb78e No need for USE_MANUAL. Use select_s() instead of select().
Added ares_getopt.o to program sample objects.
2007-04-16 16:52:56 +00:00
Daniel Stenberg
76627b322e - Robert Iakobashvil added curl_multi_socket_action() to libcurl, which is a
function that deprecates the curl_multi_socket() function. Using the new
  function the application tell libcurl what action that was found in the
  socket that it passes in. This gives a significant performance boost as it
  allows libcurl to avoid a call to poll()/select() for every call to
  curl_multi_socket*().
2007-04-16 16:34:08 +00:00
Yang Tse
827228bd69 move linkage var declarations to ares_getopt.h 2007-04-16 15:35:34 +00:00
Gunter Knauf
69c5506b69 use Makefile.inc to determine sources. 2007-04-16 13:53:58 +00:00
Gunter Knauf
3a2e623fc8 ares_getopt() command-line parser function does not belong to actual c-ares library. It is just a convinience source code helper function for use in example programs adig.c and ahost.c 2007-04-16 13:17:26 +00:00
Daniel Stenberg
8aa9f01ed8 Jay Austin added "DH PARAMETERS" to the stunnel.pem certificate 2007-04-16 11:55:43 +00:00
Yang Tse
b0b6a853f6 ares_getopt() command-line parser function does not belong to actual
c-ares library. It is just a convinience source code helper function
for use in example programs adig.c and ahost.c
2007-04-16 09:08:15 +00:00
Yang Tse
0563a7a923 ares_getopt() command-line parser function does not belong to actual
c-ares library. It is just a convinience source code helper function
for use in example programs adig.c and ahost.c
2007-04-16 09:01:16 +00:00
Dan Fandrich
945ba7cb7e Minor updates to --help output 2007-04-15 06:24:43 +00:00
Daniel Stenberg
e3dab1bea2 jayjwa added the "DH PARAMETERS" to make this work with recent stunnels 2007-04-14 20:29:09 +00:00
Daniel Stenberg
9c369c695d updates 2007-04-14 20:27:11 +00:00
Gunter Knauf
011ccbc31a removed unneeded brackets with NetWare implementation. 2007-04-14 16:55:17 +00:00
Gunter Knauf
f1596698ae ups - c&p error. 2007-04-14 16:45:43 +00:00
Gunter Knauf
c60b52ab43 use system-own getpassword() function on NetWare. 2007-04-14 16:38:13 +00:00
Dan Fandrich
71a0d50f48 Added test cases 294 and 295 to test --ftp-account handling 2007-04-13 20:59:15 +00:00
Yang Tse
8d2a0fe85b Fix test case 534 which started to fail 2007-04-13 due to the existance
of a new host on the net with the same silly domain the test was using
for a host which was supposed not to exist.
2007-04-13 11:35:19 +00:00
Yang Tse
b039d883e5 proper fix for compiler warning 2007-04-13 08:45:07 +00:00
Yang Tse
b3401ddbad Take in account that it can be built with compiler debug info and
without the curl memory debugging leak detection code enabled.
2007-04-13 08:22:56 +00:00
Yang Tse
038fe54e21 fix compiler warning 2007-04-13 07:57:31 +00:00
Daniel Stenberg
4b5a65455e update! 2007-04-12 21:53:18 +00:00
Daniel Stenberg
2566a5d4da add a 'vc8' target that (re-)builds the */Makefile.vc8 files 2007-04-12 20:41:24 +00:00
Daniel Stenberg
c38c339480 Song Ma found a memory leak in the if2ip code if you pass in an interface
name longer than the name field of the ifreq struct (typically 6 bytes), as
then it wouldn't close the used dummy socket.
2007-04-12 20:09:19 +00:00
Yang Tse
ea74b4b8e1 update MSVC project files with ares_getopt() 2007-04-12 19:14:00 +00:00
Yang Tse
2364066be0 use ares_getopt for all platforms 2007-04-12 19:01:19 +00:00
Yang Tse
b36376e12d add ares_getopt prototype 2007-04-12 18:59:46 +00:00
Yang Tse
8aae15b630 Rename function as ares_getopt() 2007-04-12 18:06:41 +00:00
Yang Tse
88bf2a2dc7 Replace tabs with spaces 2007-04-12 17:45:57 +00:00
Yang Tse
45847c5324 Add file ares_getopt.c
Original file name getopt.c  Initial import into the c-ares source tree
on 2007-04-11.  Lifted from version 5.2 of the 'Open Mash' project with
the modified BSD license, BSD license without the advertising clause.
2007-04-12 16:53:59 +00:00
Dan Fandrich
70cce4cddd Work around an out of memory situation in Curl_ftp_done instead of
returning an error code, to allow connections to be torn down
cleanly since this function can be called AFTER an OOM situation
has already been reached.
2007-04-12 01:26:02 +00:00
Daniel Stenberg
42c0ac2008 start working on 7.16.3 2007-04-11 13:32:59 +00:00
Daniel Stenberg
70ddabbfb0 restart towards 7.16.3 2007-04-11 13:31:51 +00:00
Daniel Stenberg
e3716938bd add recent contributors 2007-04-11 13:30:09 +00:00
214 changed files with 17194 additions and 12999 deletions

1409
CHANGES

File diff suppressed because it is too large Load Diff

11527
CHANGES.0

File diff suppressed because it is too large Load Diff

View File

@@ -1,835 +0,0 @@
Daniel (28 December 1999):
- Tim Verhoeven correctly identified that curl
doesn't support URL formatted file names when getting ftp. Now, there's a
problem with getting very weird file names off FTP servers. RFC 959 defines
that the file name syntax to use should be the same as in the native OS of
the server. Since we don't know the peer server system we currently just
translate the URL syntax into plain letters. It is still better and with
the solaris 2.6-supplied ftp server it works with spaces in the file names.
Daniel (27 December 1999):
- When curl parsed cookies straight off a remote site, it corrupted the input
data, which, if the downloaded headers were stored made very odd characters
in the saved data. Correctly identified and reported by Paul Harrington.
Daniel (13 December 1999):
- General cleanups in the library interface. There had been some bad kludges
added during times of stress and I did my best to clean them off. It was
both regarding the lib API as well as include file confusions.
Daniel (3 December 1999):
- A small --stderr bug was reported by Eetu Ojanen...
- who also brought the suggestion of extending the -X flag to ftp list as
well. So, now it is and the long option is now --request instead. It is
only for ftp list for now (and the former http stuff too of course).
Lars J. Aas (24 November 1999):
- Patched curl to compile and build under BeOS. Doesn't work yet though!
- Corrected the Makefile.am files to allow putting object files in
different directories than the sources.
Version 6.3.1
Daniel (23 November 1999):
- I've had this major disk crash. My good old trust-worthy source disk died
along with the machine that hosted it. Thank goodness most of all the
things I've done are either backed up elsewhere or stored in this CVS
server!
- Michael S. Steuer pointed out a bug in the -F handling
that made curl hang if you posted an empty variable such as '-F name='. It
was one of those old bugs that never have worked properly...
- Jason Baietto pointed out a general flaw in the HTTP
download. Curl didn't complain if it was prematurely aborted before the
entire download was completed. It does now.
Daniel (19 November 1999):
- Chris Maltby very accurately criticized the lack of
return code checks on the fwrite() calls. I did a thorough check for all
occurrences and corrected this.
Daniel (17 November 1999):
- Paul Harrington pointed out that the -m/--max-time option
doesn't work for the slow system calls like gethostbyname()... I don't have
any good fix yet, just a slightly less bad one that makes curl exit hard
when the timeout is reached.
- Bjorn Reese helped me point out a possible problem that might be the reason
why Thomas Hurst experience problems in his Amiga version.
Daniel (12 November 1999):
- I found a crash in the new cookie file parser. It crashed when you gave
a plain http header file as input...
Version 6.3
Daniel (10 November 1999):
- I kind of found out that the HTTP time-conditional GETs (-z) aren't always
respected by the web server and the document is therefore sent in whole
again, even though it doesn't match the requested condition. After reading
section 13.3.4 of RFC 2616, I think I'm doing the right thing now when I do
my own check as well. If curl thinks the condition isn't met, the transfer
is aborted prematurely (after all the headers have been received).
- After comments from Robert Linden I also rewrote some parts of the man page
to better describe how the -F works.
- Michael Anti put up a new curl download mirror in
China: http://www.pshowing.com/curl/
- I added the list of download mirrors to the README file
- I did add more explanations to the man page
Daniel (8 November 1999):
- I made the -b/--cookie option capable of reading netscape formatted cookie
files as well as normal http-header files. It should be able to
transparently figure out what kind of file it got as input.
Daniel (29 October 1999):
- Another one of Sebastiaan van Erk's ideas (that has been requested before
but I seem to have forgotten who it was), is to add support for ranges in
FTP downloads. As usual, one request is just a request, when they're two
it is a demand. I've added simple support for X-Y style fetches. X has to
be the lower number, though you may omit one of the numbers. Use the -r/
--range switch (previously HTTP-only).
- Sebastiaan van Erk suggested that curl should be
able to show the file size of a specified file. I think this is a splendid
idea and the -I flag is now working for FTP. It displays the file size in
this manner:
Content-Length: XXXX
As it resembles normal headers, and leaves us the opportunity to add more
info in that display if we can come up with more in the future! It also
makes sense since if you access ftp through a HTTP proxy, you'd get the
file size the same way.
I changed the order of the QUOTE command executions. They're now executed
just after the login and before any other command. I made this to enable
quote commands to run before the -I stuff is done too.
- I found out that -D/--dump-header and -V/--version weren't documented in
the man page.
- Many HTTP/1.1 servers do not support ranges. Don't ask me why. I did add
some text about this in the man page for the range option. The thread in
the mailing list that started this was initiated by Michael Anti.
- I get reports about nroff crashes on solaris 2.6+ when displaying the curl
man page. Switch to gnroff instead, it is reported to work(!). Adam Barclay
reported and brought the suggestion.
- In a dialogue with Johannes G. Kristinsson we came
up with the idea to let -H/--header specified headers replace the
internally generated headers, if you happened to select to add a header
that curl normally uses by itself. The advantage with this is not entirely
obvious, but in Johannes' case it means that he can use another Host: than
the one curl would set.
Daniel (27 October 1999):
- Jongki Suwandi brought a nice patch for (yet another) crash when following
a location:. This time you had to follow a https:// server's redirect to
get the core.
Version 6.2
Daniel (21 October 1999):
- I think I managed to remove the suspicious (nil) that has been seen just
before the "Host:" in HTTP requests when -v was used.
- I found out that if you followed a location: when using a proxy, without
having specified http:// in the URL, the protocol part was added once again
when moving to the next URL! (The protocol part has to be added to the
URL when going through a proxy since it has no protocol-guessing system
such as curl has.)
- Benjamin Ritcey reported a core dump under solaris 2.6
with OpenSSL 0.9.4. It turned out this was due to a bad free() in main.c
that occurred after the download was done and completed.
- Benjamin found ftp downloads to show the first line of the download meter
to get written twice, and I removed that problem. It was introduced with
the multiple URL support.
- Dan Zitter correctly pointed out that curl 6.1 and earlier versions didn't
honor RFC 2616 chapter 4 section 2, "Message Headers": "...Field names are
case-insensitive..." HTTP header parsing assumed a certain casing. Dan
also provided me with a patch that corrected this, which I took the liberty
of editing slightly.
- Dan Zitter also provided a nice patch for config.guess to better recognize
the Mac OS X
- Dan also corrected a minor problem in the lib/Makefile that caused linking
to fail on OS X.
Daniel (19 October 1999):
- Len Marinaccio came up with some problems with curl. Since Windows has a
crippled shell, it can't redirect stderr and that causes trouble. I added
--stderr today which allows the user to redirect the stderr stream to a
file or stdout.
Daniel (18 October 1999):
- The configure script now understands the '--without-ssl' flag, which now
totally disable SSL/https support. Previously it wasn't possible to force
the configure script to leave SSL alone. The previous functionality has
been retained. Troy Engel helped test this new one.
Version 6.1
Daniel (17 October 1999):
- I ifdef'ed or commented all the zlib stuff in the sources and configure
script. It turned out we needed to mock more with zlib than I initially
thought, to make it capable of downloading compressed HTTP documents and
uncompress them on the fly. I didn't mean the zlib parts of curl to become
more than minor so this means I halt the zlib expedition for now and wait
until someone either writes the code or zlib gets updated and better
adjusted for this kind of usage. I won't get into details here, but a
short a summary is suitable:
- zlib can't automatically detect whether to use zlib or gzip
decompression methods.
- zlib is very neat for reading gzipped files from a file descriptor,
although not as nice for reading buffer-based data such as we would
want it.
- there are still some problems with the win32 version when reading from
a file descriptor if that is a socket
Daniel (14 October 1999):
- Moved the (external) include files for libcurl into a subdirectory named
curl and adjusted all #include lines to use <curl/XXXX> to maintain a
better name space and control of the headers. This has been requested.
Daniel (12 October 1999):
- I modified the 'maketgz' script to perform a 'make' too before a release
archive is put together in an attempt to make the time stamps better and
hopefully avoid the double configure-running that use to occur.
Daniel (11 October 1999):
- Applied J<>rn's patches that fixes zlib for mingw32 compiles as well as
some other missing zlib #ifdef and more text on the multiple URL docs in
the man page.
Version 6.1beta
Daniel (6 October 1999):
- Douglas E. Wegscheid sent me a patch that made the exact same thing as I
just made: the -d switch is now capable of reading post data from a named
file or stdin. Use it similarly to the -F. To read the post data from a
given file:
curl -d @path/to/filename www.postsite.com
or let curl read it out from stdin:
curl -d @- www.postit.com
J<>rn Hartroth (3 October 1999):
- Brought some more patches for multiple URL functionality. The MIME
separation ideas are almost scrapped now, and a custom separator is being
used instead. This is still compile-time "flagged".
Daniel
- Updated curl.1 with multiple URL info.
Daniel (30 September 1999):
- Felix von Leitner brought openssl-check fixes for configure.in to work
out-of-the-box when the openssl files are installed in the system default
dirs.
Daniel (28 September 1999)
- Added libz functionality. This should enable decompressing gzip, compress
or deflate encoding HTTP documents. It also makes curl send an accept that
it accepts that kind of encoding. Compressed contents usually shortens
download time. I *need* someone to tell me a site that uses compressed HTTP
documents so that I can test this out properly.
- As a result of the adding of zlib awareness, I changed the version string
a little. I plan to add openldap version reporting in there too.
Daniel (17 September 1999)
- Made the -F option allow stdin when specifying files. By using '-' instead
of file name, the data will be read from stdin.
Version 6.0
Daniel (13 September 1999)
- Added -X/--http-request <request> to enable any HTTP command to be sent.
Do not that your server has to support the exact string you enter. This
should possibly a string like DELETE or TRACE.
- Applied Douglas' mingw32-fixes for the makefiles.
Daniel (10 September 1999)
- Douglas E. Wegscheid pointed out a problem. Curl didn't check the FTP
servers return code properly after the --quote commands were issued. It
took anything non 200 as an error, when all 2XX codes should be accepted as
OK.
- Sending cookies to the same site in multiple lines like curl used to do
turned out to be bad and breaking the cookie specs. Curl now sends all
cookies on a single Cookie: line. Curl is not yet RFC 2109 compliant, but I
doubt that many servers do use that syntax (yet).
Daniel (8 September 1999)
- J<>rn helped me make sure it still compiles nicely with mingw32 under win32.
Daniel (7 September 1999)
- FTP upload through proxy is now turned into a HTTP PUT. Requested by
Stefan Kanthak.
- Added the ldap files to the .m32 makefile.
Daniel (3 September 1999)
- Made cookie matching work while using HTTP proxy.
Bjorn Reese (31 August 1999)
- Passed his ldap:// patch. Note that this requires the openldap shared
library to be installed and that LD_LIBRARY_PATH points to the
directory where the lib will be found when curl is run with a
ldap:// URL.
J<>rn Hartroth (31 August 1999)
- Made the Mingw32 makefiles into single files.
- Made file:// work for Win32. The same code is now used for unix as well for
performance reasons.
Douglas E. Wegscheid (30 August 1999)
- Patched the Mingw32 makefiles for SSL builds.
Matthew Clarke (30 August 1999)
- Made a cool patch for configure.in to allow --with-ssl to specify the
root dir of the openssl installation, as in
./configure --with-ssl=/usr/ssl_here
- Corrected the 'reconf' script to work better with some shells.
J<>rn Hartroth (26 August 1999)
- Fixed the Mingw32 makefiles in lib/ and corrected the file.c for win32
compiles.
Version 5.11
Daniel (25 August 1999)
- John Weismiller pointed out a bug in the header-line
realloc() system in download.c.
- I added lib/file.[ch] to offer a first, simple, file:// support. It
probably won't do much good on win32 system at this point, but I see it
as a start.
- Made the release archives get a Makefile in the root dir, which can be
used to start the compiling/building process easier. I haven't really
changed any INSTALL text yet, I wanted to get some feed-back on this
first.
Daniel (17 August 1999)
- Another Location: bug. Curl didn't do proper relative locations if the
original URL had cgi-parameters that contained a slash. Nusu's page
again.
- Corrected the NO_PROXY usage. It is a list of substrings that if one of
them matches the tail of the host name it should connect to, curl should
not use a proxy to connect there. Pointed out to me by Douglas
E. Wegscheid. I also changed the README text a little regarding this.
Daniel (16 August 1999)
- Fixed a memory bug with http-servers that sent Location: to a Location:
page. Nusu's page showed this too.
- Made cookies work a lot better. Setting the same cookie name several times
used to add more cookies instead of replacing the former one which it
should've. Nusu <nus at intergorj.ro> brought me an URL that made this
painfully visible...
Troy (15 August 1999)
- Brought new .spec files as well as a patch for configure.in that lets the
configure script find the openssl files better, even when the include
files are in /usr/include/openssl
Version 5.10
Daniel (13 August 1999)
- SSL_CTX_set_default_passwd_cb() has been modified in the 0.9.4 version of
OpenSSL. Now why couldn't they simply add a *new* function instead of
modifying the parameters of an already existing function? This way, we get
a compiler warning if compiling with 0.9.4 but not with earlier. So, I had
to come up with a #if construction that deals with this...
- Made curl output the SSL version number get displayed properly with 0.9.4.
Troy (12 August 1999)
- Added MingW32 (GCC-2.95) support under Win32. The INSTALL file was also
a bit rearranged.
Daniel (12 August 1999)
- I had to copy a good <arpa/telnet.h> include file into the curl source
tree to enable the silly win32 systems to compile. The distribution rights
allows us to do that as long as the file remains unmodified.
- I corrected a few minor things that made the compiler complain when
-Wall -pedantic was used.
- I'm moving the official curl web page to http://curl.haxx.nu. I think it
will make it easier to remember as it is a lot shorter and less cryptic.
The old one still works and shows the same info.
Daniel (11 August 1999)
- Albert Chin-A-Young mailed me another correction for NROFF in the
configure.in that is supposed to be better for IRIX users.
Daniel (10 August 1999)
- Albert Chin-A-Young helped me with some stupid Makefile things, as well as
some fiddling with the getdate.c stuff that he had problems with under
HP-UX v10. getdate.y will now be compiled into getdate.c if the appropriate
yacc or bison is found by the configure script. Since this is slightly new,
we need to test the output getdate.c with win32 systems to make sure it
still compiles there.
Daniel (5 August 1999)
- I've just setup a new mailing list with the intention to keep discussions
around libcurl development in it. I mainly expect it to be for thoughts and
brainstorming around a "next generation" library, rather than nitpicking
about the current implementation or details in the current libcurl.
To join our happy bunch of future-looking geeks, enter 'subscribe
<address>' in the body of a mail and send it to
libcurl-request@listserv.fts.frontec.se. Curl bug reports, the usual curl
talk and everything else should still be kept in this mailing list. I've
started to archive this mailing list and have put the libcurl web page at
www.fts.frontec.se/~dast/libcurl/.
- Stefan Kanthak contacted me regarding a few problems in the configure
script which he discovered when trying to make curl compile and build under
Siemens SINIX-Z V5.42B2004!
- Marcus Klein very accurately informed me that src/version.h was not present
in the CVS repository. Oh, how silly...
- Linus Nielsen rewrote the telnet:// part and now curl offers limited telnet
support. If you run curl like 'curl telnet://host' you'll get all output on
the screen and curl will read input from stdin. You'll be able to login and
run commands etc, but since the output is buffered, expect to get a little
weird output.
This is still in its infancy and it might get changed. We need your
feed-back and input in how this is best done.
WIN32 NOTE: I bet we'll get problems when trying to compile the current
lib/telnet.c on win32, but I think we can sort them out in time.
- David Sanderson reported that FORCE_ALLOCA_H or HAVE_ALLOCA_H must be
defined for getdate.c to compile properly on HP-UX 11.0. I updated the
configure script to check for alloca.h which should make it.
Daniel (4 August 1999)
- I finally got to understand Marcus Klein's ftp download resume problem,
which turns out to be due to different outputs from different ftp
servers. It makes ftp download resuming a little trickier, but I've made
some modifications I really believe will work for most ftp servers and I do
hope you report if you have problems with this!
- Added text about file transfer resuming to README.curl.
Daniel (2 August 1999)
- Applied a progress-bar patch from Lars J. Aas. It offers
a new styled progress bar enabled with -#/--progress-bar.
T. Yamada <tai at imasy.or.jp> (30 July 1999)
- It breaks with segfault when 1) curl is using .netrc to obtain
username/password (option '-n'), and 2) is automatically redirected to
another location (option '-L').
There is a small bug in lib/url.c (block starting from line 641), which
tries to take out username/password from user- supplied command-line
argument ('-u' option). This block is never executed on first attempt since
CONF_USERPWD bit isn't set at first, but curl later turns it on when it
checks for CONF_NETRC bit. So when curl tries to redo everything due to
redirection, it segfaults trying to access *data->userpwd.
Version 5.9.1
Daniel (30 July 1999)
- Steve Walch pointed out that there is a memory leak in the formdata
functions. I added a FormFree() function that is now used and supposed to
correct this flaw.
- Mark Wotton reported:
'curl -L https://www.cwa.com.au/' core dumps. I managed to cure this by
correcting the cleanup procedure. The bug seems to be gone with my OpenSSL
0.9.2b, although still occurs when I run the ~100 years old SSLeay 0.8.0. I
don't know whether it is curl or SSLeay that is to blame for that.
- Marcus Klein:
Reported an FTP upload resume bug that I really can't repeat nor understand.
I leave it here so that it won't be forgotten.
Daniel (29 July 1999)
- Costya Shulyupin suggested support for longer URLs when following Location:
and I could only agree and fix it!
- Leigh Purdie found a problem in the upload/POST department. It turned out
that http.c accidentaly cleared the pointer instead of the byte counter
when supposed to.
- Costya Shulyupin pointed out a problem with port numbers and Location:. If
you had a server at a non-standard port that redirected to an URL using a
standard port number, curl still used that first port number.
- Ralph Beckmann pointed out a problem when using both CONF_FOLLOWLOCATION
and CONF_FAILONERROR simultaneously. Since the CONF_FAILONERROR exits on
the 302-code that the follow location header outputs it will never show any
html on location: pages. I have now made it look for >=400 codes if
CONF_FOLLOWLOCATION is set.
- 'struct slist' is now renamed to 'struct curl_slist' (as suggested by Ralph
Beckmann).
- Joshua Swink and Rick Welykochy were the first to point out to me that the
latest OpenSSL package now have moved the standard include path. It is now
in /usr/local/ssl/include/openssl and I have now modified the --enable-ssl
option for the configure script to use that as the primary path, and I
leave the former path too to work with older packages of OpenSSL too.
Daniel (9 June 1999)
- I finally understood the IRIX problem and now it seem to compile on it!
I am gonna remove those #define strcasecmp() things once and for all now.
Daniel (4 June 1999)
- I adjusted the FTP reply 227 parser to make the PASV command work better
with more ftp servers. Appearantly the Roxen Challanger server replied
something curl 5.9 could deal with! :-( Reported by Ashley Reid-Montanaro
and Mark Butler brought a solution for it.
Daniel (26 May 1999)
- Rearranged. README is new, the old one is now README.curl and I added a
README.libcurl with text I got from Ralph Beckmann.
- I also updated the INSTALL text.
Daniel (25 May 1999)
- David Jonathan Lowsky correctly pointed out that curl didn't properly deal
with form posting where the variable shouldn't have any content, as in curl
-F "form=" www.site.com. It was now fixed.
Version 5.9
Daniel (22 May 1999)
- I've got a bug report from Aaron Scarisbrick in which he states he has some
problems with -L under FreeBSD 3.0. I have previously got another bug
report from Stefan Grether which points at an error with similar sympthoms
when using win32. I made the allocation of the new url string a bit faster
and different, don't know if it actually improves anything though...
Daniel (20 May 1999)
- Made the cookie parser deal with CRLF newlines too.
Daniel (19 May 1999)
- Download() didn't properly deal with failing return codes from the sread()
function. Adam Coyne found the problem in the win32 version, and Troy Engel
helped me out isolating it.
Daniel (16 May 1999)
- Richard Adams pointed out a bug I introduced in 5.8. --dump-header doesn't
work anymore! :-/ I fixed it now.
- After a suggestion by Joshua Swink I added -S / --show-error to force curl
to display the error message in case of an error, even if -s/--silent was
used.
Daniel (10 May 1999)
- I moved the stuff concerning HTTP, DICT and TELNET it their own source
files now. It is a beginning on my clean-up of the sources to make them
layer all those protocols better to enable more to be added easier in the
future!
- Leon Breedt sent me some files I've not put into the main curl
archive. They're for creating the Debian package thingie. He also sent me a
debian package that I've made available for download at the web page
Daniel (9 May 1999)
- Made it compile on cygwin too.
Troy Engel (7 May 1999)
- Brought a series of patches to allow curl to compile smoothly on MSVC++ 6
again!
Daniel (6 May 1999)
- I changed the #ifdef HAVE_STRFTIME placement for the -z code so that it
will be easier to discover systems that don't have that function and thus
can't use -z successfully. Made the strftime() get used if WIN32 is defined
too.
Version 5.8
Daniel (5 May 1999)
- I've had it with this autoconf/automake mess. It seems to work allright
for most people who don't have automake installed, but for those who have
there are problems all over.
I've got like five different bug reports on this only the last
week... Claudio Neves and Federico Bianchi and root <duggerj001 at
hawaii.rr.com> are some of them reporting this.
Currently, I have no really good fix since I want to use automake myself to
generate the Makefile.in files. I've found out that the @SHELL@-problems
can often be fixed by manually invoking 'automake' in the archive root
before you run ./configure... I've hacked my maketgz script now to fiddle
a bit with this and my tests seem to work better than before at least!
Daniel (4 May 1999)
- mkhelp.pl has been doing badly lately. I corrected a case problem in
the regexes.
- I've now remade the -o option to not touch the file unless it needs to.
I had to do this to make -z option really fine, since now you can make a
curl fetch and use a local copy's time when downloading to that file, as
in:
curl -z dump -o dump remote.site.com/file.html
This will only get the file if the remote one is newer than the local.
I'm aware that this alters previous behaviour a little. Some scripts out
there may depend on that the file is always touched...
- Corrected a bug in the SSLv2/v3 selection.
- Felix von Leitner requested that curl should be able to send
"If-Modified-Since" headers, which indeed is a fair idea. I implemented it
right away! Try -z <expression> where expression is a full GNU date
expression or a file name to get the date from!
Stephan Lagerholm (30 Apr 1999)
- Pointed out a problem with the src/Makefile for FreeBSD. The RM variable
isn't set and causes the make to fail.
Daniel (26 April 1999)
- Am I silly or what? Irving Wolfe pointed out to me that the curl version
number was not set properly. Hasn't been since 5.6. This was due to a bug
in my maketgz script!
David Eriksson (25 Apr 1999)
- Found a bug in cookies.c that made it crash at times.
Version 5.7.1
Doug Kaufman (23 Apr 1999)
- Brought two sunos 4 fixes. One of them being the hostip.c fix mentioned
below and the other one a correction in include/stdcheaders.h
- Added a paragraph about compiling with the US-version of openssl to the
INSTALL file.
Daniel
- New mailing list address. Info updated on the web page as well as in the
README file
Greg Onufer (20 Apr 1999)
- hostip.c didn't compile properly on SunOS 5.5.1.
It needs an #include <sys/types.h>
Version 5.7
Daniel (Apr 20 1999)
- Decided to upload a non-beta version right now!
- Made curl support any-length HTTP headers. The destination buffer is now
simply enlarged every time it turns out to be too small!
- Added the FAQ file to the archive. Still a bit smallish, but it is a
start.
Eric Thelin (15 Apr 1999)
- Made -D accept '-' instead of filename to write to stdout.
Version 5.6.3beta
Daniel (Apr 12 1999)
- Changed two #ifdef WIN32 to better #ifdef <errorcode> when connect()ing
in url.c and ftp.c. Makes cygwin32 deal with them better too. We should
try to get some decent win32-replacement there. Anyone?
- The old -3/--crlf option is now ONLY --crlf!
- I changed the "SSL fix" to a more lame one, but that doesn't remove as
much functionality. Now I've enabled the lib to select what SSL version it
should try first. Appearantly some older SSL-servers don't like when you
talk v3 with them so you need to be able to force curl to talk v2 from the
start. The fix dated April 6 and posted on the mailing list forced curl to
use v2 at all times using a modern OpenSSL version, but we don't really
want such a crippled solution.
- Marc Boucher sent me a patch that corrected a math error for the
"Curr.Speed" progress meter.
- Eric Thelin sent me a patch that enables '-K -' to read a config file from
stdin.
- I found out we didn't close the file properly before so I added it!
Daniel (Apr 9 1999)
- Yu Xin pointed out a problem with ftp download resume. It didn't work at
all! ;-O
Daniel (Apr 6 1999)
- Corrected the version string part generated for the SSL version.
- I found a way to make some other SSL page work with openssl 0.9.1+ that
previously didn't (ssleay 0.8.0 works with it though!). Trying to get
some real info from the OpenSSL guys to see how I should do to behave the
best way. SSLeay 0.8.0 shouldn't be that much in use anyway these days!
Version 5.6.2beta
Daniel (Apr 4 1999)
- Finally have curl more cookie "aware". Now read carefully. This is how
it works.
To make curl read cookies from an already existing file, in plain header-
format (like from the headers of a previous fetch) invoke curl with the
-b flag like:
curl -b file http://site/foo.html
Curl will then use all cookies it finds matching. The old style that sets
a single cookie with -b is still supported and is used if the string
following -b includes a '=' letter, as in "-b name=daniel".
To make curl read the cookies sent in combination with a location: (which
sites often do) point curl to read a non-existing file at first (i.e
to start with no existing cookies), like:
curl -b nowhere http://site/setcookieandrelocate.html
- Added a paragraph in the TODO file about the SSL problems recently
reported. Evidently, some kind of SSL-problem curl may need to address.
- Better "Location:" following.
Douglas E. Wegscheid (Tue, 30 Mar 1999)
- A subsecond display patch.
Daniel (Mar 14 1999)
- I've separated the version number of libcurl and curl now. To make
things a little easier, I decided to start the curl numbering from
5.6 and the former version number known as "curl" is now the one
set for libcurl.
- Removed the 'enable-no-pass' from configure, I doubt anyone wanted
that.
- Made lots of tiny adjustments to compile smoothly with cygwin under
win32. It's a killer for porting this to win32, bye bye VC++! ;-)
Compiles and builds out-of-the-box now. See the new wordings in
INSTALL for details.
- Beginning experiments with downloading multiple document from a http
server while remaining connected.
Version 5.6beta
Daniel (Mar 13 1999)
- Since I've changed so much, I thought I'd just go ahead and implement the
suggestion from Douglas E. Wegscheid. -D or --dump-header is now storing
HTTP headers separately in the specified file.
- Added new text to INSTALL on what to do to build this on win32 now.
- Aaargh. I had to take a step back and prefix the shared #include files
in the sources with "../include/" to please VC++...
Daniel (Mar 12 1999)
- Split the url.c source into many tiny sources for better readability
and smaller size.
Daniel (Mar 11 1999)
- Started to change stuff for a move to make libcurl and a more separate
curl application that uses the libcurl. Made the libcurl sources into
the new lib directory while the curl application will remain in src as
before. New makefiles, adjusted configure script and so.
libcurl.a built quickly and easily. I better make a better interface to
the lib functions though.
The new root dir include/ is supposed to contain the public information
about the new libcurl. It is a little ugly so far :-)
Daniel (Mar 1 1999)
- Todd Kaufmann sent me a good link to Netscape's cookie spec as well as the
info that RFC 2109 specifies how to use them. The link is now in the
README and the RFC in the RESOURCES.
Daniel (Feb 23 1999)
- Finally made configure accept --with-ssl to look for SSL libs and includes
in the "standard" place /usr/local/ssl...
Daniel (Feb 22 1999)
- Verified that curl linked fine with OpenSSL 0.9.1c which seems to be
the most recent.
Henri Gomez (Fri Feb 5 1999)
- Sent in an updated curl-ssl.spec. I still miss the script that builds an
RPM automatically...
Version 5.5.1
Mark Butler (27 Jan 1999)
- Corrected problems in Download().
Danitel Stenberg (25 Jan 1999)
- Jeremie Petit pointed out a few flaws in the source that prevented it from
compile warning free with the native compiler under Digital Unix v4.0d.
Version 5.5
Daniel Stenberg (15 Jan 1999)
- Added Bjorns small text to the README about the DICT protocol.
Daniel Stenberg (11 Jan 1999)
- <jswink at softcom.net> reported about the win32-versioin: "Doesn't use
ALL_PROXY environment variable". Turned out to be because of the static-
buffer nature of the win32 environment variable calls!
Bjorn Reese (10 Jan 1999)
- I have attached a simple addition for the DICT protocol (RFC 2229).
It performs dictionary lookups. The output still needs to be better
formatted.
To test it try (the exact format, and more examples are described in
the RFC)
dict://dict.org/m:hello
dict://dict.org/m:hello::soundex
Vicente Garcia (10 Jan 1999)
- Corrected the progress meter for files larger than 20MB.
Daniel Stenberg (7 Jan 1999)
- Corrected the -t and -T help texts. They claimed to be FTP only.
Version 5.4
Daniel Stenberg
(7 Jan 1999)
- Irving Wolfe reported that curl -s didn't always supress the progress
reporting. It was the form post that autoamtically always switched it on
again. This is now corrected!
(4 Jan 1999)
- Andreas Kostyrka suggested I'd add PUT and he helped me out to test it. If
you use -t or -T now on a http or https server, PUT will be used for file
upload.
I removed the former use of -T with HTTP. I doubt anyone ever really used
that.
(4 Jan 1999)
- Erik Jacobsen found a width bug in the mprintf() function. I corrected it
now.
(4 Jan 1999)
- As John V. Chow pointed out to me, curl accepted very limited URL sizes. It
should now accept path parts that are up to at least 4096 bytes.
- Somehow I screwed up when applying the AIX fix from Gilbert Ramirez, so
I redid that now.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -234,6 +234,10 @@ netware-clean:
$(MAKE) -C lib -f Makefile.netware clean $(MAKE) -C lib -f Makefile.netware clean
$(MAKE) -C src -f Makefile.netware clean $(MAKE) -C src -f Makefile.netware clean
netware-install:
$(MAKE) -C lib -f Makefile.netware install
$(MAKE) -C src -f Makefile.netware install
unix: all unix: all
unix-ssl: ssl unix-ssl: ssl
@@ -241,3 +245,8 @@ unix-ssl: ssl
linux: all linux: all
linux-ssl: ssl linux-ssl: ssl
vc8:
echo "generate VC8 makefiles"
sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e 's#/GZ#/RTC1#' -e 's/wsock32.lib/wsock32.lib bufferoverflowu.lib/g' -e 's/VC6/VC8/g' lib/Makefile.vc6 > lib/Makefile.vc8
sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e 's#/GZ#/RTC1#' -e 's/wsock32.lib/wsock32.lib bufferoverflowu.lib/g' -e 's/VC6/VC8/g' src/Makefile.vc6 > src/Makefile.vc8

View File

@@ -1,56 +1,67 @@
Curl and libcurl 7.16.2 Curl and libcurl 7.16.3
Public curl release number: 98 Public curl release number: 99
Releases counted from the very beginning: 125 Releases counted from the very beginning: 126
Available command line options: 118 Available command line options: 118
Available curl_easy_setopt() options: 141 Available curl_easy_setopt() options: 141
Number of public functions in libcurl: 54 Number of public functions in libcurl: 54
Amount of public web site mirrors: 38 Amount of public web site mirrors: 38
Number of known libcurl bindings: 35 Number of known libcurl bindings: 35
Number of contributors: 539 Number of contributors: 554
This release includes the following changes: This release includes the following changes:
o added CURLOPT_TIMEOUT_MS and CURLOPT_CONNECTTIMEOUT_MS o added curl_multi_socket_action()
o added CURLOPT_HTTP_CONTENT_DECODING, CURLOPT_HTTP_TRANSFER_DECODING and o deprecated curl_multi_socket()
--raw o uses less memory in non-pipelined use cases
o added support for using the NSS library for TLS/SSL o CURLOPT_HTTP200ALIASES matched transfers assume HTTP 1.0 compliance
o changed default anonymous FTP password o more than one test harness can run at the same time without conflict
o changed the CURLOPT_FTP_SSL_CCC option to handle active and passive o SFTP now supports quote commands before a transfer
CCC shutdown o CURLMOPT_MAXCONNECTS added to curl_multi_setopt()
o added the --ftp-ssl-ccc-mode command line option o upload resume works for file:// URLs
o includes VC8 Makefiles in the release archive o asynchronous name resolves now require c-ares 1.4.0 or later
o --ftp-ssl-control is now honoured on ftps:// URLs o added SOCKS test cases
o added experimental CURL_ACKNOWLEDGE_EINTR symbol definition check o CURLOPT_FTP_CREATE_MISSING_DIRS and --ftp-create-dirs now work for SFTP
o --key and new --pubkey options for SSH public key file logins operations as well
o --pass now works for a SSH public key file, too
o select (2) support no longer needed to build the library if poll() used
o CURLOPT_POSTQUOTE works for SFTP
This release includes the following bugfixes: This release includes the following bugfixes:
o in testsuite, update test cookies expiration from 2007-Feb-1 to year 2035 o if2up too long interface name memory leak
o socks5 works o test case 534 started to fail 2007-04-13 due to the existance of a
o builds fine with VC2005 new host on the net with the same silly domain the test was using
o CURLOPT_RANGE set to NULL resets the range for FTP for a host which was supposed not to exist.
o curl_multi_remove_handle() rare crash o test suite SSL certificate works better with newer stunnel
o passive FTP transfers work with SOCKS o internal progress meter update frequency back to once per second
o multi interface HTTPS connection re-use memory leak o avoid some unnecessary calls to function gettimeofday
o libcurl.m4's --with-libcurl is improved o a double-free in the SSL-layer
o curl-config --libs and libcurl.pc no longer list unnecessary dependencies o GnuTLS free of NULL credentials
o fixed an issue with CCC not working on some servers o NSS-fix for closing down SSL
o several HTTP pipelining problems o bad warning from configure when gnutls was selected
o HTTP CONNECT thru a proxy is now less blocking when the multi interface is o compilation on VMS 64-bit mode
used o SCP/SFTP downloads could hang on the last bytes of a transfer
o HTTP Digest header parsing fix for unquoted last word ending with CRLF o curl_easy_duphandle() crash
o CURLOPT_PORT, HTTP proxy, re-using connections and non-HTTP protocols o curl -V / curl_version*() works even when GnuTLS is used on a system without
o CURLOPT_INTERFACE for ipv6 a good random source
o use-after-free issue with HTTP transfers with the multi interface o curl_multi_socket() not "noticing" newly added handles
o the progress callback can get called more frequently o lack of Content-Length and chunked encoding now requires HTTP 1.1 as well
o timeout would restart when signal caught while awaiting socket events to be treated as without response body
o curl -f with user+password embedded in the URL o connection cache growth in multi handles
o 26 flaws identified by coverity.com o better handling of out of memory conditions
o builds on QNX 6 again o overwriting an uploaded file with sftp now truncates it first
o SFTP quote commands chmod, chown, chgrp can now set a value of 0
o TFTP connect timouts less than 5 seconds
o improved curl -w for TFTP transfers
o memory leak when failed OpenSSL certificate CN field checking
o memory leak when OpenSSL failed PKCS #12 parsing
o FPL-SSL when built with NSS
o out-of-boundary write in Curl_select()
o -s/--silent can now be used to toggle off the silence again
o builds fine on 64bit HP-UX
o multi interface HTTP CONNECT glitch
o list FTP root directories when login dir is not root
o no longer slows down when getting very many URLs on the same command line
o lock share before decreasing dirty counter
o no-body FTP requests on re-used connections
This release includes the following known bugs: This release includes the following known bugs:
@@ -58,21 +69,26 @@ This release includes the following known bugs:
Other curl-related news: Other curl-related news:
o pycurl 7.16.1 was released: http://pycurl.sf.net/ o PycURL 7.16.2.1 was released: http://pycurl.sf.net/
o TclCurl 7.16.2 was released:
http://personal1.iddeo.es/andresgarci/tclcurl/english/
New curl mirrors: New curl mirrors:
o http://curl.basemirror.de is a new mirror in Germany o http://curl.spegulo.be is a new mirror in Belgium
o http://curl.xxtracker.org is a new mirror in The Netherlands o http://curl.piotrkosoft.net is a new mirror in Poland
o http://curl.smudge-it.net is a new mirror in St Louis, MO, USA
o http://curl.askapache.com is a new mirror in Indiana, USA
This release would not have looked like this without help, code, reports and This release would not have looked like this without help, code, reports and
advice from friends like these: advice from friends like these:
Yang Tse, Manfred Schwarb, Michael Wallner, Jeff Pohlmeyer, Shmulik Regev, Song Ma, Dan Fandrich, Yang Tse, Jay Austin, Robert Iakobashvil,
Rob Crittenden, Robert A. Monat, Dan Fandrich, Duncan Mac-Vicar Prett, James Housley, Daniel Black, Steve Little, Sonia Subramanian, Peter O'Gorman,
Michal Marek, Robson Braga Araujo, Ian Turner, Linus Nielsen Feltzing, Frank Hempel, Michael Wallner, Jeff Pohlmeyer, Tobias Rundstr<74>m,
Ravi Pratap, Adam D. Moss, Jose Kahan, Hang Kin Lau, Justin Fletcher, Anders Gustafsson, James Bursa, Kristian Gunstone, Feng Tu,
Robert Iakobashvili, Bryan Henderson, Eygene Ryabinkin, Daniel Johnson, Andre Guibert de Bruet, Rob Crittenden, Rich Rauenzahn, Tom Regner,
Matt Kraai, Nick Zitzmann, Rob Jones Dave Vasilevsky, Shmulik Regev, Robson Braga Araujo, Adam Piggott,
Gerrit Bruchh<68>user
Thanks! (and sorry if I forgot to mention someone) Thanks! (and sorry if I forgot to mention someone)

View File

@@ -20,3 +20,9 @@ Brad Spencer
Ravi Pratap Ravi Pratap
William Ahern William Ahern
Bram Matthys Bram Matthys
Michael Wallner
Vlad Dinulescu
Brad House
Shmulik Regev
Ashish Sharma
Brad Spencer

View File

@@ -1,16 +1,107 @@
Changelog for the c-ares project Changelog for the c-ares project
* February 19 Version 1.4.0 (June 8, 2007)
* June 4 2007 (Daniel Stenberg)
- James Bursa reported a major memory problem when resolving multi-IP names
and I found and fixed the problem. It was added by Ashish Sharma's patch
two days ago.
When I then tried to verify multiple entries in /etc/hosts after my fix, I
got another segfault and decided this code was not ripe for inclusion and I
reverted the patch.
* June 2 2007
- Brad Spencer found and fixed three flaws in the code, found with the new
gcc 4.2.0 warning: -Waddress
- Brad House fixed VS2005 compiler warnings due to time_t being 64bit.
He also made recent Microsoft compilers use _strdup() instead of strdup().
- Brad House's man pages for ares_save_options() and ares_destroy_options()
were added.
- Ashish Sharma provided a patch for supporting multiple entries in the
/etc/hosts file. Patch edited for coding style and functionality by me
(Daniel).
* May 30 2007
- Shmulik Regev brought cryptographically secure transaction IDs:
The c-ares library implementation uses a DNS "Transaction ID" field that is
seeded with a pseudo random number (based on gettimeofday) which is
incremented (++) between consecutive calls and is therefore rather
predictable. In general, predictability of DNS Transaction ID is a well
known security problem (e.g.
http://bak.spc.org/dms/archive/dns_id_attack.txt) and makes a c-ares based
implementation vulnerable to DNS poisoning. Credit goes to Amit Klein
(Trusteer) for identifying this problem.
The patch I wrote changes the implementation to use a more secure way of
generating unique IDs. It starts by obtaining a key with reasonable entropy
which is used with an RC4 stream to generate the cryptographically secure
transaction IDs.
Note that the key generation code (in ares_init:randomize_key) has two
versions, the Windows specific one uses a cryptographically safe function
provided (but undocumented :) by the operating system (described at
http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx). The
default implementation is a bit naive and uses the standard 'rand'
function. Surely a better way to generate random keys exists for other
platforms.
The patch can be tested by using the adig utility and using the '-s' option.
- Brad House added ares_save_options() and ares_destroy_options() that can be
used to keep options for later re-usal when ares_init_options() is used.
Problem: Calling ares_init() for each lookup can be unnecessarily resource
intensive. On windows, it must LoadLibrary() or search the registry
on each call to ares_init(). On unix, it must read and parse
multiple files to obtain the necessary configuration information. In
a single-threaded environment, it would make sense to only
ares_init() once, but in a heavily multi-threaded environment, it is
undesirable to ares_init() and ares_destroy() for each thread created
and track that.
Solution: Create ares_save_options() and ares_destroy_options() functions to
retrieve and free options obtained from an initialized channel. The
options populated can be used to pass back into ares_init_options(),
it should populate all needed fields and not retrieve any information
from the system. Probably wise to destroy the cache every minute or
so to prevent the data from becoming stale.
- Daniel S added ares_process_fd() to allow applications to ask for processing
on specific sockets and thus avoiding select() and associated
functions/macros. This function will be used by upcoming libcurl releases
for this very reason. It also made me export the ares_socket_t type in the
public ares.h header file, since ares_process_fd() uses that type for two of
the arguments.
* May 25 2007
- Ravi Pratap fixed a flaw in the init_by_resolv_conf() function for windows
that could cause it to return a bad return code.
* April 16 2007
- Yang Tse: Provide ares_getopt() command-line parser function as a source
code helper function, not belonging to the actual c-ares library.
* February 19 2007
- Vlad Dinulescu added ares_parse_ns_reply(). - Vlad Dinulescu added ares_parse_ns_reply().
* February 13 * February 13 2007
- Yang Tse: Fix failure to get the search sequence of /etc/hosts and - Yang Tse: Fix failure to get the search sequence of /etc/hosts and
DNS from /etc/nsswitch.conf, /etc/host.conf or /etc/svc.conf when DNS from /etc/nsswitch.conf, /etc/host.conf or /etc/svc.conf when
/etc/resolv.conf did not exist or was unable to read it. /etc/resolv.conf did not exist or was unable to read it.
* November 22 * November 22 2006
- Install ares_dns.h too - Install ares_dns.h too
@@ -18,7 +109,7 @@
struct, and there are domain/search entries in /etc/resolv.conf, the domains struct, and there are domain/search entries in /etc/resolv.conf, the domains
of the options struct will be overridden. of the options struct will be overridden.
* November 6 * November 6 2006
- Yang Tse removed a couple of potential zero size memory allocations. - Yang Tse removed a couple of potential zero size memory allocations.

View File

@@ -11,7 +11,7 @@ MSVCFILES = vc/adig/adig.dep vc/adig/adig.dsp vc/vc.dsw vc/ahost/ahost.dep \
# adig and ahost are just sample programs and thus not mentioned with the # adig and ahost are just sample programs and thus not mentioned with the
# regular sources and headers # regular sources and headers
EXTRA_DIST = CHANGES README.cares Makefile.inc adig.c ahost.c $(man_MANS) \ EXTRA_DIST = CHANGES README.cares Makefile.inc adig.c ahost.c $(man_MANS) \
$(MSVCFILES) AUTHORS config-win32.h $(MSVCFILES) AUTHORS config-win32.h RELEASE-NOTES
VER=-version-info 1:0:0 VER=-version-info 1:0:0

View File

@@ -21,7 +21,7 @@ CFLAGS += -DWATT32 -DHAVE_AF_INET6 -DHAVE_PF_INET6 -DHAVE_FIONBIO \
-DRECV_TYPE_ARG1='int' -DRECV_TYPE_ARG2='void*' \ -DRECV_TYPE_ARG1='int' -DRECV_TYPE_ARG2='void*' \
-DRECV_TYPE_ARG3='int' -DRECV_TYPE_ARG4='int' \ -DRECV_TYPE_ARG3='int' -DRECV_TYPE_ARG4='int' \
-DRECV_TYPE_RETV='int' -DHAVE_STRUCT_TIMEVAL \ -DRECV_TYPE_RETV='int' -DHAVE_STRUCT_TIMEVAL \
-UHAVE_CONFIG_H -Dselect=select_s -UHAVE_CONFIG_H
LDFLAGS = -s LDFLAGS = -s
@@ -38,7 +38,6 @@ endif
ifeq ($(USE_ZLIB),1) ifeq ($(USE_ZLIB),1)
EX_LIBS += $(ZLIB_ROOT)/libz.a EX_LIBS += $(ZLIB_ROOT)/libz.a
CFLAGS += -DUSE_MANUAL
endif endif
ifeq ($(USE_IDNA),1) ifeq ($(USE_IDNA),1)
@@ -55,10 +54,10 @@ all: $(OBJ_DIR) libcares.a ahost.exe adig.exe
libcares.a: $(OBJECTS) libcares.a: $(OBJECTS)
ar rs $@ $? ar rs $@ $?
ahost.exe: ahost.c $(OBJ_HACK) ahost.exe: ahost.c $(OBJ_DIR)/ares_getopt.o $(OBJ_HACK)
$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(EX_LIBS) $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(EX_LIBS)
adig.exe: adig.c $(OBJ_HACK) adig.exe: adig.c $(OBJ_DIR)/ares_getopt.o $(OBJ_HACK)
$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(EX_LIBS) $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(EX_LIBS)
clean: clean:

View File

@@ -18,5 +18,5 @@ MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \
ares_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3 \ ares_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3 \
ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3 \ ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3 \
ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3 ares_getnameinfo.3 \ ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3 ares_getnameinfo.3 \
ares_getsock.3 ares_parse_ns_reply.3 ares_getsock.3 ares_parse_ns_reply.3 \
ares_destroy_options.3 ares_save_options.3

View File

@@ -5,27 +5,30 @@
## Use: make -f Makefile.m32 [demos] ## Use: make -f Makefile.m32 [demos]
## ##
## Quick hack by Guenter; comments to: /dev/nul ## Quick hack by Guenter; comments to: /dev/nul
#
CC = gcc
RANLIB = ranlib
######################################################## ########################################################
## Nothing more to do below this line! ## Nothing more to do below this line!
LIB = libcares.a LIB = libcares.a
CC = gcc CC = gcc
LD = gcc
RANLIB = ranlib
#RM = rm -f
CFLAGS = -O2 -Wall CFLAGS = -O2 -Wall
LDFLAGS = -s LDFLAGS = -s
LIBS = -lwsock32 LIBS = -lwsock32
MANPAGES := $(patsubst %.c,%.o,$(wildcard ares_*.3)) # Makefile.inc provides the CSOURCES and HHEADERS defines
include Makefile.inc
OBJS := $(patsubst %.c,%.o,$(wildcard ares_*.c)) OBJLIB := $(patsubst %.c,%.o,$(strip $(CSOURCES)))
OBJS += windows_port.o inet_ntop.o inet_net_pton.o bitncmp.o
$(LIB): ${OBJS}
ar cru $@ ${OBJS} $(LIB): $(OBJLIB)
${RANLIB} $@ ar cru $@ $^
$(RANLIB) $@
all: $(LIB) demos all: $(LIB) demos
@@ -34,16 +37,13 @@ demos: adig.exe ahost.exe
tags: tags:
etags *.[ch] etags *.[ch]
adig.exe: adig.o $(LIB) %.exe: %.o ares_getopt.o $(LIB)
${CC} ${LDFLAGS} -o $@ adig.o $(LIB) ${LIBS} $(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
ahost.exe: ahost.o $(LIB) $(OBJLIB): ares.h ares_dns.h ares_private.h
${CC} ${LDFLAGS} -o $@ ahost.o $(LIB) ${LIBS}
${OBJS}: ares.h ares_dns.h ares_private.h
.c.o: .c.o:
${CC} -c ${CFLAGS} $< $(CC) $(CFLAGS) -c $<
check: check:
@@ -61,8 +61,8 @@ install:
done) done)
clean: clean:
rm -f ${OBJS} $(LIB) adig.o adig.exe ahost.o ahost.exe $(RM) ares_getopt.o $(OBJLIB) $(LIB) adig.exe ahost.exe
distclean: clean distclean: clean
rm -f config.cache config.log config.status Makefile $(RM) config.cache config.log config.status Makefile

View File

@@ -1,7 +1,7 @@
################################################################# #################################################################
# $Id$ # $Id$
# #
## Makefile for building libares (NetWare version - gnu make) ## Makefile for building libcares (NetWare version - gnu make)
## Use: make -f Makefile.netware ## Use: make -f Makefile.netware
## ##
## Comments to: Guenter Knauf http://www.gknw.de/phpbb ## Comments to: Guenter Knauf http://www.gknw.de/phpbb
@@ -70,10 +70,11 @@ CFLAGS = $(OPT) -D$(DB) -DNETWARE -DHAVE_CONFIG_H -nostdinc
ifeq ($(CC),mwccnlm) ifeq ($(CC),mwccnlm)
LD = mwldnlm LD = mwldnlm
LDFLAGS = -nostdlib $(PRELUDE) $(OBJS) $(<:.def=.o) -o $@ -commandfile LDFLAGS = -nostdlib $(PRELUDE) $(OBJEXE) $(<:.def=.o) -o $@ -commandfile
AR = mwldnlm AR = mwldnlm
ARFLAGS = -type library -w nocmdline $(OBJDIR)/*.o -o ARFLAGS = -nostdlib -type library -o
LIBEXT = lib LIBEXT = lib
#RANLIB =
CFLAGS += -msgstyle gcc -gccinc -inline off -opt nointrinsics -proc 586 CFLAGS += -msgstyle gcc -gccinc -inline off -opt nointrinsics -proc 586
CFLAGS += -relax_pointers CFLAGS += -relax_pointers
#CFLAGS += -w on #CFLAGS += -w on
@@ -91,6 +92,7 @@ LDFLAGS = -T
AR = ar AR = ar
ARFLAGS = -cq ARFLAGS = -cq
LIBEXT = a LIBEXT = a
RANLIB = ranlib
CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing
CFLAGS += -Wall -Wno-format -Wno-uninitialized # -pedantic CFLAGS += -Wall -Wno-format -Wno-uninitialized # -pedantic
ifeq ($(LIBARCH),LIBC) ifeq ($(LIBARCH),LIBC)
@@ -132,7 +134,8 @@ endif
# Makefile.inc provides the CSOURCES and HHEADERS defines # Makefile.inc provides the CSOURCES and HHEADERS defines
include Makefile.inc include Makefile.inc
OBJS := $(patsubst %.c,$(OBJDIR)/%.o,$(strip $(CSOURCES))) OBJLIB := $(patsubst %.c,$(OBJDIR)/%.o,$(strip $(CSOURCES)))
OBJEXE = $(OBJLIB) $(OBJDIR)/ares_getopt.o
.PHONY: lib nlm prebuild dist install clean .PHONY: lib nlm prebuild dist install clean
@@ -143,7 +146,7 @@ nlm: prebuild $(TARGETS)
prebuild: $(OBJDIR) $(OBJDIR)/version.inc config.h arpa/nameser.h prebuild: $(OBJDIR) $(OBJDIR)/version.inc config.h arpa/nameser.h
dist: all dist: all
-$(RM) $(OBJS) $(OBJDIR)/*.map $(OBJDIR)/*.ncv -$(RM) $(OBJLIB) $(OBJDIR)/*.map $(OBJDIR)/*.ncv
-$(RM) $(OBJDIR)/*.def $(OBJDIR)/*.xdc $(OBJDIR)/version.inc -$(RM) $(OBJDIR)/*.def $(OBJDIR)/*.xdc $(OBJDIR)/version.inc
install: $(INSTDIR) all install: $(INSTDIR) all
@@ -158,12 +161,15 @@ clean:
-$(RM) -r $(OBJDIR) -$(RM) -r $(OBJDIR)
-$(RM) -r arpa -$(RM) -r arpa
%.$(LIBEXT): $(OBJS) %.$(LIBEXT): $(OBJLIB)
@echo Creating $@ @echo Creating $@
@-$(RM) $@ @-$(RM) $@
@$(AR) $(ARFLAGS) $@ $^ @$(AR) $(ARFLAGS) $@ $^
ifdef RANLIB
@$(RANLIB) $@
endif
%.nlm: $(OBJDIR)/%.def $(OBJDIR)/%.o $(OBJDIR)/%.xdc $(OBJS) %.nlm: $(OBJDIR)/%.def $(OBJDIR)/%.o $(OBJDIR)/%.xdc $(OBJEXE)
@echo Linking $@ @echo Linking $@
@-$(RM) $@ @-$(RM) $@
@$(LD) $(LDFLAGS) $< @$(LD) $(LDFLAGS) $<
@@ -247,7 +253,7 @@ ifdef IMPORTS
@echo $(DL)import $(IMPORTS)$(DL) >> $@ @echo $(DL)import $(IMPORTS)$(DL) >> $@
endif endif
ifeq ($(LD),nlmconv) ifeq ($(LD),nlmconv)
@echo $(DL)input $(OBJS)$(DL) >> $@ @echo $(DL)input $(OBJEXE)$(DL) >> $@
@echo $(DL)input $(PRELUDE)$(DL) >> $@ @echo $(DL)input $(PRELUDE)$(DL) >> $@
@echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@ @echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@
endif endif

View File

@@ -124,11 +124,11 @@ $(DEF_FILE): $(OBJECTS) Makefile.VC6
@echo ares_gettimeofday >> $@ @echo ares_gettimeofday >> $@
@echo ares_parse_aaaa_reply >> $@ @echo ares_parse_aaaa_reply >> $@
ahost.exe: $(OBJ_DIR) $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\getopt.obj cares_imp.lib ahost.exe: $(OBJ_DIR) $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib
link $(LDFLAGS) -out:$@ $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\getopt.obj cares_imp.lib $(EX_LIBS) link $(LDFLAGS) -out:$@ $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib $(EX_LIBS)
adig.exe: $(OBJ_DIR) $(OBJ_DIR)\adig.obj $(OBJ_DIR)\getopt.obj cares_imp.lib adig.exe: $(OBJ_DIR) $(OBJ_DIR)\adig.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib
link $(LDFLAGS) -out:$@ $(OBJ_DIR)\adig.obj $(OBJ_DIR)\getopt.obj cares_imp.lib $(EX_LIBS) link $(LDFLAGS) -out:$@ $(OBJ_DIR)\adig.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib $(EX_LIBS)
clean: clean:
- del $(OBJ_DIR)\*.obj *.ilk *.pdb *.pbt *.pbi *.pbo *._xe *.map - del $(OBJ_DIR)\*.obj *.ilk *.pdb *.pbt *.pbi *.pbo *._xe *.map
@@ -229,3 +229,5 @@ $(OBJ_DIR)\bitncmp.obj: bitncmp.c bitncmp.h
$(OBJ_DIR)\inet_ntop.obj: inet_ntop.c setup.h setup_once.h nameser.h \ $(OBJ_DIR)\inet_ntop.obj: inet_ntop.c setup.h setup_once.h nameser.h \
ares_ipv6.h inet_ntop.h ares_ipv6.h inet_ntop.h
$(OBJ_DIR)\ares_getopt.obj: ares_getopt.c ares_getopt.h

9
ares/RELEASE-NOTES Normal file
View File

@@ -0,0 +1,9 @@
This is what's new and changed in the c-ares 1.4.1 release:
o
Thanks go to these friendly people for their efforts and contributions:
Have fun!

View File

@@ -32,9 +32,6 @@
#endif #endif
#include <netdb.h> #include <netdb.h>
#endif #endif
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -45,6 +42,7 @@
#include "ares.h" #include "ares.h"
#include "ares_dns.h" #include "ares_dns.h"
#include "inet_ntop.h" #include "inet_ntop.h"
#include "ares_getopt.h"
#ifdef WATT32 #ifdef WATT32
#undef WIN32 /* Redefined in MingW headers */ #undef WIN32 /* Redefined in MingW headers */
@@ -55,11 +53,6 @@
#define T_SRV 33 /* server selection */ #define T_SRV 33 /* server selection */
#endif #endif
#ifndef optind
extern int optind;
extern char *optarg;
#endif
struct nv { struct nv {
const char *name; const char *name;
int value; int value;
@@ -163,7 +156,7 @@ int main(int argc, char **argv)
options.flags = ARES_FLAG_NOCHECKRESP; options.flags = ARES_FLAG_NOCHECKRESP;
options.servers = NULL; options.servers = NULL;
options.nservers = 0; options.nservers = 0;
while ((c = getopt(argc, argv, "df:s:c:t:T:U:")) != -1) while ((c = ares_getopt(argc, argv, "df:s:c:t:T:U:")) != -1)
{ {
switch (c) switch (c)
{ {

View File

@@ -34,19 +34,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#include "ares.h" #include "ares.h"
#include "ares_dns.h" #include "ares_dns.h"
#include "inet_ntop.h" #include "inet_ntop.h"
#include "inet_net_pton.h" #include "inet_net_pton.h"
#include "ares_getopt.h"
#ifndef optind
extern int optind;
extern char *optarg;
#endif
#ifndef HAVE_STRUCT_IN6_ADDR #ifndef HAVE_STRUCT_IN6_ADDR
struct in6_addr struct in6_addr
@@ -73,7 +65,7 @@ int main(int argc, char **argv)
WSAStartup(wVersionRequested, &wsaData); WSAStartup(wVersionRequested, &wsaData);
#endif #endif
while ((c = getopt(argc,argv,"dt:h")) != -1) while ((c = ares_getopt(argc,argv,"dt:h")) != -1)
{ {
switch (c) switch (c)
{ {

View File

@@ -94,6 +94,7 @@ extern "C" {
#define ARES_OPT_DOMAINS (1 << 7) #define ARES_OPT_DOMAINS (1 << 7)
#define ARES_OPT_LOOKUPS (1 << 8) #define ARES_OPT_LOOKUPS (1 << 8)
#define ARES_OPT_SOCK_STATE_CB (1 << 9) #define ARES_OPT_SOCK_STATE_CB (1 << 9)
#define ARES_OPT_SORTLIST (1 << 10)
/* Nameinfo flag values */ /* Nameinfo flag values */
#define ARES_NI_NOFQDN (1 << 0) #define ARES_NI_NOFQDN (1 << 0)
@@ -136,6 +137,22 @@ extern "C" {
#define ARES_GETSOCK_WRITABLE(bits,num) (bits & (1 << ((num) + \ #define ARES_GETSOCK_WRITABLE(bits,num) (bits & (1 << ((num) + \
ARES_GETSOCK_MAXNUM))) ARES_GETSOCK_MAXNUM)))
/*
* Typedef our socket type
*/
#ifndef ares_socket_typedef
#ifdef WIN32
typedef SOCKET ares_socket_t;
#define ARES_SOCKET_BAD INVALID_SOCKET
#else
typedef int ares_socket_t;
#define ARES_SOCKET_BAD -1
#endif
#define ares_socket_typedef
#endif /* ares_socket_typedef */
#ifdef WIN32 #ifdef WIN32
typedef void (*ares_sock_state_cb)(void *data, typedef void (*ares_sock_state_cb)(void *data,
SOCKET socket, SOCKET socket,
@@ -148,6 +165,8 @@ typedef void (*ares_sock_state_cb)(void *data,
int writable); int writable);
#endif #endif
struct apattern;
struct ares_options { struct ares_options {
int flags; int flags;
int timeout; int timeout;
@@ -162,6 +181,8 @@ struct ares_options {
char *lookups; char *lookups;
ares_sock_state_cb sock_state_cb; ares_sock_state_cb sock_state_cb;
void *sock_state_cb_data; void *sock_state_cb_data;
struct apattern *sortlist;
int nsort;
}; };
struct hostent; struct hostent;
@@ -179,6 +200,8 @@ typedef void (*ares_nameinfo_callback)(void *arg, int status,
int ares_init(ares_channel *channelptr); int ares_init(ares_channel *channelptr);
int ares_init_options(ares_channel *channelptr, struct ares_options *options, int ares_init_options(ares_channel *channelptr, struct ares_options *options,
int optmask); int optmask);
int ares_save_options(ares_channel channel, struct ares_options *options, int *optmask);
void ares_destroy_options(struct ares_options *options);
void ares_destroy(ares_channel channel); void ares_destroy(ares_channel channel);
void ares_cancel(ares_channel channel); void ares_cancel(ares_channel channel);
void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen, void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
@@ -200,6 +223,8 @@ int ares_getsock(ares_channel channel, int *socks, int numsocks);
struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv, struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
struct timeval *tv); struct timeval *tv);
void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds); void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds);
void ares_process_fd(ares_channel channel, ares_socket_t read_fd,
ares_socket_t write_fd);
int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id, int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id,
int rd, unsigned char **buf, int *buflen); int rd, unsigned char **buf, int *buflen);

View File

@@ -183,6 +183,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
free(hostent->h_addr_list); free(hostent->h_addr_list);
free(hostent); free(hostent);
} }
*host = NULL;
return ARES_ENOMEM; return ARES_ENOMEM;
} }

View File

@@ -20,6 +20,19 @@
#include "ares.h" #include "ares.h"
#include "ares_private.h" #include "ares_private.h"
void ares_destroy_options(struct ares_options *options)
{
int i;
free(options->servers);
for (i = 0; i < options->ndomains; i++)
free(options->domains[i]);
free(options->domains);
if(options->sortlist)
free(options->sortlist);
free(options->lookups);
}
void ares_destroy(ares_channel channel) void ares_destroy(ares_channel channel)
{ {
int i; int i;

View File

@@ -0,0 +1,39 @@
.\" $Id$
.\"
.\" Copyright 1998 by the Massachusetts Institute of Technology.
.\"
.\" Permission to use, copy, modify, and distribute this
.\" software and its documentation for any purpose and without
.\" fee is hereby granted, provided that the above copyright
.\" notice appear in all copies and that both that copyright
.\" notice and this permission notice appear in supporting
.\" documentation, and that the name of M.I.T. not be used in
.\" advertising or publicity pertaining to distribution of the
.\" software without specific, written prior permission.
.\" M.I.T. makes no representations about the suitability of
.\" this software for any purpose. It is provided "as is"
.\" without express or implied warranty.
.\"
.TH ARES_DESTROY_OPTIONS 3 "1 June 2007"
.SH NAME
ares_destroy_options \- Destroy options initialized with ares_save_options
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B void ares_destroy_options(struct ares_options *\fIoptions\fP)
.fi
.SH DESCRIPTION
The
.B ares_destroy_options
function destroys the options struct identified by
.IR options ,
freeing all memory allocated by ares_save_options.
.SH SEE ALSO
.BR ares_save_options (3),
.BR ares_init_options (3)
.SH AUTHOR
Brad House
.br
Copyright 1998 by the Massachusetts Institute of Technology.

View File

@@ -33,7 +33,8 @@ void ares_free_hostent(struct hostent *host)
for (p = host->h_aliases; *p; p++) for (p = host->h_aliases; *p; p++)
free(*p); free(*p);
free(host->h_aliases); free(host->h_aliases);
free(host->h_addr_list[0]); free(host->h_addr_list[0]); /* no matter if there is one or many entries,
there is only one malloc for all of them */
free(host->h_addr_list); free(host->h_addr_list);
free(host); free(host);
} }

123
ares/ares_getopt.c Normal file
View File

@@ -0,0 +1,123 @@
/*
* Original file name getopt.c Initial import into the c-ares source tree
* on 2007-04-11. Lifted from version 5.2 of the 'Open Mash' project with
* the modified BSD license, BSD license without the advertising clause.
*
* $Id$
*/
/*
* getopt.c --
*
* Standard UNIX getopt function. Code is from BSD.
*
* Copyright (c) 1987-2001 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* A. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* B. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* C. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* #if !defined(lint)
* static char sccsid[] = "@(#)getopt.c 8.2 (Berkeley) 4/2/94";
* #endif
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ares_getopt.h"
int opterr = 1, /* if error message should be printed */
optind = 1, /* index into parent argv vector */
optopt, /* character checked for validity */
optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG (char *)""
/*
* ares_getopt --
* Parse argc/argv argument vector.
*/
int
ares_getopt(int nargc, char * const nargv[], const char *ostr)
{
static char *place = EMSG; /* option letter processing */
char *oli; /* option letter list index */
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc || *(place = nargv[optind]) != '-') {
place = EMSG;
return (EOF);
}
if (place[1] && *++place == '-') { /* found "--" */
++optind;
place = EMSG;
return (EOF);
}
} /* option letter okay? */
if ((optopt = (int)*place++) == (int)':' ||
!(oli = strchr(ostr, optopt))) {
/*
* if the user didn't specify '-' as an option,
* assume it means EOF.
*/
if (optopt == (int)'-')
return (EOF);
if (!*place)
++optind;
if (opterr && *ostr != ':')
(void)fprintf(stderr,
"%s: illegal option -- %c\n", __FILE__, optopt);
return (BADCH);
}
if (*++oli != ':') { /* don't need argument */
optarg = NULL;
if (!*place)
++optind;
}
else { /* need an argument */
if (*place) /* no white space */
optarg = place;
else if (nargc <= ++optind) { /* no arg */
place = EMSG;
if (*ostr == ':')
return (BADARG);
if (opterr)
(void)fprintf(stderr,
"%s: option requires an argument -- %c\n",
__FILE__, optopt);
return (BADCH);
}
else /* white space */
optarg = nargv[optind];
place = EMSG;
++optind;
}
return (optopt); /* dump back option letter */
}

41
ares/ares_getopt.h Normal file
View File

@@ -0,0 +1,41 @@
#ifndef ARES_GETOPT_H
#define ARES_GETOPT_H
/*
* Copyright (c) 1987-2001 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* A. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* B. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* C. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
int ares_getopt(int nargc, char * const nargv[], const char *ostr);
extern char *optarg;
extern int optind;
extern int opterr;
#endif /* ARES_GETOPT_H */

View File

@@ -61,7 +61,7 @@
#undef WIN32 /* Redefined in MingW/MSVC headers */ #undef WIN32 /* Redefined in MingW/MSVC headers */
#endif #endif
static int init_by_options(ares_channel channel, struct ares_options *options, static int init_by_options(ares_channel channel, const struct ares_options *options,
int optmask); int optmask);
static int init_by_environment(ares_channel channel); static int init_by_environment(ares_channel channel);
static int init_by_resolv_conf(ares_channel channel); static int init_by_resolv_conf(ares_channel channel);
@@ -72,6 +72,8 @@ static int config_nameserver(struct server_state **servers, int *nservers,
static int set_search(ares_channel channel, const char *str); static int set_search(ares_channel channel, const char *str);
static int set_options(ares_channel channel, const char *str); static int set_options(ares_channel channel, const char *str);
static const char *try_option(const char *p, const char *q, const char *opt); static const char *try_option(const char *p, const char *q, const char *opt);
static void init_id_key(rc4_key* key,int key_data_len);
#ifndef WIN32 #ifndef WIN32
static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat); static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
static int ip_addr(const char *s, int len, struct in_addr *addr); static int ip_addr(const char *s, int len, struct in_addr *addr);
@@ -84,6 +86,12 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
static char *try_config(char *s, const char *opt); static char *try_config(char *s, const char *opt);
#endif #endif
#define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
x->nservers > -1 && \
x->ndomains > -1 && \
x->ndots > -1 && x->timeout > -1 && \
x->tries > -1)
int ares_init(ares_channel *channelptr) int ares_init(ares_channel *channelptr)
{ {
return ares_init_options(channelptr, NULL, 0); return ares_init_options(channelptr, NULL, 0);
@@ -96,7 +104,6 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
int i; int i;
int status = ARES_SUCCESS; int status = ARES_SUCCESS;
struct server_state *server; struct server_state *server;
struct timeval tv;
#ifdef CURLDEBUG #ifdef CURLDEBUG
const char *env = getenv("CARES_MEMDEBUG"); const char *env = getenv("CARES_MEMDEBUG");
@@ -197,22 +204,85 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
server->qtail = NULL; server->qtail = NULL;
} }
/* Choose a somewhat random query ID. The main point is to avoid init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
* collisions with stale queries. An attacker trying to spoof a DNS
* answer also has to guess the query ID, but it's only a 16-bit
* field, so there's not much to be done about that.
*/
gettimeofday(&tv, NULL);
channel->next_id = (unsigned short)
((tv.tv_sec ^ tv.tv_usec ^ getpid()) & 0xffff);
channel->next_id = ares__generate_new_id(&channel->id_key);
channel->queries = NULL; channel->queries = NULL;
*channelptr = channel; *channelptr = channel;
return ARES_SUCCESS; return ARES_SUCCESS;
} }
static int init_by_options(ares_channel channel, struct ares_options *options, /* Save options from initialized channel */
int ares_save_options(ares_channel channel, struct ares_options *options,
int *optmask)
{
int i;
/* Zero everything out */
memset(options, 0, sizeof(struct ares_options));
if (!ARES_CONFIG_CHECK(channel))
return ARES_ENODATA;
(*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TIMEOUT|ARES_OPT_TRIES|ARES_OPT_NDOTS|
ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
ARES_OPT_SORTLIST);
/* Copy easy stuff */
options->flags = channel->flags;
options->timeout = channel->timeout;
options->tries = channel->tries;
options->ndots = channel->ndots;
options->udp_port = channel->udp_port;
options->tcp_port = channel->tcp_port;
options->sock_state_cb = channel->sock_state_cb;
options->sock_state_cb_data = channel->sock_state_cb_data;
/* Copy servers */
options->servers =
malloc(channel->nservers * sizeof(struct server_state));
if (!options->servers && channel->nservers != 0)
return ARES_ENOMEM;
for (i = 0; i < channel->nservers; i++)
options->servers[i] = channel->servers[i].addr;
options->nservers = channel->nservers;
/* copy domains */
options->domains = malloc(channel->ndomains * sizeof(char *));
if (!options->domains)
return ARES_ENOMEM;
for (i = 0; i < channel->ndomains; i++)
{
options->ndomains = i;
options->domains[i] = strdup(channel->domains[i]);
if (!options->domains[i])
return ARES_ENOMEM;
}
options->ndomains = channel->ndomains;
/* copy lookups */
options->lookups = strdup(channel->lookups);
if (!options->lookups)
return ARES_ENOMEM;
/* copy sortlist */
options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
if (!options->sortlist)
return ARES_ENOMEM;
for (i = 0; i < channel->nsort; i++)
{
memcpy(&(options->sortlist[i]), &(channel->sortlist[i]),
sizeof(struct apattern));
}
options->nsort = channel->nsort;
return ARES_SUCCESS;
}
static int init_by_options(ares_channel channel,
const struct ares_options *options,
int optmask) int optmask)
{ {
int i; int i;
@@ -282,6 +352,19 @@ static int init_by_options(ares_channel channel, struct ares_options *options,
return ARES_ENOMEM; return ARES_ENOMEM;
} }
/* copy sortlist */
if ((optmask & ARES_OPT_SORTLIST) && channel->nsort == -1)
{
channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
if (!channel->sortlist)
return ARES_ENOMEM;
for (i = 0; i < options->nsort; i++)
{
memcpy(&(channel->sortlist[i]), &(options->sortlist[i]), sizeof(struct apattern));
}
channel->nsort = options->nsort;
}
return ARES_SUCCESS; return ARES_SUCCESS;
} }
@@ -555,6 +638,10 @@ DhcpNameServer
if (status == ARES_SUCCESS) if (status == ARES_SUCCESS)
status = ARES_EOF; status = ARES_EOF;
else
/* Catch the case when all the above checks fail (which happens when there
is no network card or the cable is unplugged) */
status = ARES_EFILE;
#elif defined(__riscos__) #elif defined(__riscos__)
@@ -611,6 +698,10 @@ DhcpNameServer
int linesize; int linesize;
int error; int error;
/* Don't read resolv.conf and friends if we don't have to */
if (ARES_CONFIG_CHECK(channel))
return ARES_SUCCESS;
fp = fopen(PATH_RESOLV_CONF, "r"); fp = fopen(PATH_RESOLV_CONF, "r");
if (fp) { if (fp) {
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
@@ -968,7 +1059,7 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
ipbufpfx[0] = '\0'; ipbufpfx[0] = '\0';
/* Lets see if it is CIDR */ /* Lets see if it is CIDR */
/* First we'll try IPv6 */ /* First we'll try IPv6 */
if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx ? ipbufpfx : ipbuf, if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
&pat.addr.addr6, &pat.addr.addr6,
sizeof(pat.addr.addr6))) > 0) sizeof(pat.addr.addr6))) > 0)
{ {
@@ -978,7 +1069,7 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
if (!sortlist_alloc(sortlist, nsort, &pat)) if (!sortlist_alloc(sortlist, nsort, &pat))
return ARES_ENOMEM; return ARES_ENOMEM;
} }
if (ipbufpfx && if (ipbufpfx[0] &&
(bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addr.addr4, (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addr.addr4,
sizeof(pat.addr.addr4))) > 0) sizeof(pat.addr.addr4))) > 0)
{ {
@@ -991,7 +1082,7 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
/* See if it is just a regular IP */ /* See if it is just a regular IP */
else if (ip_addr(ipbuf, (int)(q-str), &pat.addr.addr4) == 0) else if (ip_addr(ipbuf, (int)(q-str), &pat.addr.addr4) == 0)
{ {
if (ipbufpfx) if (ipbufpfx[0])
{ {
memcpy(ipbuf, str, (int)(q-str)); memcpy(ipbuf, str, (int)(q-str));
ipbuf[(int)(q-str)] = '\0'; ipbuf[(int)(q-str)] = '\0';
@@ -1175,3 +1266,79 @@ static void natural_mask(struct apattern *pat)
pat->mask.addr.addr4.s_addr = htonl(IN_CLASSC_NET); pat->mask.addr.addr4.s_addr = htonl(IN_CLASSC_NET);
} }
#endif #endif
/* initialize an rc4 key. If possible a cryptographically secure random key
is generated using a suitable function (for example win32's RtlGenRandom as
described in
http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
otherwise the code defaults to cross-platform albeit less secure mechanism
using rand
*/
static void randomize_key(unsigned char* key,int key_data_len)
{
int randomized = 0;
int counter=0;
#ifdef WIN32
HMODULE lib=LoadLibrary("ADVAPI32.DLL");
if (lib) {
BOOLEAN (APIENTRY *pfn)(void*, ULONG) =
(BOOLEAN (APIENTRY *)(void*,ULONG))GetProcAddress(lib,"SystemFunction036");
if (pfn && pfn(key,key_data_len) )
randomized = 1;
FreeLibrary(lib);
}
#else /* !WIN32 */
#ifdef RANDOM_FILE
char buffer[256];
FILE *f = fopen(RANDOM_FILE, "rb");
if(f) {
size_t i;
size_t rc = fread(buffer, key_data_len, 1, f);
for(i=0; i<rc && counter < key_data_len; i++)
key[counter++]=buffer[i];
fclose(f);
}
#endif
#endif /* WIN32 */
if ( !randomized ) {
for (;counter<key_data_len;counter++)
key[counter]=rand() % 256;
}
}
static void init_id_key(rc4_key* key,int key_data_len)
{
unsigned char index1;
unsigned char index2;
unsigned char* state;
short counter;
unsigned char *key_data_ptr = 0;
key_data_ptr = calloc(1,key_data_len);
randomize_key(key->state,key_data_len);
state = &key->state[0];
for(counter = 0; counter < 256; counter++)
state[counter] = counter;
key->x = 0;
key->y = 0;
index1 = 0;
index2 = 0;
for(counter = 0; counter < 256; counter++)
{
index2 = (key_data_ptr[index1] + state[counter] +
index2) % 256;
ARES_SWAP_BYTE(&state[counter], &state[index2]);
index1 = (index1 + 1) % key_data_len;
}
free(key_data_ptr);
}
short ares__generate_new_id(rc4_key* key)
{
short r;
ares__rc4(key, (unsigned char *)&r, sizeof(r));
return r;
}

View File

@@ -80,6 +80,8 @@
#endif #endif
#define ARES_ID_KEY_LEN 31
#include "ares_ipv6.h" #include "ares_ipv6.h"
struct send_request { struct send_request {
@@ -156,6 +158,13 @@ struct apattern {
unsigned short type; unsigned short type;
}; };
typedef struct rc4_key
{
unsigned char state[256];
unsigned char x;
unsigned char y;
} rc4_key;
struct ares_channeldata { struct ares_channeldata {
/* Configuration data */ /* Configuration data */
int flags; int flags;
@@ -176,6 +185,8 @@ struct ares_channeldata {
/* ID to use for next query */ /* ID to use for next query */
unsigned short next_id; unsigned short next_id;
/* key to use when generating new ids */
rc4_key id_key;
/* Active queries */ /* Active queries */
struct query *queries; struct query *queries;
@@ -184,10 +195,15 @@ struct ares_channeldata {
void *sock_state_cb_data; void *sock_state_cb_data;
}; };
void ares__rc4(rc4_key* key,unsigned char *buffer_ptr, int buffer_len);
void ares__send_query(ares_channel channel, struct query *query, time_t now); void ares__send_query(ares_channel channel, struct query *query, time_t now);
void ares__close_sockets(ares_channel channel, struct server_state *server); void ares__close_sockets(ares_channel channel, struct server_state *server);
int ares__get_hostent(FILE *fp, int family, struct hostent **host); int ares__get_hostent(FILE *fp, int family, struct hostent **host);
int ares__read_line(FILE *fp, char **buf, int *bufsize); int ares__read_line(FILE *fp, char **buf, int *bufsize);
short ares__generate_new_id(rc4_key* key);
#define ARES_SWAP_BYTE(a,b) \
{ unsigned char swapByte = *(a); *(a) = *(b); *(b) = swapByte; }
#define SOCK_STATE_CALLBACK(c, s, r, w) \ #define SOCK_STATE_CALLBACK(c, s, r, w) \
do { \ do { \

View File

@@ -24,16 +24,16 @@ ares_process \- Process events for name resolution
.B void ares_process(ares_channel \fIchannel\fP, fd_set *\fIread_fds\fP, .B void ares_process(ares_channel \fIchannel\fP, fd_set *\fIread_fds\fP,
.B fd_set *\fIwrite_fds\fP) .B fd_set *\fIwrite_fds\fP)
.fi .fi
.PP
.B void ares_process_fd(ares_channel \fIchannel\fP,
.B ares_socket_t \fIread_fd\fP,
.B ares_socket_t \fIwrite_fd\fP)
.fi
.SH DESCRIPTION .SH DESCRIPTION
The The \fBares_process(3)\fP function handles input/output events and timeouts
.B ares_process associated with queries pending on the name service channel identified by
function handles input/output events and timeouts associated with
queries pending on the name service channel identified by
.IR channel . .IR channel .
The file descriptor sets pointed to by The file descriptor sets pointed to by \fIread_fds\fP and \fIwrite_fds\fP
.I read_fds
and
.I write_fds
should have file descriptors set in them according to whether the file should have file descriptors set in them according to whether the file
descriptors specified by \fIares_fds(3)\fP are ready for reading and writing. descriptors specified by \fIares_fds(3)\fP are ready for reading and writing.
(The easiest way to determine this information is to invoke (The easiest way to determine this information is to invoke
@@ -44,6 +44,11 @@ The
.B ares_process .B ares_process
function will invoke callbacks for pending queries if they complete function will invoke callbacks for pending queries if they complete
successfully or fail. successfully or fail.
\fBares_process_fd(3)\fP works the same way but acts and operates only on the
specific file descriptors (sockets) you pass in to the function. Use
ARES_SOCKET_BAD for "no action". This function is of course provided to allow
users of c-ares to void select() in their applications and within c-ares.
.SS EXAMPLE .SS EXAMPLE
The following code fragment waits for all pending queries on a channel The following code fragment waits for all pending queries on a channel
to complete: to complete:

View File

@@ -56,13 +56,14 @@
static int try_again(int errnum); static int try_again(int errnum);
static void write_tcp_data(ares_channel channel, fd_set *write_fds, static void write_tcp_data(ares_channel channel, fd_set *write_fds,
time_t now); ares_socket_t write_fd, time_t now);
static void read_tcp_data(ares_channel channel, fd_set *read_fds, time_t now); static void read_tcp_data(ares_channel channel, fd_set *read_fds,
ares_socket_t read_fd, time_t now);
static void read_udp_packets(ares_channel channel, fd_set *read_fds, static void read_udp_packets(ares_channel channel, fd_set *read_fds,
time_t now); ares_socket_t read_fd, time_t now);
static void process_timeouts(ares_channel channel, time_t now); static void process_timeouts(ares_channel channel, time_t now);
static void process_answer(ares_channel channel, unsigned char *abuf, static void process_answer(ares_channel channel, unsigned char *abuf,
int alen, int whichserver, int tcp, int now); int alen, int whichserver, int tcp, time_t now);
static void handle_error(ares_channel channel, int whichserver, time_t now); static void handle_error(ares_channel channel, int whichserver, time_t now);
static struct query *next_server(ares_channel channel, struct query *query, time_t now); static struct query *next_server(ares_channel channel, struct query *query, time_t now);
static int open_tcp_socket(ares_channel channel, struct server_state *server); static int open_tcp_socket(ares_channel channel, struct server_state *server);
@@ -80,12 +81,30 @@ void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds)
time_t now; time_t now;
time(&now); time(&now);
write_tcp_data(channel, write_fds, now); write_tcp_data(channel, write_fds, ARES_SOCKET_BAD, now);
read_tcp_data(channel, read_fds, now); read_tcp_data(channel, read_fds, ARES_SOCKET_BAD, now);
read_udp_packets(channel, read_fds, now); read_udp_packets(channel, read_fds, ARES_SOCKET_BAD, now);
process_timeouts(channel, now); process_timeouts(channel, now);
} }
/* Something interesting happened on the wire, or there was a timeout.
* See what's up and respond accordingly.
*/
void ares_process_fd(ares_channel channel,
ares_socket_t read_fd, /* use ARES_SOCKET_BAD or valid
file descriptors */
ares_socket_t write_fd)
{
time_t now;
time(&now);
write_tcp_data(channel, NULL, write_fd, now);
read_tcp_data(channel, NULL, read_fd, now);
read_udp_packets(channel, NULL, read_fd, now);
process_timeouts(channel, now);
}
/* Return 1 if the specified error number describes a readiness error, or 0 /* Return 1 if the specified error number describes a readiness error, or 0
* otherwise. This is mostly for HP-UX, which could return EAGAIN or * otherwise. This is mostly for HP-UX, which could return EAGAIN or
* EWOULDBLOCK. See this man page * EWOULDBLOCK. See this man page
@@ -114,7 +133,10 @@ static int try_again(int errnum)
/* If any TCP sockets select true for writing, write out queued data /* If any TCP sockets select true for writing, write out queued data
* we have for them. * we have for them.
*/ */
static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now) static void write_tcp_data(ares_channel channel,
fd_set *write_fds,
ares_socket_t write_fd,
time_t now)
{ {
struct server_state *server; struct server_state *server;
struct send_request *sendreq; struct send_request *sendreq;
@@ -124,14 +146,27 @@ static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now)
ssize_t wcount; ssize_t wcount;
size_t n; size_t n;
if(!write_fds && (write_fd == ARES_SOCKET_BAD))
/* no possible action */
return;
for (i = 0; i < channel->nservers; i++) for (i = 0; i < channel->nservers; i++)
{ {
/* Make sure server has data to send and is selected in write_fds. */ /* Make sure server has data to send and is selected in write_fds or
write_fd. */
server = &channel->servers[i]; server = &channel->servers[i];
if (!server->qhead || server->tcp_socket == ARES_SOCKET_BAD if (!server->qhead || server->tcp_socket == ARES_SOCKET_BAD)
|| !FD_ISSET(server->tcp_socket, write_fds))
continue; continue;
if(write_fds) {
if(!FD_ISSET(server->tcp_socket, write_fds))
continue;
}
else {
if(server->tcp_socket != write_fd)
continue;
}
/* Count the number of send queue items. */ /* Count the number of send queue items. */
n = 0; n = 0;
for (sendreq = server->qhead; sendreq; sendreq = sendreq->next) for (sendreq = server->qhead; sendreq; sendreq = sendreq->next)
@@ -218,20 +253,33 @@ static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now)
* allocate a buffer if we finish reading the length word, and process * allocate a buffer if we finish reading the length word, and process
* a packet if we finish reading one. * a packet if we finish reading one.
*/ */
static void read_tcp_data(ares_channel channel, fd_set *read_fds, time_t now) static void read_tcp_data(ares_channel channel, fd_set *read_fds,
ares_socket_t read_fd, time_t now)
{ {
struct server_state *server; struct server_state *server;
int i; int i;
ssize_t count; ssize_t count;
if(!read_fds && (read_fd == ARES_SOCKET_BAD))
/* no possible action */
return;
for (i = 0; i < channel->nservers; i++) for (i = 0; i < channel->nservers; i++)
{ {
/* Make sure the server has a socket and is selected in read_fds. */ /* Make sure the server has a socket and is selected in read_fds. */
server = &channel->servers[i]; server = &channel->servers[i];
if (server->tcp_socket == ARES_SOCKET_BAD || if (server->tcp_socket == ARES_SOCKET_BAD)
!FD_ISSET(server->tcp_socket, read_fds))
continue; continue;
if(read_fds) {
if(!FD_ISSET(server->tcp_socket, read_fds))
continue;
}
else {
if(server->tcp_socket != read_fd)
continue;
}
if (server->tcp_lenbuf_pos != 2) if (server->tcp_lenbuf_pos != 2)
{ {
/* We haven't yet read a length word, so read that (or /* We haven't yet read a length word, so read that (or
@@ -294,22 +342,34 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds, time_t now)
/* If any UDP sockets select true for reading, process them. */ /* If any UDP sockets select true for reading, process them. */
static void read_udp_packets(ares_channel channel, fd_set *read_fds, static void read_udp_packets(ares_channel channel, fd_set *read_fds,
time_t now) ares_socket_t read_fd, time_t now)
{ {
struct server_state *server; struct server_state *server;
int i; int i;
ssize_t count; ssize_t count;
unsigned char buf[PACKETSZ + 1]; unsigned char buf[PACKETSZ + 1];
if(!read_fds && (read_fd == ARES_SOCKET_BAD))
/* no possible action */
return;
for (i = 0; i < channel->nservers; i++) for (i = 0; i < channel->nservers; i++)
{ {
/* Make sure the server has a socket and is selected in read_fds. */ /* Make sure the server has a socket and is selected in read_fds. */
server = &channel->servers[i]; server = &channel->servers[i];
if (server->udp_socket == ARES_SOCKET_BAD || if (server->udp_socket == ARES_SOCKET_BAD)
!FD_ISSET(server->udp_socket, read_fds))
continue; continue;
if(read_fds) {
if(!FD_ISSET(server->udp_socket, read_fds))
continue;
}
else {
if(server->udp_socket != read_fd)
continue;
}
count = sread(server->udp_socket, buf, sizeof(buf)); count = sread(server->udp_socket, buf, sizeof(buf));
if (count == -1 && try_again(SOCKERRNO)) if (count == -1 && try_again(SOCKERRNO))
continue; continue;
@@ -338,7 +398,7 @@ static void process_timeouts(ares_channel channel, time_t now)
/* Handle an answer from a server. */ /* Handle an answer from a server. */
static void process_answer(ares_channel channel, unsigned char *abuf, static void process_answer(ares_channel channel, unsigned char *abuf,
int alen, int whichserver, int tcp, int now) int alen, int whichserver, int tcp, time_t now)
{ {
int id, tc, rcode; int id, tc, rcode;
struct query *query; struct query *query;

View File

@@ -39,6 +39,64 @@ struct qquery {
static void qcallback(void *arg, int status, unsigned char *abuf, int alen); static void qcallback(void *arg, int status, unsigned char *abuf, int alen);
void ares__rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len)
{
unsigned char x;
unsigned char y;
unsigned char* state;
unsigned char xorIndex;
short counter;
x = key->x;
y = key->y;
state = &key->state[0];
for(counter = 0; counter < buffer_len; counter ++)
{
x = (x + 1) % 256;
y = (state[x] + y) % 256;
ARES_SWAP_BYTE(&state[x], &state[y]);
xorIndex = (state[x] + state[y]) % 256;
buffer_ptr[counter] ^= state[xorIndex];
}
key->x = x;
key->y = y;
}
static struct query* find_query_by_id(ares_channel channel, int id)
{
int qid;
struct query* q;
DNS_HEADER_SET_QID(((unsigned char*)&qid), id);
/* Find the query corresponding to this packet. */
for (q = channel->queries; q; q = q->next)
{
if (q->qid == qid)
return q;
}
return NULL;
}
/* a unique query id is generated using an rc4 key. Since the id may already
be used by a running query (as infrequent as it may be), a lookup is
performed per id generation. In practice this search should happen only
once per newly generated id
*/
static int generate_unique_id(ares_channel channel)
{
int id;
do {
id = ares__generate_new_id(&channel->id_key);
} while (find_query_by_id(channel,id));
return id;
}
void ares_query(ares_channel channel, const char *name, int dnsclass, void ares_query(ares_channel channel, const char *name, int dnsclass,
int type, ares_callback callback, void *arg) int type, ares_callback callback, void *arg)
{ {
@@ -50,13 +108,14 @@ void ares_query(ares_channel channel, const char *name, int dnsclass,
rd = !(channel->flags & ARES_FLAG_NORECURSE); rd = !(channel->flags & ARES_FLAG_NORECURSE);
status = ares_mkquery(name, dnsclass, type, channel->next_id, rd, &qbuf, status = ares_mkquery(name, dnsclass, type, channel->next_id, rd, &qbuf,
&qlen); &qlen);
channel->next_id++;
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)
{ {
callback(arg, status, NULL, 0); callback(arg, status, NULL, 0);
return; return;
} }
channel->next_id = generate_unique_id(channel);
/* Allocate and fill in the query structure. */ /* Allocate and fill in the query structure. */
qquery = malloc(sizeof(struct qquery)); qquery = malloc(sizeof(struct qquery));
if (!qquery) if (!qquery)

49
ares/ares_save_options.3 Normal file
View File

@@ -0,0 +1,49 @@
.\" $Id$
.\"
.\" Copyright 1998 by the Massachusetts Institute of Technology.
.\"
.\" Permission to use, copy, modify, and distribute this
.\" software and its documentation for any purpose and without
.\" fee is hereby granted, provided that the above copyright
.\" notice appear in all copies and that both that copyright
.\" notice and this permission notice appear in supporting
.\" documentation, and that the name of M.I.T. not be used in
.\" advertising or publicity pertaining to distribution of the
.\" software without specific, written prior permission.
.\" M.I.T. makes no representations about the suitability of
.\" this software for any purpose. It is provided "as is"
.\" without express or implied warranty.
.\"
.TH ARES_SAVE_OPTIONS 3 "1 June 2007"
.SH NAME
ares_save_options \- Save configuration values obtained from initialized ares_channel
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B void ares_save_options(ares_channel \fIchannel\fP, struct ares_options *\fIoptions\fP, int *\fIoptmask\fP)
.fi
.SH DESCRIPTION
The
.B ares_save_options
function saves the channel data identified by
.IR channel ,
into the options struct identified by
.IR options ,
and saves the mask of options which are set to the integer
pointer (passed by reference) identified by
.IR optmask .
The resultant options and optmask are then able to be
passed directly to ares_init_options. When the options
are no longer needed, ares_destroy_options should be called
to free any associated memory.
.SH SEE ALSO
.BR ares_destroy_options (3),
.BR ares_init_options (3)
.SH AUTHOR
Brad House
.br
Copyright 1998 by the Massachusetts Institute of Technology.

View File

@@ -31,7 +31,8 @@ struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
{ {
struct query *query; struct query *query;
time_t now; time_t now;
int offset, min_offset; time_t offset, min_offset; /* these use time_t since some 32 bit systems
still use 64 bit time_t! (like VS2005) */
/* No queries, no timeout (and no fetch of the current time). */ /* No queries, no timeout (and no fetch of the current time). */
if (!channel->queries) if (!channel->queries)
@@ -57,7 +58,7 @@ struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
*/ */
if (min_offset != -1 && (!maxtv || min_offset <= maxtv->tv_sec)) if (min_offset != -1 && (!maxtv || min_offset <= maxtv->tv_sec))
{ {
tvbuf->tv_sec = min_offset; tvbuf->tv_sec = (long)min_offset;
tvbuf->tv_usec = 0; tvbuf->tv_usec = 0;
return tvbuf; return tvbuf;
} }

View File

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

View File

@@ -785,4 +785,20 @@ AC_C_BIGENDIAN(
[AC_MSG_WARN([couldn't figure out endianess, assuming little endian!])] [AC_MSG_WARN([couldn't figure out endianess, assuming little endian!])]
) )
dnl Check for user-specified random device
AC_ARG_WITH(random,
AC_HELP_STRING([--with-random=FILE],
[read randomness from FILE (default=/dev/urandom)]),
[ RANDOM_FILE="$withval" ],
[
dnl Check for random device
AC_CHECK_FILE("/dev/urandom", [ RANDOM_FILE="/dev/urandom"] )
]
)
if test -n "$RANDOM_FILE" && test X"$RANDOM_FILE" != Xno ; then
AC_SUBST(RANDOM_FILE)
AC_DEFINE_UNQUOTED(RANDOM_FILE, "$RANDOM_FILE",
[a suitable file/device to read random data from])
fi
AC_OUTPUT(Makefile) AC_OUTPUT(Makefile)

View File

@@ -3,7 +3,7 @@
/* $Id$ */ /* $Id$ */
/* Copyright (C) 2004 - 2005 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 * Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided * documentation for any purpose and without fee is hereby granted, provided
@@ -117,18 +117,6 @@
#undef VERSION #undef VERSION
#undef PACKAGE #undef PACKAGE
/*
* Typedef our socket type
*/
#ifdef USE_WINSOCK
typedef SOCKET ares_socket_t;
#define ARES_SOCKET_BAD INVALID_SOCKET
#else
typedef int ares_socket_t;
#define ARES_SOCKET_BAD -1
#endif
/* /*
* Assume a few thing unless they're set by configure * Assume a few thing unless they're set by configure
*/ */
@@ -156,6 +144,11 @@ int ares_strcasecmp(const char *s1, const char *s2);
same */ same */
#define strncasecmp(a,b,c) ares_strncasecmp(a,b,c) #define strncasecmp(a,b,c) ares_strncasecmp(a,b,c)
#define strcasecmp(a,b) ares_strcasecmp(a,b) #define strcasecmp(a,b) ares_strcasecmp(a,b)
#ifdef _MSC_VER
# if _MSC_VER >= 1400
# define strdup(a) _strdup(a)
# endif
#endif
#endif #endif
/* IPv6 compatibility */ /* IPv6 compatibility */

View File

@@ -337,5 +337,26 @@ typedef int sig_atomic_t;
#endif #endif
/*
* Actually use __32_getpwuid() on 64-bit VMS builds for getpwuid()
*/
#if defined(VMS) && \
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
#define getpwuid __32_getpwuid
#endif
/*
* Macro argv_item_t hides platform details to code using it.
*/
#ifdef VMS
#define argv_item_t __char_ptr32
#else
#define argv_item_t char *
#endif
#endif /* __SETUP_ONCE_H */ #endif /* __SETUP_ONCE_H */

View File

@@ -91,12 +91,16 @@ SOURCE=..\..\adig.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\getopt.c SOURCE=..\..\ares_getopt.c
# End Source File # End Source File
# End Group # End Group
# Begin Group "Header Files" # Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl" # PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\..\ares_getopt.h
# End Source File
# End Group # End Group
# Begin Group "Resource Files" # Begin Group "Resource Files"

View File

@@ -87,10 +87,18 @@ LINK32=link.exe
SOURCE=..\..\ahost.c SOURCE=..\..\ahost.c
# End Source File # End Source File
# Begin Source File
SOURCE=..\..\ares_getopt.c
# End Source File
# End Group # End Group
# Begin Group "Header Files" # Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl" # PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\..\ares_getopt.h
# End Source File
# End Group # End Group
# Begin Group "Resource Files" # Begin Group "Resource Files"

View File

@@ -118,12 +118,16 @@ AC_LIBTOOL_WIN32_DLL
dnl skip libtool C++ and Fortran compiler checks dnl skip libtool C++ and Fortran compiler checks
m4_ifdef([AC_PROG_CXX], [m4_undefine([AC_PROG_CXX])]) m4_ifdef([AC_PROG_CXX], [m4_undefine([AC_PROG_CXX])])
m4_defun([AC_PROG_CXX],[]) m4_defun([AC_PROG_CXX],[])
m4_ifdef([AC_PROG_CXXCPP], [m4_undefine([AC_PROG_CXXCPP])])
m4_defun([AC_PROG_CXXCPP],[true])
m4_ifdef([AC_PROG_F77], [m4_undefine([AC_PROG_F77])]) m4_ifdef([AC_PROG_F77], [m4_undefine([AC_PROG_F77])])
m4_defun([AC_PROG_F77],[]) m4_defun([AC_PROG_F77],[])
dnl skip libtool C++ and Fortran linker checks dnl skip libtool C++ and Fortran linker checks
m4_ifdef([AC_LIBTOOL_CXX], [m4_undefine([AC_LIBTOOL_CXX])]) m4_ifdef([AC_LIBTOOL_CXX], [m4_undefine([AC_LIBTOOL_CXX])])
m4_defun([AC_LIBTOOL_CXX],[]) m4_defun([AC_LIBTOOL_CXX],[])
m4_ifdef([AC_LIBTOOL_CXXCPP], [m4_undefine([AC_LIBTOOL_CXXCPP])])
m4_defun([AC_LIBTOOL_CXXCPP],[true])
m4_ifdef([AC_LIBTOOL_F77], [m4_undefine([AC_LIBTOOL_F77])]) m4_ifdef([AC_LIBTOOL_F77], [m4_undefine([AC_LIBTOOL_F77])])
m4_defun([AC_LIBTOOL_F77],[]) m4_defun([AC_LIBTOOL_F77],[])
@@ -200,6 +204,9 @@ dnl The install stuff has already been taken care of by the automake stuff
dnl AC_PROG_INSTALL dnl AC_PROG_INSTALL
AC_PROG_MAKE_SET AC_PROG_MAKE_SET
dnl check if there's a way to force code inline
AC_C_INLINE
dnl ********************************************************************** dnl **********************************************************************
dnl Make sure that our checks for headers windows.h winsock.h winsock2.h dnl Make sure that our checks for headers windows.h winsock.h winsock2.h
dnl and ws2tcpip.h take precedence over any other further checks which dnl and ws2tcpip.h take precedence over any other further checks which
@@ -412,6 +419,21 @@ then
) )
fi fi
if test "$HAVE_GETHOSTBYNAME" != "1"
then
dnl This is for Minix 3.1
AC_MSG_CHECKING([for gethostbyname for Minix 3])
AC_TRY_LINK([
/* Older Minix versions may need <net/gen/netdb.h> here instead */
#include <netdb.h>],
[gethostbyname("www.dummysite.com");],
[ dnl worked!
AC_MSG_RESULT([yes])
HAVE_GETHOSTBYNAME="1"],
AC_MSG_RESULT(no)
)
fi
if test "$HAVE_GETHOSTBYNAME" != "1" if test "$HAVE_GETHOSTBYNAME" != "1"
then then
dnl This is for eCos with a stubbed DNS implementation dnl This is for eCos with a stubbed DNS implementation
@@ -888,7 +910,7 @@ dnl Default to no CA bundle
ca="no" ca="no"
AC_ARG_WITH(ssl,dnl AC_ARG_WITH(ssl,dnl
AC_HELP_STRING([--with-ssl=PATH],[Where to look for OpenSSL, PATH points to the SSL installation (default: /usr/local/ssl); when possible, set the PKG_CONFIG_PATH environment variable instead of using this option]) AC_HELP_STRING([--with-ssl=PATH],[Where to look for OpenSSL, PATH points to the SSL installation (default: /usr/local/ssl); when possible, set the PKG_CONFIG_PATH environment variable instead of using this option])
AC_HELP_STRING([--without-ssl], [disable SSL]), AC_HELP_STRING([--without-ssl], [disable OpenSSL]),
OPT_SSL=$withval) OPT_SSL=$withval)
if test X"$OPT_SSL" != Xno; then if test X"$OPT_SSL" != Xno; then
@@ -2031,10 +2053,10 @@ fi
dnl set variable for use in automakefile(s) dnl set variable for use in automakefile(s)
AM_CONDITIONAL(USE_MANUAL, test x"$USE_MANUAL" = x1) AM_CONDITIONAL(USE_MANUAL, test x"$USE_MANUAL" = x1)
AC_MSG_CHECKING([whether to enable ares]) AC_MSG_CHECKING([whether to enable c-ares])
AC_ARG_ENABLE(ares, AC_ARG_ENABLE(ares,
AC_HELP_STRING([--enable-ares=PATH],[Enable ares for name lookups]) AC_HELP_STRING([--enable-ares=PATH],[Enable c-ares for name lookups])
AC_HELP_STRING([--disable-ares],[Disable ares for name lookups]), AC_HELP_STRING([--disable-ares],[Disable c-ares for name lookups]),
[ case "$enableval" in [ case "$enableval" in
no) no)
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
@@ -2042,10 +2064,10 @@ AC_HELP_STRING([--disable-ares],[Disable ares for name lookups]),
*) AC_MSG_RESULT(yes) *) AC_MSG_RESULT(yes)
if test "x$IPV6_ENABLED" = "x1"; then if test "x$IPV6_ENABLED" = "x1"; then
AC_MSG_NOTICE([ares may not work properly with ipv6]) AC_MSG_NOTICE([c-ares may not work properly with ipv6])
fi fi
AC_DEFINE(USE_ARES, 1, [Define if you want to enable ares support]) AC_DEFINE(USE_ARES, 1, [Define if you want to enable c-ares support])
dnl substitute HAVE_ARES for curl-config and similar dnl substitute HAVE_ARES for curl-config and similar
HAVE_ARES="1" HAVE_ARES="1"
AC_SUBST(HAVE_ARES) AC_SUBST(HAVE_ARES)
@@ -2090,7 +2112,8 @@ void curl_domalloc() { }
int main(void) int main(void)
{ {
ares_channel channel; ares_channel channel;
ares_cancel(channel); ares_cancel(channel); /* added in 1.2.0 */
ares_process_fd(channel, 0, 0); /* added in 1.4.0 */
return 0; return 0;
} }
], ],

View File

@@ -755,7 +755,9 @@ FAQ
4.9 Curl can't authenticate to the server that requires NTLM? 4.9 Curl can't authenticate to the server that requires NTLM?
This is supported in curl 7.10.6 or later. No earlier curl version knows This is supported in curl 7.10.6 or later. No earlier curl version knows
of this magic. of this magic. Later versions require the OpenSSL or Microsoft Windows
libraries to provide this functionality. Using GnuTLS or NSS libraries will
not provide NTLM authentication functionality in curl.
NTLM is a Microsoft proprietary protocol. Proprietary formats are evil. You NTLM is a Microsoft proprietary protocol. Proprietary formats are evil. You
should not use such ones. should not use such ones.

View File

@@ -33,6 +33,7 @@ libcurl supports
- supports large files (>2GB and >4GB) both upload/download - supports large files (>2GB and >4GB) both upload/download
- replacable memory functions (malloc, free, realloc, etc) - replacable memory functions (malloc, free, realloc, etc)
- asynchronous name resolving (*6) - asynchronous name resolving (*6)
- both a push and a pull style interface
HTTP HTTP
- HTTP/1.1 compliant (optionally uses 1.0) - HTTP/1.1 compliant (optionally uses 1.0)
@@ -40,6 +41,7 @@ HTTP
- PUT - PUT
- HEAD - HEAD
- POST - POST
- Pipelining
- multipart formpost (RFC1867-style) - multipart formpost (RFC1867-style)
- authentication: Basic, Digest, NTLM(*1), GSS-Negotiate/Negotiate(*3) and - authentication: Basic, Digest, NTLM(*1), GSS-Negotiate/Negotiate(*3) and
SPNEGO (*4) to server and proxy SPNEGO (*4) to server and proxy
@@ -94,6 +96,13 @@ FTPS (*1)
- explicit "AUTH TSL" and "AUTH SSL" usage to "upgrade" plain ftp:// - explicit "AUTH TSL" and "AUTH SSL" usage to "upgrade" plain ftp://
connection to use SSL for both or one of the connections connection to use SSL for both or one of the connections
SCP (*8)
- both password and public key auth
SFTP (*8)
- both password and public key auth
- with custom commands sent before/after the transfer
TFTP TFTP
- download / upload - download / upload
@@ -116,10 +125,11 @@ FILE
FOOTNOTES FOOTNOTES
========= =========
*1 = requires OpenSSL, GnuTLS or NSS *1 = requires OpenSSL, GnuTLS, NSS or yassl
*2 = requires OpenLDAP *2 = requires OpenLDAP
*3 = requires a GSSAPI-compliant library, such as Heimdal or similar. *3 = requires a GSSAPI-compliant library, such as Heimdal or similar.
*4 = requires FBopenssl *4 = requires FBopenssl
*5 = requires a krb4 library, such as the MIT one or similar. *5 = requires a krb4 library, such as the MIT one or similar.
*6 = requires c-ares *6 = requires c-ares
*7 = requires OpenSSL or NSS, as GnuTLS only supports SSLv3 and TLSv1 *7 = requires OpenSSL or NSS, as GnuTLS only supports SSLv3 and TLSv1
*8 = requires libssh2

View File

@@ -577,21 +577,32 @@ eCos
Minix Minix
===== =====
curl can be compiled on Minix 3 using gcc (ACK has a few problems due curl can be compiled on Minix 3 using gcc or ACK (starting with
to mismatched headers and libraries as of ver. 3.1.2). The gcc and bash ver. 3.1.3). The gcc and bash packages must be installed first.
packages must be installed first. The default heap size allocated to The default heap size allocated to bash is inadequate for running
bash is inadequate for running configure and will result in out of memory configure and will result in out of memory errors. Increase it with
errors. Increase it with the command: the command:
chmem =2048000 /usr/local/bin/bash chmem =2048000 /usr/local/bin/bash
Make sure gcc and bash are in the PATH then configure curl with a Make sure gcc and bash are in the PATH with the command:
command like this:
./configure GREP=/usr/bin/grep AR=/usr/gnu/bin/gar --disable-ldap export PATH=/usr/gnu/bin:$PATH
then configure curl with a command like this:
./configure CC=gcc GREP=grep AR=/usr/gnu/bin/gar --disable-ldap
Then simply run 'make'. Then simply run 'make'.
To compile with the ACK C compiler:
chmem =1024000 /usr/lib/em_cemcom.ansi
chmem =512000 /usr/lib/i386/as
./configure CC=cc LD=cc GREP=grep CPPFLAGS=-D_POSIX_SOURCE=1 \
--disable-ldap
make
CROSS COMPILE CROSS COMPILE
============= =============
@@ -728,7 +739,7 @@ PORTS
- i386 FreeBSD - i386 FreeBSD
- i386 HURD - i386 HURD
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6 - i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6
- i386 MINIX 3.1.2 - i386 MINIX 3.1
- i386 NetBSD - i386 NetBSD
- i386 Novell NetWare - i386 Novell NetWare
- i386 OS/2 - i386 OS/2

View File

@@ -3,14 +3,17 @@ 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 changelog of the current development status, as one or more of these problems
may have been fixed since this was written! may have been fixed since this was written!
44. --ftp-method nocwd does not handle URLs ending with a slash properly (it
should list the contents of that directory). See test case 351.
43. There seems to be a problem when connecting to the Microsoft telnet server.
http://curl.haxx.se/bug/view.cgi?id=1720605
41. When doing an operation over FTP that requires the ACCT command (but not 41. When doing an operation over FTP that requires the ACCT command (but not
when logging in), the operation will fail since libcurl doesn't detect this when logging in), the operation will fail since libcurl doesn't detect this
and thus fails to issue the correct command: and thus fails to issue the correct command:
http://curl.haxx.se/bug/view.cgi?id=1693337 http://curl.haxx.se/bug/view.cgi?id=1693337
40. Mac OS X test failures (Daniel Johnson)
http://curl.haxx.se/mail/lib-2007-03/0095.html
39. Steffen Rumler's Race Condition in Curl_proxyCONNECT: 39. Steffen Rumler's Race Condition in Curl_proxyCONNECT:
http://curl.haxx.se/mail/lib-2007-01/0045.html http://curl.haxx.se/mail/lib-2007-01/0045.html

View File

@@ -4,6 +4,7 @@
If you have contributed but are missing here, please let us know! If you have contributed but are missing here, please let us know!
Adam D. Moss
Adrian Schuur Adrian Schuur
Alan Pinstein Alan Pinstein
Albert Chin-A-Young Albert Chin-A-Young
@@ -92,6 +93,7 @@ Dan Fandrich
Dan Nelson Dan Nelson
Dan Torop Dan Torop
Dan Zitter Dan Zitter
Daniel Johnson
Daniel Stenberg Daniel Stenberg
Daniel at touchtunes Daniel at touchtunes
Darryl House Darryl House
@@ -135,6 +137,7 @@ Douglas E. Wegscheid
Douglas R. Horner Douglas R. Horner
Dov Murik Dov Murik
Duane Cathey Duane Cathey
Duncan Mac-Vicar Prett
Dustin Boswell Dustin Boswell
Dylan Ellicott Dylan Ellicott
Dylan Salisbury Dylan Salisbury
@@ -156,6 +159,7 @@ Erwan Legrand
Erwin Authried Erwin Authried
Eugene Kotlyarov Eugene Kotlyarov
Evan Jordan Evan Jordan
Eygene Ryabinkin
Fabrizio Ammollo Fabrizio Ammollo
Fedor Karpelevitch Fedor Karpelevitch
Felix von Leitner Felix von Leitner
@@ -191,6 +195,7 @@ Gwenole Beauchesne
G<EFBFBD>tz Babin-Ebell G<EFBFBD>tz Babin-Ebell
G<EFBFBD>nter Knauf G<EFBFBD>nter Knauf
Hamish Mackenzie Hamish Mackenzie
Hang Kin Lau
Hanno Kranzhoff Hanno Kranzhoff
Hans Steegers Hans Steegers
Hardeep Singh Hardeep Singh
@@ -200,6 +205,7 @@ Henrik Storner
Hzhijun Hzhijun
Ian Ford Ian Ford
Ian Gulliver Ian Gulliver
Ian Turner
Ian Wilkes Ian Wilkes
Ignacio Vazquez-Abrams Ignacio Vazquez-Abrams
Igor Polyakov Igor Polyakov
@@ -254,6 +260,7 @@ Jonas Forsman
Jonatan Lander Jonatan Lander
Jonathan Hseu Jonathan Hseu
Jongki Suwandi Jongki Suwandi
Jose Kahan
Josh Kapell Josh Kapell
Juan F. Codagnone Juan F. Codagnone
Juan Ignacio Herv<72>s Juan Ignacio Herv<72>s
@@ -262,6 +269,7 @@ Jukka Pihl
Julian Noble Julian Noble
Jun-ichiro itojun Hagino Jun-ichiro itojun Hagino
Jurij Smakov Jurij Smakov
Justin Fletcher
J<EFBFBD>rg Mueller-Tolk J<EFBFBD>rg Mueller-Tolk
J<EFBFBD>rn Hartroth J<EFBFBD>rn Hartroth
Kai Sommerfeld Kai Sommerfeld
@@ -309,6 +317,7 @@ Luke Call
Luong Dinh Dung Luong Dinh Dung
Maciej Karpiuk Maciej Karpiuk
Maciej W. Rozycki Maciej W. Rozycki
Manfred Schwarb
Marc Boucher Marc Boucher
Marcelo Juchem Marcelo Juchem
Marcin Konicki Marcin Konicki
@@ -330,6 +339,7 @@ Maruko
Massimiliano Ziccardi Massimiliano Ziccardi
Mathias Axelsson Mathias Axelsson
Mats Lidell Mats Lidell
Matt Kraai
Matt Veenstra Matt Veenstra
Matt Witherspoon Matt Witherspoon
Matthew Blain Matthew Blain
@@ -364,6 +374,7 @@ Neil Spring
Nic Roets Nic Roets
Nick Gimbrone Nick Gimbrone
Nick Humfrey Nick Humfrey
Nick Zitzmann
Nico Baggus Nico Baggus
Nicolas Berloquin Nicolas Berloquin
Nicolas Croiset Nicolas Croiset
@@ -432,9 +443,13 @@ Richard Gorton
Richard Prescott Richard Prescott
Rick Jones Rick Jones
Rick Richardson Rick Richardson
Rob Crittenden
Rob Jones
Rob Stanzel Rob Stanzel
Robert A. Monat
Robert D. Young Robert D. Young
Robert Foreman Robert Foreman
Robert Iakobashvili
Robert Olson Robert Olson
Robert Weaver Robert Weaver
Robin Kay Robin Kay

View File

@@ -216,7 +216,8 @@ local directory hierarchy as needed. This option creates the dirs mentioned
with the -o option, nothing else. If the -o file name uses no dir or if the with the -o option, nothing else. If the -o file name uses no dir or if the
dirs it mentions already exist, no dir will be created. dirs it mentions already exist, no dir will be created.
To create remote directories when using FTP, try \fI--ftp-create-dirs\fP. To create remote directories when using FTP or SFTP, try
\fI--ftp-create-dirs\fP.
.IP "--crlf" .IP "--crlf"
(FTP) Convert LF to CRLF in upload. Useful for MVS (OS/390). (FTP) Convert LF to CRLF in upload. Useful for MVS (OS/390).
@@ -370,7 +371,7 @@ normal cases when a HTTP server fails to deliver a document, it returns an
HTML document stating so (which often also describes why and more). This flag HTML document stating so (which often also describes why and more). This flag
will prevent curl from outputting that and return error 22. will prevent curl from outputting that and return error 22.
This method is not fail-safe and there are occasions where non-succesful This method is not fail-safe and there are occasions where non-successful
response codes will slip through, especially when authentication is involved response codes will slip through, especially when authentication is involved
(response codes 401 and 407). (response codes 401 and 407).
@@ -382,7 +383,7 @@ has been provided, this data is sent off using the ACCT command. (Added in
If this option is used twice, the second will override the previous use. If this option is used twice, the second will override the previous use.
.IP "--ftp-create-dirs" .IP "--ftp-create-dirs"
(FTP) When an FTP URL/operation uses a path that doesn't currently exist on (FTP) When an FTP or SFTP URL/operation uses a path that doesn't currently exist on
the server, the standard behavior of curl is to fail. Using this option, curl the server, the standard behavior of curl is to fail. Using this option, curl
will instead attempt to create missing directories. will instead attempt to create missing directories.
@@ -593,11 +594,11 @@ assumed.
If this option is used several times, the last one will be used. If this option is used several times, the last one will be used.
.IP "--krb4 <level>" .IP "--krb4 <level>"
(FTP) Enable kerberos4 authentication and use. The level must be entered and (FTP) Enable Kerberos4 authentication and use. The level must be entered and
should be one of 'clear', 'safe', 'confidential' or 'private'. Should you use should be one of 'clear', 'safe', 'confidential' or 'private'. Should you use
a level that is not one of these, 'private' will instead be used. a level that is not one of these, 'private' will instead be used.
This option requires that the library was built with kerberos4 support. This This option requires that the library was built with Kerberos4 support. This
is not very common. Use \fI-V/--version\fP to see if your curl supports it. is not very common. Use \fI-V/--version\fP to see if your curl supports it.
If this option is used several times, the last one will be used. If this option is used several times, the last one will be used.
@@ -689,7 +690,7 @@ subdirectories and symbolic links.
If this option is used twice, the second will again disable list only. If this option is used twice, the second will again disable list only.
.IP "--local-port <num>[-num]" .IP "--local-port <num>[-num]"
Set a prefered number or range of local port numbers to use for the Set a preferred number or range of local port numbers to use for the
connection(s). Note that port numbers by nature is a scarce resource that connection(s). Note that port numbers by nature is a scarce resource that
will be busy at times so setting this range to something too narrow might will be busy at times so setting this range to something too narrow might
cause unnecessary connection setup failures. (Added in 7.15.2) cause unnecessary connection setup failures. (Added in 7.15.2)
@@ -704,6 +705,11 @@ able to intercept the user+password. See also \fI--location-trusted\fP on how
to change this. You can limit the amount of redirects to follow by using the to change this. You can limit the amount of redirects to follow by using the
\fI--max-redirs\fP option. \fI--max-redirs\fP option.
When curl follows a redirect and the request is not a plain GET (for example
POST or PUT), it will do the following request with a GET if the HTTP response
was 301, 302, or 303. If the response code was any other 3xx code, curl will
re-send the following request using the same unmodified method.
If this option is used twice, the second will again disable location following. If this option is used twice, the second will again disable location following.
.IP "--location-trusted" .IP "--location-trusted"
(HTTP/HTTPS) Like \fI-L/--location\fP, but will allow sending the name + (HTTP/HTTPS) Like \fI-L/--location\fP, but will allow sending the name +
@@ -867,7 +873,7 @@ separate file.
If this option is used several times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-P/--ftp-port <address>" .IP "-P/--ftp-port <address>"
(FTP) Reverses the initiator/listener roles when connecting with ftp. This (FTP) Reverses the initiator/listener roles when connecting with ftp. This
switch makes Curl use the PORT command instead of PASV. In practice, PORT switch makes Curl use the PORT command instead of PASV. In practise, PORT
tells the server to connect to the client's specified address and port, while tells the server to connect to the client's specified address and port, while
PASV asks the server for an ip address and port to connect to. <address> PASV asks the server for an ip address and port to connect to. <address>
should be one of: should be one of:
@@ -891,14 +897,18 @@ If used as the first parameter on the command line, the \fIcurlrc\fP config
file will not be read and used. See the \fI-K/--config\fP for details on the file will not be read and used. See the \fI-K/--config\fP for details on the
default config file search path. default config file search path.
.IP "-Q/--quote <command>" .IP "-Q/--quote <command>"
(FTP) Send an arbitrary command to the remote FTP server. Quote commands are (FTP/SFTP) Send an arbitrary command to the remote FTP or SFTP server. Quote
sent BEFORE the transfer is taking place (just after the initial PWD command commands are sent BEFORE the transfer is taking place (just after the
to be exact). To make commands take place after a successful transfer, prefix initial PWD command in an FTP transfer, to be exact). To make commands
them with a dash '-'. To make commands get sent after libcurl has changed take place after a successful transfer, prefix them with a dash '-'.
working directory, just before the transfer command(s), prefix the command To make commands get sent after libcurl has changed working directory,
with '+'. You may specify any amount of commands. If the server returns just before the transfer command(s), prefix the command with '+' (this
failure for one of the commands, the entire operation will be aborted. You is only supported for FTP). You may specify any number of commands. If
must send syntactically correct FTP commands as RFC959 defines. the server returns failure for one of the commands, the entire operation
will be aborted. You must send syntactically correct FTP commands as
RFC959 defines to FTP servers, or one of the following commands (with
appropriate arguments) to SFTP servers: chgrp, chmod, chown, ln, mkdir,
rename, rm, rmdir, symlink.
This option can be used multiple times. This option can be used multiple times.
.IP "--random-file <file>" .IP "--random-file <file>"
@@ -936,6 +946,10 @@ specifies two separate 100 bytes ranges(*)(H)
(*) = NOTE that this will cause the server to reply with a multipart (*) = NOTE that this will cause the server to reply with a multipart
response! response!
Only digit characters (0-9) are valid in 'start' and 'stop' of range syntax
\&'start-stop'. If a non-digit character is given in the range, the server's
response will be indeterminable, depending on different server's configuration.
You should also be aware that many HTTP/1.1 servers do not have this feature You should also be aware that many HTTP/1.1 servers do not have this feature
enabled, so that when you attempt to get a range, you'll instead get the whole enabled, so that when you attempt to get a range, you'll instead get the whole
document. document.
@@ -1082,7 +1096,7 @@ If this option is used several times, each occurrence will toggle it on/off.
Specify user and password to use for server authentication. Overrides Specify user and password to use for server authentication. Overrides
\fI-n/--netrc\fP and \fI--netrc-optional\fP. \fI-n/--netrc\fP and \fI--netrc-optional\fP.
If you use an SSPI-enabled curl binary and do NTLM autentication, you can If you use an SSPI-enabled curl binary and do NTLM authentication, you can
force curl to pick up the user name and password from your environment by force curl to pick up the user name and password from your environment by
simply specifying a single colon with this option: "-u :". simply specifying a single colon with this option: "-u :".
@@ -1090,7 +1104,7 @@ If this option is used several times, the last one will be used.
.IP "-U/--proxy-user <user:password>" .IP "-U/--proxy-user <user:password>"
Specify user and password to use for proxy authentication. Specify user and password to use for proxy authentication.
If you use an SSPI-enabled curl binary and do NTLM autentication, you can If you use an SSPI-enabled curl binary and do NTLM authentication, you can
force curl to pick up the user name and password from your environment by force curl to pick up the user name and password from your environment by
simply specifying a single colon with this option: "-U :". simply specifying a single colon with this option: "-U :".
@@ -1458,7 +1472,7 @@ Internal error. A function was called in a bad order.
.IP 45 .IP 45
Interface error. A specified outgoing interface could not be used. Interface error. A specified outgoing interface could not be used.
.IP 46 .IP 46
Bad password entered. An error was signaled when the password was entered. Bad password entered. An error was signalled when the password was entered.
.IP 47 .IP 47
Too many redirects. When following redirects, curl hit the maximum amount. Too many redirects. When following redirects, curl hit the maximum amount.
.IP 48 .IP 48

View File

@@ -92,18 +92,15 @@ typedef struct _SockInfo {
/* Update the event timer after curl_multi library calls */ /* Update the event timer after curl_multi library calls */
static void update_timeout(GlobalInfo *g) static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
{ {
long timeout_ms;
struct timeval timeout; struct timeval timeout;
curl_multi_timeout(g->multi, &timeout_ms);
if(timeout_ms < 0)
return;
timeout.tv_sec = timeout_ms/1000; timeout.tv_sec = timeout_ms/1000;
timeout.tv_usec = (timeout_ms%1000)*1000; timeout.tv_usec = (timeout_ms%1000)*1000;
fprintf(MSG_OUT, "multi_timer_cb: Setting timeout to %ld ms\n", timeout_ms);
evtimer_add(&g->timer_event, &timeout); evtimer_add(&g->timer_event, &timeout);
return 0;
} }
@@ -185,9 +182,7 @@ static void event_cb(int fd, short kind, void *userp)
} while (rc == CURLM_CALL_MULTI_PERFORM); } while (rc == CURLM_CALL_MULTI_PERFORM);
mcode_or_die("event_cb: curl_multi_socket", rc); mcode_or_die("event_cb: curl_multi_socket", rc);
check_run_count(g); check_run_count(g);
if(g->still_running) { if ( g->still_running <= 0 ) {
update_timeout(g);
} else {
fprintf(MSG_OUT, "last transfer done, kill timeout\n"); fprintf(MSG_OUT, "last transfer done, kill timeout\n");
if (evtimer_pending(&g->timer_event, NULL)) { if (evtimer_pending(&g->timer_event, NULL)) {
evtimer_del(&g->timer_event); evtimer_del(&g->timer_event);
@@ -210,7 +205,6 @@ static void timer_cb(int fd, short kind, void *userp)
} while (rc == CURLM_CALL_MULTI_PERFORM); } while (rc == CURLM_CALL_MULTI_PERFORM);
mcode_or_die("timer_cb: curl_multi_socket", rc); mcode_or_die("timer_cb: curl_multi_socket", rc);
check_run_count(g); check_run_count(g);
if ( g->still_running ) { update_timeout(g); }
} }
@@ -406,10 +400,11 @@ int main(int argc, char **argv)
evtimer_set(&g.timer_event, timer_cb, &g); evtimer_set(&g.timer_event, timer_cb, &g);
curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb); curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g); curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g);
do { do {
rc = curl_multi_socket_all(g.multi, &g.still_running); rc = curl_multi_socket_all(g.multi, &g.still_running);
} while (CURLM_CALL_MULTI_PERFORM == rc); } while (CURLM_CALL_MULTI_PERFORM == rc);
update_timeout(&g);
event_dispatch(); event_dispatch();
curl_multi_cleanup(g.multi); curl_multi_cleanup(g.multi);
return 0; return 0;

View File

@@ -39,7 +39,7 @@ this function AFTER a performed transfer if you want to get transfer- oriented
data. data.
You should not free the memory returned by this function unless it is You should not free the memory returned by this function unless it is
explictly mentioned below. explicitly mentioned below.
.SH AVAILABLE INFORMATION .SH AVAILABLE INFORMATION
The following information can be extracted: The following information can be extracted:
.IP CURLINFO_EFFECTIVE_URL .IP CURLINFO_EFFECTIVE_URL

View File

@@ -345,7 +345,7 @@ A non-zero parameter tells the library to fail silently if the HTTP code
returned is equal to or larger than 400. The default action would be to return returned is equal to or larger than 400. The default action would be to return
the page normally, ignoring that code. the page normally, ignoring that code.
This method is not fail-safe and there are occasions where non-succesful This method is not fail-safe and there are occasions where non-successful
response codes will slip through, especially when authentication is involved response codes will slip through, especially when authentication is involved
(response codes 401 and 407). (response codes 401 and 407).
@@ -445,7 +445,7 @@ not an order. You cannot be guaranteed to actually get the given size. (Added
in 7.10) in 7.10)
This size is by default set as big as possible (CURL_MAX_WRITE_SIZE), so it This size is by default set as big as possible (CURL_MAX_WRITE_SIZE), so it
only makse sense to use this option if you want it smaller. only makes sense to use this option if you want it smaller.
.IP CURLOPT_PORT .IP CURLOPT_PORT
Pass a long specifying what remote port number to connect to, instead of the Pass a long specifying what remote port number to connect to, instead of the
one specified in the URL or the default port for the used protocol. one specified in the URL or the default port for the used protocol.
@@ -649,7 +649,7 @@ When setting \fICURLOPT_POST\fP to a non-zero value, it will automatically set
\fICURLOPT_NOBODY\fP to 0 (since 7.14.1). \fICURLOPT_NOBODY\fP to 0 (since 7.14.1).
If you issue a POST request and then want to make a HEAD or GET using the same If you issue a POST request and then want to make a HEAD or GET using the same
re-used handle, you must explictly set the new request type using re-used handle, you must explicitly set the new request type using
\fICURLOPT_NOBODY\fP or \fICURLOPT_HTTPGET\fP or similar. \fICURLOPT_NOBODY\fP or \fICURLOPT_HTTPGET\fP or similar.
.IP CURLOPT_POSTFIELDS .IP CURLOPT_POSTFIELDS
Pass a char * as parameter, which should be the full data to post in an HTTP Pass a char * as parameter, which should be the full data to post in an HTTP
@@ -736,10 +736,9 @@ The linked list should be a fully valid list of struct curl_slist structs, and
be properly filled in. Use \fIcurl_slist_append(3)\fP to create the list and be properly filled in. Use \fIcurl_slist_append(3)\fP to create the list and
\fIcurl_slist_free_all(3)\fP to clean up an entire list. \fIcurl_slist_free_all(3)\fP to clean up an entire list.
The alias itself is not parsed for any version strings. So if your alias is The alias itself is not parsed for any version strings. Before libcurl 7.16.3,
\&"MYHTTP/9.9", Libcurl will not treat the server as responding with HTTP Libcurl used the value set by option \fICURLOPT_HTTP_VERSION\fP, but starting
version 9.9. Instead Libcurl will use the value set by option with 7.16.3 the protocol is assumed to match HTTP 1.0 when an alias matched.
\fICURLOPT_HTTP_VERSION\fP.
.IP CURLOPT_COOKIE .IP CURLOPT_COOKIE
Pass a pointer to a zero terminated string as parameter. It will be used to Pass a pointer to a zero terminated string as parameter. It will be used to
set a cookie in the http request. The format of the string should be set a cookie in the http request. The format of the string should be
@@ -840,19 +839,20 @@ address. Default FTP operations are passive, and thus won't use PORT.
You disable PORT again and go back to using the passive version by setting You disable PORT again and go back to using the passive version by setting
this option to NULL. this option to NULL.
.IP CURLOPT_QUOTE .IP CURLOPT_QUOTE
Pass a pointer to a linked list of FTP commands to pass to the server prior to Pass a pointer to a linked list of FTP or SFTP commands to pass to
your ftp request. This will be done before any other FTP commands are issued the server prior to your ftp request. This will be done before any
(even before the CWD command). The linked list should be a fully valid list of other commands are issued (even before the CWD command for FTP). The
'struct curl_slist' structs properly filled in. Use \fIcurl_slist_append(3)\fP linked list should be a fully valid list of 'struct curl_slist' structs
to append strings (commands) to the list, and clear the entire list afterwards properly filled in with text strings. Use \fIcurl_slist_append(3)\fP
with \fIcurl_slist_free_all(3)\fP. Disable this operation again by setting a to append strings (commands) to the list, and clear the entire list
NULL to this option. afterwards with \fIcurl_slist_free_all(3)\fP. Disable this operation
again by setting a NULL to this option.
.IP CURLOPT_POSTQUOTE .IP CURLOPT_POSTQUOTE
Pass a pointer to a linked list of FTP commands to pass to the server after Pass a pointer to a linked list of FTP or SFTP commands to pass to the
your ftp transfer request. The linked list should be a fully valid list of server after your ftp transfer request. The linked list should be a
struct curl_slist structs properly filled in as described for fully valid list of struct curl_slist structs properly filled in as
\fICURLOPT_QUOTE\fP. Disable this operation again by setting a NULL to this described for \fICURLOPT_QUOTE\fP. Disable this operation again by
option. setting a NULL to this option.
.IP CURLOPT_PREQUOTE .IP CURLOPT_PREQUOTE
Pass a pointer to a linked list of FTP commands to pass to the server after Pass a pointer to a linked list of FTP commands to pass to the server after
the transfer type is set. The linked list should be a fully valid list of the transfer type is set. The linked list should be a fully valid list of
@@ -890,6 +890,11 @@ If the server is an IPv6 host, this option will have no effect as of 7.12.3.
Pass a long. If the value is non-zero, curl will attempt to create any remote Pass a long. If the value is non-zero, curl will attempt to create any remote
directory that it fails to CWD into. CWD is the command that changes working directory that it fails to CWD into. CWD is the command that changes working
directory. (Added in 7.10.7) directory. (Added in 7.10.7)
This setting also applies to SFTP-connections. curl will attempt to create
the remote directory if it can't obtain a handle to the target-location. The
creation will fail if a file of the same name as the directory to create
already exists or lack of permissions prevents creation. (Added in 7.16.3)
.IP CURLOPT_FTP_RESPONSE_TIMEOUT .IP CURLOPT_FTP_RESPONSE_TIMEOUT
Pass a long. Causes curl to set a timeout period (in seconds) on the amount Pass a long. Causes curl to set a timeout period (in seconds) on the amount
of time that the server is allowed to take in order to generate a response of time that the server is allowed to take in order to generate a response
@@ -1036,6 +1041,9 @@ 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 libcurl what the expected size of the infile is. This value should be passed
as a long. See also \fICURLOPT_INFILESIZE_LARGE\fP. as a long. See also \fICURLOPT_INFILESIZE_LARGE\fP.
For uploading using SCP, this option or \fICURLOPT_INFILESIZE_LARGE\fP is
mandatory.
Note that this option does not limit how much data libcurl will actually send, 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. as that is controlled entirely by what the read callback returns.
.IP CURLOPT_INFILESIZE_LARGE .IP CURLOPT_INFILESIZE_LARGE
@@ -1043,6 +1051,8 @@ 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 libcurl what the expected size of the infile is. This value should be passed
as a curl_off_t. (Added in 7.11.0) as a curl_off_t. (Added in 7.11.0)
For uploading using SCP, this option or \fICURLOPT_INFILESIZE\fP is mandatory.
Note that this option does not limit how much data libcurl will actually send, 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. as that is controlled entirely by what the read callback returns.
.IP CURLOPT_UPLOAD .IP CURLOPT_UPLOAD
@@ -1124,10 +1134,10 @@ speed. (Added in 7.15.5)
.IP CURLOPT_MAXCONNECTS .IP CURLOPT_MAXCONNECTS
Pass a long. The set number will be the persistent connection cache size. The Pass a long. The set number will be the persistent connection cache size. The
set amount will be the maximum amount of simultaneously open connections that set amount will be the maximum amount of simultaneously open connections that
libcurl may cache. Default is 5, and there isn't much point in changing this libcurl may cache in this easy handle. Default is 5, and there isn't much
value unless you are perfectly aware of how this work and changes libcurl's point in changing this value unless you are perfectly aware of how this work
behaviour. This concerns connection using any of the protocols that support and changes libcurl's behaviour. This concerns connection using any of the
persistent connections. protocols that support persistent connections.
When reaching the maximum limit, curl closes the oldest one in the cache to When reaching the maximum limit, curl closes the oldest one in the cache to
prevent the number of open connections to increase. prevent the number of open connections to increase.
@@ -1135,6 +1145,10 @@ prevent the number of open connections to increase.
If you already have performed transfers with this curl handle, setting a If you already have performed transfers with this curl handle, setting a
smaller MAXCONNECTS than before may cause open connections to get closed smaller MAXCONNECTS than before may cause open connections to get closed
unnecessarily. unnecessarily.
Note that if you add this easy handle to a multi handle, this setting is not
being acknowledged, but you must instead use \fIcurl_multi_setopt(3)\fP and
the \fICURLMOPT_MAXCONNECTS\fP option.
.IP CURLOPT_CLOSEPOLICY .IP CURLOPT_CLOSEPOLICY
(Obsolete) This option does nothing. (Obsolete) This option does nothing.
.IP CURLOPT_FRESH_CONNECT .IP CURLOPT_FRESH_CONNECT
@@ -1360,7 +1374,7 @@ require you to disable this in order for you to succeed. (Added in 7.16.0)
Pass a char * as parameter. Set the krb4 security level, this also enables Pass a char * as parameter. Set the krb4 security level, this also enables
krb4 awareness. This is a string, 'clear', 'safe', 'confidential' or krb4 awareness. This is a string, 'clear', 'safe', 'confidential' or
\&'private'. If the string is set but doesn't match one of these, 'private' \&'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 will be used. Set the string to NULL to disable Kerberos4. The Kerberos
support only works for FTP. support only works for FTP.
.SH SSH OPTIONS .SH SSH OPTIONS
.IP CURLOPT_SSH_AUTH_TYPES .IP CURLOPT_SSH_AUTH_TYPES

View File

@@ -25,8 +25,8 @@ queue so calling this function again will not return the same message
again. It will instead return new messages at each new invoke until the queue again. It will instead return new messages at each new invoke until the queue
is emptied. is emptied.
The data the returned pointer points to will not survive calling \fBWARNING:\fP The data the returned pointer points to will not survive
\fIcurl_multi_cleanup(3)\fP, \fIcurl_multi_remove_handle(3)\fP or calling \fIcurl_multi_cleanup(3)\fP, \fIcurl_multi_remove_handle(3)\fP or
\fIcurl_easy_cleanup(3)\fP. \fIcurl_easy_cleanup(3)\fP.
The 'CURLMsg' struct is very simple and only contain very basic information. The 'CURLMsg' struct is very simple and only contain very basic information.

View File

@@ -56,6 +56,22 @@ Pass a pointer to whatever you want passed to the
\fBcurl_multi_timer_callback\fP's third argument, the userp pointer. This is \fBcurl_multi_timer_callback\fP's third argument, the userp pointer. This is
not used by libcurl but only passed-thru as-is. Set the callback pointer with not used by libcurl but only passed-thru as-is. Set the callback pointer with
\fICURLMOPT_TIMERFUNCTION\fP. (Added in 7.16.0) \fICURLMOPT_TIMERFUNCTION\fP. (Added in 7.16.0)
.IP CURLMOPT_MAXCONNECTS
Pass a long. The set number will be used as the maximum amount of
simultaneously open connections that libcurl may cache. Default is 10, and
libcurl will enlarge the size for each added easy handle to make it fit 4
times the number of added easy handles.
By setting this option, you can prevent the cache size to grow beyond the
limit set by you.
When the cache is full, curl closes the oldest one in the cache to prevent the
number of open connections to increase.
This option is for the multi handle's use only, when using the easy interface
you should instead use the \fICURLOPT_MAXCONNECTS\fP option.
(Added in 7.16.3)
.SH RETURNS .SH RETURNS
The standard CURLMcode for multi interface error codes. Note that it returns a The standard CURLMcode for multi interface error codes. Note that it returns a
CURLM_UNKNOWN_OPTION if you try setting an option that this version of libcurl CURLM_UNKNOWN_OPTION if you try setting an option that this version of libcurl

View File

@@ -4,29 +4,40 @@
.SH NAME .SH NAME
curl_multi_socket \- reads/writes available data curl_multi_socket \- reads/writes available data
.SH SYNOPSIS .SH SYNOPSIS
.nf
#include <curl/curl.h> #include <curl/curl.h>
CURLMcode curl_multi_socket_action(CURLM * multi_handle,
curl_socket_t sockfd, int ev_bitmask,
int *running_handles);
CURLMcode curl_multi_socket(CURLM * multi_handle, curl_socket_t sockfd, CURLMcode curl_multi_socket(CURLM * multi_handle, curl_socket_t sockfd,
int *running_handles); int *running_handles);
CURLMcode curl_multi_socket_all(CURLM *multi_handle, CURLMcode curl_multi_socket_all(CURLM *multi_handle,
int *running_handles); int *running_handles);
.fi
.SH DESCRIPTION .SH DESCRIPTION
Alternative versions of \fIcurl_multi_perform(3)\fP that allows the Alternative versions of \fIcurl_multi_perform(3)\fP that allows the
application to pass in one of the file descriptors/sockets that have been application to pass in the file descriptor/socket that has been detected to
detected to have \&"action" on them and let libcurl perform. This allows have \&"action" on it and let libcurl perform. This allows libcurl to not have
libcurl to not have to scan through all possible file descriptors to check for to scan through all possible file descriptors to check for action. When the
action. When the application has detected action on a socket handled by application has detected action on a socket handled by libcurl, it should call
libcurl, it should call \fIcurl_multi_socket(3)\fP with the \fBsockfd\fP \fIcurl_multi_socket_action(3)\fP with the \fBsockfd\fP argument set to the
argument set to the socket with the action. socket with the action. When the events on a socket are known, they can be
passed as an events bitmask \fBev_bitmask\fP by first setting \fBev_bitmask\fP
to 0, and then adding using bitwise OR (|) any combination of events to be
choosen from CURL_CSELECT_IN, CURL_CSELECT_OUT or CURL_CSELECT_ERR. When the
events on a socket are unknown, pass 0 instead, and libcurl will test the
descriptor internally.
At return, the int \fBrunning_handles\fP points to will contain the number of At return, the int \fBrunning_handles\fP points to will contain the number of
still running easy handles within the multi handle. When this number reaches still running easy handles within the multi handle. When this number reaches
zero, all transfers are complete/done. Note that when you call zero, all transfers are complete/done. Note that when you call
\fIcurl_multi_socket(3)\fP on a specific socket and the counter decreases by \fIcurl_multi_socket_action(3)\fP on a specific socket and the counter
one, it DOES NOT necessarily mean that this exact socket/transfer is the one decreases by one, it DOES NOT necessarily mean that this exact socket/transfer
that completed. Use \fIcurl_multi_info_read(3)\fP to figure out which easy is the one that completed. Use \fIcurl_multi_info_read(3)\fP to figure out
handle that completed. which easy handle that completed.
The curl_multi_socket functions inform the application about updates in the The curl_multi_socket functions inform the application about updates in the
socket (file descriptor) status by doing none, one or multiple calls to the socket (file descriptor) status by doing none, one or multiple calls to the
@@ -44,6 +55,10 @@ wait for socket actions \- at most \- before doing the timeout action: call
the \fBcurl_multi_socket(3)\fP function with the \fBsockfd\fP argument set to the \fBcurl_multi_socket(3)\fP function with the \fBsockfd\fP argument set to
CURL_SOCKET_TIMEOUT. CURL_SOCKET_TIMEOUT.
Usage of \fIcurl_multi_socket(3)\fP is depricated, whereas the function is
equivalent to \fIcurl_multi_socket_action(3)\fP, when \fBev_bitmask\fP is set
to 0.
.SH "CALLBACK DETAILS" .SH "CALLBACK DETAILS"
The socket \fBcallback\fP function uses a prototype like this The socket \fBcallback\fP function uses a prototype like this
@@ -115,12 +130,15 @@ callback is called.
7. Wait for action on any of libcurl's sockets 7. Wait for action on any of libcurl's sockets
8, When action happens, call curl_multi_socket() for the socket(s) that got 8, When action happens, call curl_multi_socket_action() for the socket(s) that got
action. action.
9. Go back to step 6. 9. Go back to step 6.
.SH AVAILABILITY .SH AVAILABILITY
This function was added in libcurl 7.15.4, although not deemed stable yet. This function was added in libcurl 7.15.4, although deemed stablesince 7.16.0.
\fIcurl_multi_socket(3)\fP is deprecated, use
\fIcurl_multi_socket_action(3)\fP instead!
.SH "SEE ALSO" .SH "SEE ALSO"
.BR curl_multi_cleanup "(3), " curl_multi_init "(3), " .BR curl_multi_cleanup "(3), " curl_multi_init "(3), "
.BR curl_multi_fdset "(3), " curl_multi_info_read "(3)" .BR curl_multi_fdset "(3), " curl_multi_info_read "(3)"

View File

@@ -1,8 +1,27 @@
.\" You can view this file with: .\" **************************************************************************
.\" nroff -man [file] .\" * _ _ ____ _
.\" $Id$ .\" * 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$
.\" **************************************************************************
.\" .\"
.TH libcurl-errors 3 "9 Feb 2005" "libcurl 7.13.1" "libcurl errors" .TH libcurl-errors 3 "8 May 2007" "libcurl 7.16.3" "libcurl errors"
.SH NAME .SH NAME
libcurl-errors \- error codes in libcurl libcurl-errors \- error codes in libcurl
.SH DESCRIPTION .SH DESCRIPTION
@@ -86,9 +105,10 @@ An error occurred when writing received data to a local file, or an error was
returned to libcurl from a write callback. returned to libcurl from a write callback.
.IP "CURLE_MALFORMAT_USER (24)" .IP "CURLE_MALFORMAT_USER (24)"
This is never returned by current libcurl. This is never returned by current libcurl.
.IP "CURLE_FTP_COULDNT_STOR_FILE (25)" .IP "CURLE_UPLOAD_FAILED (25)"
FTP couldn't STOR file. The server denied the STOR operation. The error buffer Failed starting the upload. For FTP, the server typcially denied the STOR
usually contains the server's explanation to this. command. The error buffer usually contains the server's explanation to this.
(This error code was formerly known as CURLE_FTP_COULDNT_STOR_FILE.)
.IP "CURLE_READ_ERROR (26)" .IP "CURLE_READ_ERROR (26)"
There was a problem reading a local file or an error returned by the read There was a problem reading a local file or an error returned by the read
callback. callback.

View File

@@ -104,6 +104,12 @@ get more messages until the message queue is empty. The information you
receive there includes an easy handle pointer which you may use to identify receive there includes an easy handle pointer which you may use to identify
which easy handle the information regards. which easy handle the information regards.
When a single transfer is completed, the easy handle is still left added to
the multi stack. You need to first remove the easy handle with
\fIcurl_multi_remove_handle(3)\fP and then close it with
\fIcurl_easy_cleanup(3)\fP, or possibly set new options to it and add it again
with \fIcurl_multi_add_handle(3)\fP to start another transfer.
When all transfers in the multi stack are done, cleanup the multi handle with When all transfers in the multi stack are done, cleanup the multi handle with
\fIcurl_multi_cleanup(3)\fP. Be careful and please note that you \fBMUST\fP \fIcurl_multi_cleanup(3)\fP. Be careful and please note that you \fBMUST\fP
invoke separate \fIcurl_easy_cleanup(3)\fP calls on every single easy handle invoke separate \fIcurl_easy_cleanup(3)\fP calls on every single easy handle
@@ -125,10 +131,13 @@ A few areas in the code are still using blocking code, even when used from the
multi interface. While we certainly want and intend for these to get fixed in multi interface. While we certainly want and intend for these to get fixed in
the future, you should be aware of the following current restrictions: the future, you should be aware of the following current restrictions:
.nf
- Name resolves on non-windows unless c-ares is used - Name resolves on non-windows unless c-ares is used
- GnuTLS SSL connections - GnuTLS SSL connections
- Active FTP connections - Active FTP connections
- HTTP proxy CONNECT operations - HTTP proxy CONNECT operations
- SCP and SFTP connections - SCP and SFTP connections
- SFTP transfers - SFTP transfers
- TFTP transfers
- file:// transfers - file:// transfers
.fi

View File

@@ -210,9 +210,13 @@ typedef int (*curl_progress_callback)(void *clientp,
double ultotal, double ultotal,
double ulnow); double ulnow);
#ifndef CURL_MAX_WRITE_SIZE
/* Tests have proven that 20K is a very bad buffer size for uploads on /* Tests have proven that 20K is a very bad buffer size for uploads on
Windows, while 16K for some odd reason performed a lot better. */ Windows, while 16K for some odd reason performed a lot better.
We do the ifndef check to allow this value to easier be changed at build
time for those who feel adventurous. */
#define CURL_MAX_WRITE_SIZE 16384 #define CURL_MAX_WRITE_SIZE 16384
#endif
typedef size_t (*curl_write_callback)(char *buffer, typedef size_t (*curl_write_callback)(char *buffer,
size_t size, size_t size,
@@ -327,7 +331,7 @@ typedef enum {
CURLE_HTTP_RETURNED_ERROR, /* 22 */ CURLE_HTTP_RETURNED_ERROR, /* 22 */
CURLE_WRITE_ERROR, /* 23 */ CURLE_WRITE_ERROR, /* 23 */
CURLE_MALFORMAT_USER, /* 24 - NOT USED */ CURLE_MALFORMAT_USER, /* 24 - NOT USED */
CURLE_FTP_COULDNT_STOR_FILE, /* 25 - failed FTP upload */ CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */
CURLE_READ_ERROR, /* 26 - could open/read from file */ CURLE_READ_ERROR, /* 26 - could open/read from file */
CURLE_OUT_OF_MEMORY, /* 27 */ CURLE_OUT_OF_MEMORY, /* 27 */
/* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
@@ -418,6 +422,7 @@ typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */
/* backwards compatibility with older names */ /* backwards compatibility with older names */
#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR #define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED #define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED
#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED
#endif #endif
typedef enum { typedef enum {

View File

@@ -28,13 +28,13 @@
/* This is the version number of the libcurl package from which this header /* This is the version number of the libcurl package from which this header
file origins: */ file origins: */
#define LIBCURL_VERSION "7.16.2-CVS" #define LIBCURL_VERSION "7.16.3-CVS"
/* The numeric version number is also available "in parts" by using these /* The numeric version number is also available "in parts" by using these
defines: */ defines: */
#define LIBCURL_VERSION_MAJOR 7 #define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 16 #define LIBCURL_VERSION_MINOR 16
#define LIBCURL_VERSION_PATCH 2 #define LIBCURL_VERSION_PATCH 3
/* This is the numeric version of the libcurl version number, meant for easier /* This is the numeric version of the libcurl version number, meant for easier
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
@@ -51,7 +51,7 @@
and it is always a greater number in a more recent release. It makes and it is always a greater number in a more recent release. It makes
comparisons with greater than and less than work. comparisons with greater than and less than work.
*/ */
#define LIBCURL_VERSION_NUM 0x071002 #define LIBCURL_VERSION_NUM 0x071003
/* /*
* This is the date and time when the full source package was created. The * This is the date and time when the full source package was created. The

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -224,6 +224,10 @@ CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD #define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
#define CURL_CSELECT_IN 0x01
#define CURL_CSELECT_OUT 0x02
#define CURL_CSELECT_ERR 0x04
typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
curl_socket_t s, /* socket */ curl_socket_t s, /* socket */
int what, /* see above */ int what, /* see above */
@@ -249,9 +253,21 @@ typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */
CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
int *running_handles); int *running_handles);
CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle,
curl_socket_t s,
int ev_bitmask,
int *running_handles);
CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle,
int *running_handles); int *running_handles);
#ifndef CURL_ALLOW_OLD_MULTI_SOCKET
/* This macro below was added in 7.16.3 to push users who recompile to use
the new curl_multi_socket_action() instead of the old curl_multi_socket()
*/
#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z)
#endif
/* /*
* Name: curl_multi_timeout() * Name: curl_multi_timeout()
* *
@@ -293,6 +309,9 @@ typedef enum {
/* This is the argument passed to the timer callback */ /* This is the argument passed to the timer callback */
CINIT(TIMERDATA, OBJECTPOINT, 5), CINIT(TIMERDATA, OBJECTPOINT, 5),
/* maximum number of entries in the connection cache */
CINIT(MAXCONNECTS, LONG, 6),
CURLMOPT_LASTENTRY /* the last unused */ CURLMOPT_LASTENTRY /* the last unused */
} CURLMoption; } CURLMoption;

View File

@@ -25,7 +25,7 @@ endif
# Edit the path below to point to the base of your LibSSH2 package. # Edit the path below to point to the base of your LibSSH2 package.
ifndef LIBSSH2_PATH ifndef LIBSSH2_PATH
LIBSSH2_PATH = ../../libssh2-0.14 LIBSSH2_PATH = ../../libssh2-0.15
endif endif
ifndef INSTDIR ifndef INSTDIR
@@ -47,10 +47,10 @@ ifndef LIBARCH
LIBARCH = LIBC LIBARCH = LIBC
endif endif
# must be equal to DEBUG or NDEBUG # must be equal to NDEBUG or DEBUG, CURLDEBUG
ifndef DB
DB = NDEBUG DB = NDEBUG
# DB = DEBUG endif
# DB = CURLDEBUG
# Optimization: -O<n> or debugging: -g # Optimization: -O<n> or debugging: -g
ifeq ($(DB),NDEBUG) ifeq ($(DB),NDEBUG)
OPT = -O2 OPT = -O2
@@ -85,8 +85,9 @@ ifeq ($(CC),mwccnlm)
LD = mwldnlm LD = mwldnlm
LDFLAGS = -nostdlib $(PRELUDE) $(OBJL) -o $@ -commandfile LDFLAGS = -nostdlib $(PRELUDE) $(OBJL) -o $@ -commandfile
AR = mwldnlm AR = mwldnlm
ARFLAGS = -type library -w nocmdline $(OBJS) -o ARFLAGS = -nostdlib -type library -o
LIBEXT = lib LIBEXT = lib
#RANLIB =
CFLAGS += -msgstyle gcc -gccinc -inline off -opt nointrinsics -proc 586 CFLAGS += -msgstyle gcc -gccinc -inline off -opt nointrinsics -proc 586
CFLAGS += -relax_pointers CFLAGS += -relax_pointers
#CFLAGS += -w on #CFLAGS += -w on
@@ -104,6 +105,7 @@ LDFLAGS = -T
AR = ar AR = ar
ARFLAGS = -cq ARFLAGS = -cq
LIBEXT = a LIBEXT = a
RANLIB = ranlib
CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing
CFLAGS += -Wall # -pedantic CFLAGS += -Wall # -pedantic
ifeq ($(LIBARCH),LIBC) ifeq ($(LIBARCH),LIBC)
@@ -240,6 +242,9 @@ $(TARGET).$(LIBEXT): $(OBJS)
@echo Creating $@ @echo Creating $@
@-$(RM) $@ @-$(RM) $@
@$(AR) $(ARFLAGS) $@ $^ @$(AR) $(ARFLAGS) $@ $^
ifdef RANLIB
@$(RANLIB) $@
endif
$(TARGET).nlm: $(OBJDIR)/$(TARGET).def $(OBJL) $(XDCDATA) $(TARGET).nlm: $(OBJDIR)/$(TARGET).def $(OBJL) $(XDCDATA)
@echo Linking $@ @echo Linking $@
@@ -269,7 +274,7 @@ ifdef SCREEN
else else
@echo $(DL)screenname "DEFAULT"$(DL) >> $@ @echo $(DL)screenname "DEFAULT"$(DL) >> $@
endif endif
ifeq ($(DB),DEBUG) ifneq ($(DB),NDEBUG)
@echo $(DL)debug$(DL) >> $@ @echo $(DL)debug$(DL) >> $@
endif endif
@echo $(DL)threadname "$(TARGET)"$(DL) >> $@ @echo $(DL)threadname "$(TARGET)"$(DL) >> $@

View File

@@ -12,8 +12,7 @@ c-ares:
http://daniel.haxx.se/projects/c-ares/ http://daniel.haxx.se/projects/c-ares/
NOTE NOTE
The latest libcurl version requires c-ares 1.3.2 or later to work The latest libcurl version requires c-ares 1.4.0 or later.
flawlessly.
Once upon the time libcurl built fine with the "original" ares. That is no Once upon the time libcurl built fine with the "original" ares. That is no
longer true. You need to use c-ares. longer true. You need to use c-ares.

View File

@@ -59,7 +59,7 @@ static void decodeQuantum(unsigned char *dest, const char *src)
char *found; char *found;
for(i = 0; i < 4; i++) { for(i = 0; i < 4; i++) {
if((found = strchr(table64, src[i]))) if((found = strchr(table64, src[i])) != NULL)
x = (x << 6) + (unsigned int)(found - table64); x = (x << 6) + (unsigned int)(found - table64);
else if(src[i] == '=') else if(src[i] == '=')
x = (x << 6); x = (x << 6);
@@ -252,7 +252,7 @@ size_t Curl_base64_encode(struct SessionHandle *data,
#define TEST_NEED_SUCK #define TEST_NEED_SUCK
void *suck(int *); void *suck(int *);
int main(int argc, char **argv, char **envp) int main(int argc, argv_item_t argv[], char **envp)
{ {
char *base64; char *base64;
size_t base64Len; size_t base64Len;
@@ -293,7 +293,7 @@ int main(int argc, char **argv, char **envp)
#define TEST_NEED_SUCK #define TEST_NEED_SUCK
void *suck(int *); void *suck(int *);
int main(int argc, char **argv, char **envp) int main(int argc, argv_item_t argv[], char **envp)
{ {
char *base64; char *base64;
int base64Len; int base64Len;

View File

@@ -206,7 +206,7 @@ int waitconnect(curl_socket_t sockfd, /* socket */
/* timeout, no connect today */ /* timeout, no connect today */
return WAITCONN_TIMEOUT; return WAITCONN_TIMEOUT;
if(rc & CSELECT_ERR) if(rc & CURL_CSELECT_ERR)
/* error condition caught */ /* error condition caught */
return WAITCONN_FDSET_ERROR; return WAITCONN_FDSET_ERROR;
@@ -432,16 +432,15 @@ static bool verifyconnect(curl_socket_t sockfd, int *error)
#endif #endif
if( -1 == getsockopt(sockfd, SOL_SOCKET, SO_ERROR, if (0 != getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&err, &errSize))
(void *)&err, &errSize))
err = SOCKERRNO; err = SOCKERRNO;
#ifdef _WIN32_WCE #ifdef _WIN32_WCE
/* Always returns this error, bug in CE? */ /* Old WinCE versions don't support SO_ERROR */
if(WSAENOPROTOOPT==err) if (WSAENOPROTOOPT == err) {
SET_SOCKERRNO(0);
err = 0; err = 0;
}
#endif #endif
if ((0 == err) || (EISCONN == err)) if ((0 == err) || (EISCONN == err))
/* we are connected, awesome! */ /* we are connected, awesome! */
rc = TRUE; rc = TRUE;
@@ -782,6 +781,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
int num_addr; int num_addr;
Curl_addrinfo *ai; Curl_addrinfo *ai;
Curl_addrinfo *curr_addr; Curl_addrinfo *curr_addr;
int timeout_set = 0;
struct timeval after; struct timeval after;
struct timeval before = Curl_tvnow(); struct timeval before = Curl_tvnow();
@@ -789,36 +789,39 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
/************************************************************* /*************************************************************
* Figure out what maximum time we have left * Figure out what maximum time we have left
*************************************************************/ *************************************************************/
long timeout_ms= DEFAULT_CONNECT_TIMEOUT; long timeout_ms;
long timeout_per_addr; long timeout_per_addr;
*connected = FALSE; /* default to not connected */ *connected = FALSE; /* default to not connected */
if(data->set.timeout || data->set.connecttimeout) { /* if a timeout is set, use the most restrictive one */
long has_passed;
/* Evaluate in milliseconds how much time that has passed */ if (data->set.timeout > 0)
has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle); timeout_set += 1;
if (data->set.connecttimeout > 0)
timeout_set += 2;
#ifndef min switch (timeout_set) {
#define min(a, b) ((a) < (b) ? (a) : (b)) case 1:
#endif timeout_ms = data->set.timeout;
break;
/* get the most strict timeout of the ones converted to milliseconds */ case 2:
if(data->set.timeout && data->set.connecttimeout) { timeout_ms = data->set.connecttimeout;
break;
case 3:
if (data->set.timeout < data->set.connecttimeout) if (data->set.timeout < data->set.connecttimeout)
timeout_ms = data->set.timeout; timeout_ms = data->set.timeout;
else else
timeout_ms = data->set.connecttimeout; timeout_ms = data->set.connecttimeout;
break;
default:
timeout_ms = DEFAULT_CONNECT_TIMEOUT;
break;
} }
else if(data->set.timeout)
timeout_ms = data->set.timeout;
else
timeout_ms = data->set.connecttimeout;
/* subtract the passed time */
timeout_ms -= has_passed;
if (timeout_set > 0) {
/* if a timeout was already set, substract elapsed time */
timeout_ms -= Curl_tvdiff(before, data->progress.t_startsingle);
if(timeout_ms < 0) { if(timeout_ms < 0) {
/* a precaution, no need to continue if time already is up */ /* a precaution, no need to continue if time already is up */
failf(data, "Connection time-out"); failf(data, "Connection time-out");

View File

@@ -420,11 +420,14 @@ CURLcode curl_easy_perform(CURL *easy)
timeout.tv_sec = 1; timeout.tv_sec = 1;
timeout.tv_usec = 0; timeout.tv_usec = 0;
/* get file descriptors from the transfers */ /* Old deprecated style: get file descriptors from the transfers */
curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd); curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
rc = Curl_select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); rc = Curl_select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
/* The way is to extract the sockets and wait for them without using
select. This whole alternative version should probably rather use the
curl_multi_socket() approach. */
if(rc == -1) if(rc == -1)
/* select error */ /* select error */
break; break;
@@ -511,6 +514,10 @@ void Curl_easy_addmulti(struct SessionHandle *data,
void *multi) void *multi)
{ {
data->multi = multi; data->multi = multi;
if (multi == NULL)
/* the association is cleared, mark the easy handle as not used by an
interface */
data->state.used_interface = Curl_if_none;
} }
void Curl_easy_initHandleData(struct SessionHandle *data) void Curl_easy_initHandleData(struct SessionHandle *data)
@@ -636,8 +643,8 @@ CURL *curl_easy_duphandle(CURL *incurl)
if(fail) { if(fail) {
if(outcurl) { if(outcurl) {
if((outcurl->state.connc->type == CONNCACHE_PRIVATE) && if(outcurl->state.connc &&
outcurl->state.connc) (outcurl->state.connc->type == CONNCACHE_PRIVATE))
Curl_rm_connc(outcurl->state.connc); Curl_rm_connc(outcurl->state.connc);
if(outcurl->state.headerbuff) if(outcurl->state.headerbuff)
free(outcurl->state.headerbuff); free(outcurl->state.headerbuff);

View File

@@ -198,6 +198,8 @@ static CURLcode file_upload(struct connectdata *conn)
size_t nwrite; size_t nwrite;
curl_off_t bytecount = 0; curl_off_t bytecount = 0;
struct timeval now = Curl_tvnow(); struct timeval now = Curl_tvnow();
struct_stat file_stat;
char* buf2;
/* /*
* Since FILE: doesn't do the full init, we need to provide some extra * Since FILE: doesn't do the full init, we need to provide some extra
@@ -213,7 +215,11 @@ static CURLcode file_upload(struct connectdata *conn)
if(!dir[1]) if(!dir[1])
return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */ return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
if(data->reqdata.resume_from)
fp = fopen( file->path, "ab" );
else
fp = fopen(file->path, "wb"); fp = fopen(file->path, "wb");
if(!fp) { if(!fp) {
failf(data, "Can't open %s for writing", file->path); failf(data, "Can't open %s for writing", file->path);
return CURLE_WRITE_ERROR; return CURLE_WRITE_ERROR;
@@ -223,6 +229,17 @@ static CURLcode file_upload(struct connectdata *conn)
/* known size of data to "upload" */ /* known size of data to "upload" */
Curl_pgrsSetUploadSize(data, data->set.infilesize); Curl_pgrsSetUploadSize(data, data->set.infilesize);
/* treat the negative resume offset value as the case of "-" */
if(data->reqdata.resume_from < 0){
if(stat(file->path, &file_stat)){
fclose(fp);
failf(data, "Can't get the size of %s", file->path);
return CURLE_WRITE_ERROR;
}
else
data->reqdata.resume_from = (curl_off_t)file_stat.st_size;
}
while (res == CURLE_OK) { while (res == CURLE_OK) {
int readcount; int readcount;
res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount); res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount);
@@ -234,8 +251,24 @@ static CURLcode file_upload(struct connectdata *conn)
nread = (size_t)readcount; nread = (size_t)readcount;
/*skip bytes before resume point*/
if(data->reqdata.resume_from) {
if( (curl_off_t)nread <= data->reqdata.resume_from ) {
data->reqdata.resume_from -= nread;
nread = 0;
buf2 = buf;
}
else {
buf2 = buf + data->reqdata.resume_from;
nread -= data->reqdata.resume_from;
data->reqdata.resume_from = 0;
}
}
else
buf2 = buf;
/* write the data to the target */ /* write the data to the target */
nwrite = fwrite(buf, 1, nread, fp); nwrite = fwrite(buf2, 1, nread, fp);
if(nwrite != nread) { if(nwrite != nread) {
res = CURLE_SEND_ERROR; res = CURLE_SEND_ERROR;
break; break;

104
lib/ftp.c
View File

@@ -184,27 +184,46 @@ static bool isBadFtpString(const char *string)
*/ */
static CURLcode AllowServerConnect(struct connectdata *conn) static CURLcode AllowServerConnect(struct connectdata *conn)
{ {
int timeout_ms; long timeout_ms;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
curl_socket_t sock = conn->sock[SECONDARYSOCKET]; curl_socket_t sock = conn->sock[SECONDARYSOCKET];
struct timeval now = Curl_tvnow(); int timeout_set = 0;
long timespent = Curl_tvdiff(Curl_tvnow(), now);
long timeout = data->set.connecttimeout?data->set.connecttimeout:
(data->set.timeout?data->set.timeout: 0);
if(timeout) { /* if a timeout is set, use the most restrictive one */
timeout -= timespent;
if(timeout<=0) { if (data->set.timeout > 0)
timeout_set += 1;
if (data->set.connecttimeout > 0)
timeout_set += 2;
switch (timeout_set) {
case 1:
timeout_ms = data->set.timeout;
break;
case 2:
timeout_ms = data->set.connecttimeout;
break;
case 3:
if (data->set.timeout < data->set.connecttimeout)
timeout_ms = data->set.timeout;
else
timeout_ms = data->set.connecttimeout;
break;
default:
timeout_ms = 60000; /* 60 seconds default timeout */
break;
}
if (timeout_set > 0) {
/* if a timeout was already set, substract elapsed time */
timeout_ms -= Curl_tvdiff(Curl_tvnow(), conn->now);
if(timeout_ms < 0) {
failf(data, "Timed out before server could connect to us"); failf(data, "Timed out before server could connect to us");
return CURLE_OPERATION_TIMEDOUT; return CURLE_OPERATION_TIMEDOUT;
} }
} }
/* We allow the server 60 seconds to connect to us, or a custom timeout. switch (Curl_socket_ready(sock, CURL_SOCKET_BAD, (int)timeout_ms)) {
Note the typecast here. */
timeout_ms = (timeout?(int)timeout:60000);
switch (Curl_socket_ready(sock, CURL_SOCKET_BAD, timeout_ms)) {
case -1: /* error */ case -1: /* error */
/* let's die here */ /* let's die here */
failf(data, "Error while waiting for server connect"); failf(data, "Error while waiting for server connect");
@@ -1234,9 +1253,8 @@ static CURLcode ftp_state_post_rest(struct connectdata *conn)
struct FTP *ftp = conn->data->reqdata.proto.ftp; struct FTP *ftp = conn->data->reqdata.proto.ftp;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
if(ftp->no_transfer || conn->bits.no_body) { if(ftp->no_transfer) {
/* doesn't transfer any data */ /* doesn't transfer any data */
ftp->no_transfer = TRUE;
/* still possibly do PRE QUOTE jobs */ /* still possibly do PRE QUOTE jobs */
state(conn, FTP_RETR_PREQUOTE); state(conn, FTP_RETR_PREQUOTE);
@@ -2996,8 +3014,6 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status, bool premature
int ftpcode; int ftpcode;
CURLcode result=CURLE_OK; CURLcode result=CURLE_OK;
bool was_ctl_valid = ftpc->ctl_valid; bool was_ctl_valid = ftpc->ctl_valid;
size_t flen;
size_t dlen;
char *path; char *path;
char *path_to_use = data->reqdata.path; char *path_to_use = data->reqdata.path;
struct Curl_transfer_keeper *k = &data->reqdata.keep; struct Curl_transfer_keeper *k = &data->reqdata.keep;
@@ -3043,11 +3059,14 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status, bool premature
/* get the "raw" path */ /* get the "raw" path */
path = curl_easy_unescape(data, path_to_use, 0, NULL); path = curl_easy_unescape(data, path_to_use, 0, NULL);
if(!path) if(!path) {
return CURLE_OUT_OF_MEMORY; /* out of memory, but we can limp along anyway (and should try to
* since we're in the out of memory cleanup path) */
ftpc->prevpath = NULL; /* no path */
flen = ftp->file?strlen(ftp->file):0; /* file is "raw" already */ } else {
dlen = strlen(path)-flen; size_t flen = ftp->file?strlen(ftp->file):0; /* file is "raw" already */
size_t dlen = strlen(path)-flen;
if(dlen && !ftpc->cwdfail) { if(dlen && !ftpc->cwdfail) {
ftpc->prevpath = path; ftpc->prevpath = path;
if(flen) if(flen)
@@ -3059,6 +3078,7 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status, bool premature
ftpc->prevpath = NULL; /* no path */ ftpc->prevpath = NULL; /* no path */
free(path); free(path);
} }
}
/* free the dir tree and file parts */ /* free the dir tree and file parts */
freedirs(conn); freedirs(conn);
@@ -3330,7 +3350,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
DEBUGF(infof(data, "DO-MORE phase starts\n")); DEBUGF(infof(data, "DO-MORE phase starts\n"));
if(!ftp->no_transfer && !conn->bits.no_body) { if(!ftp->no_transfer) {
/* a transfer is about to take place */ /* a transfer is about to take place */
if(data->set.upload) { if(data->set.upload) {
@@ -3394,6 +3414,13 @@ CURLcode ftp_perform(struct connectdata *conn,
DEBUGF(infof(conn->data, "DO phase starts\n")); DEBUGF(infof(conn->data, "DO phase starts\n"));
if(conn->bits.no_body) {
/* requested no body means no transfer... */
struct FTP *ftp = conn->data->reqdata.proto.ftp;
ftp->no_transfer = TRUE;
}
*dophase_done = FALSE; /* not done yet */ *dophase_done = FALSE; /* not done yet */
/* start the first command in the DO phase */ /* start the first command in the DO phase */
@@ -3670,9 +3697,14 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
case FTPFILE_SINGLECWD: case FTPFILE_SINGLECWD:
/* get the last slash */ /* get the last slash */
if(!path_to_use[0]) {
/* no dir, no file */
ftpc->dirdepth = 0;
ftp->file = NULL;
break;
}
slash_pos=strrchr(cur_pos, '/'); slash_pos=strrchr(cur_pos, '/');
if(slash_pos || !*cur_pos) { if(slash_pos || !*cur_pos) {
ftpc->dirdepth = 1; /* we consider it to be a single dir */
ftpc->dirs = (char **)calloc(1, sizeof(ftpc->dirs[0])); ftpc->dirs = (char **)calloc(1, sizeof(ftpc->dirs[0]));
if(!ftpc->dirs) if(!ftpc->dirs)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
@@ -3681,9 +3713,10 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
slash_pos?(int)(slash_pos-cur_pos):1, slash_pos?(int)(slash_pos-cur_pos):1,
NULL); NULL);
if(!ftpc->dirs[0]) { if(!ftpc->dirs[0]) {
free(ftpc->dirs); freedirs(conn);
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
ftpc->dirdepth = 1; /* we consider it to be a single dir */
ftp->file = slash_pos ? slash_pos+1 : cur_pos; /* rest is file name */ ftp->file = slash_pos ? slash_pos+1 : cur_pos; /* rest is file name */
} }
else else
@@ -3698,6 +3731,13 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
if(!ftpc->dirs) if(!ftpc->dirs)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
/* we have a special case for listing the root dir only */
if(strequal(path_to_use, "/")) {
cur_pos++; /* make it point to the zero byte */
ftpc->dirs[0] = strdup("/");
ftpc->dirdepth++;
}
else {
/* parse the URL path into separate path components */ /* parse the URL path into separate path components */
while ((slash_pos = strchr(cur_pos, '/')) != NULL) { while ((slash_pos = strchr(cur_pos, '/')) != NULL) {
/* 1 or 0 to indicate absolute directory */ /* 1 or 0 to indicate absolute directory */
@@ -3710,9 +3750,8 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
CWD requires a parameter and a non-existant parameter a) doesn't CWD requires a parameter and a non-existant parameter a) doesn't
work on many servers and b) has no effect on the others. */ work on many servers and b) has no effect on the others. */
int len = (int)(slash_pos - cur_pos + absolute_dir); int len = (int)(slash_pos - cur_pos + absolute_dir);
ftpc->dirs[ftpc->dirdepth] = curl_easy_unescape(conn->data, ftpc->dirs[ftpc->dirdepth] =
cur_pos - absolute_dir, curl_easy_unescape(conn->data, cur_pos - absolute_dir, len, NULL);
len, NULL);
if (!ftpc->dirs[ftpc->dirdepth]) { /* run out of memory ... */ if (!ftpc->dirs[ftpc->dirdepth]) { /* run out of memory ... */
failf(data, "no memory"); failf(data, "no memory");
freedirs(conn); freedirs(conn);
@@ -3742,11 +3781,11 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
ftpc->dirs = (char **)bigger; ftpc->dirs = (char **)bigger;
} }
} }
}
ftp->file = cur_pos; /* the rest is the file name */ ftp->file = cur_pos; /* the rest is the file name */
} }
if(*ftp->file) { if(ftp->file && *ftp->file) {
ftp->file = curl_easy_unescape(conn->data, ftp->file, 0, NULL); ftp->file = curl_easy_unescape(conn->data, ftp->file, 0, NULL);
if(NULL == ftp->file) { if(NULL == ftp->file) {
freedirs(conn); freedirs(conn);
@@ -3762,8 +3801,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
ftp->file=NULL; /* instead of point to a zero byte, we make it a NULL ftp->file=NULL; /* instead of point to a zero byte, we make it a NULL
pointer */ pointer */
if(data->set.upload && !ftp->file && if(data->set.upload && !ftp->file && !ftp->no_transfer) {
(!ftp->no_transfer || conn->bits.no_body)) {
/* We need a file name when uploading. Return error! */ /* We need a file name when uploading. Return error! */
failf(data, "Uploading to a URL without a file name!"); failf(data, "Uploading to a URL without a file name!");
return CURLE_URL_MALFORMAT; return CURLE_URL_MALFORMAT;
@@ -3775,8 +3813,10 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
/* prevpath is "raw" so we convert the input path before we compare the /* prevpath is "raw" so we convert the input path before we compare the
strings */ strings */
char *path = curl_easy_unescape(conn->data, data->reqdata.path, 0, NULL); char *path = curl_easy_unescape(conn->data, data->reqdata.path, 0, NULL);
if(!path) if(!path) {
freedirs(conn);
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
}
dlen = strlen(path) - (ftp->file?strlen(ftp->file):0); dlen = strlen(path) - (ftp->file?strlen(ftp->file):0);
if((dlen == strlen(ftpc->prevpath)) && if((dlen == strlen(ftpc->prevpath)) &&

View File

@@ -63,7 +63,7 @@ static void tls_log_func(int level, const char *str)
fprintf(stderr, "|<%d>| %s", level, str); fprintf(stderr, "|<%d>| %s", level, str);
} }
#endif #endif
static bool gtls_inited = FALSE;
/* /*
* Custom push and pull callback functions used by GNU TLS to read and write * 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() * to the socket. These functions are simple wrappers to send() and recv()
@@ -85,16 +85,32 @@ static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len)
/* Global GnuTLS init, called from Curl_ssl_init() */ /* Global GnuTLS init, called from Curl_ssl_init() */
int Curl_gtls_init(void) int Curl_gtls_init(void)
{ {
gnutls_global_init(); /* Unfortunately we can not init here, things like curl --version will
* fail to work if there is no egd socket available because libgcrypt
* will EXIT the application!!
* By doing the actual init later (before actually trying to use GnuTLS),
* we can at least provide basic info etc.
*/
return 1;
}
static int _Curl_gtls_init(void)
{
int ret = 1;
if (!gtls_inited) {
ret = gnutls_global_init()?0:1;
#ifdef GTLSDEBUG #ifdef GTLSDEBUG
gnutls_global_set_log_function(tls_log_func); gnutls_global_set_log_function(tls_log_func);
gnutls_global_set_log_level(2); gnutls_global_set_log_level(2);
#endif #endif
return 1; gtls_inited = TRUE;
}
return ret;
} }
int Curl_gtls_cleanup(void) int Curl_gtls_cleanup(void)
{ {
if (gtls_inited)
gnutls_global_deinit(); gnutls_global_deinit();
return 1; return 1;
} }
@@ -132,7 +148,8 @@ static CURLcode handshake(struct connectdata *conn,
{ {
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
int rc; int rc;
if (!gtls_inited)
_Curl_gtls_init();
do { do {
rc = gnutls_handshake(session); rc = gnutls_handshake(session);
@@ -227,6 +244,7 @@ Curl_gtls_connect(struct connectdata *conn,
void *ssl_sessionid; void *ssl_sessionid;
size_t ssl_idsize; size_t ssl_idsize;
if (!gtls_inited) _Curl_gtls_init();
/* GnuTLS only supports TLSv1 (and SSLv3?) */ /* GnuTLS only supports TLSv1 (and SSLv3?) */
if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) { if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
failf(data, "GnuTLS does not support SSLv2"); failf(data, "GnuTLS does not support SSLv2");
@@ -502,6 +520,7 @@ static void close_one(struct connectdata *conn,
gnutls_bye(conn->ssl[index].session, GNUTLS_SHUT_RDWR); gnutls_bye(conn->ssl[index].session, GNUTLS_SHUT_RDWR);
gnutls_deinit(conn->ssl[index].session); gnutls_deinit(conn->ssl[index].session);
} }
if(conn->ssl[index].cred)
gnutls_certificate_free_credentials(conn->ssl[index].cred); gnutls_certificate_free_credentials(conn->ssl[index].cred);
} }

View File

@@ -125,6 +125,69 @@ int Curl_resolv_getsock(struct connectdata *conn,
return max; return max;
} }
/*
* ares_waitperform()
*
* 1) Ask ares what sockets it currently plays with, then
* 2) wait for the timeout period to check for action on ares' sockets.
* 3) tell ares to act on all the sockets marked as "with action"
*
* return number of sockets it worked on
*/
static int ares_waitperform(struct connectdata *conn, int timeout_ms)
{
struct SessionHandle *data = conn->data;
int nfds;
int bitmask;
int socks[ARES_GETSOCK_MAXNUM];
struct pollfd pfd[ARES_GETSOCK_MAXNUM];
int m;
int i;
int num;
bitmask = ares_getsock(data->state.areschannel, socks, ARES_GETSOCK_MAXNUM);
for(i=0; i < ARES_GETSOCK_MAXNUM; i++) {
pfd[i].events = 0;
m=0;
if(ARES_GETSOCK_READABLE(bitmask, i)) {
pfd[i].fd = socks[i];
pfd[i].events |= POLLRDNORM|POLLIN;
m=1;
}
if(ARES_GETSOCK_WRITABLE(bitmask, i)) {
pfd[i].fd = socks[i];
pfd[i].events |= POLLWRNORM|POLLOUT;
m=1;
}
pfd[i].revents=0;
if(!m)
break;
}
num = i;
if(num)
nfds = Curl_poll(pfd, num, timeout_ms);
else
nfds = 0;
if(!nfds)
/* Call ares_process() unconditonally here, even if we simply timed out
above, as otherwise the ares name resolve won't timeout! */
ares_process_fd(data->state.areschannel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
else {
/* move through the descriptors and ask for processing on them */
for(i=0; i < num; i++)
ares_process_fd(data->state.areschannel,
pfd[i].revents & (POLLRDNORM|POLLIN)?
pfd[i].fd:ARES_SOCKET_BAD,
pfd[i].revents & (POLLWRNORM|POLLOUT)?
pfd[i].fd:ARES_SOCKET_BAD);
}
return nfds;
}
/* /*
* Curl_is_resolved() is called repeatedly to check if a previous name resolve * Curl_is_resolved() is called repeatedly to check if a previous name resolve
* request has completed. It should also make sure to time-out if the * request has completed. It should also make sure to time-out if the
@@ -135,25 +198,12 @@ int Curl_resolv_getsock(struct connectdata *conn,
CURLcode Curl_is_resolved(struct connectdata *conn, CURLcode Curl_is_resolved(struct connectdata *conn,
struct Curl_dns_entry **dns) struct Curl_dns_entry **dns)
{ {
fd_set read_fds, write_fds;
struct timeval tv={0,0};
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
int nfds;
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
(void)Curl_select(nfds, &read_fds, &write_fds, NULL,
(struct timeval *)&tv);
/* Call ares_process() unconditonally here, even if we simply timed out
above, as otherwise the ares name resolve won't timeout! */
ares_process(data->state.areschannel, &read_fds, &write_fds);
*dns = NULL; *dns = NULL;
ares_waitperform(conn, 0);
if(conn->async.done) { if(conn->async.done) {
/* we're done, kill the ares handle */ /* we're done, kill the ares handle */
if(!conn->async.dns) { if(!conn->async.dns) {
@@ -194,28 +244,20 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
/* Wait for the name resolve query to complete. */ /* Wait for the name resolve query to complete. */
while (1) { while (1) {
int nfds=0;
fd_set read_fds, write_fds;
struct timeval *tvp, tv, store; struct timeval *tvp, tv, store;
int count;
struct timeval now = Curl_tvnow(); struct timeval now = Curl_tvnow();
long timediff; long timediff;
store.tv_sec = (int)timeout/1000; store.tv_sec = (int)timeout/1000;
store.tv_usec = (timeout%1000)*1000; store.tv_usec = (timeout%1000)*1000;
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
if (nfds == 0)
/* no file descriptors means we're done waiting */
break;
tvp = ares_timeout(data->state.areschannel, &store, &tv); tvp = ares_timeout(data->state.areschannel, &store, &tv);
count = Curl_select(nfds, &read_fds, &write_fds, NULL, tvp);
if ((count < 0) && (SOCKERRNO != EINVAL))
break;
ares_process(data->state.areschannel, &read_fds, &write_fds); /* use the timeout period ares returned to us above */
ares_waitperform(conn, tv.tv_sec * 1000 + tv.tv_usec/1000);
if(conn->async.done)
break;
timediff = Curl_tvdiff(Curl_tvnow(), now); /* spent time */ timediff = Curl_tvdiff(Curl_tvnow(), now); /* spent time */
timeout -= timediff?timediff:1; /* always deduct at least 1 */ timeout -= timediff?timediff:1; /* always deduct at least 1 */

View File

@@ -598,6 +598,14 @@ struct namebuf {
Curl_addrinfo *Curl_ip2addr(in_addr_t num, const char *hostname, int port) Curl_addrinfo *Curl_ip2addr(in_addr_t num, const char *hostname, int port)
{ {
Curl_addrinfo *ai; Curl_addrinfo *ai;
#if defined(VMS) && \
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
#pragma pointer_size save
#pragma pointer_size short
#pragma message disable PTRMISMATCH
#endif
struct hostent *h; struct hostent *h;
struct in_addr *addrentry; struct in_addr *addrentry;
struct namebuf buffer; struct namebuf buffer;
@@ -624,10 +632,16 @@ Curl_addrinfo *Curl_ip2addr(in_addr_t num, const char *hostname, int port)
/* Now store the dotted version of the address */ /* Now store the dotted version of the address */
snprintf((char *)h->h_name, 16, "%s", hostname); snprintf((char *)h->h_name, 16, "%s", hostname);
#if defined(VMS) && \
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
#pragma pointer_size restore
#pragma message enable PTRMISMATCH
#endif
ai = Curl_he2ai(h, port); ai = Curl_he2ai(h, port);
return ai; return ai;
} }
#endif #endif /* CURLRES_IPV4 || CURLRES_ARES */

View File

@@ -179,28 +179,21 @@ struct thread_sync_data {
static static
void destroy_thread_sync_data(struct thread_sync_data * tsd) void destroy_thread_sync_data(struct thread_sync_data * tsd)
{ {
if (tsd->hostname) { if (tsd->hostname)
free(tsd->hostname); free(tsd->hostname);
tsd->hostname = NULL; if (tsd->event_terminate)
}
if (tsd->event_terminate) {
CloseHandle(tsd->event_terminate); CloseHandle(tsd->event_terminate);
tsd->event_terminate = NULL; if (tsd->mutex_terminate)
}
if (tsd->mutex_terminate) {
CloseHandle(tsd->mutex_terminate); CloseHandle(tsd->mutex_terminate);
tsd->mutex_terminate = NULL; if (tsd->mutex_waiting)
}
if (tsd->mutex_waiting) {
CloseHandle(tsd->mutex_waiting); CloseHandle(tsd->mutex_waiting);
tsd->mutex_waiting = NULL; memset(tsd,0,sizeof(*tsd));
}
} }
/* Initialize resolver thread synchronization data */ /* Initialize resolver thread synchronization data */
static static
BOOL init_thread_sync_data(struct thread_data * td, BOOL init_thread_sync_data(struct thread_data * td,
char * hostname, const char * hostname,
struct thread_sync_data * tsd) struct thread_sync_data * tsd)
{ {
HANDLE curr_proc = GetCurrentProcess(); HANDLE curr_proc = GetCurrentProcess();
@@ -293,6 +286,7 @@ static unsigned __stdcall gethostbyname_thread (void *arg)
* due to a resolver timeout. * due to a resolver timeout.
*/ */
struct thread_sync_data tsd = { 0,0,0,NULL }; struct thread_sync_data tsd = { 0,0,0,NULL };
if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) { if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) {
/* thread synchronization data initialization failed */ /* thread synchronization data initialization failed */
return (unsigned)-1; return (unsigned)-1;
@@ -353,6 +347,7 @@ static unsigned __stdcall getaddrinfo_thread (void *arg)
* due to a resolver timeout. * due to a resolver timeout.
*/ */
struct thread_sync_data tsd = { 0,0,0,NULL }; struct thread_sync_data tsd = { 0,0,0,NULL };
if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) { if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) {
/* thread synchronization data initialization failed */ /* thread synchronization data initialization failed */
return -1; return -1;
@@ -595,7 +590,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
timeout = timeout =
conn->data->set.connecttimeout ? conn->data->set.connecttimeout : conn->data->set.connecttimeout ? conn->data->set.connecttimeout :
conn->data->set.timeout ? conn->data->set.timeout : conn->data->set.timeout ? conn->data->set.timeout :
CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */ CURL_TIMEOUT_RESOLVE * 1000; /* default name resolve timeout */
ticks = GetTickCount(); ticks = GetTickCount();
/* wait for the thread to resolve the name */ /* wait for the thread to resolve the name */

View File

@@ -98,8 +98,10 @@ char *Curl_if2ip(const char *interface, char *buf, int buf_size)
struct ifreq req; struct ifreq req;
size_t len = strlen(interface); size_t len = strlen(interface);
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
if(len >= sizeof(req.ifr_name)) if(len >= sizeof(req.ifr_name)) {
sclose(dummy);
return NULL; /* this can't be a fine interface name */ return NULL; /* this can't be a fine interface name */
}
memcpy(req.ifr_name, interface, len+1); memcpy(req.ifr_name, interface, len+1);
req.ifr_addr.sa_family = AF_INET; req.ifr_addr.sa_family = AF_INET;
#ifdef IOCTL_3_ARGS #ifdef IOCTL_3_ARGS

View File

@@ -116,7 +116,7 @@ inet_pton4(const char *src, unsigned char *dst)
if (val > 255) if (val > 255)
return (0); return (0);
*tp = val; *tp = (unsigned char)val;
if (! saw_digit) { if (! saw_digit) {
if (++octets > 4) if (++octets > 4)
return (0); return (0);

View File

@@ -31,7 +31,7 @@ VS_VERSION_INFO VERSIONINFO
FILEVERSION RC_VERSION FILEVERSION RC_VERSION
PRODUCTVERSION RC_VERSION PRODUCTVERSION RC_VERSION
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#if CURLDEBUG #if defined(CURLDEBUG) || defined(_DEBUG)
FILEFLAGS 1 FILEFLAGS 1
#else #else
FILEFLAGS 0 FILEFLAGS 0

View File

@@ -73,6 +73,10 @@ void curl_memdebug(const char *logname)
logfile = fopen(logname, "w"); logfile = fopen(logname, "w");
else else
logfile = stderr; logfile = stderr;
#ifdef MEMDEBUG_LOG_SYNC
/* Flush the log file after every line so the log isn't lost in a crash */
setvbuf(logfile, (char *)NULL, _IOLBF, 0);
#endif
} }
} }

View File

@@ -121,9 +121,9 @@ struct Curl_one_easy {
#define CURL_MULTI_HANDLE 0x000bab1e #define CURL_MULTI_HANDLE 0x000bab1e
#define GOOD_MULTI_HANDLE(x) \ #define GOOD_MULTI_HANDLE(x) \
((x)&&(((struct Curl_multi *)x)->type == CURL_MULTI_HANDLE)) ((x)&&(((struct Curl_multi *)(x))->type == CURL_MULTI_HANDLE))
#define GOOD_EASY_HANDLE(x) \ #define GOOD_EASY_HANDLE(x) \
(((struct SessionHandle *)x)->magic == CURLEASY_MAGIC_NUMBER) (((struct SessionHandle *)(x))->magic == CURLEASY_MAGIC_NUMBER)
/* This is the struct known as CURLM on the outside */ /* This is the struct known as CURLM on the outside */
struct Curl_multi { struct Curl_multi {
@@ -160,6 +160,8 @@ struct Curl_multi {
/* shared connection cache */ /* shared connection cache */
struct conncache *connc; struct conncache *connc;
long maxconnects; /* if >0, a fixed limit of the maximum number of entries
we're allowed to grow the connection cache to */
/* list of easy handles kept around for doing nice connection closures */ /* list of easy handles kept around for doing nice connection closures */
struct closure *closure; struct closure *closure;
@@ -180,7 +182,7 @@ static void add_closure(struct Curl_multi *multi,
static int update_timer(struct Curl_multi *multi); static int update_timer(struct Curl_multi *multi);
#ifdef CURLDEBUG #ifdef CURLDEBUG
static const char *statename[]={ static const char * const statename[]={
"INIT", "INIT",
"CONNECT", "CONNECT",
"WAITRESOLVE", "WAITRESOLVE",
@@ -469,6 +471,14 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
/* make the SessionHandle struct refer back to this struct */ /* make the SessionHandle struct refer back to this struct */
easy->easy_handle->set.one_easy = easy; easy->easy_handle->set.one_easy = easy;
/* Set the timeout for this handle to expire really soon so that it will
be taken care of even when this handle is added in the midst of operation
when only the curl_multi_socket() API is used. During that flow, only
sockets that time-out or have actions will be dealt with. Since this
handle has no action yet, we make sure it times out to get things to
happen. */
Curl_expire(easy->easy_handle, 10);
/* increase the node-counter */ /* increase the node-counter */
multi->num_easy++; multi->num_easy++;
@@ -476,12 +486,20 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
/* We want the connection cache to have plenty room. Before we supported /* We want the connection cache to have plenty room. Before we supported
the shared cache every single easy handle had 5 entries in their cache the shared cache every single easy handle had 5 entries in their cache
by default. */ by default. */
CURLcode res = Curl_ch_connc(easy_handle, multi->connc, int newmax = multi->num_easy * 4;
multi->connc->num*4);
if(multi->maxconnects && (multi->maxconnects < newmax))
/* don't grow beyond the allowed size */
newmax = multi->maxconnects;
if(newmax > multi->connc->num) {
/* we only do this is we can in fact grow the cache */
CURLcode res = Curl_ch_connc(easy_handle, multi->connc, newmax);
if(res != CURLE_OK) if(res != CURLE_OK)
/* TODO: we need to do some cleaning up here! */ /* TODO: we need to do some cleaning up here! */
return CURLM_OUT_OF_MEMORY; return CURLM_OUT_OF_MEMORY;
} }
}
/* increase the alive-counter */ /* increase the alive-counter */
multi->num_alive++; multi->num_alive++;
@@ -796,7 +814,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
struct Curl_message *msg = NULL; struct Curl_message *msg = NULL;
bool connected; bool connected;
bool async; bool async;
bool protocol_connect; bool protocol_connect = FALSE;
bool dophase_done; bool dophase_done;
bool done; bool done;
CURLMcode result = CURLM_OK; CURLMcode result = CURLM_OK;
@@ -888,9 +906,9 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
if(CURLE_OK == easy->result) { if(CURLE_OK == easy->result) {
/* Add this handle to the send pipeline */ /* Add this handle to the send pipeline */
Curl_addHandleToPipeline(easy->easy_handle, easy->result = Curl_addHandleToPipeline(easy->easy_handle,
easy->easy_conn->send_pipe); easy->easy_conn->send_pipe);
if(CURLE_OK == easy->result) {
if(async) if(async)
/* We're now waiting for an asynchronous name lookup */ /* We're now waiting for an asynchronous name lookup */
multistate(easy, CURLM_STATE_WAITRESOLVE); multistate(easy, CURLM_STATE_WAITRESOLVE);
@@ -912,6 +930,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
} }
} }
} }
}
break; break;
case CURLM_STATE_WAITRESOLVE: case CURLM_STATE_WAITRESOLVE:
@@ -988,7 +1007,14 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
if(!protocol_connect) { if(!protocol_connect) {
/* We have a TCP connection, but 'protocol_connect' may be false /* We have a TCP connection, but 'protocol_connect' may be false
and then we continue to 'STATE_PROTOCONNECT'. If protocol and then we continue to 'STATE_PROTOCONNECT'. If protocol
connect is TRUE, we move on to STATE_DO. */ connect is TRUE, we move on to STATE_DO.
BUT if we are using a proxy we must change to WAITPROXYCONNECT
*/
#ifndef CURL_DISABLE_HTTP
if (easy->easy_conn->bits.tunnel_connecting)
multistate(easy, CURLM_STATE_WAITPROXYCONNECT);
else
#endif
multistate(easy, CURLM_STATE_PROTOCONNECT); multistate(easy, CURLM_STATE_PROTOCONNECT);
} }
else { else {
@@ -1145,7 +1171,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
Curl_removeHandleFromPipeline(easy->easy_handle, Curl_removeHandleFromPipeline(easy->easy_handle,
easy->easy_conn->send_pipe); easy->easy_conn->send_pipe);
/* Add ourselves to the recv pipeline */ /* Add ourselves to the recv pipeline */
Curl_addHandleToPipeline(easy->easy_handle, easy->result = Curl_addHandleToPipeline(easy->easy_handle,
easy->easy_conn->recv_pipe); easy->easy_conn->recv_pipe);
multistate(easy, CURLM_STATE_WAITPERFORM); multistate(easy, CURLM_STATE_WAITPERFORM);
result = CURLM_CALL_MULTI_PERFORM; result = CURLM_CALL_MULTI_PERFORM;
@@ -1385,6 +1411,17 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
multi->num_msgs++; /* increase message counter */ multi->num_msgs++; /* increase message counter */
} }
if(CURLM_CALL_MULTI_PERFORM == result)
/* Set the timeout for this handle to expire really soon so that it will
be taken care of even when this handle is added in the midst of
operation when only the curl_multi_socket() API is used. During that
flow, only sockets that time-out or have actions will be dealt
with. Since this handle has no action yet, we make sure it times out to
get things to happen. Also, this makes it less important for callers of
the curl_multi_* functions to bother about the CURLM_CALL_MULTI_PERFORM
return code, as long as they deal with the timeouts properly. */
Curl_expire(easy->easy_handle, 10);
return result; return result;
} }
@@ -1443,7 +1480,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
*running_handles = multi->num_alive; *running_handles = multi->num_alive;
if ( CURLM_OK == returncode ) if ( CURLM_OK >= returncode )
update_timer(multi); update_timer(multi);
return returncode; return returncode;
} }
@@ -1661,6 +1698,7 @@ static void singlesocket(struct Curl_multi *multi,
static CURLMcode multi_socket(struct Curl_multi *multi, static CURLMcode multi_socket(struct Curl_multi *multi,
bool checkall, bool checkall,
curl_socket_t s, curl_socket_t s,
int ev_bitmask,
int *running_handles) int *running_handles)
{ {
CURLMcode result = CURLM_OK; CURLMcode result = CURLM_OK;
@@ -1698,9 +1736,15 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
/* bad bad bad bad bad bad bad */ /* bad bad bad bad bad bad bad */
return CURLM_INTERNAL_ERROR; return CURLM_INTERNAL_ERROR;
if (data->set.one_easy->easy_conn) /* set socket event bitmask */
data->set.one_easy->easy_conn->cselect_bits = ev_bitmask;
result = multi_runsingle(multi, data->set.one_easy); result = multi_runsingle(multi, data->set.one_easy);
if(result == CURLM_OK) if (data->set.one_easy->easy_conn)
data->set.one_easy->easy_conn->cselect_bits = 0;
if(CURLM_OK >= result)
/* get the socket(s) and check if the state has been changed since /* get the socket(s) and check if the state has been changed since
last */ last */
singlesocket(multi, data->set.one_easy); singlesocket(multi, data->set.one_easy);
@@ -1726,7 +1770,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
if(data) { if(data) {
result = multi_runsingle(multi, data->set.one_easy); result = multi_runsingle(multi, data->set.one_easy);
if(result == CURLM_OK) if(CURLM_OK >= result)
/* get the socket(s) and check if the state has been changed since /* get the socket(s) and check if the state has been changed since
last */ last */
singlesocket(multi, data->set.one_easy); singlesocket(multi, data->set.one_easy);
@@ -1783,6 +1827,9 @@ CURLMcode curl_multi_setopt(CURLM *multi_handle,
case CURLMOPT_TIMERDATA: case CURLMOPT_TIMERDATA:
multi->timer_userp = va_arg(param, void *); multi->timer_userp = va_arg(param, void *);
break; break;
case CURLMOPT_MAXCONNECTS:
multi->maxconnects = va_arg(param, long);
break;
default: default:
res = CURLM_UNKNOWN_OPTION; res = CURLM_UNKNOWN_OPTION;
break; break;
@@ -1791,13 +1838,25 @@ CURLMcode curl_multi_setopt(CURLM *multi_handle,
return res; return res;
} }
/* we define curl_multi_socket() in the public multi.h header */
#undef curl_multi_socket
CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
int *running_handles) int *running_handles)
{ {
CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s, CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
running_handles); 0, running_handles);
if (CURLM_OK == result) if (CURLM_OK >= result)
update_timer((struct Curl_multi *)multi_handle);
return result;
}
CURLMcode curl_multi_socket_action(CURLM *multi_handle, curl_socket_t s,
int ev_bitmask, int *running_handles)
{
CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
ev_bitmask, running_handles);
if (CURLM_OK >= result)
update_timer((struct Curl_multi *)multi_handle); update_timer((struct Curl_multi *)multi_handle);
return result; return result;
} }
@@ -1806,8 +1865,8 @@ CURLMcode curl_multi_socket_all(CURLM *multi_handle, int *running_handles)
{ {
CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, CURLMcode result = multi_socket((struct Curl_multi *)multi_handle,
TRUE, CURL_SOCKET_BAD, running_handles); TRUE, CURL_SOCKET_BAD, 0, running_handles);
if (CURLM_OK == result) if (CURLM_OK >= result)
update_timer((struct Curl_multi *)multi_handle); update_timer((struct Curl_multi *)multi_handle);
return result; return result;
} }

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -227,7 +227,7 @@ int Curl_parsenetrc(char *host,
} }
#ifdef _NETRC_DEBUG #ifdef _NETRC_DEBUG
int main(int argc, char **argv) int main(int argc, argv_item_t argv[])
{ {
char login[64]=""; char login[64]="";
char password[64]=""; char password[64]="";

View File

@@ -74,6 +74,8 @@ PRFileDesc *PR_ImportTCPSocket(PRInt32 osfd);
static int initialized = 0; static int initialized = 0;
static int noverify = 0; static int noverify = 0;
#define HANDSHAKE_TIMEOUT 30
typedef struct { typedef struct {
PRInt32 retryCount; PRInt32 retryCount;
struct SessionHandle *data; struct SessionHandle *data;
@@ -513,6 +515,12 @@ CURLcode Curl_nss_connect(struct connectdata * conn, int sockindex)
SSL_SetURL(connssl->handle, conn->host.name); SSL_SetURL(connssl->handle, conn->host.name);
/* Force the handshake now */
if (SSL_ForceHandshakeWithTimeout(connssl->handle,
PR_SecondsToInterval(HANDSHAKE_TIMEOUT))
!= SECSuccess)
goto error;
return CURLE_OK; return CURLE_OK;
error: error:

View File

@@ -245,6 +245,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
long ulestimate=0; long ulestimate=0;
long dlestimate=0; long dlestimate=0;
long total_estimate; long total_estimate;
bool shownow=FALSE;
now = Curl_tvnow(); /* what time is it */ now = Curl_tvnow(); /* what time is it */
@@ -266,6 +267,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
/* Calculations done at most once a second, unless end is reached */ /* Calculations done at most once a second, unless end is reached */
if(data->progress.lastshow != (long)now.tv_sec) { if(data->progress.lastshow != (long)now.tv_sec) {
shownow = TRUE;
data->progress.lastshow = now.tv_sec; data->progress.lastshow = now.tv_sec;
@@ -346,7 +348,12 @@ int Curl_pgrsUpdate(struct connectdata *conn)
return result; return result;
} }
/* If there's no external callback set, use internal code to show progress */ if(!shownow)
/* only show the internal progress meter once per second */
return 0;
/* If there's no external callback set, use internal code to show
progress */
if(!(data->progress.flags & PGRS_HEADERS_OUT)) { if(!(data->progress.flags & PGRS_HEADERS_OUT)) {
if(data->reqdata.resume_from) { if(data->reqdata.resume_from) {
@@ -422,7 +429,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
/* we flush the output stream to make it appear as soon as possible */ /* we flush the output stream to make it appear as soon as possible */
fflush(data->set.err); fflush(data->set.err);
} } /* !(data->progress.flags & PGRS_HIDE) */
return 0; return 0;
} }

View File

@@ -76,12 +76,12 @@
#define elapsed_ms (int)curlx_tvdiff(curlx_tvnow(), initial_tv) #define elapsed_ms (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
#ifdef CURL_ACKNOWLEDGE_EINTR #ifdef CURL_ACKNOWLEDGE_EINTR
#define error_not_EINTR (error != EINTR) #define error_is_EINTR (error == EINTR)
#else #else
#define error_not_EINTR (1) #define error_is_EINTR (0)
#endif #endif
#define SMALL_POLLNFDS 0X20 #define SMALL_POLLNFDS 0x20
/* /*
* Internal function used for waiting a specific amount of ms * Internal function used for waiting a specific amount of ms
@@ -136,9 +136,15 @@ static int wait_ms(int timeout_ms)
pending_tv.tv_usec = (pending_ms % 1000) * 1000; pending_tv.tv_usec = (pending_ms % 1000) * 1000;
r = select(0, NULL, NULL, NULL, &pending_tv); r = select(0, NULL, NULL, NULL, &pending_tv);
#endif /* HAVE_POLL_FINE */ #endif /* HAVE_POLL_FINE */
} while ((r == -1) && (error = SOCKERRNO) && if (r != -1)
(error != EINVAL) && error_not_EINTR && break;
((pending_ms = timeout_ms - elapsed_ms) > 0)); error = SOCKERRNO;
if ((error == EINVAL) || error_is_EINTR)
break;
pending_ms = timeout_ms - elapsed_ms;
if (pending_ms <= 0)
break;
} while (r == -1);
#endif /* USE_WINSOCK */ #endif /* USE_WINSOCK */
if (r) if (r)
r = -1; r = -1;
@@ -161,9 +167,10 @@ static int wait_ms(int timeout_ms)
* Return values: * Return values:
* -1 = system call error or fd >= FD_SETSIZE * -1 = system call error or fd >= FD_SETSIZE
* 0 = timeout * 0 = timeout
* CSELECT_IN | CSELECT_OUT | CSELECT_ERR * CURL_CSELECT_IN | CURL_CSELECT_OUT | CURL_CSELECT_ERR
*/ */
int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms) int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd,
int timeout_ms)
{ {
#ifdef HAVE_POLL_FINE #ifdef HAVE_POLL_FINE
struct pollfd pfd[2]; struct pollfd pfd[2];
@@ -177,7 +184,7 @@ int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd, int timeout_m
curl_socket_t maxfd; curl_socket_t maxfd;
#endif #endif
struct timeval initial_tv; struct timeval initial_tv;
int pending_ms; int pending_ms = 0;
int error; int error;
int r; int r;
int ret; int ret;
@@ -187,8 +194,15 @@ int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd, int timeout_m
return r; return r;
} }
/* Avoid initial timestamp, avoid gettimeofday() call, when elapsed
time in this function does not need to be measured. This happens
when function is called with a zero timeout or a negative timeout
value indicating a blocking call should be performed. */
if (timeout_ms > 0) {
pending_ms = timeout_ms; pending_ms = timeout_ms;
initial_tv = curlx_tvnow(); initial_tv = curlx_tvnow();
}
#ifdef HAVE_POLL_FINE #ifdef HAVE_POLL_FINE
@@ -209,10 +223,20 @@ int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd, int timeout_m
do { do {
if (timeout_ms < 0) if (timeout_ms < 0)
pending_ms = -1; pending_ms = -1;
else if (!timeout_ms)
pending_ms = 0;
r = poll(pfd, num, pending_ms); r = poll(pfd, num, pending_ms);
} while ((r == -1) && (error = SOCKERRNO) && if (r != -1)
(error != EINVAL) && error_not_EINTR && break;
((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0))); error = SOCKERRNO;
if ((error == EINVAL) || error_is_EINTR)
break;
if (timeout_ms > 0) {
pending_ms = timeout_ms - elapsed_ms;
if (pending_ms <= 0)
break;
}
} while (r == -1);
if (r < 0) if (r < 0)
return -1; return -1;
@@ -223,16 +247,16 @@ int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd, int timeout_m
num = 0; num = 0;
if (readfd != CURL_SOCKET_BAD) { if (readfd != CURL_SOCKET_BAD) {
if (pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP)) if (pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
ret |= CSELECT_IN; ret |= CURL_CSELECT_IN;
if (pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL)) if (pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
ret |= CSELECT_ERR; ret |= CURL_CSELECT_ERR;
num++; num++;
} }
if (writefd != CURL_SOCKET_BAD) { if (writefd != CURL_SOCKET_BAD) {
if (pfd[num].revents & (POLLWRNORM|POLLOUT)) if (pfd[num].revents & (POLLWRNORM|POLLOUT))
ret |= CSELECT_OUT; ret |= CURL_CSELECT_OUT;
if (pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL)) if (pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL))
ret |= CSELECT_ERR; ret |= CURL_CSELECT_ERR;
} }
return ret; return ret;
@@ -262,14 +286,26 @@ int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd, int timeout_m
ptimeout = (timeout_ms < 0) ? NULL : &pending_tv; ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
do { do {
if (ptimeout) { if (timeout_ms > 0) {
pending_tv.tv_sec = pending_ms / 1000; pending_tv.tv_sec = pending_ms / 1000;
pending_tv.tv_usec = (pending_ms % 1000) * 1000; pending_tv.tv_usec = (pending_ms % 1000) * 1000;
} }
else if (!timeout_ms) {
pending_tv.tv_sec = 0;
pending_tv.tv_usec = 0;
}
r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout); r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
} while ((r == -1) && (error = SOCKERRNO) && if (r != -1)
(error != EINVAL) && (error != EBADF) && error_not_EINTR && break;
((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0))); error = SOCKERRNO;
if ((error == EINVAL) || (error == EBADF) || error_is_EINTR)
break;
if (timeout_ms > 0) {
pending_ms = timeout_ms - elapsed_ms;
if (pending_ms <= 0)
break;
}
} while (r == -1);
if (r < 0) if (r < 0)
return -1; return -1;
@@ -279,15 +315,15 @@ int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd, int timeout_m
ret = 0; ret = 0;
if (readfd != CURL_SOCKET_BAD) { if (readfd != CURL_SOCKET_BAD) {
if (FD_ISSET(readfd, &fds_read)) if (FD_ISSET(readfd, &fds_read))
ret |= CSELECT_IN; ret |= CURL_CSELECT_IN;
if (FD_ISSET(readfd, &fds_err)) if (FD_ISSET(readfd, &fds_err))
ret |= CSELECT_ERR; ret |= CURL_CSELECT_ERR;
} }
if (writefd != CURL_SOCKET_BAD) { if (writefd != CURL_SOCKET_BAD) {
if (FD_ISSET(writefd, &fds_write)) if (FD_ISSET(writefd, &fds_write))
ret |= CSELECT_OUT; ret |= CURL_CSELECT_OUT;
if (FD_ISSET(writefd, &fds_err)) if (FD_ISSET(writefd, &fds_err))
ret |= CSELECT_ERR; ret |= CURL_CSELECT_ERR;
} }
return ret; return ret;
@@ -325,7 +361,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
struct timeval initial_tv; struct timeval initial_tv;
bool fds_none = TRUE; bool fds_none = TRUE;
unsigned int i; unsigned int i;
int pending_ms; int pending_ms = 0;
int error; int error;
int r; int r;
@@ -342,18 +378,35 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
return r; return r;
} }
/* Avoid initial timestamp, avoid gettimeofday() call, when elapsed
time in this function does not need to be measured. This happens
when function is called with a zero timeout or a negative timeout
value indicating a blocking call should be performed. */
if (timeout_ms > 0) {
pending_ms = timeout_ms; pending_ms = timeout_ms;
initial_tv = curlx_tvnow(); initial_tv = curlx_tvnow();
}
#ifdef HAVE_POLL_FINE #ifdef HAVE_POLL_FINE
do { do {
if (timeout_ms < 0) if (timeout_ms < 0)
pending_ms = -1; pending_ms = -1;
else if (!timeout_ms)
pending_ms = 0;
r = poll(ufds, nfds, pending_ms); r = poll(ufds, nfds, pending_ms);
} while ((r == -1) && (error = SOCKERRNO) && if (r != -1)
(error != EINVAL) && error_not_EINTR && break;
((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0))); error = SOCKERRNO;
if ((error == EINVAL) || error_is_EINTR)
break;
if (timeout_ms > 0) {
pending_ms = timeout_ms - elapsed_ms;
if (pending_ms <= 0)
break;
}
} while (r == -1);
#else /* HAVE_POLL_FINE */ #else /* HAVE_POLL_FINE */
@@ -383,14 +436,26 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
ptimeout = (timeout_ms < 0) ? NULL : &pending_tv; ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
do { do {
if (ptimeout) { if (timeout_ms > 0) {
pending_tv.tv_sec = pending_ms / 1000; pending_tv.tv_sec = pending_ms / 1000;
pending_tv.tv_usec = (pending_ms % 1000) * 1000; pending_tv.tv_usec = (pending_ms % 1000) * 1000;
} }
else if (!timeout_ms) {
pending_tv.tv_sec = 0;
pending_tv.tv_usec = 0;
}
r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout); r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
} while ((r == -1) && (error = SOCKERRNO) && if (r != -1)
(error != EINVAL) && (error != EBADF) && error_not_EINTR && break;
((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0))); error = SOCKERRNO;
if ((error == EINVAL) || (error == EBADF) || error_is_EINTR)
break;
if (timeout_ms > 0) {
pending_ms = timeout_ms - elapsed_ms;
if (pending_ms <= 0)
break;
}
} while (r == -1);
if (r < 0) if (r < 0)
return -1; return -1;
@@ -417,189 +482,6 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
return r; return r;
} }
/*
* This is a wrapper around select(). It uses poll() when a fine
* poll() is available, in order to avoid limits with FD_SETSIZE,
* otherwise select() is used. An error is returned if select() is
* being used and a the number of file descriptors is larger than
* FD_SETSIZE. A NULL timeout pointer makes this function wait
* indefinitely, unles no valid file descriptor is given, when this
* happens the NULL timeout is ignored and the function times out
* immediately. When compiled with CURL_ACKNOWLEDGE_EINTR defined,
* EINTR condition is honored and function might exit early without
* awaiting timeout, otherwise EINTR will be ignored.
*
* Return values:
* -1 = system call error or nfds > FD_SETSIZE
* 0 = timeout
* N = number of file descriptors kept in file descriptor sets.
*/
int Curl_select(int nfds,
fd_set *fds_read, fd_set *fds_write, fd_set *fds_excep,
struct timeval *timeout)
{
struct timeval initial_tv;
int timeout_ms;
int pending_ms;
int error;
int r;
#ifdef HAVE_POLL_FINE
struct pollfd small_fds[SMALL_POLLNFDS];
struct pollfd *poll_fds;
int ix;
int fd;
int poll_nfds = 0;
#else
struct timeval pending_tv;
struct timeval *ptimeout;
#endif
int ret = 0;
if ((nfds < 0) ||
((nfds > 0) && (!fds_read && !fds_write && !fds_excep))) {
SET_SOCKERRNO(EINVAL);
return -1;
}
if (timeout) {
if ((timeout->tv_sec < 0) ||
(timeout->tv_usec < 0) ||
(timeout->tv_usec >= 1000000)) {
SET_SOCKERRNO(EINVAL);
return -1;
}
timeout_ms = (int)(timeout->tv_sec * 1000) + (int)(timeout->tv_usec / 1000);
}
else {
timeout_ms = -1;
}
if ((!nfds) || (!fds_read && !fds_write && !fds_excep)) {
r = wait_ms(timeout_ms);
return r;
}
pending_ms = timeout_ms;
initial_tv = curlx_tvnow();
#ifdef HAVE_POLL_FINE
if (fds_read || fds_write || fds_excep) {
fd = nfds;
while (fd--) {
if ((fds_read && (0 != FD_ISSET(fd, fds_read))) ||
(fds_write && (0 != FD_ISSET(fd, fds_write))) ||
(fds_excep && (0 != FD_ISSET(fd, fds_excep))))
poll_nfds++;
}
}
if (!poll_nfds)
poll_fds = NULL;
else if (poll_nfds <= SMALL_POLLNFDS)
poll_fds = small_fds;
else {
poll_fds = calloc((size_t)poll_nfds, sizeof(struct pollfd));
if (!poll_fds) {
SET_SOCKERRNO(ENOBUFS);
return -1;
}
}
if (poll_fds) {
ix = 0;
fd = nfds;
while (fd--) {
poll_fds[ix].events = 0;
if (fds_read && (0 != FD_ISSET(fd, fds_read)))
poll_fds[ix].events |= (POLLRDNORM|POLLIN);
if (fds_write && (0 != FD_ISSET(fd, fds_write)))
poll_fds[ix].events |= (POLLWRNORM|POLLOUT);
if (fds_excep && (0 != FD_ISSET(fd, fds_excep)))
poll_fds[ix].events |= (POLLRDBAND|POLLPRI);
if (poll_fds[ix].events) {
poll_fds[ix].fd = fd;
poll_fds[ix].revents = 0;
ix++;
}
}
}
do {
if (timeout_ms < 0)
pending_ms = -1;
r = poll(poll_fds, poll_nfds, pending_ms);
} while ((r == -1) && (error = SOCKERRNO) &&
(error != EINVAL) && error_not_EINTR &&
((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0)));
if (r < 0)
ret = -1;
if (r > 0) {
ix = poll_nfds;
while (ix--) {
if (poll_fds[ix].revents & POLLNVAL) {
SET_SOCKERRNO(EBADF);
ret = -1;
break;
}
}
}
if (!ret) {
ix = poll_nfds;
while (ix--) {
if (fds_read && (0 != FD_ISSET(poll_fds[ix].fd, fds_read))) {
if (0 == (poll_fds[ix].revents & (POLLRDNORM|POLLERR|POLLHUP|POLLIN)))
FD_CLR(poll_fds[ix].fd, fds_read);
else
ret++;
}
if (fds_write && (0 != FD_ISSET(poll_fds[ix].fd, fds_write))) {
if (0 == (poll_fds[ix].revents & (POLLWRNORM|POLLERR|POLLHUP|POLLOUT)))
FD_CLR(poll_fds[ix].fd, fds_write);
else
ret++;
}
if (fds_excep && (0 != FD_ISSET(poll_fds[ix].fd, fds_excep))) {
if (0 == (poll_fds[ix].revents & (POLLRDBAND|POLLERR|POLLHUP|POLLPRI)))
FD_CLR(poll_fds[ix].fd, fds_excep);
else
ret++;
}
}
}
if (poll_fds && (poll_nfds > SMALL_POLLNFDS))
free(poll_fds);
#else /* HAVE_POLL_FINE */
VERIFY_NFDS(nfds);
ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
do {
if (ptimeout) {
pending_tv.tv_sec = pending_ms / 1000;
pending_tv.tv_usec = (pending_ms % 1000) * 1000;
}
r = select(nfds, fds_read, fds_write, fds_excep, ptimeout);
} while ((r == -1) && (error = SOCKERRNO) &&
(error != EINVAL) && (error != EBADF) && error_not_EINTR &&
((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0)));
if (r < 0)
ret = -1;
else
ret = r;
#endif /* HAVE_POLL_FINE */
return ret;
}
#ifdef TPF #ifdef TPF
/* /*
* This is a replacement for select() on the TPF platform. * This is a replacement for select() on the TPF platform.

View File

@@ -46,7 +46,7 @@
* Definition of pollfd struct and constants for platforms lacking them. * Definition of pollfd struct and constants for platforms lacking them.
*/ */
#ifndef HAVE_POLL #ifndef HAVE_SYS_POLL_H
#define POLLIN 0x01 #define POLLIN 0x01
#define POLLPRI 0x02 #define POLLPRI 0x02
@@ -76,18 +76,11 @@ struct pollfd
#define POLLRDBAND POLLPRI #define POLLRDBAND POLLPRI
#endif #endif
#define CSELECT_IN 0x01 int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd,
#define CSELECT_OUT 0x02 int timeout_ms);
#define CSELECT_ERR 0x04
int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms);
int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms); int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
int Curl_select(int nfds,
fd_set *fds_read, fd_set *fds_write, fd_set *fds_excep,
struct timeval *timeout);
#ifdef TPF #ifdef TPF
int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes, int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
fd_set* excepts, struct timeval* tv); fd_set* excepts, struct timeval* tv);

View File

@@ -79,11 +79,11 @@ static struct curl_slist *slist_get_last(struct curl_slist *list)
} }
/* /*
* curl_slist_append() appends a string to the linked list. It always retunrs * curl_slist_append() appends a string to the linked list. It always returns
* the address of the first record, so that you can sure this function as an * the address of the first record, so that you can use this function as an
* initialization function as well as an append function. If you find this * initialization function as well as an append function. If you find this
* bothersome, then simply create a separate _init function and call it * bothersome, then simply create a separate _init function and call it
* appropriately from within the proram. * appropriately from within the program.
*/ */
struct curl_slist *curl_slist_append(struct curl_slist *list, struct curl_slist *curl_slist_append(struct curl_slist *list,
const char *data) const char *data)
@@ -495,7 +495,7 @@ int Curl_read(struct connectdata *conn, /* connection data */
} }
/* If we come here, it means that there is no data to read from the buffer, /* If we come here, it means that there is no data to read from the buffer,
* so we read from the socket */ * so we read from the socket */
bytesfromsocket = MIN(sizerequested, sizeof(conn->master_buffer)); bytesfromsocket = MIN(sizerequested, BUFSIZE * sizeof (char));
buffertofill = conn->master_buffer; buffertofill = conn->master_buffer;
} }
else { else {

View File

@@ -259,6 +259,12 @@
#define sclose(x) CloseSocket(x) #define sclose(x) CloseSocket(x)
#endif #endif
#ifdef __minix
/* Minix 3 versions up to at least 3.1.3 are missing these prototypes */
extern char * strtok_r(char *s, const char *delim, char **last);
extern struct tm * gmtime_r(const time_t * const timep, struct tm *tmp);
#endif
#define DIR_CHAR "/" #define DIR_CHAR "/"
#ifndef DOT_CHAR #ifndef DOT_CHAR
#define DOT_CHAR "." #define DOT_CHAR "."

View File

@@ -344,5 +344,108 @@ typedef int sig_atomic_t;
#endif #endif
/*
* Actually use __32_getpwuid() on 64-bit VMS builds for getpwuid()
*/
#if defined(VMS) && \
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
#define getpwuid __32_getpwuid
#endif
/*
* Macro argv_item_t hides platform details to code using it.
*/
#ifdef VMS
#define argv_item_t __char_ptr32
#else
#define argv_item_t char *
#endif
#if defined (__LP64__) && defined(__hpux) && !defined(_XOPEN_SOURCE_EXTENDED)
#include <sys/socket.h>
/* HP-UX has this oddity where it features a few functions that don't work
with socklen_t so we need to convert to ints
This is due to socklen_t being a 64bit int under 64bit ABI, but the
pre-xopen (default) interfaces require an int, which is 32bits.
Therefore, Anytime socklen_t is passed by pointer, the libc function
truncates the 64bit socklen_t value by treating it as a 32bit value.
Note that some socket calls are allowed to have a NULL pointer for
the socklen arg.
*/
inline static int Curl_hp_getsockname(int s, struct sockaddr *name,
socklen_t *namelen)
{
int rc;
if(namelen) {
int len = *namelen;
rc = getsockname(s, name, &len);
*namelen = len;
}
else
rc = getsockname(s, name, 0);
return rc;
}
inline static int Curl_hp_getsockopt(int s, int level, int optname,
void *optval, socklen_t *optlen)
{
int rc;
if(optlen) {
int len = *optlen;
rc = getsockopt(s, level, optname, optval, &len);
*optlen = len;
}
else
rc = getsockopt(s, level, optname, optval, 0);
return rc;
}
inline static int Curl_hp_accept(int sockfd, struct sockaddr *addr,
socklen_t *addrlen)
{
int rc;
if(addrlen) {
int len = *addrlen;
rc = accept(sockfd, addr, &len);
*addrlen = len;
}
else
rc = accept(sockfd, addr, 0);
return rc;
}
inline static ssize_t Curl_hp_recvfrom(int s, void *buf, size_t len, int flags,
struct sockaddr *from,
socklen_t *fromlen)
{
ssize_t rc;
if(fromlen) {
int fromlen32 = *fromlen;
rc = recvfrom(s, buf, len, flags, from, &fromlen32);
*fromlen = fromlen32;
}
else {
rc = recvfrom(s, buf, len, flags, from, 0);
}
return rc;
}
#define getsockname(a,b,c) Curl_hp_getsockname((a),(b),(c))
#define getsockopt(a,b,c,d,e) Curl_hp_getsockopt((a),(b),(c),(d),(e))
#define accept(a,b,c) Curl_hp_accept((a),(b),(c))
#define recvfrom(a,b,c,d,e,f) Curl_hp_recvfrom((a),(b),(c),(d),(e),(f))
#endif /* HPUX work-around */
#endif /* __SETUP_ONCE_H */ #endif /* __SETUP_ONCE_H */

View File

@@ -98,6 +98,11 @@ static int blockread_all(struct connectdata *conn, /* connection data */
result = CURLE_OK; result = CURLE_OK;
break; break;
} }
if(!nread) {
result = ~CURLE_OK;
break;
}
buffersize -= nread; buffersize -= nread;
buf += nread; buf += nread;
allread += nread; allread += nread;
@@ -383,7 +388,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
return CURLE_OPERATION_TIMEDOUT; return CURLE_OPERATION_TIMEDOUT;
} }
if(result & CSELECT_ERR) { if(result & CURL_CSELECT_ERR) {
failf(conn->data, "SOCKS5: error occured during connection"); failf(conn->data, "SOCKS5: error occured during connection");
return CURLE_COULDNT_CONNECT; return CURLE_COULDNT_CONNECT;
} }
@@ -415,7 +420,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
return CURLE_OPERATION_TIMEDOUT; return CURLE_OPERATION_TIMEDOUT;
} }
if(result & CSELECT_ERR) { if(result & CURL_CSELECT_ERR) {
failf(conn->data, "SOCKS5 read error occured"); failf(conn->data, "SOCKS5 read error occured");
return CURLE_RECV_ERROR; return CURLE_RECV_ERROR;
} }

View File

@@ -21,6 +21,8 @@
* $Id$ * $Id$
***************************************************************************/ ***************************************************************************/
#include "setup.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -364,7 +366,7 @@ void Curl_splayprint(struct Curl_tree * t, int d, char output)
/* A sample use of these functions. Start with the empty tree, insert some /* A sample use of these functions. Start with the empty tree, insert some
stuff into it, and then delete it */ stuff into it, and then delete it */
int main(int argc, char **argv) int main(int argc, argv_item_t argv[])
{ {
struct Curl_tree *root, *t; struct Curl_tree *root, *t;
void *ptrs[MAX]; void *ptrs[MAX];

1120
lib/ssh.c

File diff suppressed because it is too large Load Diff

View File

@@ -27,6 +27,7 @@
#ifdef USE_LIBSSH2 #ifdef USE_LIBSSH2
CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done); CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done);
CURLcode Curl_ssh_multi_statemach(struct connectdata *conn, bool *done);
CURLcode Curl_scp_do(struct connectdata *conn, bool *done); CURLcode Curl_scp_do(struct connectdata *conn, bool *done);
CURLcode Curl_scp_done(struct connectdata *conn, CURLcode, bool premature); CURLcode Curl_scp_done(struct connectdata *conn, CURLcode, bool premature);

View File

@@ -413,17 +413,14 @@ void Curl_ssl_close(struct connectdata *conn)
if(conn->ssl[FIRSTSOCKET].use) { if(conn->ssl[FIRSTSOCKET].use) {
#ifdef USE_SSLEAY #ifdef USE_SSLEAY
Curl_ossl_close(conn); Curl_ossl_close(conn);
#else #endif /* USE_SSLEAY */
#ifdef USE_GNUTLS #ifdef USE_GNUTLS
Curl_gtls_close(conn); Curl_gtls_close(conn);
#else
#ifdef USE_GNUTLS
Curl_nss_close(conn);
#else
(void)conn;
#endif /* USE_NSS */
#endif /* USE_GNUTLS */ #endif /* USE_GNUTLS */
#endif /* USE_SSLEAY */ #ifdef USE_NSS
Curl_nss_close(conn);
#endif /* USE_NSS */
conn->ssl[FIRSTSOCKET].use = FALSE;
} }
} }

View File

@@ -377,6 +377,7 @@ int cert_stuff(struct connectdata *conn,
failf(data, failf(data,
"could not parse PKCS12 file, check password, OpenSSL error %s", "could not parse PKCS12 file, check password, OpenSSL error %s",
ERR_error_string(ERR_get_error(), NULL) ); ERR_error_string(ERR_get_error(), NULL) );
PKCS12_free(p12);
return 0; return 0;
} }
@@ -1123,7 +1124,8 @@ static CURLcode verifyhost(struct connectdata *conn,
rc = Curl_convert_from_utf8(data, peer_CN, strlen(peer_CN)); rc = Curl_convert_from_utf8(data, peer_CN, strlen(peer_CN));
/* Curl_convert_from_utf8 calls failf if unsuccessful */ /* Curl_convert_from_utf8 calls failf if unsuccessful */
if (rc != CURLE_OK) { if (rc != CURLE_OK) {
return(rc); OPENSSL_free(peer_CN);
return rc;
} }
} }
#endif /* CURL_DOES_CONVERSIONS */ #endif /* CURL_DOES_CONVERSIONS */

View File

@@ -38,7 +38,7 @@ char *curlx_strdup(const char *str)
if (!newstr) if (!newstr)
return (char *)NULL; return (char *)NULL;
strcpy(newstr,str); memcpy(newstr,str,(len+1)*sizeof(char));
return newstr; return newstr;

View File

@@ -123,8 +123,8 @@ curl_easy_strerror(CURLcode error)
case CURLE_WRITE_ERROR: case CURLE_WRITE_ERROR:
return "failed writing received data to disk/application"; return "failed writing received data to disk/application";
case CURLE_FTP_COULDNT_STOR_FILE: case CURLE_UPLOAD_FAILED:
return "failed FTP upload (the STOR command)"; return "upload failed (at start/before it took off)";
case CURLE_READ_ERROR: case CURLE_READ_ERROR:
return "failed to open/read local data from file/application"; return "failed to open/read local data from file/application";

View File

@@ -136,7 +136,6 @@ typedef struct tftp_state_data {
time_t max_time; time_t max_time;
unsigned short block; unsigned short block;
struct Curl_sockaddr_storage local_addr; struct Curl_sockaddr_storage local_addr;
socklen_t local_addrlen;
struct Curl_sockaddr_storage remote_addr; struct Curl_sockaddr_storage remote_addr;
socklen_t remote_addrlen; socklen_t remote_addrlen;
int rbytes; int rbytes;
@@ -180,6 +179,10 @@ void tftp_set_timeouts(tftp_state_data_t *state)
/* Average restart after 5 seconds */ /* Average restart after 5 seconds */
state->retry_max = timeout/5; state->retry_max = timeout/5;
if(state->retry_max < 1)
/* avoid division by zero below */
state->retry_max = 1;
/* Compute the re-start interval to suit the timeout */ /* Compute the re-start interval to suit the timeout */
state->retry_time = timeout/state->retry_max; state->retry_time = timeout/state->retry_max;
if(state->retry_time<1) if(state->retry_time<1)
@@ -367,6 +370,7 @@ static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
state->remote_addrlen); state->remote_addrlen);
if(sbytes < 0) { if(sbytes < 0) {
failf(data, "%s\n", Curl_strerror(state->conn, SOCKERRNO)); failf(data, "%s\n", Curl_strerror(state->conn, SOCKERRNO));
return CURLE_SEND_ERROR;
} }
/* Check if completed (That is, a less than full packet is received) */ /* Check if completed (That is, a less than full packet is received) */
@@ -396,6 +400,7 @@ static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
/* Check all sbytes were sent */ /* Check all sbytes were sent */
if(sbytes<0) { if(sbytes<0) {
failf(data, "%s\n", Curl_strerror(state->conn, SOCKERRNO)); failf(data, "%s\n", Curl_strerror(state->conn, SOCKERRNO));
return CURLE_SEND_ERROR;
} }
} }
break; break;
@@ -406,10 +411,9 @@ static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
default: default:
failf(data, "%s\n", "tftp_rx: internal error"); failf(data, "%s\n", "tftp_rx: internal error");
break; return CURLE_TFTP_ILLEGAL; /* not really the perfect return code for
this */
} }
Curl_pgrsSetDownloadCounter(data,
(curl_off_t) state->block*TFTP_BLOCKSIZE);
return CURLE_OK; return CURLE_OK;
} }
@@ -426,6 +430,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
int sbytes; int sbytes;
int rblock; int rblock;
CURLcode res = CURLE_OK; CURLcode res = CURLE_OK;
struct Curl_transfer_keeper *k = &data->reqdata.keep;
switch(event) { switch(event) {
@@ -478,7 +483,11 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
/* Check all sbytes were sent */ /* Check all sbytes were sent */
if(sbytes<0) { if(sbytes<0) {
failf(data, "%s\n", Curl_strerror(state->conn, SOCKERRNO)); failf(data, "%s\n", Curl_strerror(state->conn, SOCKERRNO));
return CURLE_SEND_ERROR;
} }
/* Update the progress meter */
k->writebytecount += state->sbytes;
Curl_pgrsSetUploadCounter(data, k->writebytecount);
break; break;
case TFTP_EVENT_TIMEOUT: case TFTP_EVENT_TIMEOUT:
@@ -490,7 +499,8 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
if(state->retries > state->retry_max) { if(state->retries > state->retry_max) {
state->error = TFTP_ERR_TIMEOUT; state->error = TFTP_ERR_TIMEOUT;
state->state = TFTP_STATE_FIN; state->state = TFTP_STATE_FIN;
} else { }
else {
/* Re-send the data packet */ /* Re-send the data packet */
sbytes = sendto(state->sockfd, (void *)&state->spacket, sbytes = sendto(state->sockfd, (void *)&state->spacket,
4+state->sbytes, SEND_4TH_ARG, 4+state->sbytes, SEND_4TH_ARG,
@@ -499,7 +509,10 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
/* Check all sbytes were sent */ /* Check all sbytes were sent */
if(sbytes<0) { if(sbytes<0) {
failf(data, "%s\n", Curl_strerror(state->conn, SOCKERRNO)); failf(data, "%s\n", Curl_strerror(state->conn, SOCKERRNO));
return CURLE_SEND_ERROR;
} }
/* since this was a re-send, we remain at the still byte position */
Curl_pgrsSetUploadCounter(data, k->writebytecount);
} }
break; break;
@@ -512,9 +525,6 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
break; break;
} }
/* Update the progress meter */
Curl_pgrsSetUploadCounter(data, (curl_off_t) state->block*TFTP_BLOCKSIZE);
return res; return res;
} }
@@ -659,6 +669,7 @@ CURLcode Curl_tftp(struct connectdata *conn, bool *done)
struct Curl_sockaddr_storage fromaddr; struct Curl_sockaddr_storage fromaddr;
socklen_t fromlen; socklen_t fromlen;
int check_time = 0; int check_time = 0;
struct Curl_transfer_keeper *k = &data->reqdata.keep;
*done = TRUE; *done = TRUE;
@@ -675,13 +686,18 @@ CURLcode Curl_tftp(struct connectdata *conn, bool *done)
state = (tftp_state_data_t *)conn->data->reqdata.proto.tftp; state = (tftp_state_data_t *)conn->data->reqdata.proto.tftp;
} }
code = Curl_readwrite_init(conn);
if(code)
return code;
/* Run the TFTP State Machine */ /* Run the TFTP State Machine */
for(code=tftp_state_machine(state, TFTP_EVENT_INIT); for(code=tftp_state_machine(state, TFTP_EVENT_INIT);
(state->state != TFTP_STATE_FIN) && (code == CURLE_OK); (state->state != TFTP_STATE_FIN) && (code == CURLE_OK);
code=tftp_state_machine(state, event) ) { code=tftp_state_machine(state, event) ) {
/* Wait until ready to read or timeout occurs */ /* Wait until ready to read or timeout occurs */
rc=Curl_socket_ready(state->sockfd, CURL_SOCKET_BAD, state->retry_time * 1000); rc=Curl_socket_ready(state->sockfd, CURL_SOCKET_BAD,
state->retry_time * 1000);
if(rc == -1) { if(rc == -1) {
/* bail out */ /* bail out */
@@ -730,6 +746,8 @@ CURLcode Curl_tftp(struct connectdata *conn, bool *done)
state->rbytes-4); state->rbytes-4);
if(code) if(code)
return code; return code;
k->bytecount += state->rbytes-4;
Curl_pgrsSetDownloadCounter(data, (curl_off_t) k->bytecount);
} }
break; break;
case TFTP_EVENT_ERROR: case TFTP_EVENT_ERROR:

View File

@@ -270,7 +270,10 @@ CURLcode Curl_readrewind(struct connectdata *conn)
static int data_pending(struct connectdata *conn) static int data_pending(struct connectdata *conn)
{ {
return Curl_ssl_data_pending(conn, FIRSTSOCKET); /* in the case of libssh2, we can never be really sure that we have emptied
its internal buffers so we MUST always try until we get EAGAIN back */
return conn->protocol&(PROT_SCP|PROT_SFTP) ||
Curl_ssl_data_pending(conn, FIRSTSOCKET);
} }
#ifndef MIN #ifndef MIN
@@ -289,8 +292,13 @@ static void read_rewind(struct connectdata *conn,
size_t show; size_t show;
show = MIN(conn->buf_len - conn->read_pos, sizeof(buf)-1); show = MIN(conn->buf_len - conn->read_pos, sizeof(buf)-1);
if (conn->master_buffer) {
memcpy(buf, conn->master_buffer + conn->read_pos, show); memcpy(buf, conn->master_buffer + conn->read_pos, show);
buf[show] = '\0'; buf[show] = '\0';
}
else {
buf[0] = '\0';
}
DEBUGF(infof(conn->data, DEBUGF(infof(conn->data,
"Buffer after stream rewind (read_pos = %d): [%s]", "Buffer after stream rewind (read_pos = %d): [%s]",
@@ -314,9 +322,10 @@ CURLcode Curl_readwrite(struct connectdata *conn,
curl_socket_t fd_read; curl_socket_t fd_read;
curl_socket_t fd_write; curl_socket_t fd_write;
int select_res;
curl_off_t contentlength; curl_off_t contentlength;
int select_res = conn->cselect_bits;
conn->cselect_bits = 0;
/* only use the proper socket if the *_HOLD bit is not set simultaneously as /* 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 */ then we are in rate limiting state in that transfer direction */
@@ -331,8 +340,12 @@ CURLcode Curl_readwrite(struct connectdata *conn,
else else
fd_write = CURL_SOCKET_BAD; fd_write = CURL_SOCKET_BAD;
if (!select_res) { /* Call for select()/poll() only, if read/write/error
status is not known. */
select_res = Curl_socket_ready(fd_read, fd_write, 0); select_res = Curl_socket_ready(fd_read, fd_write, 0);
if(select_res == CSELECT_ERR) { }
if(select_res == CURL_CSELECT_ERR) {
failf(data, "select/poll returned error"); failf(data, "select/poll returned error");
return CURLE_SEND_ERROR; return CURLE_SEND_ERROR;
} }
@@ -342,7 +355,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
the stream was rewound (in which case we have data in a the stream was rewound (in which case we have data in a
buffer) */ buffer) */
if((k->keepon & KEEP_READ) && if((k->keepon & KEEP_READ) &&
((select_res & CSELECT_IN) || conn->bits.stream_was_rewound)) { ((select_res & CURL_CSELECT_IN) || conn->bits.stream_was_rewound)) {
/* read */ /* read */
bool is_empty_data = FALSE; bool is_empty_data = FALSE;
@@ -366,7 +379,6 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* receive data from the network! */ /* receive data from the network! */
readrc = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread); readrc = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread);
DEBUGF(infof(data, "Read %ld bytes from stream (readrc = %d)\n", nread, readrc));
/* subzero, this would've blocked */ /* subzero, this would've blocked */
if(0 > readrc) if(0 > readrc)
break; /* get out of loop */ break; /* get out of loop */
@@ -561,8 +573,9 @@ CURLcode Curl_readwrite(struct connectdata *conn,
else { else {
k->header = FALSE; /* no more header to parse! */ k->header = FALSE; /* no more header to parse! */
if((k->size == -1) && !conn->bits.chunk && !conn->bits.close) if((k->size == -1) && !conn->bits.chunk && !conn->bits.close &&
/* When connection is not to get closed, but no (k->httpversion >= 11) )
/* On HTTP 1.1, when connection is not to get closed, but no
Content-Length nor Content-Encoding chunked have been Content-Length nor Content-Encoding chunked have been
received, there is no body in this response. We don't set received, there is no body in this response. We don't set
stop_reading TRUE since that would also prevent necessary stop_reading TRUE since that would also prevent necessary
@@ -752,8 +765,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if (checkhttpprefix(data, k->p)) { if (checkhttpprefix(data, k->p)) {
nc = 1; nc = 1;
k->httpcode = 200; k->httpcode = 200;
k->httpversion = k->httpversion = 10;
(data->set.httpversion==CURL_HTTP_VERSION_1_0)? 10 : 11;
} }
} }
} }
@@ -1350,7 +1362,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* If we still have writing to do, we check if we have a writable /* If we still have writing to do, we check if we have a writable
socket. */ socket. */
if((k->keepon & KEEP_WRITE) && (select_res & CSELECT_OUT)) { if((k->keepon & KEEP_WRITE) && (select_res & CURL_CSELECT_OUT)) {
/* write */ /* write */
int i, si; int i, si;
@@ -1618,8 +1630,8 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* /*
* Curl_readwrite_init() inits the readwrite session. This is inited each time for a * Curl_readwrite_init() inits the readwrite session. This is inited each time
* transfer, sometimes multiple times on the same SessionHandle * for a transfer, sometimes multiple times on the same SessionHandle
*/ */
CURLcode Curl_readwrite_init(struct connectdata *conn) CURLcode Curl_readwrite_init(struct connectdata *conn)
@@ -1779,9 +1791,11 @@ Transfer(struct connectdata *conn)
struct Curl_transfer_keeper *k = &data->reqdata.keep; struct Curl_transfer_keeper *k = &data->reqdata.keep;
bool done=FALSE; bool done=FALSE;
if(!(conn->protocol & PROT_FILE)) { if(!(conn->protocol & (PROT_FILE|PROT_TFTP))) {
/* Only do this if we are not transferring FILE:, since the file: treatment /* Only do this if we are not transferring FILE or TFTP, since those
is different*/ transfers are treated differently. They do their entire transfers in
the DO function and just returns from this. That is ugly indeed.
*/
Curl_readwrite_init(conn); Curl_readwrite_init(conn);
Curl_pre_readwrite(conn); Curl_pre_readwrite(conn);
} }

153
lib/url.c
View File

@@ -310,6 +310,9 @@ CURLcode Curl_close(struct SessionHandle *data)
} }
} }
if(data->reqdata.rangestringalloc)
free(data->reqdata.range);
/* Free the pathbuffer */ /* Free the pathbuffer */
Curl_safefree(data->reqdata.pathbuffer); Curl_safefree(data->reqdata.pathbuffer);
Curl_safefree(data->reqdata.proto.generic); Curl_safefree(data->reqdata.proto.generic);
@@ -375,8 +378,11 @@ CURLcode Curl_close(struct SessionHandle *data)
#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ #endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
/* No longer a dirty share, if it exists */ /* No longer a dirty share, if it exists */
if (data->share) if (data->share) {
Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
data->share->dirty--; data->share->dirty--;
Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
}
free(data); free(data);
return CURLE_OK; return CURLE_OK;
@@ -1789,6 +1795,7 @@ static void conn_free(struct connectdata *conn)
Curl_safefree(conn->trailer); Curl_safefree(conn->trailer);
Curl_safefree(conn->host.rawalloc); /* host name buffer */ Curl_safefree(conn->host.rawalloc); /* host name buffer */
Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */ Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
Curl_safefree(conn->master_buffer);
Curl_llist_destroy(conn->send_pipe, NULL); Curl_llist_destroy(conn->send_pipe, NULL);
Curl_llist_destroy(conn->recv_pipe, NULL); Curl_llist_destroy(conn->recv_pipe, NULL);
@@ -1829,16 +1836,6 @@ CURLcode Curl_disconnect(struct connectdata *conn)
Curl_expire(data, 0); /* shut off timers */ Curl_expire(data, 0); /* shut off timers */
Curl_hostcache_prune(data); /* kill old DNS cache entries */ Curl_hostcache_prune(data); /* kill old DNS cache entries */
/*
* The range string is usually freed in curl_done(), but we might
* get here *instead* if we fail prematurely. Thus we need to be able
* to free this resource here as well.
*/
if(data->reqdata.rangestringalloc) {
free(data->reqdata.range);
data->reqdata.rangestringalloc = FALSE;
}
if((conn->ntlm.state != NTLMSTATE_NONE) || if((conn->ntlm.state != NTLMSTATE_NONE) ||
(conn->proxyntlm.state != NTLMSTATE_NONE)) { (conn->proxyntlm.state != NTLMSTATE_NONE)) {
/* Authentication data is a mix of connection-related and sessionhandle- /* Authentication data is a mix of connection-related and sessionhandle-
@@ -1931,7 +1928,7 @@ static bool IsPipeliningEnabled(struct SessionHandle *handle)
return FALSE; return FALSE;
} }
void Curl_addHandleToPipeline(struct SessionHandle *data, CURLcode Curl_addHandleToPipeline(struct SessionHandle *data,
struct curl_llist *pipe) struct curl_llist *pipe)
{ {
#ifdef CURLDEBUG #ifdef CURLDEBUG
@@ -1941,7 +1938,9 @@ void Curl_addHandleToPipeline(struct SessionHandle *data,
infof(data, "PIPE when no PIPE supposed!\n"); infof(data, "PIPE when no PIPE supposed!\n");
} }
#endif #endif
Curl_llist_insert_next(pipe, pipe->tail, data); if (!Curl_llist_insert_next(pipe, pipe->tail, data))
return CURLE_OUT_OF_MEMORY;
return CURLE_OK;
} }
@@ -2001,6 +2000,9 @@ static void signalPipeClose(struct curl_llist *pipe)
{ {
struct curl_llist_element *curr; struct curl_llist_element *curr;
if (!pipe)
return;
curr = pipe->head; curr = pipe->head;
while (curr) { while (curr) {
struct curl_llist_element *next = curr->next; struct curl_llist_element *next = curr->next;
@@ -2059,9 +2061,6 @@ ConnectionExists(struct SessionHandle *data,
from the multi */ from the multi */
} }
DEBUGF(infof(data, "Examining connection #%ld for reuse"
" (pipeLen = %ld)\n", check->connectindex, pipeLen));
if(pipeLen > 0 && !canPipeline) { if(pipeLen > 0 && !canPipeline) {
/* can only happen within multi handles, and means that another easy /* can only happen within multi handles, and means that another easy
handle is using this connection */ handle is using this connection */
@@ -2350,6 +2349,8 @@ static CURLcode ConnectPlease(struct SessionHandle *data,
break; break;
} }
} }
if(result)
*connected = FALSE; /* mark it as not connected */
return result; return result;
} }
@@ -2755,6 +2756,37 @@ static void llist_dtor(void *user, void *element)
/* Do nothing */ /* Do nothing */
} }
static CURLcode setup_range(struct SessionHandle *data)
{
/*
* If we're doing a resumed transfer, we need to setup our stuff
* properly.
*/
struct HandleData *req = &data->reqdata;
req->resume_from = data->set.set_resume_from;
if (req->resume_from || data->set.set_range) {
if (req->rangestringalloc == TRUE)
free(req->range);
if(req->resume_from)
req->range = aprintf("%" FORMAT_OFF_T "-", req->resume_from);
else
req->range = strdup(data->set.set_range);
req->rangestringalloc = req->range?TRUE:FALSE;
if(!req->range)
return CURLE_OUT_OF_MEMORY;
/* tell ourselves to fetch this range */
req->use_range = TRUE; /* enable range download */
}
else
req->use_range = FALSE; /* disable range download */
return CURLE_OK;
}
/** /**
* CreateConnection() sets up a new connectdata struct, or re-uses an already * CreateConnection() sets up a new connectdata struct, or re-uses an already
@@ -2825,7 +2857,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
to not have to modify everything at once, we allocate a temporary to not have to modify everything at once, we allocate a temporary
connection data struct and fill in for comparison purposes. */ connection data struct and fill in for comparison purposes. */
conn = (struct connectdata *)calloc(sizeof(struct connectdata), 1); conn = (struct connectdata *)calloc(1, sizeof(struct connectdata));
if(!conn) { if(!conn) {
*in_connect = NULL; /* clear the pointer */ *in_connect = NULL; /* clear the pointer */
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
@@ -2861,21 +2893,9 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->read_pos = 0; conn->read_pos = 0;
conn->buf_len = 0; conn->buf_len = 0;
/* Initialize the pipeline lists */
conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
if (!conn->send_pipe || !conn->recv_pipe)
return CURLE_OUT_OF_MEMORY;
/* Store creation time to help future close decision making */ /* Store creation time to help future close decision making */
conn->created = Curl_tvnow(); conn->created = Curl_tvnow();
/* range status */
data->reqdata.use_range = (bool)(NULL != data->set.set_range);
data->reqdata.range = data->set.set_range; /* clone the range setting */
data->reqdata.resume_from = data->set.set_resume_from;
conn->bits.user_passwd = (bool)(NULL != data->set.userpwd); conn->bits.user_passwd = (bool)(NULL != data->set.userpwd);
conn->bits.proxy_user_passwd = (bool)(NULL != data->set.proxyuserpwd); conn->bits.proxy_user_passwd = (bool)(NULL != data->set.proxyuserpwd);
conn->bits.no_body = data->set.opt_no_body; conn->bits.no_body = data->set.opt_no_body;
@@ -2883,6 +2903,20 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
if (data->multi && Curl_multi_canPipeline(data->multi) &&
!conn->master_buffer) {
/* Allocate master_buffer to be used for pipelining */
conn->master_buffer = calloc(BUFSIZE, sizeof (char));
if (!conn->master_buffer)
return CURLE_OUT_OF_MEMORY;
}
/* Initialize the pipeline lists */
conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
if (!conn->send_pipe || !conn->recv_pipe)
return CURLE_OUT_OF_MEMORY;
/* This initing continues below, see the comment "Continue connectdata /* This initing continues below, see the comment "Continue connectdata
* initialization here" */ * initialization here" */
@@ -3697,28 +3731,6 @@ else {
if(!conn->user || !conn->passwd) if(!conn->user || !conn->passwd)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
#ifndef CURL_DISABLE_HTTP
/************************************************************
* RESUME on a HTTP page is a tricky business. First, let's just check that
* 'range' isn't used, then set the range parameter and leave the resume as
* it is to inform about this situation for later use. We will then
* "attempt" to resume, and if we're talking to a HTTP/1.1 (or later)
* server, we will get the document resumed. If we talk to a HTTP/1.0
* server, we just fail since we can't rewind the file writing from within
* this function.
***********************************************************/
if(data->reqdata.resume_from) {
if(!data->reqdata.use_range) {
/* if it already was in use, we just skip this */
data->reqdata.range = aprintf("%" FORMAT_OFF_T "-", data->reqdata.resume_from);
if(!data->reqdata.range)
return CURLE_OUT_OF_MEMORY;
data->reqdata.rangestringalloc = TRUE; /* mark as allocated */
data->reqdata.use_range = 1; /* switch on range usage */
}
}
#endif
/************************************************************* /*************************************************************
* Check the current list of connections to see if we can * Check the current list of connections to see if we can
* re-use an already existing one or if we have to create a * re-use an already existing one or if we have to create a
@@ -3803,37 +3815,10 @@ else {
Curl_safefree(old_conn->proxypasswd); Curl_safefree(old_conn->proxypasswd);
Curl_llist_destroy(old_conn->send_pipe, NULL); Curl_llist_destroy(old_conn->send_pipe, NULL);
Curl_llist_destroy(old_conn->recv_pipe, NULL); Curl_llist_destroy(old_conn->recv_pipe, NULL);
Curl_safefree(old_conn->master_buffer);
free(old_conn); /* we don't need this anymore */ free(old_conn); /* we don't need this anymore */
/*
* If we're doing a resumed transfer, we need to setup our stuff
* properly.
*/
data->reqdata.resume_from = data->set.set_resume_from;
if (data->reqdata.resume_from) {
if (data->reqdata.rangestringalloc == TRUE)
free(data->reqdata.range);
data->reqdata.range = aprintf("%" FORMAT_OFF_T "-",
data->reqdata.resume_from);
if(!data->reqdata.range)
return CURLE_OUT_OF_MEMORY;
/* tell ourselves to fetch this range */
data->reqdata.use_range = TRUE; /* enable range download */
data->reqdata.rangestringalloc = TRUE; /* mark range string allocated */
}
else if (data->set.set_range) {
/* There is a range, but is not a resume, useful for random ftp access */
data->reqdata.range = strdup(data->set.set_range);
if(!data->reqdata.range)
return CURLE_OUT_OF_MEMORY;
data->reqdata.rangestringalloc = TRUE; /* mark range string allocated */
data->reqdata.use_range = TRUE; /* enable range download */
}
else
data->reqdata.use_range = FALSE; /* disable range download */
*in_connect = conn; /* return this instead! */ *in_connect = conn; /* return this instead! */
infof(data, "Re-using existing connection! (#%ld) with host %s\n", infof(data, "Re-using existing connection! (#%ld) with host %s\n",
@@ -3848,6 +3833,10 @@ else {
ConnectionStore(data, conn); ConnectionStore(data, conn);
} }
result = setup_range(data);
if(result)
return result;
/* Continue connectdata initialization here. */ /* Continue connectdata initialization here. */
/* /*
@@ -4226,12 +4215,6 @@ CURLcode Curl_done(struct connectdata **connp,
conn->writechannel_inuse) conn->writechannel_inuse)
conn->writechannel_inuse = FALSE; conn->writechannel_inuse = FALSE;
/* cleanups done even if the connection is re-used */
if(data->reqdata.rangestringalloc) {
free(data->reqdata.range);
data->reqdata.rangestringalloc = FALSE;
}
/* Cleanup possible redirect junk */ /* Cleanup possible redirect junk */
if(data->reqdata.newurl) { if(data->reqdata.newurl) {
free(data->reqdata.newurl); free(data->reqdata.newurl);

View File

@@ -62,7 +62,7 @@ int Curl_doing_getsock(struct connectdata *conn,
curl_socket_t *socks, curl_socket_t *socks,
int numsocks); int numsocks);
void Curl_addHandleToPipeline(struct SessionHandle *handle, CURLcode Curl_addHandleToPipeline(struct SessionHandle *handle,
struct curl_llist *pipe); struct curl_llist *pipe);
int Curl_removeHandleFromPipeline(struct SessionHandle *handle, int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
struct curl_llist *pipe); struct curl_llist *pipe);

View File

@@ -406,6 +406,31 @@ struct ftp_conn {
ftpstate state; /* always use ftp.c:state() to change state! */ ftpstate state; /* always use ftp.c:state() to change state! */
}; };
/****************************************************************************
* SSH unique setup
***************************************************************************/
typedef enum {
SSH_STOP, /* do nothing state, stops the state machine */
SSH_S_STARTUP, /* Session startup */
SSH_AUTHLIST,
SSH_AUTH_PKEY_INIT,
SSH_AUTH_PKEY,
SSH_AUTH_PASS_INIT,
SSH_AUTH_PASS,
SSH_AUTH_HOST_INIT,
SSH_AUTH_HOST,
SSH_AUTH_KEY_INIT,
SSH_AUTH_KEY,
SSH_AUTH_DONE,
SSH_SFTP_INIT,
SSH_SFTP_REALPATH,
SSH_GET_WORKINGPATH,
SSH_SFTP_SHUTDOWN,
SSH_SESSION_FREE,
SSH_QUIT,
SSH_LAST /* never used */
} sshstate;
struct SSHPROTO { struct SSHPROTO {
curl_off_t *bytecountp; curl_off_t *bytecountp;
char *user; char *user;
@@ -421,6 +446,18 @@ struct SSHPROTO {
#endif /* USE_LIBSSH2 */ #endif /* USE_LIBSSH2 */
}; };
/* ssh_conn is used for struct connection-oriented data in the connectdata
struct */
struct ssh_conn {
const char *authlist; /* List of auth. methods, managed by libssh2 */
const char *passphrase;
char *rsa_pub;
char *rsa;
bool authed;
sshstate state; /* always use ssh.c:state() to change state! */
CURLcode actualCode; /* the actual error code */
};
/**************************************************************************** /****************************************************************************
* FILE unique setup * FILE unique setup
@@ -868,7 +905,8 @@ struct connectdata {
struct curl_llist *recv_pipe; /* List of handles waiting to read struct curl_llist *recv_pipe; /* List of handles waiting to read
their responses on this pipeline */ their responses on this pipeline */
char master_buffer[BUFSIZE]; /* The master buffer for this connection. */ char* master_buffer; /* The master buffer allocated on-demand;
used for pipelining. */
size_t read_pos; /* Current read position in the master buffer */ size_t read_pos; /* Current read position in the master buffer */
size_t buf_len; /* Length of the buffer?? */ size_t buf_len; /* Length of the buffer?? */
@@ -899,7 +937,10 @@ struct connectdata {
union { union {
struct ftp_conn ftpc; struct ftp_conn ftpc;
struct ssh_conn sshc;
} proto; } proto;
int cselect_bits; /* bitmask of socket events */
}; };
/* The end of connectdata. */ /* The end of connectdata. */

View File

@@ -21,7 +21,9 @@ $!
$! Parameter(s): $! Parameter(s):
$! $!
$! P1 - LISTING will create .lis files during the C compile $! P1 - LISTING will create .lis files during the C compile
$! DEBUG will compile and link with debug $! DEBUG will compile and link with debug; also will create
$! compiler listings and linker map files
$! 64 will compile and link with 64-bit pointers
$! $!
$! Revisions: $! Revisions:
$! $!
@@ -44,6 +46,7 @@ $! USE_SSLEAY to define if the target has SSL support built
$! in. Changed the cc/define parameter accordingly. $! in. Changed the cc/define parameter accordingly.
$! 11-FEB-2005, MSK, If [--.LIB]AMIGAOS.C and NWLIB.C are there, rename them $! 11-FEB-2005, MSK, If [--.LIB]AMIGAOS.C and NWLIB.C are there, rename them
$! 23-MAR-2005, MSK, relocated cc_qual define so that DEBUG option would work $! 23-MAR-2005, MSK, relocated cc_qual define so that DEBUG option would work
$! 25-APR-2007, STL, allow compilation in 64-bit mode.
$! $!
$ on control_y then goto Common_Exit $ on control_y then goto Common_Exit
$ ctrl_y = 1556 $ ctrl_y = 1556
@@ -75,25 +78,27 @@ $ set def 'thisdir'
$! $!
$ hpssl = 0 $ hpssl = 0
$ openssl = 0 $ openssl = 0
$ cc_qual = "/define=HAVE_CONFIG_H=1/OBJ=OBJDIR:" $ cc_qual = "/define=HAVE_CONFIG_H=1"
$ link_qual = "" $ link_qual = ""
$ if f$trnlnm( "CURL_BUILD_NOSSL") .eqs. "" $ if f$trnlnm( "CURL_BUILD_NOSSL") .eqs. ""
$ then $ then
$ if f$trnlnm( "OPENSSL") .nes. "" $ if f$trnlnm( "OPENSSL") .nes. ""
$ then $ then
$ openssl = 1 $ openssl = 1
$ cc_qual = "/define=(HAVE_CONFIG_H=1,USE_SSLEAY=1)/OBJ=OBJDIR:" $ cc_qual = "/define=(HAVE_CONFIG_H=1,USE_SSLEAY=1)"
$ if ( f$trnlnm( "SSL$INCLUDE") .nes. "") .and. - $ if ( f$trnlnm( "SSL$INCLUDE") .nes. "") .and. -
( f$trnlnm( "CURL_BUILD_NOHPSSL") .eqs. "") ( f$trnlnm( "CURL_BUILD_NOHPSSL") .eqs. "")
$ then hpssl = 1 $ then hpssl = 1
$ endif $ endif
$ endif $ endif
$ endif $ endif
$ if p1 .eqs. "LISTING" then cc_qual = cc_qual + "/LIST/MACHINE" $ cc_qual = cc_qual + "/OBJ=OBJDIR:"
$ if p1 .eqs. "64" then cc_qual = cc_qual + "/POINTER=64"
$ if p1 .eqs. "LISTING" then cc_qual = cc_qual + "/LIST/SHOW=ALL"
$ if p1 .eqs. "DEBUG" $ if p1 .eqs. "DEBUG"
$ then $ then
$ cc_qual = cc_qual + "/LIST/MACHINE/DEBUG/NOOPT" $ cc_qual = cc_qual + "/LIST/SHOW=ALL/DEBUG/NOOPT"
$ link_qual = "/DEBUG" $ link_qual = "/DEBUG/MAP"
$ endif $ endif
$ msg_qual = "/OBJ=OBJDIR:" $ msg_qual = "/OBJ=OBJDIR:"
$! $!

View File

@@ -25,7 +25,7 @@ endif
# Edit the path below to point to the base of your LibSSH2 package. # Edit the path below to point to the base of your LibSSH2 package.
ifndef LIBSSH2_PATH ifndef LIBSSH2_PATH
LIBSSH2_PATH = ../../libssh2-0.14 LIBSSH2_PATH = ../../libssh2-0.15
endif endif
ifndef INSTDIR ifndef INSTDIR
@@ -48,9 +48,10 @@ ifndef LIBARCH
LIBARCH = LIBC LIBARCH = LIBC
endif endif
# must be equal to DEBUG or NDEBUG # must be equal to NDEBUG or DEBUG, CURLDEBUG
ifndef DB
DB = NDEBUG DB = NDEBUG
# DB = DEBUG endif
# Optimization: -O<n> or debugging: -g # Optimization: -O<n> or debugging: -g
ifeq ($(DB),NDEBUG) ifeq ($(DB),NDEBUG)
OPT = -O2 OPT = -O2
@@ -252,7 +253,7 @@ ifdef SCREEN
else else
@echo $(DL)screenname "DEFAULT"$(DL) >> $@ @echo $(DL)screenname "DEFAULT"$(DL) >> $@
endif endif
ifeq ($(DB),DEBUG) ifneq ($(DB),NDEBUG)
@echo $(DL)debug$(DL) >> $@ @echo $(DL)debug$(DL) >> $@
endif endif
@echo $(DL)threadname "$(TARGET)"$(DL) >> $@ @echo $(DL)threadname "$(TARGET)"$(DL) >> $@

View File

@@ -31,7 +31,7 @@ VS_VERSION_INFO VERSIONINFO
FILEVERSION RC_VERSION FILEVERSION RC_VERSION
PRODUCTVERSION RC_VERSION PRODUCTVERSION RC_VERSION
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#if CURLDEBUG #if defined(CURLDEBUG) || defined(_DEBUG)
FILEFLAGS 1 FILEFLAGS 1
#else #else
FILEFLAGS 0 FILEFLAGS 0

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