Compare commits

..

205 Commits

Author SHA1 Message Date
Daniel Stenberg
bdb5e5a250 7.10.6 2003-07-28 12:13:48 +00:00
Daniel Stenberg
48a580e609 clear http->send_buffer when we have freed the memory it pointed to 2003-07-28 10:21:57 +00:00
Daniel Stenberg
1361fc69b9 updated to the new ftp dir parsing code that allows a preceeding double
slash
2003-07-28 09:02:15 +00:00
Daniel Stenberg
93352e56d8 As noticed by Kevin Roth, we shall not speak of root dir when it isn't
necessarily the root...
2003-07-28 08:53:12 +00:00
Daniel Stenberg
d9246ff24d Franois Pons brought a patch that once again made curl deal with ftp and
"double slash" as indicating the root directory. In the RFC1738-fix of April
30, that ability was removed (since it is not the "right" way).
2003-07-28 08:50:02 +00:00
Daniel Stenberg
9301bc3444 use the correct 'test71' file name for the temp file 2003-07-28 08:23:46 +00:00
Daniel Stenberg
76352c4e2d got a bug report on -F in config files, so I wrote up this test to verify
that is works... and it did! ;-)
2003-07-28 08:21:07 +00:00
Daniel Stenberg
428f41bd12 having it in CVS causes us problems *grrr* 2003-07-25 09:46:07 +00:00
Daniel Stenberg
99c32e460f Andrs Garca updated with the added files etc 2003-07-25 08:59:55 +00:00
Daniel Stenberg
83f249cf65 With an unknown CA path, we undef the variable. To build properly without
SSL/CA.
2003-07-25 08:47:34 +00:00
Daniel Stenberg
2c2baa93ea only check for CA bundle path if build with SSL support
set a conditional for the makefile if we know the CA path or not
2003-07-25 08:47:10 +00:00
Daniel Stenberg
f0278ca114 Removed #include <sys/resource.h>, as pointed out by Henry Bland we don't
need it.
2003-07-25 08:30:58 +00:00
Daniel Stenberg
297b1b5013 the test compared numericly if though it could contain a string, and I
lowered the number of retries to 10
2003-07-23 17:28:36 +00:00
Daniel Stenberg
e9f63bf4e8 When we re-use an existing connection we must make sure that we don't
accidentally re-use the connect_addr field, as that might no longer be
around. Fix verified by Tracy Boehrer who basicly debugged and tracked down
this problem.
2003-07-23 17:06:21 +00:00
Daniel Stenberg
556ce1c6a1 minor code style fix 2003-07-23 12:55:24 +00:00
Daniel Stenberg
cc4ff62681 Split out the changes from the year 2002 into a separate file, named
CHANGES.2002.
2003-07-23 11:59:20 +00:00
Daniel Stenberg
0423fd9b55 SSLCERTS was moved into the docs/ directory 2003-07-23 11:39:05 +00:00
Daniel Stenberg
789ab20bf7 moved SSLCERTS into the docs/ directory 2003-07-23 11:38:19 +00:00
Daniel Stenberg
b47462bd68 Daniel Kouril's fix to make the GSS-Negotiate work fine. 2003-07-23 11:28:59 +00:00
Daniel Stenberg
1a94fee42d Juan F. Codagnone's fixes to build properly on Windows again 2003-07-23 08:21:21 +00:00
Daniel Stenberg
a91ce6a5d6 Plain default version of this file, to allow users to build easier from
CVS. This will be updated by the configure script, and a default is placed
here by the maketgz script.
2003-07-23 08:11:28 +00:00
Daniel Stenberg
981ffd9fce reversed the check for GSSAPI when request that auth 2003-07-22 11:15:46 +00:00
Daniel Stenberg
e76c960624 CURLDEBUG, not MALLOCDEBUG 2003-07-22 10:00:37 +00:00
Daniel Stenberg
416c92cc6f More support for NTLM on proxies, now proxy state and nonce is stored in
a separate struct properly.
2003-07-22 09:59:36 +00:00
Daniel Stenberg
fb731eb3e7 The NTLM functions now take a 'proxy' argument as well. 2003-07-22 09:58:57 +00:00
Daniel Stenberg
6f2a4d290f Added a separate struct for the proxyntlm data, as it will/can be different
than the remote server's. That is, both the server and the proxy can in
fact require NTLM auth.
2003-07-22 09:58:18 +00:00
Daniel Stenberg
cefc8ba938 CURLDEBUG is the symbol now 2003-07-22 09:57:09 +00:00
Daniel Stenberg
d0bd644eef Don't depend on the TIME_WITH_SYS_TIME define. win32 doesn't have sys/time.h
and I don't think we need it.
2003-07-22 08:23:16 +00:00
Daniel Stenberg
071c95128e moved the proxyuser and proxypasswd fields from the sessionhandle to the
connectdata to work as expected
2003-07-21 13:16:30 +00:00
Daniel Stenberg
1a192c489b adjusted to support NTLM for proxies 2003-07-21 13:16:01 +00:00
Daniel Stenberg
56014e74a0 krb4-fixes for the moved user+password fields within the structs 2003-07-21 09:19:48 +00:00
Daniel Stenberg
172271498d pre4-commit 2003-07-21 08:25:31 +00:00
Daniel Stenberg
f2882cb88c pre4 2003-07-21 08:25:21 +00:00
Daniel Stenberg
152f1fee40 the CWD-null bug fix 2003-07-21 07:54:20 +00:00
Daniel Stenberg
968234e6ae the fixed skip-blanks in the FTP CWD code called for this adjustment 2003-07-20 00:19:44 +00:00
Daniel Stenberg
5e133e2dff David Gardner pointed out in bug report 770755 that using the FTP command CWD
with a blank argument is a bad idea. Now skip blanks.
2003-07-20 00:18:11 +00:00
Daniel Stenberg
0049c09fc3 If NTLM is requested, only re-use connections that have the exact same
credentials.
2003-07-20 00:02:47 +00:00
Daniel Stenberg
a2a63c27f4 explains my fixes just committed 2003-07-19 23:58:21 +00:00
Daniel Stenberg
c50a601f1a modified to work fine with the new persistant connection working test suite
HTTP server
2003-07-19 23:57:08 +00:00
Daniel Stenberg
bc0fd6db71 swsclose added 2003-07-19 23:56:44 +00:00
Daniel Stenberg
52b631fade Access the user and passwd fields from the connectdata struct now instead
of the sessionhandle struct, as that was not good.
2003-07-19 23:56:33 +00:00
Daniel Stenberg
2f0bc9d1f7 No longer stores user+password in the sessionhandle, now doing that in the
connectdata struct instead. Each being an allocated pointer.

The passwdgiven field was turned into a local variable in the only
function it was being used.
2003-07-19 23:55:15 +00:00
Daniel Stenberg
5ef6520d4e fixed the CONNECT thing again 2003-07-19 23:54:15 +00:00
Daniel Stenberg
2c1925161e If the data contents contains the word 'swsclose', then this server will
disconnect the client after the response have been sent. This also happens
if the respons is zero byte long.

In all other cases (unless an error happens), it will now maintain the
connection to allow proper persistant connection testing. This was required
for the NTLM testing to work so I finally had to fix this. Of course most of
the existing HTTP tests will be adjusted to work with this new rule of test
file syntax for HTTP tests.

Also fixed the log function to deal with varargs for better logging.
2003-07-19 23:44:22 +00:00
Daniel Stenberg
0529b349d5 recent changes 2003-07-16 00:04:45 +00:00
Daniel Stenberg
b4620364a2 more fixes from Doug Kaufman for DJGPP builds for DOS 2003-07-15 23:47:25 +00:00
Daniel Stenberg
634aef3895 updated to work with Dan Winship's NTLM domain stuff fix 2003-07-15 23:38:06 +00:00
Daniel Stenberg
06c86d1a8c Moved the NTLM credentials to the connectdata struct instead, as NTLM
authenticates connections and not single requests. This should make it work
better when we mix requests from multiple hosts. Problem pointed out by
Cris Bailiff.
2003-07-15 23:36:50 +00:00
Daniel Stenberg
79749f8eb4 Fix to the endless loop of bad Basic authentication as reported in Cris
Bailiff's bug report 768275.
2003-07-15 23:06:02 +00:00
Daniel Stenberg
b036986b3e Dan Winship's patch added that makes use of DOMAIN\USER or DOMAIN/USER
for the user field. I changed it slightly to stay with strchr() only instead
of strpbrk() for portability reasons.
2003-07-15 22:58:36 +00:00
Daniel Stenberg
938f1d1da7 Dan Winship's fix to make the new auth stuff such as NTLM to work with
the multi interface
2003-07-15 22:46:01 +00:00
Daniel Stenberg
58b6b3df06 Dan Winship pointed out this flaw 2003-07-15 22:44:48 +00:00
Daniel Stenberg
f9c3347f7c re-use existing variable instead of declaring a new local one 2003-07-05 13:27:02 +00:00
Daniel Stenberg
5b72eb0b03 Some of Doug Kaufman's changes for the DOS port 2003-07-05 13:13:49 +00:00
Daniel Stenberg
6dd4c13bc0 the latest changes 2003-07-04 18:18:17 +00:00
Daniel Stenberg
e4e7db551f HAVE_SETVBUF removed, no longer used 2003-07-04 18:17:58 +00:00
Daniel Stenberg
ebfde8da56 removed 2003-07-04 18:15:53 +00:00
Daniel Stenberg
756bc0f4b7 Dan Grayson pointed out that we set the CURL_CA_BUNDLE variable wrongly in
the configure script. We set it differently now and generate the
lib/ca-bundle.h file entirely.
2003-07-04 18:15:25 +00:00
Daniel Stenberg
269d491b6a remove the usage of setvbuf() and use fflush() instead if no buffering should
be done on the output
2003-07-04 17:16:34 +00:00
Daniel Stenberg
449e5bc2ad CURLDEBUG not MALLOCDEBUG anymore 2003-07-04 16:37:16 +00:00
Daniel Stenberg
8736c11d84 adjusted to the NTLM updates 2003-07-04 16:36:31 +00:00
Daniel Stenberg
45fc760985 Peter Sylvester's patch was applied that introduces the following:
CURLOPT_SSL_CTX_FUNCTION to set a callback that gets called with the
   OpenSSL's ssl_ctx pointer passed in and allow a callback to act on it. If
   anything but CURLE_OK is returned, that will also be returned by libcurl
   all the way back. If this function changes the CURLOPT_URL, libcurl will
   detect this and instead go use the new URL.

   CURLOPT_SSL_CTX_DATA is a pointer you set to get passed to the callback set
   with CURLOPT_SSL_CTX_FUNCTION.
2003-07-04 16:29:23 +00:00
Daniel Stenberg
7968e3c2de David Byron's patch that allows a client to make the server quit with a
magic url.
2003-07-01 15:21:42 +00:00
Daniel Stenberg
964a41c75c new CVS info 2003-07-01 12:12:10 +00:00
Daniel Stenberg
5931d53637 Gisle Vanem found a lib handle leak in the ldap code 2003-07-01 10:12:52 +00:00
Daniel Stenberg
3ed3ae5bcf When I introduced the DIST_SUBDIRS usage, I broken the 'make install' for
include files and docs, so now I've added a custom install hook to run
make install for docs and install when data is installed at the top-level.
2003-06-27 14:37:38 +00:00
Sterling Hughes
6519cc70c5 revert out my bogus commit. ;-) 2003-06-26 21:30:48 +00:00
Sterling Hughes
505a4f27fa test commit 2003-06-26 21:17:29 +00:00
Daniel Stenberg
79144eba99 new tests 2003-06-26 11:45:04 +00:00
Daniel Stenberg
26e17d89c9 produce a skip-report at the end of all tests, and thus record and count
them properly
2003-06-26 11:44:01 +00:00
Daniel Stenberg
4322c1106f beautified and added comments all over 2003-06-26 11:42:54 +00:00
Daniel Stenberg
73071dfd4f mention the new flag bits we support 2003-06-26 11:41:24 +00:00
Daniel Stenberg
b7c14b3c27 mention that it copies the string you add 2003-06-26 11:41:08 +00:00
Daniel Stenberg
3130b44535 added lots, mostly the new auth-related option(s) 2003-06-26 11:40:44 +00:00
Daniel Stenberg
a2bd73334f added lots of auth stuff and updated other things too 2003-06-26 11:40:04 +00:00
Daniel Stenberg
1a393f5625 mention COOKIES, removed added entries, corrected the FPL-SSL link/reference 2003-06-26 11:38:53 +00:00
Daniel Stenberg
d4951e837e mention the other formats the docs come in 2003-06-26 11:37:13 +00:00
Daniel Stenberg
26f6365e93 adjusted to recent changes 2003-06-26 11:36:32 +00:00
Daniel Stenberg
3a552b1e63 we do support NTLM now... 2003-06-26 11:35:48 +00:00
Daniel Stenberg
69eb1790da CURLDEBUG is the symbol to use, no longer MALLOCDEBUG 2003-06-26 11:34:36 +00:00
Daniel Stenberg
a1af6f3614 adjusted the compressed generation to be more helpful in comments etc 2003-06-26 11:34:07 +00:00
Daniel Stenberg
3aced61465 support for the new auth stuff
more output on --version/-V
mention --manual on the help output text
2003-06-26 11:33:29 +00:00
Daniel Stenberg
6f02ddfce8 new httpauth support, changed filetime variable kind 2003-06-26 11:31:50 +00:00
Daniel Stenberg
c2faa39b62 added CURLOPT_HTTPAUTH support 2003-06-26 11:30:59 +00:00
Daniel Stenberg
2d3734b8b5 Adjusted to work properly with the new authentication stuff
Added code to deal with white spaces in relocation headers.
2003-06-26 11:30:26 +00:00
Daniel Stenberg
ed908b7f89 use CURLDEBUG instead of MALLOCDEBUG 2003-06-26 11:28:26 +00:00
Daniel Stenberg
f7d795a364 use CURLDEBUG 2003-06-26 11:27:38 +00:00
Daniel Stenberg
8919b39d54 adjusted to use the same API as the OpenSSL version of the MD5 functions 2003-06-26 11:27:22 +00:00
Daniel Stenberg
84cedc094e added ntlm flag bits 2003-06-26 11:26:50 +00:00
Daniel Stenberg
3b2b2496d7 Many fixes, most of them based on comments by Eric Glass 2003-06-26 11:26:26 +00:00
Daniel Stenberg
445684c409 new proto for Curl_input_negotiate 2003-06-26 11:25:42 +00:00
Daniel Stenberg
898e067ccc kill warnings 2003-06-26 11:25:23 +00:00
Daniel Stenberg
12859e345f major adjustments to the new authentication support 2003-06-26 11:24:55 +00:00
Daniel Stenberg
89f4af695e include GSS in the debug string if available, support a few new flag
booleans
2003-06-26 11:22:48 +00:00
Daniel Stenberg
308bc9d919 use CURLDEBUG instead of MALLOCDEBUG for preprocessor conditions 2003-06-26 11:22:12 +00:00
Daniel Stenberg
db566c54ae use CURLDEBUG instead of MALLOCDEBUG 2003-06-26 11:16:37 +00:00
Daniel Stenberg
81d403e207 one typecast less for the localtime(), use CURLDEBUG instead of MALLOCDEBUG 2003-06-26 06:52:48 +00:00
Daniel Stenberg
2bd71d70ff use CURLDEBUG instead of MALLOCDEBUG 2003-06-26 06:50:32 +00:00
Daniel Stenberg
1eef6f44ba CURLDEBUG instead of MALLOCDEBUG 2003-06-26 06:47:20 +00:00
Daniel Stenberg
204f03912f We noe use CURLDEBUG instead of MALLOCDEBUG 2003-06-26 06:45:15 +00:00
Daniel Stenberg
f8c3b3aa18 moved from former CVS 2003-06-26 06:21:29 +00:00
Daniel Stenberg
d4df981463 Added time_t 2003-06-26 06:19:37 +00:00
Daniel Stenberg
497c6d516d up to date with the actual situation 2003-06-25 23:40:48 +00:00
Daniel Stenberg
8288862b7e Cris Bailiff's patch that should make us do NTLM correctly. When we've
authenticated our connection, we can continue without any Authorization:
headers as long as our connection is maintained.
2003-06-13 10:15:55 +00:00
Daniel Stenberg
9aae16c236 stdout is good enough 2003-06-13 09:09:04 +00:00
Daniel Stenberg
80c194a70a work more on pids, less on pidfiles to be able to do better kills at the
end of the test where the pidfiles aren't found, but "our" server is running
2003-06-13 09:04:08 +00:00
Daniel Stenberg
c832b2db5b fixed NTLM test 67, added test 68 for bad NTLM name/password 2003-06-13 08:03:45 +00:00
Daniel Stenberg
27018882ec Cris Bailiff's bugfix 2003-06-13 07:56:38 +00:00
Daniel Stenberg
caf6e9c540 use more curlish strings, these should be able to change... 2003-06-13 07:14:46 +00:00
Daniel Stenberg
e727fb82f2 Marty Kuhrt's #include fixes for VMS 2003-06-13 06:48:04 +00:00
Daniel Stenberg
c78df56801 get and use only the first line of the curl --version output 2003-06-12 23:05:12 +00:00
Daniel Stenberg
d13202f43b modified 2003-06-12 23:03:08 +00:00
Daniel Stenberg
9d139a6b35 Make the HTTP auth stuff work, Dan Fandrich made --version output a list
of all supported protocols.
2003-06-12 23:02:36 +00:00
Daniel Stenberg
d2abe44e6f remove the dumpit file after use 2003-06-12 19:17:08 +00:00
Daniel Stenberg
bc67228576 corrected a comment 2003-06-12 17:40:56 +00:00
Daniel Stenberg
ecf32c964a CURLHTTP* renamed to CURLAUTH* and NEGOTIATE is now GSSNEGOTIATE as there's
a "plain" Negotiate as well.
2003-06-12 17:34:27 +00:00
Daniel Stenberg
e58f30b82a NTLM test case 2003-06-12 16:39:35 +00:00
Daniel Stenberg
654e3f1101 require the netrc_debug feature the same way we now can require SSL
present client-side
2003-06-12 16:38:14 +00:00
Daniel Stenberg
86689dc524 now test cases can be set to be dependent on the presence of "SSL" in the
client/library
2003-06-12 16:22:52 +00:00
Daniel Stenberg
5f62a0c1ca make it build with older OpenSSL 2003-06-12 13:55:40 +00:00
Daniel Stenberg
ad1bf0f389 attempt to make older OpenSSL versions work with the DES stuff 2003-06-12 13:18:10 +00:00
Daniel Stenberg
9c7703ace1 Based on Dan Fandrich's patch and gzip unpack function, we now compress
the 'hugehelp' text if libz and gzip are available at build time.
2003-06-12 12:54:34 +00:00
Daniel Stenberg
4a8155b53c store HAVE_LIBZ as an automake conditional 2003-06-12 12:53:38 +00:00
Daniel Stenberg
80d6d5c5c4 fixing details for NTLM 2003-06-11 16:14:45 +00:00
Daniel Stenberg
c624be8388 more how I envision it _should_ work, but it still doesn't... 2003-06-11 15:33:09 +00:00
Daniel Stenberg
09df1cd41e to support "redirects" after the full body is transfered 2003-06-11 15:31:40 +00:00
Daniel Stenberg
52c5b57200 made a nicer output for the decode test, as it served as a nice tool for me ;-) 2003-06-11 15:31:06 +00:00
Daniel Stenberg
5ea04a852e when we get the auth headers, we still need to read out the full body response
as otherwise we can re-send requests on the same connection nicely
2003-06-11 15:30:30 +00:00
Daniel Stenberg
a2eef05198 correct mistakes 2003-06-11 14:05:13 +00:00
Daniel Stenberg
55f75af353 describe the NTLM mechanism too 2003-06-11 13:44:58 +00:00
Daniel Stenberg
fb6a51b8fd basic NTLM support 2003-06-11 13:44:31 +00:00
Daniel Stenberg
252cc2213e ntlm added 2003-06-11 13:42:53 +00:00
Daniel Stenberg
73c5f24fa4 Initial take at NTLM authentication. It doesn't really work at this point
but the infrastructure is there.
2003-06-11 13:38:55 +00:00
Daniel Stenberg
4c80e103a0 clarify the CUSTOMREQUEST and HTTPHEADER options slightly 2003-06-10 13:06:38 +00:00
Daniel Stenberg
39ea557360 CURLOPT_HTTPAUTH docu 2003-06-10 12:58:40 +00:00
Daniel Stenberg
d0cc92a01a Set auth type differently, we use one CURLOPT_HTTPAUTH instead as we plan
to add more method in the future.
2003-06-10 12:49:16 +00:00
Daniel Stenberg
d7980c1a45 Daniel Kouril for the HTTP negotiate stuff 2003-06-10 12:25:01 +00:00
Daniel Stenberg
e56ae1426c Daniel Kouril's patch that adds HTTP negotiation support to libcurl was
added.
2003-06-10 12:22:19 +00:00
Daniel Stenberg
696843c020 we fix more 2003-06-10 12:07:10 +00:00
Daniel Stenberg
6ff5621dd7 more generic 2003-06-10 12:05:12 +00:00
Daniel Stenberg
e7fb72a732 Pass the error stream pointer to the URL globber, so that it can report
errors correctly to the user, if need be.

Also fixed so that a missing ] in the globbing process no longer leads
to core dump.
2003-06-10 09:42:22 +00:00
Daniel Stenberg
8d30d34e0c When doing very big GET requests over HTTPS, we need to add some extra
funky logic in order to make re-tries work fine with OpenSSL. This corrects
the problem David Orrell noticed.
2003-06-06 14:58:26 +00:00
Daniel Stenberg
bc7fe85f8a Just moved around some logic in Curl_write() to make it easier to debug. 2003-06-06 14:56:50 +00:00
Daniel Stenberg
89352d92c5 spellfix 2003-06-06 06:44:05 +00:00
Daniel Stenberg
c32390d84c Reversed the logic to only include the <sys/select.h> header on systems
known to really NEED it as another system that doesn't have it came up:
very old Linux libc5-based systems (as addition to all HPUX versions).

The only known system at this point is AIX.
2003-06-05 14:04:44 +00:00
Daniel Stenberg
45ca866a2d LDAP problem added as mention in bug report #735752 2003-06-03 08:10:53 +00:00
Daniel Stenberg
ceef206c21 include the time headers just like we used to do in the curl/curl.h header
once upon the time
2003-06-03 08:07:06 +00:00
Daniel Stenberg
7c6424f0a9 we want the time defines too 2003-06-03 08:06:23 +00:00
Daniel Stenberg
bc942de6f1 Content-Length: now overrides other means of knowing when the stream has
ended.
2003-06-03 07:53:18 +00:00
Daniel Stenberg
06984df5cb Make the Content-Length info override the Connection: close header, so that
libcurl will stop reading when the number of bytes have arrived and not wait
for a closed socket.
2003-06-02 14:57:08 +00:00
Daniel Stenberg
4f136a3a76 the 500-599 test case range 2003-06-02 14:48:27 +00:00
Daniel Stenberg
363bf3ba30 ignore more 2003-06-02 13:55:40 +00:00
Daniel Stenberg
acb895956a ignore 2003-06-02 13:53:13 +00:00
Daniel Stenberg
21e87b9bb3 David Byron's fix to get the progress-bar use the local size too when
doing a resumed download.
2003-06-02 13:42:42 +00:00
Daniel Stenberg
c896ebcf12 makefile fiddle
changed how http requests are sent - now in one chunk more often
HPUX include fix in the external headers
better SSL work-arounds for bad SSL servers
modified error message when CURLE_HTTP_RETURNED_ERROR is returned
2003-06-02 13:31:25 +00:00
Daniel Stenberg
d288222e80 work-around SSL implementation flaws better, pointed out in bug report
#745122.
2003-06-02 13:27:03 +00:00
Daniel Stenberg
4eb2a6c9a3 make a more descriptive error message when CURLE_HTTP_RETURNED_ERROR is
returned
2003-06-02 13:14:57 +00:00
Daniel Stenberg
2563731c4d haven't updates this in a loooong time 2003-05-28 10:24:20 +00:00
Daniel Stenberg
4e410111db Posting static data using POST and chunked encoded now also appends the
data to the initial request buffer, if the total post data is less than
100K.
2003-05-28 07:54:33 +00:00
Daniel Stenberg
5670563a26 include sys/time.h, we didn't have a time() proto anymore. Did one of the
changes in curl/curl.h make this occur?
2003-05-27 22:56:01 +00:00
Daniel Stenberg
6caa656d01 Documented which rules the public headers must follow when we write
preprocessor checks for condititions.
2003-05-27 12:51:46 +00:00
Daniel Stenberg
c12af7aed1 oops, removed a # too many 2003-05-27 12:51:15 +00:00
Daniel Stenberg
dcb6d1c01d remove usage of HAVE_* defines, we cannot and shall not depend on any such
defines in the public external header files
2003-05-27 12:45:51 +00:00
Daniel Stenberg
18234cbdac sys/select.h is not present on HPUX, avoid including it 2003-05-27 12:34:48 +00:00
Daniel Stenberg
06bf988dc1 made it work ;-) 2003-05-27 12:18:00 +00:00
Daniel Stenberg
55ff4c3f08 if cvs update fails, attempt again after 5 seconds and retry 50 times
before giving up
2003-05-27 12:03:24 +00:00
Daniel Stenberg
4915002168 Only build in lib and src by default, make the others dist-subdirs.
Make the test stuff get built when we run 'make test' instead.
2003-05-27 08:51:09 +00:00
Daniel Stenberg
5bd8d60e41 Rudy Koento experienced problems with curl's recent habit of POSTing data in
two separate send() calls, first the headers and then the data. I've now made
a fix that for static and known content that isn't to be chunked-encoded,
everything is now sent in one single system call again. This is also better
for network performance reasons.
2003-05-27 08:33:08 +00:00
Daniel Stenberg
fc872808c5 runs on DOS now 2003-05-27 07:37:34 +00:00
Daniel Stenberg
0f4feda382 include file flaw and yet another socks5-fix 2003-05-27 06:41:06 +00:00
Daniel Stenberg
90b0f38316 Another socks5-fix. Make sure that when we use a socks-proxy, it is not the
same as using a httpproxy so we must make sure to better check for http
proxies before we do HTTP proxy stuff. This included authorization and
URI usage in the request etc.
2003-05-27 06:28:25 +00:00
Daniel Stenberg
18f630ab21 CURLOPT_HTTPDIGEST is added 2003-05-27 06:25:56 +00:00
Daniel Stenberg
e97fd44151 language 2003-05-26 12:32:22 +00:00
Daniel Stenberg
b75679778f ftp ASCII transfers in general need fixing 2003-05-26 08:19:06 +00:00
Daniel Stenberg
35a84ad576 Chris Lewis mentioned that he doesn't get WIN32 defined, only _WIN32 so we
make an adjustment to catch this.
2003-05-26 07:57:53 +00:00
Daniel Stenberg
4ed28be75a even more 2003-05-23 11:24:39 +00:00
Daniel Stenberg
e2f4656a86 Ricardo Cadime found a socket leak when listing directories without
contents. Test cases 144 and 145 were added to verify the fix.

Now we deal with return code 450 properly and other codes also do proper
cleanup.
2003-05-23 11:14:09 +00:00
Daniel Stenberg
1e14da5c60 more ftp testing using NLST and no contents and bad return code 2003-05-23 11:10:35 +00:00
Daniel Stenberg
b2ef79ef3d Rudy Koento's problem fixed, test case 66 verifies this. 2003-05-23 09:47:57 +00:00
Daniel Stenberg
f488874ff5 test 66 returns one line of data with no header (HTTP) 2003-05-23 09:46:19 +00:00
Daniel Stenberg
23258648da --digest added, --compressed rephrased 2003-05-23 08:06:31 +00:00
Daniel Stenberg
6b84ebe501 include digest.h for proto 2003-05-23 06:44:24 +00:00
Daniel Stenberg
07dd067f73 DJGPP fix by Gisle Vanem 2003-05-23 06:43:14 +00:00
Daniel Stenberg
420744d048 more more more 2003-05-22 22:47:48 +00:00
Daniel Stenberg
01108e3a63 warning-free is better 2003-05-22 22:45:38 +00:00
Daniel Stenberg
8026b1e194 Introducing --digest 2003-05-22 22:40:01 +00:00
Daniel Stenberg
a39d77227f Better Digest stuff 2003-05-22 22:39:38 +00:00
Daniel Stenberg
9f69deec7d Added CURLOPT_HTTPDIGEST support
SOCKS5 fix as suggested by Jis in bugreport #741841.
2003-05-22 22:38:46 +00:00
Daniel Stenberg
e912f772e0 Document the <dataNUM> thing we use, 2003-05-22 22:37:00 +00:00
Daniel Stenberg
0102726aeb Digest support added 2003-05-22 22:36:39 +00:00
Daniel Stenberg
1e7aa04040 Digest testing added 2003-05-22 22:36:22 +00:00
Daniel Stenberg
00a7c6fe6b proper header added 2003-05-22 16:23:27 +00:00
Daniel Stenberg
87f8c0d471 hush the compiler 2003-05-22 16:12:30 +00:00
Daniel Stenberg
334d78cd18 Initial Digest support. At least partly working. 2003-05-22 16:09:54 +00:00
Daniel Stenberg
2356325592 David Balazic pointed out the lack of checks for a valid %XX code when
we unescape a string. We now check and decode only valid %XX strings.
2003-05-21 15:53:59 +00:00
Daniel Stenberg
d78ec593fa fix the makefile in packages/DOS too 2003-05-21 08:12:52 +00:00
Daniel Stenberg
d5043133e6 Gisle Vanem made curl build with djgpp on DOS. 2003-05-21 08:08:48 +00:00
Daniel Stenberg
509f69a457 Gisle Vanem's fix to make the 'curl -M' output nicer 2003-05-21 07:21:44 +00:00
Daniel Stenberg
662c659220 missing semicolon, by Gisle Vanem 2003-05-20 12:44:55 +00:00
Daniel Stenberg
9a6566e774 Gisle Vanem's code for not trusting h_aliases to always be non-NULL 2003-05-20 09:41:39 +00:00
Daniel Stenberg
4da0428d9e Remind about the gpg command lines 2003-05-20 06:33:13 +00:00
Daniel Stenberg
8ee1177206 support user name and password in proxy environment variables 2003-05-19 13:14:26 +00:00
Daniel Stenberg
e9154b2549 the proxy environment variables now may contain user name and password 2003-05-19 13:09:41 +00:00
Daniel Stenberg
d398a0dd58 remove debug output 2003-05-19 13:08:48 +00:00
Daniel Stenberg
7723a24297 setenv support added to allow test cases to require a set of environment
variables
2003-05-19 13:06:10 +00:00
174 changed files with 7322 additions and 2478 deletions

View File

@@ -9,3 +9,6 @@ config.status
curl-config curl-config
autom4te.cache autom4te.cache
depcomp depcomp
config.guess
config.sub
ltmain.sh

1789
CHANGES

File diff suppressed because it is too large Load Diff

1504
CHANGES.2002 Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -16,8 +16,8 @@ Compile and build instructions follow below.
CHANGES.$year contains changes for the particular year. CHANGES.$year contains changes for the particular year.
tests/memanalyze.pl tests/memanalyze.pl
is for analyzing the output generated by curl if -DMALLOCDEBUG is for analyzing the output generated by curl if -DCURLDEBUG
is used when compiling is used when compiling (run configure with --enable-debug)
buildconf builds the makefiles and configure stuff buildconf builds the makefiles and configure stuff

View File

@@ -4,12 +4,13 @@
AUTOMAKE_OPTIONS = foreign AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = CHANGES COPYING maketgz SSLCERTS reconf Makefile.dist \ EXTRA_DIST = CHANGES COPYING maketgz reconf Makefile.dist \
curl-config.in build_vms.com curl-style.el sample.emacs testcurl.sh curl-config.in build_vms.com curl-style.el sample.emacs testcurl.sh
bin_SCRIPTS = curl-config bin_SCRIPTS = curl-config
SUBDIRS = docs lib src include tests packages SUBDIRS = lib src
DIST_SUBDIRS = $(SUBDIRS) tests include packages docs
# create a root makefile in the distribution: # create a root makefile in the distribution:
dist-hook: dist-hook:
@@ -25,10 +26,10 @@ pdf:
check: test check: test
test: test:
@(cd tests; $(MAKE) quiet-test) @(cd tests; $(MAKE) all quiet-test)
test-full: test-full:
@(cd tests; $(MAKE) full-test) @(cd tests; $(MAKE) all full-test)
# #
# Build source and binary rpms. For rpm-3.0 and above, the ~/.rpmmacros # Build source and binary rpms. For rpm-3.0 and above, the ~/.rpmmacros
@@ -77,3 +78,8 @@ pkgadd:
# resulting .tar.bz2 file will end up at packages/Win32/cygwin # resulting .tar.bz2 file will end up at packages/Win32/cygwin
cygwinbin: cygwinbin:
$(MAKE) -C packages/Win32/cygwin cygwinbin $(MAKE) -C packages/Win32/cygwin cygwinbin
# We extend the standard install with a custom hook:
install-data-hook:
cd include && $(MAKE) install
cd docs && $(MAKE) install

View File

@@ -59,6 +59,10 @@ vc-ssl-dll:
cd ..\src cd ..\src
nmake -f Makefile.vc6 nmake -f Makefile.vc6
djgpp:
make -C lib -f Makefile.dj
make -C src -f Makefile.dj
cygwin: cygwin:
./configure ./configure
make make

8
README
View File

@@ -49,15 +49,15 @@ CVS
To download the very latest source off the CVS server do this: To download the very latest source off the CVS server do this:
cvs -d :pserver:anonymous@cvs.curl.sourceforge.net:/cvsroot/curl login cvs -d :pserver:cvsread@cvs.php.net:/repository login
(just press enter when asked for password) (enter "phpfi" when asked for password)
cvs -d :pserver:anonymous@cvs.curl.sourceforge.net:/cvsroot/curl co curl cvs -d :pserver:cvsread@cvs.php.net:/repository co curl
(you'll get a directory named curl created, filled with the source code) (you'll get a directory named curl created, filled with the source code)
cvs -d :pserver:anonymous@cvs.curl.sourceforge.net:/cvsroot/curl logout cvs -d :pserver:cvsread@cvs.php.net:/repository logout
(you're off the hook!) (you're off the hook!)

View File

@@ -14,7 +14,7 @@ This configure script may be copied, distributed and modified under the
terms of the curl license; see COPYING for more details]) terms of the curl license; see COPYING for more details])
AC_CONFIG_SRCDIR([lib/urldata.h]) AC_CONFIG_SRCDIR([lib/urldata.h])
AM_CONFIG_HEADER(lib/config.h src/config.h tests/server/config.h lib/ca-bundle.h) AM_CONFIG_HEADER(lib/config.h src/config.h tests/server/config.h )
AM_MAINTAINER_MODE AM_MAINTAINER_MODE
AC_PATH_PROG( SED, sed, , $PATH:/usr/bin:/usr/local/bin) AC_PATH_PROG( SED, sed, , $PATH:/usr/bin:/usr/local/bin)
@@ -454,6 +454,63 @@ else
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
fi fi
dnl **********************************************************************
dnl Check for GSS-API libraries
dnl **********************************************************************
AC_ARG_WITH(gssapi-includes,
AC_HELP_STRING([--with-gssapi-includes=DIR],
[Specify location of GSSAPI header]),
[ GSSAPI_INCS="-I$withval"
want_gss="yes" ]
)
AC_ARG_WITH(gssapi-libs,
AC_HELP_STRING([--with-gssapi-libs=DIR],
[Specify location of GSSAPI libs]),
[ GSSAPI_LIBS="-L$withval -lgssapi"
want_gss="yes" ]
)
AC_ARG_WITH(gssapi,
AC_HELP_STRING([--with-gssapi=DIR],
[Where to look for GSSAPI]),
[ GSSAPI_ROOT="$withval"
want_gss="yes" ]
)
AC_MSG_CHECKING([if GSSAPI support is requested])
if test x"$want_gss" = xyes; then
if test -z "$GSSAPI_INCS"; then
if test -f "$GSSAPI_ROOT/bin/krb5-config"; then
gss_cppflags=`$GSSAPI_ROOT/bin/krb5-config --cflags gssapi`
CPPFLAGS="$CPPFLAGS $gss_cppflags"
else
CPPFLAGS="$GSSAPI_ROOT/include"
fi
else
CPPFLAGS="$CPPFLAGS $GSSAPI_INCS"
fi
if test -z "$GSSAPI_LIB_DIR"; then
if test -f "$GSSAPI_ROOT/bin/krb5-config"; then
gss_ldflags=`$GSSAPI_ROOT/bin/krb5-config --libs gssapi`
LDFLAGS="$LDFLAGS $gss_ldflags"
else
LDFLAGS="$LDFLAGS $GSSAPI_ROOT/lib -lgssapi"
fi
else
LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR"
fi
AC_MSG_RESULT(yes)
AC_DEFINE(GSSAPI, 1, [if you have the gssapi libraries])
else
AC_MSG_RESULT(no)
fi
dnl Detect the pkg-config tool, as it may have extra info about the dnl Detect the pkg-config tool, as it may have extra info about the
dnl openssl installation we can use. I *believe* this is what we are dnl openssl installation we can use. I *believe* this is what we are
dnl expected to do on really recent Redhat Linux hosts. dnl expected to do on really recent Redhat Linux hosts.
@@ -486,6 +543,8 @@ dnl **********************************************************************
dnl Default to compiler & linker defaults for SSL files & libraries. dnl Default to compiler & linker defaults for SSL files & libraries.
OPT_SSL=off OPT_SSL=off
dnl Default to no CA bundle
ca="no"
AC_ARG_WITH(ssl,dnl AC_ARG_WITH(ssl,dnl
AC_HELP_STRING([--with-ssl=PATH],[where to look for SSL, PATH points to the SSL installation (default: /usr/local/ssl)]) AC_HELP_STRING([--with-ssl=PATH],[where to look for SSL, PATH points to the SSL installation (default: /usr/local/ssl)])
AC_HELP_STRING([--without-ssl], [disable SSL]), AC_HELP_STRING([--without-ssl], [disable SSL]),
@@ -569,13 +628,29 @@ else
AC_SUBST(OPENSSL_ENABLED) AC_SUBST(OPENSSL_ENABLED)
AC_MSG_CHECKING([CA cert bundle install path])
AC_ARG_WITH(ca-bundle,
AC_HELP_STRING([--with-ca-bundle=FILE], [File name to install the CA bundle as])
AC_HELP_STRING([--without-ca-bundle], [Don't install the CA bundle]),
[ ca="$withval" ],
[
if test "x$prefix" != xNONE; then
ca="\${prefix}/share/curl/curl-ca-bundle.crt"
else
ca="$ac_default_prefix/share/curl/curl-ca-bundle.crt"
fi
] )
if test X"$OPT_SSL" = Xno; then
ca="no"
fi fi
if test X"$OPT_SSL" != Xoff && if test "x$ca" != "xno"; then
test "$OPENSSL_ENABLED" != "1"; then CURL_CA_BUNDLE='"'$ca'"'
AC_MSG_ERROR([OpenSSL libs and/or directories were not found where specified!]) AC_SUBST(CURL_CA_BUNDLE)
fi fi
AC_MSG_RESULT([$ca])
dnl these can only exist if openssl exists dnl these can only exist if openssl exists
@@ -583,8 +658,17 @@ else
RAND_screen \ RAND_screen \
RAND_egd ) RAND_egd )
fi
if test X"$OPT_SSL" != Xoff &&
test "$OPENSSL_ENABLED" != "1"; then
AC_MSG_ERROR([OpenSSL libs and/or directories were not found where specified!])
fi
fi fi
AM_CONDITIONAL(CABUNDLE, test x$ca != xno)
dnl ********************************************************************** dnl **********************************************************************
dnl Check for the presence of ZLIB libraries and headers dnl Check for the presence of ZLIB libraries and headers
dnl ********************************************************************** dnl **********************************************************************
@@ -627,6 +711,9 @@ case "$OPT_ZLIB" in
;; ;;
esac esac
dnl set variable for use in automakefile(s)
AM_CONDITIONAL(HAVE_LIBZ, test x"$HAVE_LIBZ" = x1)
dnl Default is to try the thread-safe versions of a few functions dnl Default is to try the thread-safe versions of a few functions
OPT_THREAD=on OPT_THREAD=on
@@ -774,7 +861,6 @@ AC_CHECK_FUNCS( socket \
tcgetattr \ tcgetattr \
perror \ perror \
closesocket \ closesocket \
setvbuf \
sigaction \ sigaction \
signal \ signal \
getpass_r \ getpass_r \
@@ -822,36 +908,6 @@ AC_PATH_PROGS( NROFF, gnroff nroff, ,
$PATH:/usr/bin/:/usr/local/bin ) $PATH:/usr/bin/:/usr/local/bin )
AC_SUBST(NROFF) AC_SUBST(NROFF)
AC_MSG_CHECKING([CA cert bundle install path])
AC_ARG_WITH(ca-bundle,
AC_HELP_STRING([--with-ca-bundle=FILE], [File name to install the CA bundle as])
AC_HELP_STRING([--without-ca-bundle], [Don't install the CA bundle]),
[ ca="$withval" ],
[
if test "x$prefix" != xNONE; then
ca="$prefix/share/curl/curl-ca-bundle.crt"
else
ca="$ac_default_prefix/share/curl/curl-ca-bundle.crt"
fi
] )
if test X"$OPT_SSL" = Xno
then
ca="no"
fi
if test "x$ca" = "xno"; then
dnl let's not keep "no" as path name, blank it instead
ca=""
else
AC_DEFINE_UNQUOTED(CURL_CA_BUNDLE, "$ca", [CA bundle full path name])
fi
CURL_CA_BUNDLE="$ca"
AC_SUBST(CURL_CA_BUNDLE)
AC_MSG_RESULT([$ca])
AC_PROG_YACC AC_PROG_YACC
dnl AC_PATH_PROG( RANLIB, ranlib, /usr/bin/ranlib, dnl AC_PATH_PROG( RANLIB, ranlib, /usr/bin/ranlib,
@@ -871,7 +927,7 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]),
;; ;;
*) AC_MSG_RESULT(yes) *) AC_MSG_RESULT(yes)
CPPFLAGS="$CPPFLAGS -DMALLOCDEBUG" CPPFLAGS="$CPPFLAGS -DCURLDEBUG"
CFLAGS="$CFLAGS -g" CFLAGS="$CFLAGS -g"
if test "$GCC" = "yes"; then if test "$GCC" = "yes"; then
CFLAGS="$CFLAGS -W -Wall -Wwrite-strings -pedantic -Wundef -Wpointer-arith -Wnested-externs" CFLAGS="$CFLAGS -W -Wall -Wwrite-strings -pedantic -Wundef -Wpointer-arith -Wnested-externs"
@@ -914,6 +970,7 @@ AC_CONFIG_FILES([Makefile \
packages/Linux/RPM/curl.spec \ packages/Linux/RPM/curl.spec \
packages/Linux/RPM/curl-ssl.spec \ packages/Linux/RPM/curl-ssl.spec \
packages/Solaris/Makefile \ packages/Solaris/Makefile \
packages/DOS/Makefile \
packages/EPM/curl.list \ packages/EPM/curl.list \
packages/EPM/Makefile \ packages/EPM/Makefile \
curl-config curl-config

View File

@@ -37,7 +37,7 @@
(setq tab-width 8 (setq tab-width 8
indent-tabs-mode nil ; Use spaces. Not tabs. indent-tabs-mode nil ; Use spaces. Not tabs.
comment-column 40 comment-column 40
c-font-lock-extra-types (append '("bool" "CURL" "CURLcode" "ssize_t" "size_t" "socklen_t" "fd_set")) c-font-lock-extra-types (append '("bool" "CURL" "CURLcode" "ssize_t" "size_t" "socklen_t" "fd_set" "time_t"))
) )
;; keybindings for C, C++, and Objective-C. We can put these in ;; keybindings for C, C++, and Objective-C. We can put these in
;; c-mode-base-map because of inheritance ... ;; c-mode-base-map because of inheritance ...

View File

@@ -1,4 +1,4 @@
Updated: May 9, 2003 (http://curl.haxx.se/docs/faq.html) Updated: June 17, 2003 (http://curl.haxx.se/docs/faq.html)
_ _ ____ _ _ _ ____ _
___| | | | _ \| | ___| | | | _ \| |
/ __| | | | |_) | | / __| | | | |_) | |
@@ -593,9 +593,11 @@ 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?
NTLM is a Microsoft proprietary protocol. Unfortunately, curl does not This is supported in curl 7.10.6 or later. No earlier curl version knows
currently support that. Proprietary formats are evil. You should not use of this magic.
such ones.
NTLM is a Microsoft proprietary protocol. Proprietary formats are evil. You
should not use such ones.
4.10 My HTTP request using HEAD, PUT or DELETE doesn't work! 4.10 My HTTP request using HEAD, PUT or DELETE doesn't work!
@@ -776,6 +778,5 @@ FAQ
discussions and a large amount of people have contributed with source code discussions and a large amount of people have contributed with source code
knowing that this is the license we use. This license puts the restrictions knowing that this is the license we use. This license puts the restrictions
we want on curl/libcurl and it does not spread to other programs or we want on curl/libcurl and it does not spread to other programs or
libraries that use it. The recent dual license modification should make it libraries that use it. It should be possible for everyone to use libcurl or
possible for everyone to use libcurl or curl in their projects, no matter curl in their projects, no matter what license they already have in use.
what license they already have in use.

View File

@@ -17,27 +17,30 @@ Misc
- progress bar/time specs while downloading - progress bar/time specs while downloading
- "standard" proxy environment variables support - "standard" proxy environment variables support
- config file support - config file support
- compiles on win32 (reported built on 29 operating systems) - compiles on win32 (reported builds on 40+ operating systems)
- redirectable stderr - redirectable stderr
- use selected network interface for outgoing traffic - selectable network interface for outgoing traffic
- IPv6 support - IPv6 support
- persistant connections - persistant connections
- socks5 support
- supports user name + password in proxy environment variables
- operations through proxy "tunnel" (using CONNECT)
HTTP HTTP
- HTTP/1.1 compliant - HTTP/1.1 compliant (optionally uses 1.0)
- GET - GET
- PUT - PUT
- HEAD - HEAD
- POST - POST
- multipart POST - multipart formpost (RFC1867-style)
- authentication - authentication (Basic, Digest, NTLM(*1), GSS-Negotiate(*3))
- resume (both GET and PUT) - resume (both GET and PUT)
- follow redirects - follow redirects
- maximum amount of redirects to follow - maximum amount of redirects to follow
- custom HTTP request - custom HTTP request
- cookie get/send fully parsed - cookie get/send fully parsed
- understands the netscape cookie file format - reads/writes the netscape cookie file format
- custom headers (that can replace/remove internally generated headers) - custom headers (replace/remove internally generated headers)
- custom user-agent string - custom user-agent string
- custom referer string - custom referer string
- range - range
@@ -45,12 +48,16 @@ HTTP
- time conditions - time conditions
- via http-proxy - via http-proxy
- retrieve file modification date - retrieve file modification date
- Content-Encoding support for deflate and gzip
- "Transfer-Encoding: chunked" support for "uploads"
HTTPS (*1) HTTPS (*1)
- (all the HTTP features) - (all the HTTP features)
- using certificates - using certificates
- verify server certificate - verify server certificate
- via http-proxy - via http-proxy
- select desired encryption
- force usage of a specific SSL version (SSLv2, SSLv3 or TLSv1)
FTP FTP
- download - download
@@ -92,3 +99,4 @@ FILE
*1 = requires OpenSSL *1 = requires OpenSSL
*2 = requires OpenLDAP *2 = requires OpenLDAP
*3 = requires a GSSAPI-compliant library, such as Heimdal or similar.

View File

@@ -448,6 +448,7 @@ PORTS
- StrongARM NetBSD 1.4.1 - StrongARM NetBSD 1.4.1
- Ultrix 4.3a - Ultrix 4.3a
- i386 BeOS - i386 BeOS
- i386 DOS
- i386 FreeBSD - i386 FreeBSD
- i386 HURD - i386 HURD
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4 - i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4

View File

@@ -3,6 +3,12 @@ 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!
* LDAP output is garbled. Hardly anyone seems to care about LDAP functionality
in curl/libcurl why this report has been closed and set to be solved later.
If you feel this is something you want fixed, get in touch and we'll start
working.
http://sourceforge.net/tracker/index.php?func=detail&aid=735752&group_id=976&atid=100976
* IPv6 support on AIX 4.3.3 doesn't work due to a missing sockaddr_storage * IPv6 support on AIX 4.3.3 doesn't work due to a missing sockaddr_storage
struct. It has been reported to work on AIX 5.1 though. struct. It has been reported to work on AIX 5.1 though.

View File

@@ -11,7 +11,7 @@ SIMPLE USAGE
curl http://www.netscape.com/ curl http://www.netscape.com/
Get the root README file from funet's ftp-server: Get the README file the user's home directory at funet's ftp-server:
curl ftp://ftp.funet.fi/README curl ftp://ftp.funet.fi/README
@@ -19,7 +19,7 @@ SIMPLE USAGE
curl http://www.weirdserver.com:8000/ curl http://www.weirdserver.com:8000/
Get a list of the root directory of an FTP site: Get a list of a directory of an FTP site:
curl ftp://cool.haxx.se/ curl ftp://cool.haxx.se/

View File

@@ -19,7 +19,7 @@ PDFPAGES = \
SUBDIRS = examples libcurl SUBDIRS = examples libcurl
EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS \ EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS SSLCERTS \
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS \ README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS \
VERSIONS KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) \ VERSIONS KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) \
HISTORY INSTALL libcurl-the-guide $(PDFPAGES) HISTORY INSTALL libcurl-the-guide $(PDFPAGES)

View File

@@ -13,8 +13,8 @@ README.win32
are win32-based. are win32-based.
The unix-style man pages are tricky to read on windows, so therefore are all The unix-style man pages are tricky to read on windows, so therefore are all
those pages also converted to HTML and those are also included in the those pages converted to HTML as well as pdf, and included in the release
release archives. archives.
The main curl.1 man page is also "built-in" in the command line tool. Use a The main curl.1 man page is also "built-in" in the command line tool. Use a
command line similar to this in order to extract a separate text file: command line similar to this in order to extract a separate text file:

View File

@@ -90,3 +90,4 @@ that have contributed with non-trivial parts:
- Dan Fandrich <dan@coneharvesters.com> - Dan Fandrich <dan@coneharvesters.com>
- Jean-Philippe Barrette-LaPierre <jpb@rrette.com> - Jean-Philippe Barrette-LaPierre <jpb@rrette.com>
- Richard Bramante <RBramante@on.com> - Richard Bramante <RBramante@on.com>
- Daniel Kouril <kouril@ics.muni.cz>

View File

@@ -16,7 +16,7 @@ TODO
know what cookies that are received. Pushing interface that calls a know what cookies that are received. Pushing interface that calls a
callback on each received cookie? Querying interface that asks about callback on each received cookie? Querying interface that asks about
existing cookies? We probably need both. Enable applications to modify existing cookies? We probably need both. Enable applications to modify
existing cookies as well. existing cookies as well. http://curl.haxx.se/dev/COOKIES
* Make content encoding/decoding internally be made using a filter system. * Make content encoding/decoding internally be made using a filter system.
@@ -50,10 +50,6 @@ TODO
requested. That is, the download should not even begin but be aborted requested. That is, the download should not even begin but be aborted
immediately. immediately.
* Allow the http_proxy (and other) environment variables to contain user and
password as well in the style: http://proxyuser:proxypasswd@proxy:port
Berend Reitsma suggested.
LIBCURL - multi interface LIBCURL - multi interface
* Make sure we don't ever loop because of non-blocking sockets return * Make sure we don't ever loop because of non-blocking sockets return
@@ -76,55 +72,21 @@ TODO
* Make CURLOPT_FTPPORT support an additional port number on the IP/if/name, * Make CURLOPT_FTPPORT support an additional port number on the IP/if/name,
like "blabla:[port]" or possibly even "blabla:[portfirst]-[portsecond]". like "blabla:[port]" or possibly even "blabla:[portfirst]-[portsecond]".
* FTP ASCII upload does not follow RFC959 section 3.1.1.1: "The sender * FTP ASCII transfers do not follow RFC959. They don't convert the data
converts the data from an internal character representation to the standard accordingly.
8-bit NVT-ASCII representation (see the Telnet specification). The
receiver will convert the data from the standard form to his own internal
form."
* Since USERPWD always override the user and password specified in URLs, we * Since USERPWD always override the user and password specified in URLs, we
might need another way to specify user+password for anonymous ftp logins. might need another way to specify user+password for anonymous ftp logins.
* An option to only download remote FTP files if they're newer than the local
one is a good idea, and it would fit right into the same syntax as the
already working http dito works (-z). It of course requires that 'MDTM'
works, and it isn't a standard FTP command.
* Add FTPS support with SSL for the data connection too. This should be made * Add FTPS support with SSL for the data connection too. This should be made
according to the specs written in draft-murray-auth-ftp-ssl-08.txt, according to the specs written in draft-murray-auth-ftp-ssl-11.txt,
"Securing FTP with TLS" "Securing FTP with TLS", valid until September 27th 2003.
http://curl.haxx.se/rfc/draft-murray-auth-ftp-ssl-11.txt
* --disable-epsv exists, but for active connections we have no --disable-eprt
(or even --disable-lprt).
HTTP HTTP
* If the "body" of the POST is < MSS it really aught to be sent along with * Digest, NTLM and GSS-Negotiate support for HTTP proxies. They all work
the headers. More generally, if the last chunk of the POST body is < MSS, on direct-connections to the server.
it should be sent with the previous chunk (which may be the POST headers).
So long as any one send is larger than MSS (or there is only one send when
< MSS :), the Nagle Algorithm will not be a problem on any stack where
Nagle is implemented correctly. (pointed out by Rick Jones)
* Authentication: NTLM. Support for that MS crap called NTLM
authentication. MS proxies and servers sometime require that. Since that
protocol is a proprietary one, it involves reverse engineering and network
sniffing. This should however be a library-based functionality. There are a
few different efforts "out there" to make open source HTTP clients support
this and it should be possible to take advantage of other people's hard
work. http://modntlm.sourceforge.net/ is one. There's a web page at
http://www.innovation.ch/java/ntlm.html that contains detailed reverse-
engineered info.
* RFC2617 compliance, "Digest Access Authentication" A valid test page seem
to exist at: http://hopf.math.nwu.edu/testpage/digest/ And some friendly
person's server source code is available at
http://hopf.math.nwu.edu/digestauth/index.html Then there's the Apache
mod_digest source code too of course. It seems as if Netscape doesn't
support this, and not many servers do. Although this is a lot better
authentication method than the more common "Basic". Basic sends the
password in cleartext over the network, this "Digest" method uses a
challange-response protocol which increases security quite a lot.
* Pipelining. Sending multiple requests before the previous one(s) are done. * Pipelining. Sending multiple requests before the previous one(s) are done.
This could possibly be implemented using the multi interface to queue This could possibly be implemented using the multi interface to queue

View File

@@ -2,7 +2,7 @@
.\" nroff -man curl.1 .\" nroff -man curl.1
.\" Written by Daniel Stenberg .\" Written by Daniel Stenberg
.\" .\"
.TH curl 1 "14 Feb 2003" "Curl 7.10.3" "Curl Manual" .TH curl 1 "18 June 2003" "Curl 7.10.6" "Curl Manual"
.SH NAME .SH NAME
curl \- transfer a URL curl \- transfer a URL
.SH SYNOPSIS .SH SYNOPSIS
@@ -10,14 +10,18 @@ curl \- transfer a URL
.I [URL...] .I [URL...]
.SH DESCRIPTION .SH DESCRIPTION
.B curl .B curl
is a client to get documents/files from or send documents to a server, using is a tool to transfer data from or to a server, using one of the supported
any of the supported protocols (HTTP, HTTPS, FTP, GOPHER, DICT, TELNET, LDAP protocols (HTTP, HTTPS, FTP, FTPS, GOPHER, DICT, TELNET, LDAP or FILE). The
or FILE). The command is designed to work without user interaction or any kind command is designed to work without user interaction.
of interactivity.
curl offers a busload of useful tricks like proxy support, user curl offers a busload of useful tricks like proxy support, user
authentication, ftp upload, HTTP post, SSL (https:) connections, cookies, file authentication, ftp upload, HTTP post, SSL (https:) connections, cookies, file
transfer resume and more. transfer resume and more. As you will see below, the amount of features will
make your head spin!
curl is powered by libcurl for all transfer-related features. See
.BR libcurl (3)
for details.
.SH URL .SH URL
The URL syntax is protocol dependent. You'll find a detailed description in The URL syntax is protocol dependent. You'll find a detailed description in
RFC 2396. RFC 2396.
@@ -48,10 +52,8 @@ specified on a single command line and cannot be used between separate curl
invokes. invokes.
.SH OPTIONS .SH OPTIONS
.IP "-a/--append" .IP "-a/--append"
(FTP) (FTP) When used in an FTP upload, this will tell curl to append to the target
When used in a ftp upload, this will tell curl to append to the target file instead of overwriting it. If the file doesn't exist, it will be created.
file instead of overwriting it. If the file doesn't exist, it will
be created.
If this option is used twice, the second one will disable append mode again. If this option is used twice, the second one will disable append mode again.
.IP "-A/--user-agent <agent string>" .IP "-A/--user-agent <agent string>"
@@ -63,6 +65,16 @@ surround the string with single quote marks. This can also be set with the
If this option is set more than once, the last one will be the one that's If this option is set more than once, the last one will be the one that's
used. used.
.IP "--anyauth"
(HTTP) Tells curl to figure out authentication method by itself, and use the
most secure one the remote site claims it supports. This is done by first
doing a request and checking the response-headers, thus inducing an extra
network round-trip. This is used instead of setting a specific authentication
method, which you can do with \fI--digest\fP, \fI--ntlm\fP, and
\fI--negotiate\fP. (Added in 7.10.6)
If this option is used several times, the following occurrences make no
difference.
.IP "-b/--cookie <name=data>" .IP "-b/--cookie <name=data>"
(HTTP) (HTTP)
Pass the data to the HTTP server as a cookie. It is supposedly the Pass the data to the HTTP server as a cookie. It is supposedly the
@@ -90,6 +102,14 @@ also be enforced by using an URL that ends with ";type=A". This option causes
data sent to stdout to be in text mode for win32 systems. data sent to stdout to be in text mode for win32 systems.
If this option is used twice, the second one will disable ASCII usage. If this option is used twice, the second one will disable ASCII usage.
.IP "--basic"
(HTTP) Tells curl to use HTTP Basic authentication. This is the default and
this option is usually pointless, unless you use it to override a previously
set option that sets a different authentication method (such as \fI--ntlm\fP,
\fI--digest\fP and \fI--negotiate\fP). (Added in 7.10.6)
If this option is used several times, the following occurrences make no
difference.
.IP "--ciphers <list of ciphers>" .IP "--ciphers <list of ciphers>"
(SSL) Specifies which ciphers to use in the connection. The list of ciphers (SSL) Specifies which ciphers to use in the connection. The list of ciphers
must be using valid ciphers. Read up on SSL cipher list details on this URL: must be using valid ciphers. Read up on SSL cipher list details on this URL:
@@ -97,9 +117,11 @@ must be using valid ciphers. Read up on SSL cipher list details on this URL:
If this option is used several times, the last one will override the others. If this option is used several times, the last one will override the others.
.IP "--compressed" .IP "--compressed"
(HTTP) Request a compressed response using the deflate or gzip (HTTP) Request a compressed response using one of the algorithms libcurl
algorithms and return the uncompressed document. If this option is used supports, and return the uncompressed document. If this option is used and
and the server sends an unsupported encoding, Curl will report an error. the server sends an unsupported encoding, Curl will report an error.
If this option is used several times, each occurrence will toggle it on/off.
.IP "--connect-timeout <seconds>" .IP "--connect-timeout <seconds>"
Maximum time in seconds that you allow the connection to the server to take. Maximum time in seconds that you allow the connection to the server to take.
This only limits the connection phase, once curl has connected this option is This only limits the connection phase, once curl has connected this option is
@@ -176,9 +198,27 @@ want to post a binary file without the strip-newlines feature of the
If this option is used several times, the ones following the first will If this option is used several times, the ones following the first will
append data. append data.
.IP "--digest"
(HTTP) Enables HTTP Digest authentication. This is a authentication that
prevents the password from being sent over the wire in clear text. Use this in
combination with the normal -u/--user option to set user name and
password. See also \fI--ntlm\fP, \fP--negotiate\fI and \fI--anyauth\fP for
related options. (Added in curl 7.10.6)
If this option is used several times, the following occurrences make no
difference.
.IP "--disable-eprt"
(FTP) Tell curl to disable the use of the EPRT and LPRT commands when doing
active FTP transfers. Curl will normally always first attempt to use EPRT,
then LPRT before using PORT, but with this option, it will use PORT right
away. EPRT and LPRT are extensions to the original FTP protocol, may not work
on all servers but enable more functionality in a better way than the
traditional PORT command. (Aded in 7.10.5)
If this option is used several times, each occurrence will toggle this on/off.
.IP "--disable-epsv" .IP "--disable-epsv"
(FTP) Tell curl to disable the use of the EPSV command when doing passive FTP (FTP) Tell curl to disable the use of the EPSV command when doing passive FTP
downloads. Curl will normally always first attempt to use EPSV before PASV, transfers. Curl will normally always first attempt to use EPSV before PASV,
but with this option, it will not try using EPSV. but with this option, it will not try using EPSV.
If this option is used several times, each occurrence will toggle this on/off. If this option is used several times, each occurrence will toggle this on/off.
@@ -397,9 +437,18 @@ If this option is used twice, the second will again disable list only.
(HTTP/HTTPS) If the server reports that the requested page has a different (HTTP/HTTPS) If the server reports that the requested page has a different
location (indicated with the header line Location:) this flag will let curl location (indicated with the header line Location:) this flag will let curl
attempt to reattempt the get on the new place. If used together with -i or -I, attempt to reattempt the get on the new place. If used together with -i or -I,
headers from all requested pages will be shown. If this flag is used when headers from all requested pages will be shown. If authentication is used,
making a HTTP POST, curl will automatically switch to GET after the initial curl will only send its credentials to the initial host, so if a redirect
POST has been done. takes curl to a different host, it won't intercept the user+password. See also
\fI--location-trusted\fP on how to change this.
If this option is used twice, the second will again disable location following.
.IP "--location-trusted"
(HTTP/HTTPS) Like \fI--location\fP, but will allow sending the name + password
to all hosts that the site may redirect to. This may or may not introduce a
security breach if the site redirects you do a site to which you'll send your
authentication info (which is plaintext in the case of HTTP Basic
authentication).
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 "-m/--max-time <seconds>" .IP "-m/--max-time <seconds>"
@@ -433,6 +482,19 @@ to allow curl to ftp to the machine host.domain.com with user name
.B "machine host.domain.com login myself password secret" .B "machine host.domain.com login myself password secret"
If this option is used twice, the second will again disable netrc usage. If this option is used twice, the second will again disable netrc usage.
.IP "--negotiate"
(HTTP) Enables GSS-Negotiate authentication. The GSS-Negotiate method was
designed by Microsoft and is used in their web aplications. It is primarily
meant as a support for Kerberos5 authentication but may be also used along
with another authentication methods. For more information see IETF draft
draft-brezak-spnego-http-04.txt. (Added in 7.10.6)
\fBNOTE\fP that this option requiures that the library was built with GSSAPI
support. This is not very common. Use \fIcurl --version\fP to see if your
version supports GSS-Negotiate.
If this option is used several times, the following occurrences make no
difference.
.IP "-N/--no-buffer" .IP "-N/--no-buffer"
Disables the buffering of the output stream. In normal work situations, curl Disables the buffering of the output stream. In normal work situations, curl
will use a standard buffered output stream that will have the effect that it will use a standard buffered output stream that will have the effect that it
@@ -440,6 +502,19 @@ will output the data in chunks, not necessarily exactly when the data arrives.
Using this option will disable that buffering. Using this option will disable that buffering.
If this option is used twice, the second will again switch on buffering. If this option is used twice, the second will again switch on buffering.
.IP "--ntlm"
(HTTP) Enables NTLM authentication. The NTLM authentication method was
designed by Microsoft and is used by IIS web servers. It is a proprietary
protocol, reversed engineered by clever people and implemented in curl based
on their efforts. This kind of behavior should not be endorsed, you should
encourage everyone who uses NTLM to switch to a public and documented
authentication method instead. Such as Digest. (Added in 7.10.6)
\fBNOTE\fP that this option requiures that the library was built with SSL
support. Use \fIcurl --version\fP to see if your version supports NTLM.
If this option is used several times, the following occurrences make no
difference.
.IP "-o/--output <file>" .IP "-o/--output <file>"
Write output to <file> instead of stdout. If you are using {} or [] to fetch Write output to <file> instead of stdout. If you are using {} or [] to fetch
multiple documents, you can use '#' followed by a number in the <file> multiple documents, you can use '#' followed by a number in the <file>
@@ -456,8 +531,8 @@ You may use this option as many times as you have number of URLs.
See also the --create-dirs option to create the local directories dynamically. See also the --create-dirs option to create the local directories dynamically.
.IP "-O/--remote-name" .IP "-O/--remote-name"
Write output to a local file named like the remote file we get. (Only Write output to a local file named like the remote file we get. (Only the file
the file part of the remote file is used, the path is cut off.) part of the remote file is used, the path is cut off.)
You may use this option as many times as you have number of URLs. You may use this option as many times as you have number of URLs.
.IP "-p/--proxytunnel" .IP "-p/--proxytunnel"
@@ -596,7 +671,7 @@ descriptive information, to the given output file. Use "-" as filename to have
the output sent to stdout. the output sent to stdout.
If this option is used several times, the last one will be used. (Added in If this option is used several times, the last one will be used. (Added in
curl 7.9.7) 7.9.7)
.IP "--trace-ascii <file>" .IP "--trace-ascii <file>"
Enables a full trace dump of all incoming and outgoing data, including Enables a full trace dump of all incoming and outgoing data, including
descriptive information, to the given output file. Use "-" as filename to have descriptive information, to the given output file. Use "-" as filename to have
@@ -607,12 +682,15 @@ the ASCII part of the dump. It makes smaller output that might be easier to
read for untrained humans. read for untrained humans.
If this option is used several times, the last one will be used. (Added in If this option is used several times, the last one will be used. (Added in
curl 7.9.7) 7.9.7)
.IP "-u/--user <user:password>" .IP "-u/--user <user:password>"
Specify user and password to use when fetching. Read the MANUAL for detailed Specify user and password to use when fetching. Read the MANUAL for detailed
examples of how to use this. If no password is specified, curl will ask for it examples of how to use this. If no password is specified, curl will ask for it
interactively. interactively.
You can also use the --digest option to enable Digest authentication when
communicating with HTTP 1.1 servers.
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 "-U/--proxy-user <user:password>" .IP "-U/--proxy-user <user:password>"
Specify user and password to use for Proxy authentication. If no Specify user and password to use for Proxy authentication. If no
@@ -642,8 +720,17 @@ If you think this option still doesn't give you enough details, consider using
If this option is used twice, the second will again disable verbose. If this option is used twice, the second will again disable verbose.
.IP "-V/--version" .IP "-V/--version"
Displays the full version of curl, libcurl and other 3rd party libraries Displays information about curl and the libcurl version it uses.
linked with the executable.
The first line includes the full version of curl, libcurl and other 3rd party
libraries linked with the executable.
The second line (starts with "Protocols:") shows all protocols that libcurl
reports to support.
The third line (starts with "Features:") shows specific features libcurl
reports to offer.
.IP "-w/--write-out <format>" .IP "-w/--write-out <format>"
Defines what to display after a completed and successful operation. The format Defines what to display after a completed and successful operation. The format
is a string that may contain plain text mixed with any number of variables. The is a string that may contain plain text mixed with any number of variables. The

View File

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

31
docs/examples/makefile.dj Normal file
View File

@@ -0,0 +1,31 @@
#
# Adapted for djgpp / Watt-32 / DOS by
# Gisle Vanem <giva@bgnett.no>
#
include ../../packages/DOS/common.dj
CFLAGS += -I../../include
LIBS = ../../lib/libcurl.a
ifeq ($(USE_SSL),1)
LIBS += $(OPENSSL_ROOT)/lib/libssl.a $(OPENSSL_ROOT)/lib/libcrypt.a
endif
LIBS += $(WATT32_ROOT)/lib/libwatt.a $(ZLIB_ROOT)/libz.a
PROGRAMS = fopen.exe ftpget.exe ftpgetre.exe ftpuploa.exe getinmem.exe \
http-pos.exe httpput.exe multi-ap.exe multi-do.exe \
multi-po.exe multi-si.exe persista.exe post-cal.exe \
postit2.exe sepheade.exe simple.exe simpless.exe
all: $(PROGRAMS)
.c.exe:
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
@echo
clean:
rm -f $(PROGRAMS)

View File

@@ -40,7 +40,7 @@ int main(int argc, char **argv)
FILE *headerfile; FILE *headerfile;
const char *pCertFile = "testcert.pem"; const char *pCertFile = "testcert.pem";
const char *pCACertFile="cacert.pem" const char *pCACertFile="cacert.pem";
const char *pKeyName; const char *pKeyName;
const char *pKeyType; const char *pKeyType;

View File

@@ -1,7 +1,7 @@
.\" nroff -man [file] .\" nroff -man [file]
.\" $Id$ .\" $Id$
.\" .\"
.TH curl_easy_setopt 3 "3 Dec 2002" "libcurl 7.10.3" "libcurl Manual" .TH curl_easy_setopt 3 "10 Jun 2003" "libcurl 7.10.6" "libcurl Manual"
.SH NAME .SH NAME
curl_easy_setopt - set options for a curl easy handle curl_easy_setopt - set options for a curl easy handle
.SH SYNOPSIS .SH SYNOPSIS
@@ -272,7 +272,7 @@ The main point of this would be that the write callback gets called more often
and with smaller chunks. This is just treated as a request, not an order. You and with smaller chunks. This is just treated as a request, not an order. You
cannot be guaranteed to actually get the given size. (Added in 7.10) cannot be guaranteed to actually get the given size. (Added in 7.10)
.PP .PP
.SH NAMES and PASSWORDS OPTIONS .SH NAMES and PASSWORDS OPTIONS (Authentication)
.TP 0.4i .TP 0.4i
.B CURLOPT_NETRC .B CURLOPT_NETRC
This parameter controls the preference of libcurl between using user names and This parameter controls the preference of libcurl between using user names and
@@ -322,15 +322,60 @@ prompt function.
When using HTTP and CURLOPT_FOLLOWLOCATION, libcurl might perform several When using HTTP and CURLOPT_FOLLOWLOCATION, libcurl might perform several
requests to possibly different hosts. libcurl will only send this user and requests to possibly different hosts. libcurl will only send this user and
password information to hosts using the initial host name, so if libcurl password information to hosts using the initial host name (unless
follows locations to other hosts it will not send the user and password to CURLOPT_UNRESTRICTED_AUTH is set), so if libcurl follows locations to other
those. This is enforced to prevent accidental information leakage. hosts it will not send the user and password to those. This is enforced to
prevent accidental information leakage.
.TP .TP
.B CURLOPT_PROXYUSERPWD .B CURLOPT_PROXYUSERPWD
Pass a char * as parameter, which should be [user name]:[password] to use for Pass a char * as parameter, which should be [user name]:[password] to use for
the connection to the HTTP proxy. If the password is left out, you will be the connection to the HTTP proxy. If the password is left out, you will be
prompted for it. \fICURLOPT_PASSWDFUNCTION\fP can be used to set your own prompted for it. \fICURLOPT_PASSWDFUNCTION\fP can be used to set your own
prompt function. prompt function.
.TP
.B CURLOPT_HTTPAUTH
Pass a long as parameter, which is set to a bitmask, to tell libcurl what
authentication method(s) you want it to use. The available bits are listed
below. If more than one bit is set, libcurl will first query the site to see
what authentication methods it supports and then pick the best one you allow
it to use. Note that for some methods, this will induce an extra network
round-trip. Set the actual name and password with the \fICURLOPT_USERPWD\fP
option. (Added in 7.10.6)
.RS
.TP 5
.B CURLAUTH_BASIC
HTTP Basic authentication. This is the default choice, and the only method
that is in wide-spread use and supported virtually everywhere. This is sending
the user name and password over the network in plain text, easily captured by
others.
.TP
.B CURLAUTH_DIGEST
HTTP Digest authentication. Digest authentication is defined in RFC2617 and
is a more secure way to do authentication over public networks than the
regular old-fashioned Basic method.
.TP
.B CURLAUTH_GSSNEGOTIATE
HTTP GSS-Negotiate authentication. The GSS-Negotiate method was designed by
Microsoft and is used in their web aplications. It is primarily meant as a
support for Kerberos5 authentication but may be also used along with another
authentication methods. For more information see IETF draft
draft-brezak-spnego-http-04.txt.
.TP
.B CURLAUTH_NTLM
HTTP NTLM authentication. A proprietary protocol invented and used by
Microsoft. It uses a challenge-response and hash concept similar to Digest to
prevent the password from being evesdropped.
.TP
.B CURLAUTH_ANY
This is a convenience macro that sets all bits and thus makes libcurl pick any
it finds suitable. libcurl will automaticly select the one it finds most
secure.
.TP
.B CURLAUTH_ANYSAFE
This is a convenience macro that sets all bits except Basic and thus makes
libcurl pick any it finds suitable. libcurl will automaticly select the one it
finds most secure.
.RE
.PP .PP
.SH HTTP OPTIONS .SH HTTP OPTIONS
.TP 0.4i .TP 0.4i
@@ -437,6 +482,10 @@ curl adds CRLF after each header item. Failure to comply with this will
result in strange bugs because the server will most likely ignore part result in strange bugs because the server will most likely ignore part
of the headers you specified. of the headers you specified.
The first line in a request (usually containing a GET or POST) is not a header
and cannot be replaced using this option. Only the lines following the
request-line are headers.
\fBNOTE:\fPThe most commonly replaced headers have "shortcuts" in the options \fBNOTE:\fPThe most commonly replaced headers have "shortcuts" in the options
CURLOPT_COOKIE, CURLOPT_USERAGENT and CURLOPT_REFERER. CURLOPT_COOKIE, CURLOPT_USERAGENT and CURLOPT_REFERER.
.TP .TP
@@ -615,9 +664,18 @@ want the transfer to start from.
.TP .TP
.B CURLOPT_CUSTOMREQUEST .B CURLOPT_CUSTOMREQUEST
Pass a pointer to a zero terminated string as parameter. It will be user Pass a pointer to a zero terminated string as parameter. It will be user
instead of GET or HEAD when doing the HTTP request. This is useful for doing instead of GET or HEAD when doing a HTTP request, or instead of LIST or NLST
DELETE or other more or less obscure HTTP requests. Don't do this at will, when doing an ftp directory listing. This is useful for doing DELETE or other
make sure your server supports the command first. more or less obscure HTTP requests. Don't do this at will, make sure your
server supports the command first.
NOTE: many people have wrongly used this option to replace the entire request
with their own, including multiple headers and POST contents. While that might
work in many cases, it will cause libcurl to send invalid requests and it
could possibly confuse the remote server badly. Use \fICURLOPT_POST\fP and
\fICURLOPT_POSTFIELDS\fP to set POST data. Use \fICURLOPT_HTTPHEADER\fP to
replace or extend the set of headers sent by libcurl. Use
\fICURLOPT_HTTP_VERSION\fP to change HTTP version.
.TP .TP
.B CURLOPT_FILETIME .B CURLOPT_FILETIME
Pass a long. If it is a non-zero value, libcurl will attempt to get the Pass a long. If it is a non-zero value, libcurl will attempt to get the

View File

@@ -2,7 +2,7 @@
.\" nroff -man [file] .\" nroff -man [file]
.\" $Id$ .\" $Id$
.\" .\"
.TH curl_slist_append 3 "21 Feb 2003" "libcurl 7.10.4" "libcurl Manual" .TH curl_slist_append 3 "19 Jun 2003" "libcurl 7.10.4" "libcurl Manual"
.SH NAME .SH NAME
curl_slist_append - add a string to an slist curl_slist_append - add a string to an slist
.SH SYNOPSIS .SH SYNOPSIS
@@ -15,7 +15,8 @@ curl_slist_append - add a string to an slist
curl_slist_append() appends a specified string to a linked list of curl_slist_append() appends a specified string to a linked list of
strings. The existing \fIlist\fP should be passed as the first argument while strings. The existing \fIlist\fP should be passed as the first argument while
the new list is returned from this function. The specified \fIstring\fP has the new list is returned from this function. The specified \fIstring\fP has
been appended when this function returns. been appended when this function returns. curl_slist_append() copies the
string.
The list should be freed again (after usage) with \fBcurl_slist_free_all()\fP. The list should be freed again (after usage) with \fBcurl_slist_free_all()\fP.
.SH RETURN VALUE .SH RETURN VALUE

View File

@@ -2,7 +2,7 @@
.\" nroff -man [file] .\" nroff -man [file]
.\" $Id$ .\" $Id$
.\" .\"
.TH curl_version_info 3 "30 Sep 2002" "libcurl 7.10" "libcurl Manual" .TH curl_version_info 3 "17 Jun 2003" "libcurl 7.10.6" "libcurl Manual"
.SH NAME .SH NAME
curl_version_info - returns run-time libcurl version info curl_version_info - returns run-time libcurl version info
.SH SYNOPSIS .SH SYNOPSIS
@@ -69,6 +69,16 @@ supports SSL (HTTPS/FTPS)
.TP .TP
.B CURL_VERSION_LIBZ .B CURL_VERSION_LIBZ
supports HTTP deflate using libz supports HTTP deflate using libz
.TP
.B CURL_VERSION_NTLM
supports HTTP NTLM (added in 7.10.6)
.TP
.B CURL_VERSION_GSSNEGOTIATE
supports HTTP GSS-Negotiate (added in 7.10.6)
.TP
.B CURL_VERSION_DEBUG
libcurl was built with extra debug capabilities built-in. This is mainly of
interest for libcurl hackers. (added in 7.10.6)
.PP .PP
\fIssl_version\fP is an ascii string for the OpenSSL version used. If libcurl \fIssl_version\fP is an ascii string for the OpenSSL version used. If libcurl
has no SSL support, this is NULL. has no SSL support, this is NULL.
@@ -83,8 +93,6 @@ libcurl has no libz support, this is NULL.
names protocols that libcurl supports (using lowercase letters). The protocol names protocols that libcurl supports (using lowercase letters). The protocol
names are the same as would be used in URLs. The array is terminated by a NULL names are the same as would be used in URLs. The array is terminated by a NULL
entry. entry.
.SH RETURN VALUE .SH RETURN VALUE
A pointer to a curl_version_info_data struct. A pointer to a curl_version_info_data struct.
.SH "SEE ALSO" .SH "SEE ALSO"

View File

@@ -13,3 +13,26 @@ of environment. You should include files from here using...
... style and point the compiler's include path to the directory holding the ... style and point the compiler's include path to the directory holding the
curl subdirectory. It makes it more likely to survive future modifications. curl subdirectory. It makes it more likely to survive future modifications.
NOTE FOR LIBCURL HACKERS
All the include files in this tree are written and intended to be installed on
a system that may serve multiple platforms and multiple applications, all
using libcurl (possibly even different libcurl installations using different
versions). Therefore, all header files in here must obey these rules:
* They cannot depend on or use configure-generated results from libcurl's or
curl's directories. Other applications may not run configure as (lib)curl
does, and using platform dependent info here may break other platforms.
* We cannot assume anything else but very basic compiler features being
present. While libcurl requires an ANSI C compiler to build, some of the
earlier ANSI compilers clearly can't deal with some preprocessor operators.
* Newlines must remain unix-style for older compilers' sake.
* Comments must be written in the old-style /* unnested C-fashion */
To figure out how to do good and portable checks for features, operating
systems or specific hardwarare, a very good resource is Bjorn Reese's
collection at http://predef.sf.net/

View File

@@ -23,23 +23,39 @@
* $Id$ * $Id$
***************************************************************************/ ***************************************************************************/
/* If you have problems, all libcurl docs and details are found here:
http://curl.haxx.se/libcurl/
*/
/* This is the version number of the libcurl package from which this header
file origins: */
#define LIBCURL_VERSION "7.10.6"
/* This is the numeric version of the libcurl version number, meant for easier
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
always follow this syntax:
0xXXYYZZ
Where XX, YY and ZZ are the main version, release and patch numbers in
hexadecimal. All three numbers are always represented using two digits. 1.2
would appear as "0x010200" while version 9.11.7 appears as "0x090b07".
This 6-digit hexadecimal number does not show pre-release number, and it is
always a greater number in a more recent release. It makes comparisons with
greater than and less than work.
*/
#define LIBCURL_VERSION_NUM 0x070a06
#include <stdio.h> #include <stdio.h>
/* The include stuff here is mainly for time_t! */
/* The include stuff here below is mainly for time_t! */
#ifdef vms #ifdef vms
# include <types.h> # include <types.h>
# include <time.h> # include <time.h>
#else #else
# include <sys/types.h> # include <sys/types.h>
# ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h> # include <time.h>
# else
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
# endif
#endif /* defined (vms) */ #endif /* defined (vms) */
#ifndef TRUE #ifndef TRUE
@@ -55,8 +71,8 @@
extern "C" { extern "C" {
#endif #endif
/* stupid #define trick to preserve functionality with older code, but /* silly trick to preserve functionality with older code, but making it use
making it use our name space for the future */ our name space for the future */
#define HttpPost curl_httppost #define HttpPost curl_httppost
struct curl_httppost { struct curl_httppost {
@@ -65,15 +81,13 @@ struct curl_httppost {
long namelength; /* length of name length */ long namelength; /* length of name length */
char *contents; /* pointer to allocated data contents */ char *contents; /* pointer to allocated data contents */
long contentslength; /* length of contents field */ long contentslength; /* length of contents field */
/* CMC: Added support for buffer uploads */
char *buffer; /* pointer to allocated buffer contents */ char *buffer; /* pointer to allocated buffer contents */
long bufferlength; /* length of buffer field */ long bufferlength; /* length of buffer field */
char *contenttype; /* Content-Type */ char *contenttype; /* Content-Type */
struct curl_slist* contentheader; /* list of extra headers for this form */ struct curl_slist* contentheader; /* list of extra headers for this form */
struct curl_httppost *more; /* if one field name has more than one file, this struct curl_httppost *more; /* if one field name has more than one
link should link to following files */ file, this link should link to following
files */
long flags; /* as defined below */ long flags; /* as defined below */
#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */ #define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */
#define HTTPPOST_READFILE (1<<1) /* specified content is a file name */ #define HTTPPOST_READFILE (1<<1) /* specified content is a file name */
@@ -81,13 +95,12 @@ struct curl_httppost {
do not free in formfree */ do not free in formfree */
#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer #define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
do not free in formfree */ do not free in formfree */
/* CMC: Added support for buffer uploads */
#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */ #define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */
#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */ #define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */
char *showfilename; /* The file name to show. If not set, the actual char *showfilename; /* The file name to show. If not set, the
file name will be used (if this is a file part) */ actual file name will be used (if this
is a file part) */
}; };
typedef int (*curl_progress_callback)(void *clientp, typedef int (*curl_progress_callback)(void *clientp,
@@ -130,7 +143,7 @@ typedef int (*curl_debug_callback)
curl_infotype type, /* what kind of data */ curl_infotype type, /* what kind of data */
char *data, /* points to the data */ char *data, /* points to the data */
size_t size, /* size of the data pointed to */ size_t size, /* size of the data pointed to */
void *userp); /* whatever the user please */ void *userptr); /* whatever the user please */
/* All possible error codes from all sorts of curl functions. Future versions /* All possible error codes from all sorts of curl functions. Future versions
may return other values, stay prepared. may return other values, stay prepared.
@@ -207,6 +220,11 @@ typedef enum {
CURL_LAST /* never use! */ CURL_LAST /* never use! */
} CURLcode; } CURLcode;
typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */
void *ssl_ctx, /* actually an
OpenSSL SSL_CTX */
void *userptr);
/* Make a spelling correction for the operation timed-out define */ /* Make a spelling correction for the operation timed-out define */
#define CURLE_OPERATION_TIMEDOUT CURLE_OPERATION_TIMEOUTED #define CURLE_OPERATION_TIMEDOUT CURLE_OPERATION_TIMEOUTED
#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR #define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
@@ -217,6 +235,14 @@ typedef enum {
CURLPROXY_SOCKS5 = 5 CURLPROXY_SOCKS5 = 5
} curl_proxytype; } curl_proxytype;
#define CURLAUTH_NONE 0 /* nothing */
#define CURLAUTH_BASIC (1<<0) /* Basic (default) */
#define CURLAUTH_DIGEST (1<<1) /* Digest */
#define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */
#define CURLAUTH_NTLM (1<<3) /* NTLM */
#define CURLAUTH_ANY ~0 /* all types set */
#define CURLAUTH_ANYSAFE (~CURLAUTH_BASIC)
/* this was the error code 50 in 7.7.3 and a few earlier versions, this /* this was the error code 50 in 7.7.3 and a few earlier versions, this
is no longer used by libcurl but is instead #defined here only to not is no longer used by libcurl but is instead #defined here only to not
make programs break */ make programs break */
@@ -266,6 +292,12 @@ typedef enum {
#define CINIT(name,type,number) CURLOPT_/**/name = type + number #define CINIT(name,type,number) CURLOPT_/**/name = type + number
#endif #endif
/*
* This macro-mania below setups the CURLOPT_[what] enum, to be used with
* curl_easy_setopt(). The first argument in the CINIT() macro is the [what]
* word.
*/
typedef enum { typedef enum {
CINIT(NOTHING, LONG, 0), /********* the first one is unused ************/ CINIT(NOTHING, LONG, 0), /********* the first one is unused ************/
@@ -275,24 +307,19 @@ typedef enum {
/* The full URL to get/put */ /* The full URL to get/put */
CINIT(URL, OBJECTPOINT, 2), CINIT(URL, OBJECTPOINT, 2),
/* Port number to connect to, if other than default. Specify the CONF_PORT /* Port number to connect to, if other than default. */
flag in the CURLOPT_FLAGS to activate this */
CINIT(PORT, LONG, 3), CINIT(PORT, LONG, 3),
/* Name of proxy to use. Specify the CONF_PROXY flag in the CURLOPT_FLAGS to /* Name of proxy to use. */
activate this */
CINIT(PROXY, OBJECTPOINT, 4), CINIT(PROXY, OBJECTPOINT, 4),
/* Name and password to use when fetching. Specify the CONF_USERPWD flag in /* "name:password" to use when fetching. */
the CURLOPT_FLAGS to activate this */
CINIT(USERPWD, OBJECTPOINT, 5), CINIT(USERPWD, OBJECTPOINT, 5),
/* Name and password to use with Proxy. Specify the CONF_PROXYUSERPWD /* "name:password" to use with proxy. */
flag in the CURLOPT_FLAGS to activate this */
CINIT(PROXYUSERPWD, OBJECTPOINT, 6), CINIT(PROXYUSERPWD, OBJECTPOINT, 6),
/* Range to get, specified as an ASCII string. Specify the CONF_RANGE flag /* Range to get, specified as an ASCII string. */
in the CURLOPT_FLAGS to activate this */
CINIT(RANGE, OBJECTPOINT, 7), CINIT(RANGE, OBJECTPOINT, 7),
/* not used */ /* not used */
@@ -413,7 +440,6 @@ typedef enum {
as described elsewhere. */ as described elsewhere. */
CINIT(WRITEINFO, OBJECTPOINT, 40), CINIT(WRITEINFO, OBJECTPOINT, 40),
/* Previous FLAG bits */
CINIT(VERBOSE, LONG, 41), /* talk a lot */ CINIT(VERBOSE, LONG, 41), /* talk a lot */
CINIT(HEADER, LONG, 42), /* throw the header out too */ CINIT(HEADER, LONG, 42), /* throw the header out too */
CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */
@@ -629,6 +655,20 @@ typedef enum {
attempted before the good old traditional PORT command. */ attempted before the good old traditional PORT command. */
CINIT(FTP_USE_EPRT, LONG, 106), CINIT(FTP_USE_EPRT, LONG, 106),
/* Set this to a bitmask value to enable the particular authentications
methods you like. Use this in combination with CURLOPT_USERPWD.
Note that setting multiple bits may cause extra network round-trips. */
CINIT(HTTPAUTH, LONG, 107),
/* Set the ssl context callback function, currently only for OpenSSL ssl_ctx
in second argument. The function must be matching the
curl_ssl_ctx_callback proto. */
CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108),
/* Set the userdata for the ssl context callback function's third
argument */
CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
CURLOPT_LASTENTRY /* the last unused */ CURLOPT_LASTENTRY /* the last unused */
} CURLoption; } CURLoption;
@@ -697,9 +737,9 @@ typedef enum {
#endif #endif
/* These functions are in the libcurl, they're here for portable reasons and /* These functions are in libcurl, they're here for portable reasons and they
they are used by the 'curl' client. They really should be moved to some kind are used by the 'curl' client. They really should be moved to some kind of
of "portability library" since it has nothing to do with file transfers and "portability library" since it has nothing to do with file transfers and
might be usable to other programs... might be usable to other programs...
NOTE: they return TRUE if the strings match *case insensitively*. NOTE: they return TRUE if the strings match *case insensitively*.
@@ -707,9 +747,12 @@ typedef enum {
extern int (curl_strequal)(const char *s1, const char *s2); extern int (curl_strequal)(const char *s1, const char *s2);
extern int (curl_strnequal)(const char *s1, const char *s2, size_t n); extern int (curl_strnequal)(const char *s1, const char *s2, size_t n);
/* DEPRECATED function to build formdata */ #ifdef CURL_OLDSTYLE
/* DEPRECATED function to build formdata. Stop using this, it will cease
to exist. */
int curl_formparse(char *, struct curl_httppost **, int curl_formparse(char *, struct curl_httppost **,
struct curl_httppost **_post); struct curl_httppost **_post);
#endif
/* name is uppercase CURLFORM_<name> */ /* name is uppercase CURLFORM_<name> */
#ifdef CFINIT #ifdef CFINIT
@@ -788,47 +831,122 @@ typedef enum {
CURL_FORMADD_LAST /* last */ CURL_FORMADD_LAST /* last */
} CURLFORMcode; } CURLFORMcode;
/*
* NAME curl_formadd()
*
* DESCRIPTION
*
* Pretty advanved function for building multi-part formposts. Each invoke
* adds one part that together construct a full post. Then use
* CURLOPT_HTTPPOST to send it off to libcurl.
*/
CURLFORMcode curl_formadd(struct curl_httppost **httppost, CURLFORMcode curl_formadd(struct curl_httppost **httppost,
struct curl_httppost **last_post, struct curl_httppost **last_post,
...); ...);
/* cleanup a form: */ /*
* NAME curl_formfree()
*
* DESCRIPTION
*
* Free a multipart formpost previously built with curl_formadd().
*/
void curl_formfree(struct curl_httppost *form); void curl_formfree(struct curl_httppost *form);
/* Unix and Win32 getenv function call, this returns a malloc()'ed string that /*
MUST be free()ed after usage is complete. */ * NAME curl_getenv()
*
* DESCRIPTION
*
* Returns a malloc()'ed string that MUST be curl_free()ed after usage is
* complete.
*/
char *curl_getenv(const char *variable); char *curl_getenv(const char *variable);
/* Returns a static ascii string of the libcurl version. */ /*
* NAME curl_version()
*
* DESCRIPTION
*
* Returns a static ascii string of the libcurl version.
*/
char *curl_version(void); char *curl_version(void);
/* Escape and unescape URL encoding in strings. The functions return a new /*
* allocated string or NULL if an error occurred. */ * NAME curl_escape()
*
* DESCRIPTION
*
* Escapes URL strings (converts all letters consider illegal in URLs to their
* %XX versions). This function returns a new allocated string or NULL if an
* error occurred.
*/
char *curl_escape(const char *string, int length); char *curl_escape(const char *string, int length);
/*
* NAME curl_unescape()
*
* DESCRIPTION
*
* Unescapes URL encoding in strings (converts all %XX codes to their 8bit
* versions). This function returns a new allocated string or NULL if an error
* occurred.
*/
char *curl_unescape(const char *string, int length); char *curl_unescape(const char *string, int length);
/* 20020912 WJM. Provide for a de-allocation in the same translation unit
that did the allocation. Added in libcurl 7.10 */ /*
* NAME curl_free()
*
* DESCRIPTION
*
* Provided for de-allocation in the same translation unit that did the
* allocation. Added in libcurl 7.10
*/
void curl_free(void *p); void curl_free(void *p);
/* curl_global_init() should be invoked exactly once for each application that /*
uses libcurl */ * NAME curl_global_init()
*
* DESCRIPTION
*
* curl_global_init() should be invoked exactly once for each application that
* uses libcurl
*/
CURLcode curl_global_init(long flags); CURLcode curl_global_init(long flags);
/* curl_global_cleanup() should be invoked exactly once for each application /*
that uses libcurl */ * NAME curl_global_cleanup()
*
* DESCRIPTION
*
* curl_global_cleanup() should be invoked exactly once for each application
* that uses libcurl
*/
void curl_global_cleanup(void); void curl_global_cleanup(void);
/* This is the version number */
#define LIBCURL_VERSION "7.10.5"
#define LIBCURL_VERSION_NUM 0x070a05
/* linked-list structure for the CURLOPT_QUOTE option (and other) */ /* linked-list structure for the CURLOPT_QUOTE option (and other) */
struct curl_slist { struct curl_slist {
char *data; char *data;
struct curl_slist *next; struct curl_slist *next;
}; };
/*
* NAME curl_slist_append()
*
* DESCRIPTION
*
* Appends a string to a linked list. If no list exists, it will be created
* first. Returns the new list, after appending.
*/
struct curl_slist *curl_slist_append(struct curl_slist *, const char *); struct curl_slist *curl_slist_append(struct curl_slist *, const char *);
/*
* NAME curl_slist_free_all()
*
* DESCRIPTION
*
* free a previously built curl_slist.
*/
void curl_slist_free_all(struct curl_slist *); void curl_slist_free_all(struct curl_slist *);
/* /*
@@ -996,8 +1114,18 @@ typedef struct {
#define CURL_VERSION_KERBEROS4 (1<<1) #define CURL_VERSION_KERBEROS4 (1<<1)
#define CURL_VERSION_SSL (1<<2) #define CURL_VERSION_SSL (1<<2)
#define CURL_VERSION_LIBZ (1<<3) #define CURL_VERSION_LIBZ (1<<3)
#define CURL_VERSION_NTLM (1<<4)
#define CURL_VERSION_GSSNEGOTIATE (1<<5)
#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */
/* returns a pointer to a static copy of the version info struct */ /*
* NAME curl_version_info()
*
* DESCRIPTION
*
* This function returns a pointer to a static copy of the version info
* struct. See above.
*/
curl_version_info_data *curl_version_info(CURLversion); curl_version_info_data *curl_version_info(CURLversion);
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -45,11 +45,23 @@
file descriptors simultaneous easily. file descriptors simultaneous easily.
*/ */
#if defined(_WIN32) && !defined(WIN32)
/* Chris Lewis mentioned that he doesn't get WIN32 defined, only _WIN32 so we
make this adjustment to catch this. */
#define WIN32 1
#endif
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <winsock.h> #include <winsock.h>
#else #else
#ifdef _AIX
/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
libc5-based Linux systems. Only include it on system that are known to
require it! */
#include <sys/select.h> #include <sys/select.h>
#endif
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>

View File

@@ -23,9 +23,7 @@
* $Id$ * $Id$
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#endif
size_t fread (void *, size_t, size_t, FILE *); size_t fread (void *, size_t, size_t, FILE *);
size_t fwrite (const void *, size_t, size_t, FILE *); size_t fwrite (const void *, size_t, size_t, FILE *);

View File

@@ -7,7 +7,8 @@ AUTOMAKE_OPTIONS = foreign nostdinc
EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32 \ EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32 \
Makefile.vc6 Makefile.riscos libcurl.def curllib.dsp \ Makefile.vc6 Makefile.riscos libcurl.def curllib.dsp \
curllib.dsw config-vms.h config-win32.h config-riscos.h config-mac.h \ curllib.dsw config-vms.h config-win32.h config-riscos.h config-mac.h \
config.h.in ca-bundle.crt README.encoding README.memoryleak config.h.in ca-bundle.crt README.encoding README.memoryleak \
makefile.dj config.dj
lib_LTLIBRARIES = libcurl.la lib_LTLIBRARIES = libcurl.la
@@ -66,16 +67,29 @@ getpass.c netrc.c telnet.h getinfo.c getinfo.h transfer.c strequal.c \
strequal.h easy.c security.h security.c krb4.c krb4.h memdebug.c \ strequal.h easy.c security.h security.c krb4.c krb4.h memdebug.c \
memdebug.h inet_ntoa_r.h http_chunks.c http_chunks.h strtok.c strtok.h \ memdebug.h inet_ntoa_r.h http_chunks.c http_chunks.h strtok.c strtok.h \
connect.c connect.h llist.c llist.h hash.c hash.h multi.c \ connect.c connect.h llist.c llist.h hash.c hash.h multi.c \
content_encoding.c content_encoding.h share.c share.h content_encoding.c content_encoding.h share.c share.h http_digest.c \
md5.c md5.h http_digest.h http_negotiate.c http_negotiate.h \
http_ntlm.c http_ntlm.h ca-bundle.h
noinst_HEADERS = setup.h transfer.h noinst_HEADERS = setup.h transfer.h
BUILT_SOURCES = $(srcdir)/getdate.c $(srcdir)/ca-bundle.h
# Say $(srcdir), so GNU make does not report an ambiguity with the .y.c rule. # Say $(srcdir), so GNU make does not report an ambiguity with the .y.c rule.
$(srcdir)/getdate.c: getdate.y $(srcdir)/getdate.c: getdate.y
cd $(srcdir) && \ cd $(srcdir) && \
$(YACC) $(YFLAGS) getdate.y; \ $(YACC) $(YFLAGS) getdate.y; \
mv -f y.tab.c getdate.c mv -f y.tab.c getdate.c
$(srcdir)/ca-bundle.h: Makefile.in Makefile
cd $(srcdir) && \
echo "/* The file is generated automaticly */" > $@
if CABUNDLE
echo '#define CURL_CA_BUNDLE @CURL_CA_BUNDLE@' >> $@
else
echo '#undef CURL_CA_BUNDLE /* unknown */' >> $@
endif
install-data-hook: install-data-hook:
@if test -n "@CURL_CA_BUNDLE@"; then \ @if test -n "@CURL_CA_BUNDLE@"; then \
$(mkinstalldirs) `dirname $(DESTDIR)@CURL_CA_BUNDLE@`; \ $(mkinstalldirs) `dirname $(DESTDIR)@CURL_CA_BUNDLE@`; \
@@ -85,4 +99,4 @@ install-data-hook:
# this hook is mainly for non-unix systems to build even if configure # this hook is mainly for non-unix systems to build even if configure
# isn't run # isn't run
dist-hook: dist-hook:
cp $(srcdir)/ca-bundle.h.in $(distdir)/ca-bundle.h echo "/* ca bundle path set in here*/" > $(distdir)/ca-bundle.h

View File

@@ -35,15 +35,19 @@ COMPILE = $(CC) $(INCLUDES) $(CFLAGS)
libcurl_a_LIBRARIES = libcurl.a libcurl_a_LIBRARIES = libcurl.a
libcurl_a_SOURCES = arpa_telnet.h file.c getpass.h netrc.h timeval.c base64.c \ libcurl_a_SOURCES = arpa_telnet.h file.c getpass.h netrc.h timeval.c base64.c \
file.h hostip.c progress.c timeval.h base64.h formdata.c hostip.h progress.h \ file.h hostip.c progress.c timeval.h base64.h formdata.c hostip.h \
cookie.c formdata.h http.c sendf.c cookie.h ftp.c http.h sendf.h url.c dict.c \ progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c \
ftp.h if2ip.c speedcheck.c url.h dict.h getdate.c if2ip.h speedcheck.h \ http.h sendf.h url.c dict.c ftp.h if2ip.c speedcheck.c url.h \
urldata.h transfer.c getdate.h ldap.c ssluse.c version.c transfer.h getenv.c \ dict.h getdate.c if2ip.h speedcheck.h urldata.h transfer.c getdate.h \
ldap.h ssluse.h escape.c getenv.h mprintf.c telnet.c escape.h getpass.c netrc.c \ ldap.c ssluse.c version.c transfer.h getenv.c \
telnet.h getinfo.c strequal.c strequal.h easy.c security.h \ ldap.h ssluse.h escape.c getenv.h mprintf.c telnet.c escape.h \
security.c krb4.h krb4.c memdebug.h memdebug.c inet_ntoa_r.h http_chunks.h http_chunks.c \ getpass.c netrc.c telnet.h getinfo.c strequal.c strequal.h easy.c \
strtok.c connect.c hash.c llist.c multi.c share.c share.h\ security.h security.c krb4.h krb4.c memdebug.h memdebug.c \
content_encoding.h content_encoding.c inet_ntoa_r.h http_chunks.h http_chunks.c \
strtok.c connect.c hash.c llist.c multi.c share.c share.h \
content_encoding.h content_encoding.c http_digest.h http_digest.c \
http_negotiate.c http_negotiate.h http_ntlm.c http_ntlm.h md5.h \
md5.c
libcurl_a_OBJECTS = file.o timeval.o base64.o hostip.o progress.o \ libcurl_a_OBJECTS = file.o timeval.o base64.o hostip.o progress.o \
formdata.o cookie.o http.o sendf.o ftp.o url.o dict.o if2ip.o \ formdata.o cookie.o http.o sendf.o ftp.o url.o dict.o if2ip.o \
@@ -51,7 +55,7 @@ libcurl_a_OBJECTS = file.o timeval.o base64.o hostip.o progress.o \
getenv.o escape.o mprintf.o telnet.o getpass.o netrc.o getinfo.o \ getenv.o escape.o mprintf.o telnet.o getpass.o netrc.o getinfo.o \
strequal.o easy.o security.o krb4.o memdebug.o http_chunks.o \ strequal.o easy.o security.o krb4.o memdebug.o http_chunks.o \
strtok.o connect.o hash.o llist.o multi.o share.o \ strtok.o connect.o hash.o llist.o multi.o share.o \
content_encoding.o content_encoding.o http_digest.o http_negotiate.o http_ntlm.o md5.o
LIBRARIES = $(libcurl_a_LIBRARIES) LIBRARIES = $(libcurl_a_LIBRARIES)
SOURCES = $(libcurl_a_SOURCES) SOURCES = $(libcurl_a_SOURCES)

View File

@@ -202,7 +202,9 @@ X_OBJS= \
$(DIROBJ)\hash.obj \ $(DIROBJ)\hash.obj \
$(DIROBJ)\llist.obj \ $(DIROBJ)\llist.obj \
$(DIROBJ)\share.obj \ $(DIROBJ)\share.obj \
$(DIROBJ)\multi.obj $(DIROBJ)\multi.obj \
$(DIROBJ)\http_digest.obj \
$(DIROBJ)\md5.obj
all : $(TARGET) all : $(TARGET)
@@ -224,3 +226,6 @@ clean:
-@erase $(DIROBJ)\*.obj -@erase $(DIROBJ)\*.obj
-@erase vc60.idb -@erase vc60.idb
-@erase vc60.pch -@erase vc60.pch
getdate.c: getdate.c.cvs
copy getdate.c.cvs getdate.c

View File

@@ -17,7 +17,7 @@ Single-threaded
Build Build
Rebuild libcurl with -DMALLOCDEBUG (usually, rerunning configure with Rebuild libcurl with -DCURLDEBUG (usually, rerunning configure with
--enable-debug fixes this). 'make clean' first, then 'make' so that all --enable-debug fixes this). 'make clean' first, then 'make' so that all
files actually are rebuilt properly. It will also make sense to build files actually are rebuilt properly. It will also make sense to build
libcurl with the debug option (usually -g to the compiler) so that debugging libcurl with the debug option (usually -g to the compiler) so that debugging

View File

@@ -42,7 +42,7 @@
#include "base64.h" #include "base64.h"
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif
@@ -220,6 +220,8 @@ int main(int argc, char **argv, char **envp)
#ifdef TEST_DECODE #ifdef TEST_DECODE
/* decoding test harness. Read in a base64 string from stdin and write out the /* decoding test harness. Read in a base64 string from stdin and write out the
* length returned by Curl_base64_decode, followed by the decoded data itself * length returned by Curl_base64_decode, followed by the decoded data itself
*
* gcc -DTEST_DECODE base64.c -o base64 mprintf.o memdebug.o
*/ */
#include <stdio.h> #include <stdio.h>
@@ -232,13 +234,31 @@ int main(int argc, char **argv, char **envp)
int base64Len; int base64Len;
unsigned char *data; unsigned char *data;
int dataLen; int dataLen;
int i, j;
base64 = (char *)suck(&base64Len); base64 = (char *)suck(&base64Len);
data = (unsigned char *)malloc(base64Len * 3/4 + 8); data = (unsigned char *)malloc(base64Len * 3/4 + 8);
dataLen = Curl_base64_decode(base64, data); dataLen = Curl_base64_decode(base64, data);
fprintf(stderr, "%d\n", dataLen); fprintf(stderr, "%d\n", dataLen);
fwrite(data,1,dataLen,stdout);
for(i=0; i < dataLen; i+=0x10) {
printf("0x%02x: ", i);
for(j=0; j < 0x10; j++)
if((j+i) < dataLen)
printf("%02x ", data[i+j]);
else
printf(" ");
printf(" | ");
for(j=0; j < 0x10; j++)
if((j+i) < dataLen)
printf("%c", isgraph(data[i+j])?data[i+j]:'.');
else
break;
puts("");
}
free(base64); free(data); free(base64); free(data);
return 0; return 0;

92
lib/config.dj Normal file
View File

@@ -0,0 +1,92 @@
#ifndef _CURL_CONFIG_DJGPP_H
#define _CURL_CONFIG_DJGPP_H
#define OS "djgpp"
#define PACKAGE "curl"
#define CURL_CA_BUNDLE "/dev/env/CURL_CA_BUNDLE"
#if (DJGPP_MINOR >= 4)
/* #define HAVE_DLOPEN 1 maybe not (DXE3) */
#endif
#if 1 /* use ioctlsocket() via fsext'ed fcntl() */
#define HAVE_O_NONBLOCK 1
#else
#define HAVE_IOCTLSOCKET 1
#endif
#define HAVE_ALARM 1
#define HAVE_ARPA_INET_H 1
#define HAVE_CLOSESOCKET 1
#define HAVE_FCNTL_H 1
#define HAVE_GETHOSTBYADDR 1
#define HAVE_GETHOSTNAME 1
#define HAVE_GETPASS 1
#define HAVE_GETSERVBYNAME 1
#define HAVE_GETTIMEOFDAY 1
#define HAVE_INET_ADDR 1
#define HAVE_INET_NTOA 1
#define HAVE_IO_H 1
#define HAVE_MALLOC_H 1
#define HAVE_MEMORY_H 1
#define HAVE_NETDB_H 1
#define HAVE_NETINET_IN_H 1
#define HAVE_NET_IF_H 1
#define HAVE_PERROR 1
#define HAVE_SELECT 1
#define HAVE_SETJMP_H 1
#define HAVE_SETVBUF 1
#define HAVE_SIGNAL 1
#define HAVE_SIGACTION 1
#define HAVE_SIGSETJMP 1
#define HAVE_SOCKET 1
#define HAVE_STRCASECMP 1
#define HAVE_STRDUP 1
#define HAVE_STRFTIME 1
#define HAVE_STRICMP 1
#define HAVE_STRSTR 1
#define HAVE_SYS_SOCKET_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_TERMIOS_H 1
#define HAVE_TIME_H 1
#define HAVE_UNAME 1
#define HAVE_UNISTD_H 1
#define HAVE_VPRINTF 1
#define RETSIGTYPE void
#define SIZEOF_LONG_DOUBLE 16
#define SIZEOF_LONG_LONG 8
#define STDC_HEADERS 1
#define TIME_WITH_SYS_TIME 1
#define BSD
#define USE_ZLIB
/* #define MALLOCDEBUG */
#ifdef HAVE_OPENSSL_ENGINE_H /* on cmd-line */
#define HAVE_OPENSSL_X509_H 1
#define HAVE_OPENSSL_SSL_H 1
#define HAVE_OPENSSL_RSA_H 1
#define HAVE_OPENSSL_PEM_H 1
#define HAVE_OPENSSL_ERR_H 1
#define HAVE_OPENSSL_CRYPTO_H 1
#define HAVE_LIBSSL 1
#define HAVE_LIBCRYPTO 1
#define OPENSSL_NO_KRB5 1
#endif
#define in_addr_t u_long
#define socklen_t int
#define ssize_t int
#include <stdlib.h>
#include <string.h>
#include <tcp.h> /* Watt-32 API */
#undef word
#endif /* _CURL_CONFIG_DJGPP_H */

View File

@@ -77,7 +77,7 @@
#include "if2ip.h" #include "if2ip.h"
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif

View File

@@ -92,7 +92,7 @@ Example set of cookies:
#include "strtok.h" #include "strtok.h"
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif

View File

@@ -389,6 +389,22 @@ SOURCE=.\url.h
SOURCE=.\urldata.h SOURCE=.\urldata.h
# End Source File # End Source File
# Begin Source File
SOURCE=.\http_digest.c
# End Source File
# Begin Source File
SOURCE=.\md5.c
# End Source File
# Begin Source File
SOURCE=.\http_digest.h
# End Source File
# Begin Source File
SOURCE=.\md5.h
# End Source File
# End Group # End Group
# Begin Group "Resource Files" # Begin Group "Resource Files"

View File

@@ -44,7 +44,6 @@
#endif #endif
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif

View File

@@ -46,7 +46,6 @@
#endif #endif
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif

View File

@@ -33,7 +33,7 @@
#include <string.h> #include <string.h>
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif
@@ -79,6 +79,10 @@ char *curl_escape(const char *string, int length)
return ns; return ns;
} }
#define ishex(in) ((in >= 'a' && in <= 'f') || \
(in >= 'A' && in <= 'F') || \
(in >= '0' && in <= '9'))
char *curl_unescape(const char *string, int length) char *curl_unescape(const char *string, int length)
{ {
int alloc = (length?length:(int)strlen(string))+1; int alloc = (length?length:(int)strlen(string))+1;
@@ -93,14 +97,20 @@ char *curl_unescape(const char *string, int length)
while(--alloc > 0) { while(--alloc > 0) {
in = *string; in = *string;
if('%' == in) { if(('%' == in) && ishex(string[1]) && ishex(string[2])) {
/* encoded part */ /* this is two hexadecimal digits following a '%' */
if(sscanf(string+1, "%02X", &hex)) { char hexstr[3];
char *ptr;
hexstr[0] = string[1];
hexstr[1] = string[2];
hexstr[2] = 0;
hex = strtol(hexstr, &ptr, 16);
in = hex; in = hex;
string+=2; string+=2;
alloc-=2; alloc-=2;
} }
}
ns[index++] = in; ns[index++] = in;
string++; string++;
@@ -109,6 +119,9 @@ char *curl_unescape(const char *string, int length)
return ns; return ns;
} }
/* For operating systems/environments that use different malloc/free
ssystems for the app and for this library, we provide a free that uses
the library's memory system */
void curl_free(void *p) void curl_free(void *p)
{ {
free(p); free(p);

View File

@@ -48,7 +48,6 @@
#include <netinet/in.h> #include <netinet/in.h>
#endif #endif
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
@@ -88,7 +87,7 @@
#include <curl/mprintf.h> #include <curl/mprintf.h>
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif

View File

@@ -124,7 +124,7 @@ Content-Disposition: form-data; name="FILECONTENT"
#include "strequal.h" #include "strequal.h"
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif

View File

@@ -94,7 +94,7 @@
#include <curl/mprintf.h> #include <curl/mprintf.h>
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif
@@ -409,9 +409,9 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
/* get some initial data into the ftp struct */ /* get some initial data into the ftp struct */
ftp->bytecountp = &conn->bytecount; ftp->bytecountp = &conn->bytecount;
/* no need to duplicate them, the data struct won't change */ /* no need to duplicate them, this connectdata struct won't change */
ftp->user = data->state.user; ftp->user = conn->user;
ftp->passwd = data->state.passwd; ftp->passwd = conn->passwd;
ftp->response_time = 3600; /* set default response time-out */ ftp->response_time = 3600; /* set default response time-out */
if (data->set.tunnel_thru_httpproxy) { if (data->set.tunnel_thru_httpproxy) {
@@ -512,7 +512,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
/* we may need to issue a KAUTH here to have access to the files /* we may need to issue a KAUTH here to have access to the files
* do it if user supplied a password * do it if user supplied a password
*/ */
if(data->state.passwd && *data->state.passwd) { if(conn->passwd && *conn->passwd) {
result = Curl_krb_kauth(conn); result = Curl_krb_kauth(conn);
if(result) if(result)
return result; return result;
@@ -1184,7 +1184,6 @@ CURLcode ftp_use_port(struct connectdata *conn)
return result; return result;
if (ftpcode != 200) { if (ftpcode != 200) {
failf(data, "Server does not grok %s", *modep);
continue; continue;
} }
else else
@@ -1193,6 +1192,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
if (!*modep) { if (!*modep) {
sclose(portsock); sclose(portsock);
failf(data, "PORT command attempts failed");
return CURLE_FTP_PORT_FAILED; return CURLE_FTP_PORT_FAILED;
} }
/* we set the secondary socket variable to this for now, it /* we set the secondary socket variable to this for now, it
@@ -1930,10 +1930,16 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
if(result) if(result)
return result; return result;
} }
else {
if(dirlist && (ftpcode == 450)) {
/* simply no matching files */
ftp->no_transfer = TRUE; /* don't think we should download anything */
}
else { else {
failf(data, "%s", buf+4); failf(data, "%s", buf+4);
return CURLE_FTP_COULDNT_RETR_FILE; return CURLE_FTP_COULDNT_RETR_FILE;
} }
}
} }
/* end of transfer */ /* end of transfer */
@@ -2055,7 +2061,7 @@ CURLcode ftp_perform(struct connectdata *conn,
struct tm buffer; struct tm buffer;
tm = (struct tm *)localtime_r(&data->info.filetime, &buffer); tm = (struct tm *)localtime_r(&data->info.filetime, &buffer);
#else #else
tm = localtime((unsigned long *)&data->info.filetime); tm = localtime(&data->info.filetime);
#endif #endif
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
strftime(buf, BUFSIZE-1, "Last-Modified: %a, %d %b %Y %H:%M:%S GMT\r\n", strftime(buf, BUFSIZE-1, "Last-Modified: %a, %d %b %Y %H:%M:%S GMT\r\n",
@@ -2128,17 +2134,28 @@ CURLcode Curl_ftp(struct connectdata *conn)
/* parse the URL path into separate path components */ /* parse the URL path into separate path components */
while((slash_pos=strchr(cur_pos, '/'))) { while((slash_pos=strchr(cur_pos, '/'))) {
/* 1 or 0 to indicate absolute directory */
bool absolute_dir = (cur_pos - conn->ppath > 0) && (path_part == 0);
/* seek out the next path component */ /* seek out the next path component */
if (0 == slash_pos-cur_pos) /* empty path component, like "x//y" */ if (slash_pos-cur_pos) {
ftp->dirs[path_part] = strdup(""); /* empty string */ /* we skip empty path components, like "x//y" since the FTP command CWD
else requires a parameter and a non-existant parameter a) doesn't work on
ftp->dirs[path_part] = curl_unescape(cur_pos,slash_pos-cur_pos); many servers and b) has no effect on the others. */
ftp->dirs[path_part] = curl_unescape(cur_pos - absolute_dir,
slash_pos - cur_pos + absolute_dir);
if (!ftp->dirs[path_part]) { /* run out of memory ... */ if (!ftp->dirs[path_part]) { /* run out of memory ... */
failf(data, "no memory"); failf(data, "no memory");
retcode = CURLE_OUT_OF_MEMORY; retcode = CURLE_OUT_OF_MEMORY;
} }
}
else { else {
cur_pos = slash_pos + 1; /* jump to the rest of the string */
continue;
}
if(!retcode) {
cur_pos = slash_pos + 1; /* jump to the rest of the string */ cur_pos = slash_pos + 1; /* jump to the rest of the string */
if(++path_part >= (CURL_MAX_FTP_DIRDEPTH-1)) { if(++path_part >= (CURL_MAX_FTP_DIRDEPTH-1)) {
/* too deep, we need the last entry to be kept NULL at all /* too deep, we need the last entry to be kept NULL at all
@@ -2180,17 +2197,20 @@ CURLcode Curl_ftp(struct connectdata *conn)
if(CURLE_OK == retcode) { if(CURLE_OK == retcode) {
if(connected) if(connected)
retcode = Curl_ftp_nextconnect(conn); retcode = Curl_ftp_nextconnect(conn);
else {
if(ftp->no_transfer) { if(retcode && (conn->secondarysocket >= 0)) {
/* Failure detected, close the second socket if it was created already */
sclose(conn->secondarysocket);
conn->secondarysocket = -1;
}
if(ftp->no_transfer)
/* no data to transfer */ /* no data to transfer */
retcode=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); retcode=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
} else if(!connected)
else {
/* since we didn't connect now, we want do_more to get called */ /* since we didn't connect now, we want do_more to get called */
conn->bits.do_more = TRUE; conn->bits.do_more = TRUE;
} }
}
}
return retcode; return retcode;
} }

View File

@@ -35,7 +35,7 @@
#include <unixlib.h> #include <unixlib.h>
#endif #endif
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif

View File

@@ -36,7 +36,7 @@
#endif #endif
/* Make this the last #include */ /* Make this the last #include */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#else #else
#include <stdlib.h> #include <stdlib.h>

View File

@@ -89,7 +89,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
#endif #endif
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif
@@ -99,7 +99,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
char infp_fclose = 0; char infp_fclose = 0;
FILE *outfp; FILE *outfp;
RETSIGTYPE (*sigint)(); RETSIGTYPE (*sigint)();
#ifndef __EMX__ #ifdef SIGTSTP
RETSIGTYPE (*sigtstp)(); RETSIGTYPE (*sigtstp)();
#endif #endif
size_t bytes_read; size_t bytes_read;
@@ -117,9 +117,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
#endif #endif
sigint = signal(SIGINT, SIG_IGN); sigint = signal(SIGINT, SIG_IGN);
/* 20000318 mgs #ifdef SIGTSTP
* this is needed by the emx system, SIGTSTP is not a supported signal */
#ifndef __EMX__
sigtstp = signal(SIGTSTP, SIG_IGN); sigtstp = signal(SIGTSTP, SIG_IGN);
#endif #endif
@@ -181,7 +179,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
#endif #endif
signal(SIGINT, sigint); signal(SIGINT, sigint);
#ifndef __EMX__ #ifdef SIGTSTP
signal(SIGTSTP, sigtstp); signal(SIGTSTP, sigtstp);
#endif #endif

View File

@@ -29,7 +29,7 @@
#include "hash.h" #include "hash.h"
#include "llist.h" #include "llist.h"
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
/* this must be the last include file */ /* this must be the last include file */
#include "memdebug.h" #include "memdebug.h"
#endif #endif

View File

@@ -74,7 +74,7 @@
#endif #endif
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif
@@ -192,7 +192,7 @@ hostcache_prune(curl_hash *hostcache, int cache_timeout, int now)
hostcache_timestamp_remove); hostcache_timestamp_remove);
} }
#if defined(MALLOCDEBUG) && defined(AGGRESIVE_TEST) #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
/* Called from Curl_done() to check that there's no DNS cache entry with /* Called from Curl_done() to check that there's no DNS cache entry with
a non-zero counter left. */ a non-zero counter left. */
void Curl_scan_cache_used(void *user, void *ptr) void Curl_scan_cache_used(void *user, void *ptr)
@@ -252,9 +252,7 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
return NULL; return NULL;
if(data->share) if(data->share)
{
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
}
/* See if its already in our dns cache */ /* See if its already in our dns cache */
dns = Curl_hash_pick(data->hostcache, entry_id, entry_len+1); dns = Curl_hash_pick(data->hostcache, entry_id, entry_len+1);
@@ -282,7 +280,7 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
dns->timestamp = now; dns->timestamp = now;
dns->inuse++; /* mark entry as in-use */ dns->inuse++; /* mark entry as in-use */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
dns->entry_id = entry_id; dns->entry_id = entry_id;
#endif #endif
@@ -297,14 +295,13 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns) void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
{ {
if(data->share) if(data->share)
{
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
}
dns->inuse--; dns->inuse--;
if(data->share) if(data->share)
{
Curl_share_unlock(data, CURL_LOCK_DATA_DNS); Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
}
} }
/* /*
@@ -337,7 +334,7 @@ void Curl_freednsinfo(void *freethis)
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
/* These two are strictly for memory tracing and are using the same /* These two are strictly for memory tracing and are using the same
* style as the family otherwise present in memdebug.c. I put these ones * style as the family otherwise present in memdebug.c. I put these ones
* here since they require a bunch of struct types I didn't wanna include * here since they require a bunch of struct types I didn't wanna include
@@ -455,18 +452,22 @@ static struct hostent* pack_hostent(char** buf, struct hostent* orig)
copy->h_aliases = (char**)bufptr; copy->h_aliases = (char**)bufptr;
/* Figure out how many aliases there are */ /* Figure out how many aliases there are */
for (i = 0; orig->h_aliases[i] != NULL; ++i); for (i = 0; orig->h_aliases && orig->h_aliases[i]; ++i);
/* Reserve room for the array */ /* Reserve room for the array */
bufptr += (i + 1) * sizeof(char*); bufptr += (i + 1) * sizeof(char*);
/* Clone all known aliases */ /* Clone all known aliases */
if(orig->h_aliases) {
for(i = 0; (str = orig->h_aliases[i]); i++) { for(i = 0; (str = orig->h_aliases[i]); i++) {
len = strlen(str) + 1; len = strlen(str) + 1;
strncpy(bufptr, str, len); strncpy(bufptr, str, len);
copy->h_aliases[i] = bufptr; copy->h_aliases[i] = bufptr;
bufptr += len; bufptr += len;
} }
}
/* if(!orig->h_aliases) i was already set to 0 */
/* Terminate the alias list with a NULL */ /* Terminate the alias list with a NULL */
copy->h_aliases[i] = NULL; copy->h_aliases[i] = NULL;
@@ -627,7 +628,7 @@ static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
step_size+=200; step_size+=200;
} }
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
infof(data, "gethostbyname_r() uses %d bytes\n", step_size); infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
#endif #endif
@@ -677,7 +678,7 @@ static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
if(!h) /* failure */ if(!h) /* failure */
res=1; res=1;
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
infof(data, "gethostbyname_r() uses %d bytes\n", step_size); infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
#endif #endif
if(!res) { if(!res) {

View File

@@ -41,7 +41,7 @@ struct Curl_dns_entry {
time_t timestamp; time_t timestamp;
long inuse; /* use-counter, make very sure you decrease this long inuse; /* use-counter, make very sure you decrease this
when you're done using the address you received */ when you're done using the address you received */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
char *entry_id; char *entry_id;
#endif #endif
}; };
@@ -70,7 +70,7 @@ void Curl_freeaddrinfo(Curl_addrinfo *freeaddr);
/* free cached name info */ /* free cached name info */
void Curl_freednsinfo(void *freethis); void Curl_freednsinfo(void *freethis);
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
void curl_freeaddrinfo(struct addrinfo *freethis, void curl_freeaddrinfo(struct addrinfo *freethis,
int line, const char *source); int line, const char *source);
int curl_getaddrinfo(char *hostname, char *service, int curl_getaddrinfo(char *hostname, char *service,

View File

@@ -54,7 +54,6 @@
#endif #endif
#endif #endif
#include <sys/resource.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
@@ -89,12 +88,15 @@
#include "cookie.h" #include "cookie.h"
#include "strequal.h" #include "strequal.h"
#include "ssluse.h" #include "ssluse.h"
#include "http_digest.h"
#include "http_ntlm.h"
#include "http_negotiate.h"
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif
@@ -190,6 +192,7 @@ CURLcode add_buffer_send(send_buffer *in,
char *ptr; char *ptr;
int size; int size;
struct HTTP *http = conn->proto.http; struct HTTP *http = conn->proto.http;
int sendsize;
/* The looping below is required since we use non-blocking sockets, but due /* The looping below is required since we use non-blocking sockets, but due
to the circumstances we will just loop and try again and again etc */ to the circumstances we will just loop and try again and again etc */
@@ -197,7 +200,28 @@ CURLcode add_buffer_send(send_buffer *in,
ptr = in->buffer; ptr = in->buffer;
size = in->size_used; size = in->size_used;
res = Curl_write(conn, sockfd, ptr, size, &amount); if(conn->protocol & PROT_HTTPS) {
/* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
when we speak HTTPS, as if only a fraction of it is sent now, this data
needs to fit into the normal read-callback buffer later on and that
buffer is using this size.
*/
sendsize= (size > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:size;
/* OpenSSL is very picky and we must send the SAME buffer pointer to the
library when we attempt to re-send this buffer. Sending the same data
is not enough, we must use the exact same address. For this reason, we
must copy the data to the uploadbuffer first, since that is the buffer
we will be using if this send is retried later.
*/
memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
ptr = conn->data->state.uploadbuffer;
}
else
sendsize = size;
res = Curl_write(conn, sockfd, ptr, sendsize, &amount);
if(CURLE_OK == res) { if(CURLE_OK == res) {
@@ -213,7 +237,8 @@ CURLcode add_buffer_send(send_buffer *in,
and wait until it might work again. */ and wait until it might work again. */
size -= amount; size -= amount;
ptr += amount;
ptr = in->buffer + amount;
/* backup the currently set pointers */ /* backup the currently set pointers */
http->backup.fread = conn->fread; http->backup.fread = conn->fread;
@@ -591,11 +616,15 @@ CURLcode Curl_http_done(struct connectdata *conn)
conn->fread = data->set.fread; /* restore */ conn->fread = data->set.fread; /* restore */
conn->fread_in = data->set.in; /* restore */ conn->fread_in = data->set.in; /* restore */
if (http == NULL)
return CURLE_OK;
if(http->send_buffer) { if(http->send_buffer) {
send_buffer *buff = http->send_buffer; send_buffer *buff = http->send_buffer;
free(buff->buffer); free(buff->buffer);
free(buff); free(buff);
http->send_buffer = NULL; /* cleaer the pointer */
} }
if(HTTPREQ_POST_FORM == data->set.httpreq) { if(HTTPREQ_POST_FORM == data->set.httpreq) {
@@ -616,6 +645,25 @@ CURLcode Curl_http_done(struct connectdata *conn)
return CURLE_OK; return CURLE_OK;
} }
static CURLcode Curl_output_basic(struct connectdata *conn)
{
char *authorization;
struct SessionHandle *data=conn->data;
sprintf(data->state.buffer, "%s:%s", conn->user, conn->passwd);
if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
&authorization) >= 0) {
if(conn->allocptr.userpwd)
free(conn->allocptr.userpwd);
conn->allocptr.userpwd = aprintf( "Authorization: Basic %s\015\012",
authorization);
free(authorization);
}
else
return CURLE_OUT_OF_MEMORY;
return CURLE_OK;
}
CURLcode Curl_http(struct connectdata *conn) CURLcode Curl_http(struct connectdata *conn)
{ {
struct SessionHandle *data=conn->data; struct SessionHandle *data=conn->data;
@@ -627,6 +675,7 @@ CURLcode Curl_http(struct connectdata *conn)
char *host = conn->name; char *host = conn->name;
const char *te = ""; /* tranfer-encoding */ const char *te = ""; /* tranfer-encoding */
char *ptr; char *ptr;
char *request;
if(!conn->proto.http) { if(!conn->proto.http) {
/* Only allocate this struct if we don't already have it! */ /* Only allocate this struct if we don't already have it! */
@@ -648,6 +697,13 @@ CURLcode Curl_http(struct connectdata *conn)
data->set.httpreq = HTTPREQ_PUT; data->set.httpreq = HTTPREQ_PUT;
} }
request = data->set.customrequest?
data->set.customrequest:
(data->set.no_body?(char *)"HEAD":
((HTTPREQ_POST == data->set.httpreq) ||
(HTTPREQ_POST_FORM == data->set.httpreq))?(char *)"POST":
(HTTPREQ_PUT == data->set.httpreq)?(char *)"PUT":(char *)"GET");
/* The User-Agent string has been built in url.c already, because it might /* The User-Agent string has been built in url.c already, because it might
have been used in the proxy connect, but if we have got a header with have been used in the proxy connect, but if we have got a header with
the user-agent string specified, we erase the previously made string the user-agent string specified, we erase the previously made string
@@ -657,27 +713,50 @@ CURLcode Curl_http(struct connectdata *conn)
conn->allocptr.uagent=NULL; conn->allocptr.uagent=NULL;
} }
if((conn->bits.user_passwd) && !checkheaders(data, "Authorization:")) {
char *authorization;
/* To prevent the user+password to get sent to other than the original /* To prevent the user+password to get sent to other than the original
host due to a location-follow, we do some weirdo checks here */ host due to a location-follow, we do some weirdo checks here */
if(!data->state.this_is_a_follow || if(!data->state.this_is_a_follow ||
!data->state.auth_host || !data->state.auth_host ||
curl_strequal(data->state.auth_host, conn->hostname) || curl_strequal(data->state.auth_host, conn->hostname) ||
data->set.http_disable_hostname_check_before_authentication) { data->set.http_disable_hostname_check_before_authentication) {
sprintf(data->state.buffer, "%s:%s",
data->state.user, data->state.passwd); #ifdef GSSAPI
if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer), if((data->state.authwant == CURLAUTH_GSSNEGOTIATE) &&
&authorization) >= 0) { data->state.negotiate.context &&
if(conn->allocptr.userpwd) !GSS_ERROR(data->state.negotiate.status)) {
free(conn->allocptr.userpwd); result = Curl_output_negotiate(conn);
conn->allocptr.userpwd = aprintf( "Authorization: Basic %s\015\012", if (result)
authorization); return result;
free(authorization); }
else
#endif
#ifdef USE_SSLEAY
if(data->state.authwant == CURLAUTH_NTLM) {
result = Curl_output_ntlm(conn, FALSE);
if(result)
return result;
}
else
#endif
{
if((data->state.authwant == CURLAUTH_DIGEST) &&
data->state.digest.nonce) {
result = Curl_output_digest(conn,
(unsigned char *)request,
(unsigned char *)ppath);
if(result)
return result;
}
else if((data->state.authwant == CURLAUTH_BASIC) && /* Basic */
conn->bits.user_passwd &&
!checkheaders(data, "Authorization:")) {
result = Curl_output_basic(conn);
if(result)
return result;
} }
} }
} }
if((data->change.referer) && !checkheaders(data, "Referer:")) { if((data->change.referer) && !checkheaders(data, "Referer:")) {
if(conn->allocptr.ref) if(conn->allocptr.ref)
free(conn->allocptr.ref); free(conn->allocptr.ref);
@@ -773,7 +852,7 @@ CURLcode Curl_http(struct connectdata *conn)
(bool)(conn->protocol&PROT_HTTPS?TRUE:FALSE)); (bool)(conn->protocol&PROT_HTTPS?TRUE:FALSE));
} }
if (data->change.proxy && *data->change.proxy && if (conn->bits.httpproxy &&
!data->set.tunnel_thru_httpproxy && !data->set.tunnel_thru_httpproxy &&
!(conn->protocol&PROT_HTTPS)) { !(conn->protocol&PROT_HTTPS)) {
/* The path sent to the proxy is in fact the entire URL */ /* The path sent to the proxy is in fact the entire URL */
@@ -888,13 +967,14 @@ CURLcode Curl_http(struct connectdata *conn)
} }
} }
do { {
/* Use 1.1 unless the use specificly asked for 1.0 */ /* Use 1.1 unless the use specificly asked for 1.0 */
const char *httpstring= const char *httpstring=
data->set.httpversion==CURL_HTTP_VERSION_1_0?"1.0":"1.1"; data->set.httpversion==CURL_HTTP_VERSION_1_0?"1.0":"1.1";
send_buffer *req_buffer; send_buffer *req_buffer;
struct curl_slist *headers=data->set.headers; struct curl_slist *headers=data->set.headers;
size_t postsize;
/* initialize a dynamic send-buffer */ /* initialize a dynamic send-buffer */
req_buffer = add_buffer_init(); req_buffer = add_buffer_init();
@@ -902,7 +982,7 @@ CURLcode Curl_http(struct connectdata *conn)
/* add the main request stuff */ /* add the main request stuff */
add_bufferf(req_buffer, add_bufferf(req_buffer,
"%s " /* GET/HEAD/POST/PUT */ "%s " /* GET/HEAD/POST/PUT */
"%s HTTP/%s\r\n" /* path */ "%s HTTP/%s\r\n" /* path + HTTP version */
"%s" /* proxyuserpwd */ "%s" /* proxyuserpwd */
"%s" /* userpwd */ "%s" /* userpwd */
"%s" /* range */ "%s" /* range */
@@ -915,16 +995,12 @@ CURLcode Curl_http(struct connectdata *conn)
"%s" /* referer */ "%s" /* referer */
"%s",/* transfer-encoding */ "%s",/* transfer-encoding */
data->set.customrequest?data->set.customrequest: request,
(data->set.no_body?"HEAD": ppath,
((HTTPREQ_POST == data->set.httpreq) || httpstring,
(HTTPREQ_POST_FORM == data->set.httpreq))?"POST": (conn->bits.httpproxy && conn->allocptr.proxyuserpwd)?
(HTTPREQ_PUT == data->set.httpreq)?"PUT":"GET"), conn->allocptr.proxyuserpwd:"",
ppath, httpstring, conn->allocptr.userpwd?conn->allocptr.userpwd:"",
(conn->bits.proxy_user_passwd &&
conn->allocptr.proxyuserpwd)?conn->allocptr.proxyuserpwd:"",
(conn->bits.user_passwd && conn->allocptr.userpwd)?
conn->allocptr.userpwd:"",
(conn->bits.use_range && conn->allocptr.rangeline)? (conn->bits.use_range && conn->allocptr.rangeline)?
conn->allocptr.rangeline:"", conn->allocptr.rangeline:"",
(data->set.useragent && *data->set.useragent && conn->allocptr.uagent)? (data->set.useragent && *data->set.useragent && conn->allocptr.uagent)?
@@ -1132,6 +1208,11 @@ CURLcode Curl_http(struct connectdata *conn)
case HTTPREQ_POST: case HTTPREQ_POST:
/* this is the simple POST, using x-www-form-urlencoded style */ /* this is the simple POST, using x-www-form-urlencoded style */
/* store the size of the postfields */
postsize = data->set.postfieldsize?
data->set.postfieldsize:
(data->set.postfields?strlen(data->set.postfields):0);
if(!conn->bits.upload_chunky) { if(!conn->bits.upload_chunky) {
/* We only set Content-Length and allow a custom Content-Length if /* We only set Content-Length and allow a custom Content-Length if
we don't upload data chunked, as RFC2616 forbids us to set both we don't upload data chunked, as RFC2616 forbids us to set both
@@ -1140,11 +1221,7 @@ CURLcode Curl_http(struct connectdata *conn)
if(!checkheaders(data, "Content-Length:")) if(!checkheaders(data, "Content-Length:"))
/* we allow replacing this header, although it isn't very wise to /* we allow replacing this header, although it isn't very wise to
actually set your own */ actually set your own */
add_bufferf(req_buffer, add_bufferf(req_buffer, "Content-Length: %d\r\n", postsize);
"Content-Length: %d\r\n",
data->set.postfieldsize?
data->set.postfieldsize:
(data->set.postfields?strlen(data->set.postfields):0) );
} }
if(!checkheaders(data, "Content-Type:")) if(!checkheaders(data, "Content-Type:"))
@@ -1153,12 +1230,28 @@ CURLcode Curl_http(struct connectdata *conn)
add_buffer(req_buffer, "\r\n", 2); add_buffer(req_buffer, "\r\n", 2);
/* and here we setup the pointers to the actual data */
if(data->set.postfields) { if(data->set.postfields) {
if(data->set.postfieldsize)
http->postsize = data->set.postfieldsize; if(postsize < (100*1024)) {
else /* The post data is less than 100K, then append it to the header.
http->postsize = strlen(data->set.postfields); This limit is no magic limit but only set to prevent really huge
POSTs to get the data duplicated with malloc() and family. */
if(!conn->bits.upload_chunky)
/* We're not sending it 'chunked', append it to the request
already now to reduce the number if send() calls */
add_buffer(req_buffer, data->set.postfields, postsize);
else {
/* Append the POST data chunky-style */
add_bufferf(req_buffer, "%x\r\n", postsize);
add_buffer(req_buffer, data->set.postfields, postsize);
add_buffer(req_buffer, "\r\n0\r\n", 5); /* end of a chunked
transfer stream */
}
}
else {
/* A huge POST coming up, do data separate from the request */
http->postsize = postsize;
http->postdata = data->set.postfields; http->postdata = data->set.postfields;
http->sending = HTTPSEND_BODY; http->sending = HTTPSEND_BODY;
@@ -1169,6 +1262,7 @@ CURLcode Curl_http(struct connectdata *conn)
/* set the upload size to the progress meter */ /* set the upload size to the progress meter */
Curl_pgrsSetUploadSize(data, http->postsize); Curl_pgrsSetUploadSize(data, http->postsize);
} }
}
else else
/* set the upload size to the progress meter */ /* set the upload size to the progress meter */
Curl_pgrsSetUploadSize(data, data->set.infilesize); Curl_pgrsSetUploadSize(data, data->set.infilesize);
@@ -1183,8 +1277,8 @@ CURLcode Curl_http(struct connectdata *conn)
result = result =
Curl_Transfer(conn, conn->firstsocket, -1, TRUE, Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
&http->readbytecount, &http->readbytecount,
conn->firstsocket, http->postdata?conn->firstsocket:-1,
&http->writebytecount); http->postdata?&http->writebytecount:NULL);
break; break;
default: default:
@@ -1205,8 +1299,7 @@ CURLcode Curl_http(struct connectdata *conn)
} }
if(result) if(result)
return result; return result;
} while (0); /* this is just a left-over from the multiple document download }
attempts */
return CURLE_OK; return CURLE_OK;
} }

View File

@@ -39,7 +39,7 @@
#include <curl/mprintf.h> #include <curl/mprintf.h>
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif

231
lib/http_digest.c Normal file
View File

@@ -0,0 +1,231 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#include "setup.h"
#ifndef CURL_DISABLE_HTTP
/* -- WIN32 approved -- */
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#include "urldata.h"
#include "sendf.h"
#include "strequal.h"
#include "md5.h"
#include "http_digest.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
/* The last #include file should be: */
#ifdef CURLDEBUG
#include "memdebug.h"
#endif
/* Test example header:
WWW-Authenticate: Digest realm="testrealm", nonce="1053604598"
*/
CURLdigest Curl_input_digest(struct connectdata *conn,
char *header) /* rest of the www-authenticate:
header */
{
bool more = TRUE;
struct SessionHandle *data=conn->data;
/* skip initial whitespaces */
while(*header && isspace((int)*header))
header++;
if(checkprefix("Digest", header)) {
header += strlen("Digest");
/* clear off any former leftovers and init to defaults */
Curl_digest_cleanup(data);
while(more) {
char value[32];
char content[128];
int totlen=0;
while(*header && isspace((int)*header))
header++;
/* how big can these strings be? */
if(2 == sscanf(header, "%31[^=]=\"%127[^\"]\"",
value, content)) {
if(strequal(value, "nonce")) {
data->state.digest.nonce = strdup(content);
}
else if(strequal(value, "cnonce")) {
data->state.digest.cnonce = strdup(content);
}
else if(strequal(value, "realm")) {
data->state.digest.realm = strdup(content);
}
else if(strequal(value, "algorithm")) {
if(strequal(content, "MD5-sess"))
data->state.digest.algo = CURLDIGESTALGO_MD5SESS;
/* else, remain using the default md5 */
}
else {
/* unknown specifier, ignore it! */
}
totlen = strlen(value)+strlen(content)+3;
}
else
break; /* we're done here */
header += totlen;
if(',' == *header)
/* allow the list to be comma-separated */
header++;
}
if(!data->state.digest.nonce)
return CURLDIGEST_BAD;
}
else
/* else not a digest, get out */
return CURLDIGEST_NONE;
return CURLDIGEST_FINE;
}
/* convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/
static void md5_to_ascii(unsigned char *source, /* 16 bytes */
unsigned char *dest) /* 33 bytes */
{
int i;
for(i=0; i<16; i++)
sprintf((char *)&dest[i*2], "%02x", source[i]);
}
CURLcode Curl_output_digest(struct connectdata *conn,
unsigned char *request,
unsigned char *uripath)
{
/* We have a Digest setup for this, use it!
Now, to get all the details for this sorted out, I must urge you dear friend
to read up on the RFC2617 section 3.2.2, */
unsigned char md5buf[16]; /* 16 bytes/128 bits */
unsigned char ha1[33]; /* 32 digits and 1 zero byte */
unsigned char ha2[33];
unsigned char request_digest[33];
unsigned char *md5this;
struct SessionHandle *data = conn->data;
/*
if the algorithm is "MD5" or unspecified (which then defaults to MD5):
A1 = unq(username-value) ":" unq(realm-value) ":" passwd
if the algorithm is "MD5-sess" then:
A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd )
":" unq(nonce-value) ":" unq(cnonce-value)
*/
if(data->state.digest.algo == CURLDIGESTALGO_MD5SESS) {
md5this = (unsigned char *)
aprintf("%s:%s:%s:%s:%s",
conn->user,
data->state.digest.realm,
conn->passwd,
data->state.digest.nonce,
data->state.digest.cnonce);
}
else {
md5this = (unsigned char *)
aprintf("%s:%s:%s",
conn->user,
data->state.digest.realm,
conn->passwd);
}
Curl_md5it(md5buf, md5this);
free(md5this); /* free this again */
md5_to_ascii(md5buf, ha1);
/*
A2 = Method ":" digest-uri-value
(The "Method" value is the HTTP request method as specified in section
5.1.1 of RFC 2616)
*/
md5this = (unsigned char *)aprintf("%s:%s", request, uripath);
Curl_md5it(md5buf, md5this);
free(md5this); /* free this again */
md5_to_ascii(md5buf, ha2);
md5this = (unsigned char *)aprintf("%s:%s:%s", ha1, data->state.digest.nonce,
ha2);
Curl_md5it(md5buf, md5this);
free(md5this); /* free this again */
md5_to_ascii(md5buf, request_digest);
/* for test case 64 (snooped from a Mozilla 1.3a request)
Authorization: Digest username="testuser", realm="testrealm", \
nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
*/
conn->allocptr.userpwd =
aprintf( "Authorization: Digest "
"username=\"%s\", "
"realm=\"%s\", "
"nonce=\"%s\", "
"uri=\"%s\", "
"response=\"%s\"\r\n",
conn->user,
data->state.digest.realm,
data->state.digest.nonce,
uripath, /* this is the PATH part of the URL */
request_digest );
return CURLE_OK;
}
void Curl_digest_cleanup(struct SessionHandle *data)
{
if(data->state.digest.nonce)
free(data->state.digest.nonce);
data->state.digest.nonce = NULL;
if(data->state.digest.cnonce)
free(data->state.digest.cnonce);
data->state.digest.cnonce = NULL;
if(data->state.digest.realm)
free(data->state.digest.realm);
data->state.digest.realm = NULL;
data->state.digest.algo = CURLDIGESTALGO_MD5; /* default algorithm */
}
#endif

48
lib/http_digest.h Normal file
View File

@@ -0,0 +1,48 @@
#ifndef __HTTP_DIGEST_H
#define __HTTP_DIGEST_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2003, 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$
***************************************************************************/
typedef enum {
CURLDIGEST_NONE, /* not a digest */
CURLDIGEST_BAD, /* a digest, but one we don't like */
CURLDIGEST_FINE, /* a digest we act on */
CURLDIGEST_LAST /* last entry in this enum, don't use */
} CURLdigest;
enum {
CURLDIGESTALGO_MD5,
CURLDIGESTALGO_MD5SESS
};
/* this is for digest header input */
CURLdigest Curl_input_digest(struct connectdata *conn, char *header);
/* this is for creating digest header output */
CURLcode Curl_output_digest(struct connectdata *conn,
unsigned char *request,
unsigned char *uripath);
void Curl_digest_cleanup(struct SessionHandle *data);
#endif

216
lib/http_negotiate.c Normal file
View File

@@ -0,0 +1,216 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#include "setup.h"
#ifdef GSSAPI
#ifndef CURL_DISABLE_HTTP
/* -- WIN32 approved -- */
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include "urldata.h"
#include "sendf.h"
#include "strequal.h"
#include "base64.h"
#include "http_negotiate.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
/* The last #include file should be: */
#ifdef CURLDEBUG
#include "memdebug.h"
#endif
static int
get_gss_name(struct connectdata *conn, gss_name_t *server)
{
OM_uint32 major_status, minor_status;
gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
char name[2048];
/* GSSAPI implementation by Globus (known as GSI) requires the name to be
of form "<service>/<fqdn>" instead of <service>@<fqdn> (ie. slash instead
of at-sign). Also GSI servers are often identified as 'host' not 'khttp'.
Change following lines if you want to use GSI */
token.length = strlen("khttp@") + strlen(conn->hostname) + 1;
if (token.length + 1 > sizeof(name))
return EMSGSIZE;
sprintf(name, "khttp@%s", conn->hostname);
token.value = (void *) name;
major_status = gss_import_name(&minor_status,
&token,
GSS_C_NT_HOSTBASED_SERVICE,
server);
return GSS_ERROR(major_status) ? -1 : 0;
}
static void
log_gss_error(struct connectdata *conn, OM_uint32 error_status, char *prefix)
{
OM_uint32 maj_stat, min_stat;
OM_uint32 msg_ctx = 0;
gss_buffer_desc status_string;
char buf[1024];
size_t len;
snprintf(buf, sizeof(buf), "%s", prefix);
len = strlen(buf);
do {
maj_stat = gss_display_status (&min_stat,
error_status,
GSS_C_MECH_CODE,
GSS_C_NO_OID,
&msg_ctx,
&status_string);
if (sizeof(buf) > len + status_string.length + 1) {
sprintf(buf + len, ": %s", (char*) status_string.value);
len += status_string.length;
}
gss_release_buffer(&min_stat, &status_string);
} while (!GSS_ERROR(maj_stat) && msg_ctx != 0);
infof(conn->data, buf);
}
int Curl_input_negotiate(struct connectdata *conn, char *header)
{
struct negotiatedata *neg_ctx = &conn->data->state.negotiate;
OM_uint32 major_status, minor_status, minor_status2;
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
int ret;
size_t len;
while(*header && isspace((int)*header))
header++;
if(!checkprefix("GSS-Negotiate", header))
return -1;
if (neg_ctx->context && neg_ctx->status == GSS_S_COMPLETE) {
/* We finished succesfully our part of authentication, but server
* rejected it (since we're again here). Exit with an error since we
* can't invent anything better */
Curl_cleanup_negotiate(conn->data);
return -1;
}
if (neg_ctx->server_name == NULL &&
(ret = get_gss_name(conn, &neg_ctx->server_name)))
return ret;
header += strlen("GSS-Negotiate");
while(*header && isspace((int)*header))
header++;
len = strlen(header);
if (len > 0) {
int rawlen;
input_token.length = (len+3)/4 * 3;
input_token.value = malloc(input_token.length);
if (input_token.value == NULL)
return ENOMEM;
rawlen = Curl_base64_decode(header, input_token.value);
if (rawlen < 0)
return -1;
input_token.length = rawlen;
}
major_status = gss_init_sec_context(&minor_status,
GSS_C_NO_CREDENTIAL,
&neg_ctx->context,
neg_ctx->server_name,
GSS_C_NO_OID,
GSS_C_DELEG_FLAG,
0,
GSS_C_NO_CHANNEL_BINDINGS,
&input_token,
NULL,
&output_token,
NULL,
NULL);
if (input_token.length > 0)
gss_release_buffer(&minor_status2, &input_token);
neg_ctx->status = major_status;
if (GSS_ERROR(major_status)) {
/* Curl_cleanup_negotiate(conn->data) ??? */
log_gss_error(conn, minor_status,
(char *)"gss_init_sec_context() failed: ");
return -1;
}
if (output_token.length == 0) {
return -1;
}
neg_ctx->output_token = output_token;
/* conn->bits.close = FALSE; */
return 0;
}
CURLcode Curl_output_negotiate(struct connectdata *conn)
{
struct negotiatedata *neg_ctx = &conn->data->state.negotiate;
OM_uint32 minor_status;
char *encoded = NULL;
int len = Curl_base64_encode(neg_ctx->output_token.value,
neg_ctx->output_token.length,
&encoded);
if (len < 0)
return CURLE_OUT_OF_MEMORY;
conn->allocptr.userpwd =
aprintf("Authorization: GSS-Negotiate %s\r\n", encoded);
free(encoded);
gss_release_buffer(&minor_status, &neg_ctx->output_token);
return (conn->allocptr.userpwd == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
}
void Curl_cleanup_negotiate(struct SessionHandle *data)
{
OM_uint32 minor_status;
struct negotiatedata *neg_ctx = &data->state.negotiate;
if (neg_ctx->context != GSS_C_NO_CONTEXT)
gss_delete_sec_context(&minor_status, &neg_ctx->context, GSS_C_NO_BUFFER);
if (neg_ctx->output_token.length != 0)
gss_release_buffer(&minor_status, &neg_ctx->output_token);
if (neg_ctx->server_name != GSS_C_NO_NAME)
gss_release_name(&minor_status, &neg_ctx->server_name);
memset(neg_ctx, 0, sizeof(*neg_ctx));
}
#endif
#endif

39
lib/http_negotiate.h Normal file
View File

@@ -0,0 +1,39 @@
#ifndef __HTTP_NEGOTIATE_H
#define __HTTP_NEGOTIATE_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#ifdef GSSAPI
/* this is for Negotiate header input */
int Curl_input_negotiate(struct connectdata *conn, char *header);
/* this is for creating Negotiate header output */
CURLcode Curl_output_negotiate(struct connectdata *conn);
void Curl_cleanup_negotiate(struct SessionHandle *data);
#endif
#endif

571
lib/http_ntlm.c Normal file
View File

@@ -0,0 +1,571 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#include "setup.h"
/* NTLM details:
http://davenport.sourceforge.net/ntlm.html
http://www.innovation.ch/java/ntlm.html
*/
#ifndef CURL_DISABLE_HTTP
#ifdef USE_SSLEAY
/* We need OpenSSL for the crypto lib to provide us with MD4 and DES */
/* -- WIN32 approved -- */
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#include "urldata.h"
#include "sendf.h"
#include "strequal.h"
#include "base64.h"
#include "http_ntlm.h"
#include "url.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include <openssl/des.h>
#include <openssl/md4.h>
#include <openssl/ssl.h>
#if OPENSSL_VERSION_NUMBER < 0x00907001L
#define DES_key_schedule des_key_schedule
#define DES_cblock des_cblock
#define DES_set_odd_parity des_set_odd_parity
#define DES_set_key des_set_key
#define DES_ecb_encrypt des_ecb_encrypt
/* This is how things were done in the old days */#define DESKEY(x) x
#define DESKEY(x) x
#define DESKEYARG(x) x
#else
/* Modern version */
#define DESKEYARG(x) *x
#define DESKEY(x) &x
#endif
/* The last #include file should be: */
#ifdef CURLDEBUG
#include "memdebug.h"
#endif
/* Define this to make the type-3 message include the NT response message */
#undef USE_NTRESPONSES
/*
(*) = A "security buffer" is a triplet consisting of two shorts and one
long:
1. a 'short' containing the length of the buffer in bytes
2. a 'short' containing the allocated space for the buffer in bytes
3. a 'long' containing the offset to the start of the buffer from the
beginning of the NTLM message, in bytes.
*/
CURLntlm Curl_input_ntlm(struct connectdata *conn,
bool proxy, /* if proxy or not */
char *header) /* rest of the www-authenticate:
header */
{
/* point to the correct struct with this */
struct ntlmdata *ntlm;
ntlm = proxy?&conn->proxyntlm:&conn->ntlm;
/* skip initial whitespaces */
while(*header && isspace((int)*header))
header++;
if(checkprefix("NTLM", header)) {
unsigned char buffer[256];
header += strlen("NTLM");
while(*header && isspace((int)*header))
header++;
if(*header) {
/* We got a type-2 message here:
Index Description Content
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
(0x4e544c4d53535000)
8 NTLM Message Type long (0x02000000)
12 Target Name security buffer(*)
20 Flags long
24 Challenge 8 bytes
(32) Context (optional) 8 bytes (two consecutive longs)
(40) Target Information (optional) security buffer(*)
32 (48) start of data block
*/
int size = Curl_base64_decode(header, buffer);
ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
if(size >= 48)
/* the nonce of interest is index [24 .. 31], 8 bytes */
memcpy(ntlm->nonce, &buffer[24], 8);
/* at index decimal 20, there's a 32bit NTLM flag field */
}
else {
if(ntlm->state >= NTLMSTATE_TYPE1)
return CURLNTLM_BAD;
ntlm->state = NTLMSTATE_TYPE1; /* we should sent away a type-1 */
}
}
return CURLNTLM_FINE;
}
/*
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
* key schedule ks is also set.
*/
static void setup_des_key(unsigned char *key_56,
DES_key_schedule DESKEYARG(ks))
{
DES_cblock key;
key[0] = key_56[0];
key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
key[7] = (key_56[6] << 1) & 0xFF;
DES_set_odd_parity(&key);
DES_set_key(&key, ks);
}
/*
* takes a 21 byte array and treats it as 3 56-bit DES keys. The
* 8 byte plaintext is encrypted with each key and the resulting 24
* bytes are stored in the results array.
*/
static void calc_resp(unsigned char *keys,
unsigned char *plaintext,
unsigned char *results)
{
DES_key_schedule ks;
setup_des_key(keys, DESKEY(ks));
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
DESKEY(ks), DES_ENCRYPT);
setup_des_key(keys+7, DESKEY(ks));
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+8),
DESKEY(ks), DES_ENCRYPT);
setup_des_key(keys+14, DESKEY(ks));
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+16),
DESKEY(ks), DES_ENCRYPT);
}
/*
* Set up lanmanager and nt hashed passwords
*/
static void mkhash(char *password,
unsigned char *nonce, /* 8 bytes */
unsigned char *lmresp /* must fit 0x18 bytes */
#ifdef USE_NTRESPONSES
, unsigned char *ntresp /* must fit 0x18 bytes */
#endif
)
{
unsigned char lmbuffer[21];
#ifdef USE_NTRESPONSES
unsigned char ntbuffer[21];
#endif
unsigned char *pw;
static const unsigned char magic[] = {
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25
};
int i;
int len = strlen(password);
/* make it fit at least 14 bytes */
pw = malloc(len<7?14:len*2);
if(!pw)
return; /* this will lead to a badly generated package */
if (len > 14)
len = 14;
for (i=0; i<len; i++)
pw[i] = toupper(password[i]);
for (; i<14; i++)
pw[i] = 0;
{
/* create LanManager hashed password */
DES_key_schedule ks;
setup_des_key(pw, DESKEY(ks));
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
DESKEY(ks), DES_ENCRYPT);
setup_des_key(pw+7, DESKEY(ks));
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
DESKEY(ks), DES_ENCRYPT);
memset(lmbuffer+16, 0, 5);
}
/* create LM responses */
calc_resp(lmbuffer, nonce, lmresp);
#ifdef USE_NTRESPONSES
{
/* create NT hashed password */
MD4_CTX MD4;
len = strlen(password);
for (i=0; i<len; i++) {
pw[2*i] = password[i];
pw[2*i+1] = 0;
}
MD4_Init(&MD4);
MD4_Update(&MD4, pw, 2*len);
MD4_Final(ntbuffer, &MD4);
memset(ntbuffer+16, 0, 8);
}
calc_resp(ntbuffer, nonce, ntresp);
#endif
free(pw);
}
#define SHORTPAIR(x) ((x) & 0xff), ((x) >> 8)
#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \
(((x) >>16)&0xff), ((x)>>24)
/* this is for creating ntlm header output */
CURLcode Curl_output_ntlm(struct connectdata *conn,
bool proxy)
{
const char *domain=""; /* empty */
const char *host=""; /* empty */
int domlen=strlen(domain);
int hostlen = strlen(host);
int hostoff; /* host name offset */
int domoff; /* domain name offset */
int size;
char *base64=NULL;
unsigned char ntlmbuf[256]; /* enough, unless the host/domain is very long */
/* point to the address of the pointer that holds the string to sent to the
server, which is for a plain host or for a HTTP proxy */
char **allocuserpwd;
/* point to the name and password for this */
char *userp;
char *passwdp;
/* point to the correct struct with this */
struct ntlmdata *ntlm;
if(proxy) {
allocuserpwd = &conn->allocptr.proxyuserpwd;
userp = conn->proxyuser;
passwdp = conn->proxypasswd;
ntlm = &conn->proxyntlm;
}
else {
allocuserpwd = &conn->allocptr.userpwd;
userp = conn->user;
passwdp = conn->passwd;
ntlm = &conn->ntlm;
}
switch(ntlm->state) {
case NTLMSTATE_TYPE1:
default: /* for the weird cases we (re)start here */
hostoff = 32;
domoff = hostoff + hostlen;
/* Create and send a type-1 message:
Index Description Content
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
(0x4e544c4d53535000)
8 NTLM Message Type long (0x01000000)
12 Flags long
16 Supplied Domain security buffer(*)
24 Supplied Workstation security buffer(*)
32 start of data block
*/
snprintf((char *)ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c"
"\x01%c%c%c" /* 32-bit type = 1 */
"%c%c%c%c" /* 32-bit NTLM flag field */
"%c%c" /* domain length */
"%c%c" /* domain allocated space */
"%c%c" /* domain name offset */
"%c%c" /* 2 zeroes */
"%c%c" /* host length */
"%c%c" /* host allocated space */
"%c%c" /* host name offset */
"%c%c" /* 2 zeroes */
"%s" /* host name */
"%s", /* domain string */
0, /* trailing zero */
0,0,0, /* part of type-1 long */
LONGQUARTET(
NTLMFLAG_NEGOTIATE_OEM| /* 2 */
NTLMFLAG_NEGOTIATE_NTLM_KEY /* 200 */
/* equals 0x0202 */
),
SHORTPAIR(domlen),
SHORTPAIR(domlen),
SHORTPAIR(domoff),
0,0,
SHORTPAIR(hostlen),
SHORTPAIR(hostlen),
SHORTPAIR(hostoff),
0,0,
host, domain);
/* initial packet length */
size = 32 + hostlen + domlen;
/* now keeper of the base64 encoded package size */
size = Curl_base64_encode(ntlmbuf, size, &base64);
if(size >0 ) {
Curl_safefree(*allocuserpwd);
*allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
proxy?"Proxy-":"",
base64);
free(base64);
}
else
return CURLE_OUT_OF_MEMORY; /* FIX TODO */
break;
case NTLMSTATE_TYPE2:
/* We received the type-2 already, create a type-3 message:
Index Description Content
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
(0x4e544c4d53535000)
8 NTLM Message Type long (0x03000000)
12 LM/LMv2 Response security buffer(*)
20 NTLM/NTLMv2 Response security buffer(*)
28 Domain Name security buffer(*)
36 User Name security buffer(*)
44 Workstation Name security buffer(*)
(52) Session Key (optional) security buffer(*)
(60) Flags (optional) long
52 (64) start of data block
*/
{
int lmrespoff;
int ntrespoff;
int useroff;
unsigned char lmresp[0x18]; /* fixed-size */
#ifdef USE_NTRESPONSES
unsigned char ntresp[0x18]; /* fixed-size */
#endif
const char *user;
int userlen;
user = strchr(userp, '\\');
if(!user)
user = strchr(userp, '/');
if (user) {
domain = userp;
domlen = user - domain;
user++;
}
else
user = userp;
userlen = strlen(user);
mkhash(passwdp, &ntlm->nonce[0], lmresp
#ifdef USE_NTRESPONSES
, ntresp
#endif
);
domoff = 64; /* always */
useroff = domoff + domlen;
hostoff = useroff + userlen;
lmrespoff = hostoff + hostlen;
ntrespoff = lmrespoff + 0x18;
/* Create the big type-3 message binary blob */
size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf),
"NTLMSSP%c"
"\x03%c%c%c" /* type-3, 32 bits */
"%c%c%c%c" /* LanManager length + allocated space */
"%c%c" /* LanManager offset */
"%c%c" /* 2 zeroes */
"%c%c" /* NT-response length */
"%c%c" /* NT-response allocated space */
"%c%c" /* NT-response offset */
"%c%c" /* 2 zeroes */
"%c%c" /* domain length */
"%c%c" /* domain allocated space */
"%c%c" /* domain name offset */
"%c%c" /* 2 zeroes */
"%c%c" /* user length */
"%c%c" /* user allocated space */
"%c%c" /* user offset */
"%c%c" /* 2 zeroes */
"%c%c" /* host length */
"%c%c" /* host allocated space */
"%c%c" /* host offset */
"%c%c%c%c%c%c" /* 6 zeroes */
"\xff\xff" /* message length */
"%c%c" /* 2 zeroes */
"\x01\x82" /* flags */
"%c%c" /* 2 zeroes */
/* domain string */
/* user string */
/* host string */
/* LanManager response */
/* NT response */
,
0, /* zero termination */
0,0,0, /* type-3 long, the 24 upper bits */
SHORTPAIR(0x18), /* LanManager response length, twice */
SHORTPAIR(0x18),
SHORTPAIR(lmrespoff),
0x0, 0x0,
#ifdef USE_NTRESPONSES
SHORTPAIR(0x18), /* NT-response length, twice */
SHORTPAIR(0x18),
#else
0x0, 0x0,
0x0, 0x0,
#endif
SHORTPAIR(ntrespoff),
0x0, 0x0,
SHORTPAIR(domlen),
SHORTPAIR(domlen),
SHORTPAIR(domoff),
0x0, 0x0,
SHORTPAIR(userlen),
SHORTPAIR(userlen),
SHORTPAIR(useroff),
0x0, 0x0,
SHORTPAIR(hostlen),
SHORTPAIR(hostlen),
SHORTPAIR(hostoff),
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0,
0x0, 0x0);
/* size is now 64 */
size=64;
ntlmbuf[62]=ntlmbuf[63]=0;
memcpy(&ntlmbuf[size], domain, domlen);
size += domlen;
memcpy(&ntlmbuf[size], user, userlen);
size += userlen;
/* we append the binary hashes to the end of the blob */
if(size < ((int)sizeof(ntlmbuf) - 0x18)) {
memcpy(&ntlmbuf[size], lmresp, 0x18);
size += 0x18;
}
#ifdef USE_NTRESPONSES
if(size < ((int)sizeof(ntlmbuf) - 0x18)) {
memcpy(&ntlmbuf[size], ntresp, 0x18);
size += 0x18;
}
#endif
ntlmbuf[56] = size & 0xff;
ntlmbuf[57] = size >> 8;
/* convert the binary blob into base64 */
size = Curl_base64_encode(ntlmbuf, size, &base64);
if(size >0 ) {
Curl_safefree(*allocuserpwd);
*allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
proxy?"Proxy-":"",
base64);
free(base64);
}
else
return CURLE_OUT_OF_MEMORY; /* FIX TODO */
ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
}
break;
case NTLMSTATE_TYPE3:
/* connection is already authenticated,
* don't send a header in future requests */
if(*allocuserpwd) {
free(*allocuserpwd);
*allocuserpwd=NULL;
}
break;
}
return CURLE_OK;
}
#endif /* USE_SSLEAY */
#endif /* !CURL_DISABLE_HTTP */

143
lib/http_ntlm.h Normal file
View File

@@ -0,0 +1,143 @@
#ifndef __HTTP_NTLM_H
#define __HTTP_NTLM_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2003, 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$
***************************************************************************/
typedef enum {
CURLNTLM_NONE, /* not a ntlm */
CURLNTLM_BAD, /* an ntlm, but one we don't like */
CURLNTLM_FIRST, /* the first 401-reply we got with NTLM */
CURLNTLM_FINE, /* an ntlm we act on */
CURLNTLM_LAST /* last entry in this enum, don't use */
} CURLntlm;
/* this is for ntlm header input */
CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy, char *header);
/* this is for creating ntlm header output */
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
void Curl_ntlm_cleanup(struct SessionHandle *data);
/* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */
#define NTLMFLAG_NEGOTIATE_UNICODE (1<<0)
/* Indicates that Unicode strings are supported for use in security buffer
data. */
#define NTLMFLAG_NEGOTIATE_OEM (1<<1)
/* Indicates that OEM strings are supported for use in security buffer data. */
#define NTLMFLAG_REQUEST_TARGET (1<<2)
/* Requests that the server's authentication realm be included in the Type 2
message. */
/* unknown (1<<3) */
#define NTLMFLAG_NEGOTIATE_SIGN (1<<4)
/* Specifies that authenticated communication between the client and server
should carry a digital signature (message integrity). */
#define NTLMFLAG_NEGOTIATE_SEAL (1<<5)
/* Specifies that authenticated communication between the client and server
should be encrypted (message confidentiality). */
#define NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE (1<<6)
/* unknown purpose */
#define NTLMFLAG_NEGOTIATE_LM_KEY (1<<7)
/* Indicates that the LAN Manager session key should be used for signing and
sealing authenticated communications. */
#define NTLMFLAG_NEGOTIATE_NETWARE (1<<8)
/* unknown purpose */
#define NTLMFLAG_NEGOTIATE_NTLM_KEY (1<<9)
/* Indicates that NTLM authentication is being used. */
/* unknown (1<<10) */
/* unknown (1<<11) */
#define NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED (1<<12)
/* Sent by the client in the Type 1 message to indicate that a desired
authentication realm is included in the message. */
#define NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED (1<<13)
/* Sent by the client in the Type 1 message to indicate that the client
workstation's name is included in the message. */
#define NTLMFLAG_NEGOTIATE_LOCAL_CALL (1<<14)
/* Sent by the server to indicate that the server and client are on the same
machine. Implies that the client may use a pre-established local security
context rather than responding to the challenge. */
#define NTLMFLAG_NEGOTIATE_ALWAYS_SIGN (1<<15)
/* Indicates that authenticated communication between the client and server
should be signed with a "dummy" signature. */
#define NTLMFLAG_TARGET_TYPE_DOMAIN (1<<16)
/* Sent by the server in the Type 2 message to indicate that the target
authentication realm is a domain. */
#define NTLMFLAG_TARGET_TYPE_SERVER (1<<17)
/* Sent by the server in the Type 2 message to indicate that the target
authentication realm is a server. */
#define NTLMFLAG_TARGET_TYPE_SHARE (1<<18)
/* Sent by the server in the Type 2 message to indicate that the target
authentication realm is a share. Presumably, this is for share-level
authentication. Usage is unclear. */
#define NTLMFLAG_NEGOTIATE_NTLM2_KEY (1<<19)
/* Indicates that the NTLM2 signing and sealing scheme should be used for
protecting authenticated communications. */
#define NTLMFLAG_REQUEST_INIT_RESPONSE (1<<20)
/* unknown purpose */
#define NTLMFLAG_REQUEST_ACCEPT_RESPONSE (1<<21)
/* unknown purpose */
#define NTLMFLAG_REQUEST_NONNT_SESSION_KEY (1<<22)
/* unknown purpose */
#define NTLMFLAG_NEGOTIATE_TARGET_INFO (1<<23)
/* Sent by the server in the Type 2 message to indicate that it is including a
Target Information block in the message. */
/* unknown (1<24) */
/* unknown (1<25) */
/* unknown (1<26) */
/* unknown (1<27) */
/* unknown (1<28) */
#define NTLMFLAG_NEGOTIATE_128 (1<<29)
/* Indicates that 128-bit encryption is supported. */
#define NTLMFLAG_NEGOTIATE_KEY_EXCHANGE (1<<30)
/* unknown purpose */
#define NTLMFLAG_NEGOTIATE_56 (1<<31)
/* Indicates that 56-bit encryption is supported. */
#endif

View File

@@ -73,10 +73,14 @@
#endif #endif
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif
#ifdef DJGPP
#define IOCTL_3_ARGS
#endif
#define SYS_ERROR -1 #define SYS_ERROR -1
char *Curl_if2ip(char *interface, char *buf, int buf_size) char *Curl_if2ip(char *interface, char *buf, int buf_size)

View File

@@ -64,7 +64,7 @@
#endif #endif
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif
@@ -322,7 +322,7 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
save = Curl_set_command_prot(conn, prot_private); save = Curl_set_command_prot(conn, prot_private);
result = Curl_ftpsendf(conn, "SITE KAUTH %s", conn->data->state.user); result = Curl_ftpsendf(conn, "SITE KAUTH %s", conn->user);
if(result) if(result)
return result; return result;
@@ -363,7 +363,7 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++); for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++);
*p = 0; *p = 0;
des_string_to_key (conn->data->state.passwd, &key); des_string_to_key (conn->passwd, &key);
des_key_sched(&key, schedule); des_key_sched(&key, schedule);
des_pcbc_encrypt((void *)tkt.dat, (void *)tktcopy.dat, des_pcbc_encrypt((void *)tkt.dat, (void *)tktcopy.dat,

View File

@@ -74,7 +74,7 @@ static void DynaOpen(void)
* liblber.so automatically, but since it does not we will * liblber.so automatically, but since it does not we will
* handle it here by opening liblber.so as global. * handle it here by opening liblber.so as global.
*/ */
dlopen("liblber.so", liblber = dlopen("liblber.so",
#ifdef RTLD_LAZY_GLOBAL /* It turns out some systems use this: */ #ifdef RTLD_LAZY_GLOBAL /* It turns out some systems use this: */
RTLD_LAZY_GLOBAL RTLD_LAZY_GLOBAL
#else #else
@@ -178,8 +178,8 @@ CURLcode Curl_ldap(struct connectdata *conn)
status = CURLE_COULDNT_CONNECT; status = CURLE_COULDNT_CONNECT;
} else { } else {
rc = ldap_simple_bind_s(server, rc = ldap_simple_bind_s(server,
conn->bits.user_passwd?data->state.user:NULL, conn->bits.user_passwd?conn->user:NULL,
conn->bits.user_passwd?data->state.passwd:NULL); conn->bits.user_passwd?conn->passwd:NULL);
if (rc != 0) { if (rc != 0) {
failf(data, "LDAP: %s", ldap_err2string(rc)); failf(data, "LDAP: %s", ldap_err2string(rc));
status = CURLE_LDAP_CANNOT_BIND; status = CURLE_LDAP_CANNOT_BIND;

View File

@@ -28,7 +28,7 @@
#include "llist.h" #include "llist.h"
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
/* this must be the last include file */ /* this must be the last include file */
#include "memdebug.h" #include "memdebug.h"
#endif #endif

157
lib/makefile.dj Normal file
View File

@@ -0,0 +1,157 @@
#
# Adapted for djgpp2 / Watt-32 / DOS by
# Gisle Vanem <giva@bgnett.no>
#
DEPEND_PREREQ = config.h getdate.c
include ../packages/DOS/common.dj
ifeq ($(USE_SSL),1)
CFLAGS += -I$(OPENSSL_ROOT)
endif
SOURCES = base64.c connect.c content_.c cookie.c dict.c \
easy.c escape.c file.c formdata.c ftp.c \
getdate.c getenv.c getinfo.c getpass.c hash.c \
hostip.c http.c http_chu.c if2ip.c krb4.c \
ldap.c llist.c memdebug.c mprintf.c multi.c \
netrc.c progress.c security.c sendf.c share.c \
speedche.c ssluse.c strequal.c strtok.c telnet.c \
timeval.c transfer.c url.c version.c
OBJECTS = $(SOURCES:.c=.o)
CURL_LIB = libcurl.a
all: config.h $(CURL_LIB)
$(CURL_LIB): $(OBJECTS)
ar rs $@ $?
config.h: config.dj
@echo '#include "./config.dj"' > $@
getdate.c: getdate.y
$(YACC) -o $@ $^
clean:
- rm -f $(OBJECTS) $(CURL_LIB) Makefile.bak config.h getdate.c
# DO NOT DELETE THIS LINE
base64.o: base64.c setup.h config.h config.dj ../include/curl/mprintf.h \
base64.h
connect.o: connect.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h sendf.h if2ip.h
content_.o: content_.c setup.h config.h config.dj
cookie.o: cookie.c setup.h config.h config.dj cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h getdate.h strequal.h strtok.h
dict.o: dict.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h transfer.h sendf.h progress.h strequal.h \
../include/curl/mprintf.h
easy.o: easy.c setup.h config.h config.dj strequal.h urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h transfer.h ssluse.h url.h getinfo.h \
../include/curl/mprintf.h
escape.o: escape.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h
file.o: file.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h progress.h sendf.h escape.h ../include/curl/mprintf.h
formdata.o: formdata.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
formdata.h strequal.h
ftp.o: ftp.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
llist.h sendf.h if2ip.h progress.h transfer.h escape.h http.h ftp.h \
strequal.h ssluse.h connect.h ../include/curl/mprintf.h
getdate.o: getdate.c setup.h config.h config.dj getdate.h
getenv.o: getenv.c setup.h config.h config.dj
getinfo.o: getinfo.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
llist.h
getpass.o: getpass.c setup.h config.h config.dj
hash.o: hash.c setup.h config.h config.dj hash.h llist.h
hostip.o: hostip.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h sendf.h share.h ../include/curl/mprintf.h
http.o: http.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h transfer.h sendf.h progress.h base64.h strequal.h \
ssluse.h ../include/curl/mprintf.h
http_chu.o: http_chu.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h sendf.h content_encoding.h ../include/curl/mprintf.h
if2ip.o: if2ip.c setup.h config.h config.dj
krb4.o: krb4.c setup.h config.h config.dj
ldap.o: ldap.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h sendf.h escape.h transfer.h ../include/curl/mprintf.h
llist.o: llist.c setup.h config.h config.dj llist.h
memdebug.o: memdebug.c
mprintf.o: mprintf.c setup.h config.h config.dj
multi.o: multi.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
llist.h transfer.h url.h connect.h progress.h
netrc.o: netrc.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
strequal.h strtok.h
progress.o: progress.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
llist.h sendf.h progress.h ../include/curl/mprintf.h
security.o: security.c setup.h config.h config.dj
sendf.o: sendf.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
llist.h sendf.h connect.h ../include/curl/mprintf.h
share.o: share.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
llist.h share.h
speedche.o: speedche.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
llist.h sendf.h speedcheck.h
ssluse.o: ssluse.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h sendf.h url.h
strequal.o: strequal.c setup.h config.h config.dj
strtok.o: strtok.c setup.h config.h config.dj
telnet.o: telnet.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h transfer.h sendf.h ../include/curl/mprintf.h \
arpa_telnet.h
timeval.o: timeval.c timeval.h setup.h config.h config.dj
transfer.o: transfer.c setup.h config.h config.dj strequal.h urldata.h \
cookie.h ../include/curl/curl.h ../include/curl/types.h \
../include/curl/easy.h ../include/curl/multi.h formdata.h timeval.h \
http_chunks.h hostip.h hash.h llist.h netrc.h content_encoding.h \
transfer.h sendf.h speedcheck.h getpass.h progress.h getdate.h http.h \
url.h getinfo.h ssluse.h ../include/curl/mprintf.h
url.o: url.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h netrc.h base64.h ssluse.h if2ip.h transfer.h sendf.h \
getpass.h progress.h strequal.h escape.h strtok.h share.h \
content_encoding.h ftp.h dict.h telnet.h http.h file.h ldap.h url.h \
connect.h ca-bundle.h ../include/curl/mprintf.h
version.o: version.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
llist.h

356
lib/md5.c Normal file
View File

@@ -0,0 +1,356 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#include "setup.h"
#ifndef USE_SSLEAY
/* This code segment is only used if OpenSSL is not provided, as if it is
we use the MD5-function provided there instead. No good duplicating
code! */
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#include <string.h>
/* UINT4 defines a four byte word */
typedef unsigned long int UINT4;
/* MD5 context. */
struct md5_ctx {
UINT4 state[4]; /* state (ABCD) */
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
};
typedef struct md5_ctx MD5_CTX;
static void MD5_Init(struct md5_ctx *);
static void MD5_Update(struct md5_ctx *, unsigned char *, unsigned int);
static void MD5_Final(unsigned char [16], struct md5_ctx *);
/* Constants for MD5Transform routine.
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static void MD5Transform(UINT4 [4], unsigned char [64]);
static void Encode(unsigned char *, UINT4 *, unsigned int);
static void Decode(UINT4 *, unsigned char *, unsigned int);
#define MD5_memcpy(dst,src,len) memcpy(dst,src,len)
#define MD5_memset(dst,val,len) memset(dst,val,len)
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
static void MD5_Init (context)
struct md5_ctx *context; /* context */
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.
*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
static void MD5_Update (context, input, inputLen)
struct md5_ctx *context; /* context */
unsigned char *input; /* input block */
unsigned int inputLen; /* length of input block */
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen << 3))
context->count[1]++;
context->count[1] += ((UINT4)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible. */
if (inputLen >= partLen) {
MD5_memcpy((void *)&context->buffer[index], (void *)input, partLen);
MD5Transform(context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform(context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
MD5_memcpy((void *)&context->buffer[index], (void *)&input[i],
inputLen-i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
static void MD5_Final (digest, context)
unsigned char digest[16]; /* message digest */
struct md5_ctx *context; /* context */
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64. */
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5_Update (context, PADDING, padLen);
/* Append length (before padding) */
MD5_Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information. */
MD5_memset ((void *)context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block. */
static void MD5Transform (state, block)
UINT4 state[4];
unsigned char block[64];
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information. */
MD5_memset ((void *)x, 0, sizeof (x));
}
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode (unsigned char *output,
UINT4 *input,
unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (UINT4 *output,
unsigned char *input,
unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
#else
/* If OpenSSL is present */
#include <openssl/md5.h>
#include <string.h>
#endif
void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
unsigned char *input)
{
MD5_CTX ctx;
MD5_Init(&ctx);
MD5_Update(&ctx, input, strlen((char *)input));
MD5_Final(outbuffer, &ctx);
}

View File

@@ -1,31 +1,29 @@
#ifndef __CA_BUNDLE_H #ifndef __MD5_H
#define __CA_BUNDLE_H #define __MD5_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* In order to be useful for every potential user, curl and libcurl are * This software is licensed as described in the file COPYING, which
* dual-licensed under the MPL and the MIT/X-derivate licenses. * 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 * 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 * copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the MPL or the MIT/X-derivate * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
void Curl_md5it(unsigned char *output,
unsigned char *input);
#ifndef CURL_CA_BUNDLE
/* Set this to the full path file name of the ca cert bundle */
#undef CURL_CA_BUNDLE
#endif #endif
#endif /* __CA_BUNDLE_H */

View File

@@ -1,4 +1,4 @@
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
/*************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
@@ -220,4 +220,4 @@ int curl_fclose(FILE *file, int line, const char *source)
#ifdef VMS #ifdef VMS
int VOID_VAR_MEMDEBUG; int VOID_VAR_MEMDEBUG;
#endif #endif
#endif /* MALLOCDEBUG */ #endif /* CURLDEBUG */

View File

@@ -1,4 +1,4 @@
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
/*************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |

View File

@@ -48,7 +48,7 @@
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif

View File

@@ -31,6 +31,9 @@
#ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif #endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <curl/curl.h> #include <curl/curl.h>
@@ -41,7 +44,7 @@
#include "progress.h" #include "progress.h"
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif
@@ -299,7 +302,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
easy=multi->easy.next; easy=multi->easy.next;
while(easy) { while(easy) {
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
fprintf(stderr, "HANDLE %p: State: %x\n", fprintf(stderr, "HANDLE %p: State: %x\n",
(char *)easy, easy->state); (char *)easy, easy->state);
#endif #endif
@@ -437,8 +440,9 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
/* When we follow redirects, must to go back to the CONNECT state */ /* When we follow redirects, must to go back to the CONNECT state */
if(easy->easy_conn->newurl) { if(easy->easy_conn->newurl) {
easy->result = Curl_follow(easy->easy_handle, char *newurl = easy->easy_conn->newurl;
strdup(easy->easy_conn->newurl)); easy->easy_conn->newurl = NULL;
easy->result = Curl_follow(easy->easy_handle, newurl);
if(CURLE_OK == easy->result) { if(CURLE_OK == easy->result) {
easy->state = CURLM_STATE_CONNECT; easy->state = CURLM_STATE_CONNECT;
result = CURLM_CALL_MULTI_PERFORM; result = CURLM_CALL_MULTI_PERFORM;

View File

@@ -46,7 +46,7 @@
#include "strtok.h" #include "strtok.h"
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif
@@ -119,7 +119,7 @@ int Curl_parsenetrc(char *host,
sprintf(netrcbuffer, "%s%s%s", home, DIR_CHAR, NETRC); sprintf(netrcbuffer, "%s%s%s", home, DIR_CHAR, NETRC);
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
{ {
/* This is a hack to allow testing. /* This is a hack to allow testing.
* If compiled with --enable-debug and CURL_DEBUG_NETRC is defined, * If compiled with --enable-debug and CURL_DEBUG_NETRC is defined,
@@ -141,7 +141,7 @@ int Curl_parsenetrc(char *host,
free(override); free(override);
} }
} }
#endif /* MALLOCDEBUG */ #endif /* CURLDEBUG */
file = fopen(netrcbuffer, "r"); file = fopen(netrcbuffer, "r");
if(file) { if(file) {

View File

@@ -60,7 +60,7 @@
#include "ftp.h" #include "ftp.h"
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif

View File

@@ -56,7 +56,7 @@
#endif #endif
#include <string.h> #include <string.h>
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif
@@ -94,7 +94,6 @@ struct curl_slist *curl_slist_append(struct curl_slist *list,
new_item->data = strdup(data); new_item->data = strdup(data);
} }
if (new_item == NULL || new_item->data == NULL) { if (new_item == NULL || new_item->data == NULL) {
fprintf(stderr, "Cannot allocate memory for QUOTE list.\n");
return NULL; return NULL;
} }
@@ -229,6 +228,7 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
ssize_t *written) ssize_t *written)
{ {
ssize_t bytes_written; ssize_t bytes_written;
CURLcode retcode;
(void)conn; (void)conn;
#ifdef USE_SSLEAY #ifdef USE_SSLEAY
@@ -244,13 +244,28 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
switch(err) { switch(err) {
case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_WRITE:
/* this is basicly the EWOULDBLOCK equivalent */ /* The operation did not complete; the same TLS/SSL I/O function
should be called again later. This is basicly an EWOULDBLOCK
equivalent. */
*written = 0; *written = 0;
return CURLE_OK; return CURLE_OK;
case SSL_ERROR_SYSCALL: case SSL_ERROR_SYSCALL:
failf(conn->data, "SSL_write() returned SYSCALL, errno = %d\n", failf(conn->data, "SSL_write() returned SYSCALL, errno = %d\n",
Curl_ourerrno()); Curl_ourerrno());
return CURLE_SEND_ERROR; return CURLE_SEND_ERROR;
case SSL_ERROR_SSL:
{
/* A failure in the SSL library occurred, usually a
protocol error. The OpenSSL error queue contains more
information on the error. */
char error_buffer[120]; /* OpenSSL documents that this must be at least
120 bytes long. */
int sslerror = ERR_get_error();
failf(conn->data, "SSL_write() error: %s\n",
ERR_error_string(sslerror, error_buffer));
return CURLE_SEND_ERROR;
}
break;
} }
/* a true error */ /* a true error */
failf(conn->data, "SSL_write() return error %d\n", err); failf(conn->data, "SSL_write() return error %d\n", err);
@@ -271,27 +286,30 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
} }
if(-1 == bytes_written) { if(-1 == bytes_written) {
int err = Curl_ourerrno(); int err = Curl_ourerrno();
#ifdef WIN32
if(WSAEWOULDBLOCK == err) if(
#ifdef WSAEWOULDBLOCK
/* This is how Windows does it */
(WSAEWOULDBLOCK == err)
#else #else
/* As pointed out by Christophe Demory on March 11 2003, errno /* As pointed out by Christophe Demory on March 11 2003, errno
may be EWOULDBLOCK or on some systems EAGAIN when it returned may be EWOULDBLOCK or on some systems EAGAIN when it returned
due to its inability to send off data without blocking. We due to its inability to send off data without blocking. We
therefor treat both error codes the same here */ therefor treat both error codes the same here */
if((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)) (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
#endif #endif
{ )
/* this is just a case of EWOULDBLOCK */ /* this is just a case of EWOULDBLOCK */
*written=0; bytes_written=0;
return CURLE_OK;
}
} }
#ifdef USE_SSLEAY #ifdef USE_SSLEAY
} }
#endif #endif
*written = bytes_written; *written = bytes_written;
return (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR; retcode = (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
return retcode;
} }
/* client_write() sends data to the write callback(s) /* client_write() sends data to the write callback(s)

View File

@@ -135,20 +135,40 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
#define HAVE_ALARM #define HAVE_ALARM
#endif #endif
#define PATH_CHAR ";"
#define DIR_CHAR "\\" #define DIR_CHAR "\\"
#define DOT_CHAR "_" #define DOT_CHAR "_"
#else #else
#ifdef DJGPP
#define sclose(x) close_s(x)
#define sread(x,y,z) read_s(x,y,z)
#define swrite(x,y,z) write_s(x,y,z)
#define select(n,r,w,x,t) select_s(n,r,w,x,t)
#define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z))
#define IOCTL_3_ARGS
#include <tcp.h>
#ifdef word
#undef word
#endif
#else
#define sclose(x) close(x) #define sclose(x) close(x)
#define sread(x,y,z) recv(x,y,z,0) #define sread(x,y,z) recv(x,y,z,0)
#define swrite(x,y,z) send(x,y,z,0) #define swrite(x,y,z) send(x,y,z,0)
#define HAVE_ALARM #define HAVE_ALARM
#define PATH_CHAR ":" #endif
#define DIR_CHAR "/" #define DIR_CHAR "/"
#define DOT_CHAR "." #define DOT_CHAR "."
#ifdef DJGPP
#undef DOT_CHAR
#define DOT_CHAR "_"
#endif
#ifdef HAVE_STRCASECMP #ifdef HAVE_STRCASECMP
/* this is for "-ansi -Wall -pedantic" to stop complaining! */ /* this is for "-ansi -Wall -pedantic" to stop complaining! */
extern int (strcasecmp)(const char *s1, const char *s2); extern int (strcasecmp)(const char *s1, const char *s2);

View File

@@ -24,12 +24,13 @@
#include "setup.h" #include "setup.h"
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <curl/curl.h> #include <curl/curl.h>
#include "urldata.h" #include "urldata.h"
#include "share.h" #include "share.h"
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif

View File

@@ -46,7 +46,7 @@
#include <openssl/rand.h> #include <openssl/rand.h>
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif
@@ -786,6 +786,16 @@ Curl_SSLConnect(struct connectdata *conn)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
/* OpenSSL contains code to work-around lots of bugs and flaws in various
SSL-implementations. SSL_CTX_set_options() is used to enabled those
work-arounds. The man page for this option states that SSL_OP_ALL enables
ll the work-arounds and that "It is usually safe to use SSL_OP_ALL to
enable the bug workaround options if compatibility with somewhat broken
implementations is desired."
*/
SSL_CTX_set_options(conn->ssl.ctx, SSL_OP_ALL);
if(data->set.cert) { if(data->set.cert) {
if (!cert_stuff(conn, if (!cert_stuff(conn,
data->set.cert, data->set.cert,
@@ -805,7 +815,7 @@ Curl_SSLConnect(struct connectdata *conn)
} }
} }
if(data->set.ssl.verifypeer){ if(data->set.ssl.verifypeer) {
SSL_CTX_set_verify(conn->ssl.ctx, SSL_CTX_set_verify(conn->ssl.ctx,
SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT| SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
SSL_VERIFY_CLIENT_ONCE, SSL_VERIFY_CLIENT_ONCE,
@@ -821,6 +831,15 @@ Curl_SSLConnect(struct connectdata *conn)
else else
SSL_CTX_set_verify(conn->ssl.ctx, SSL_VERIFY_NONE, cert_verify_callback); SSL_CTX_set_verify(conn->ssl.ctx, SSL_VERIFY_NONE, cert_verify_callback);
/* give application a chance to interfere with SSL set up. */
if (data->set.ssl.fsslctx) {
retcode = (*data->set.ssl.fsslctx)(data, conn->ssl.ctx,
data->set.ssl.fsslctxp);
if (retcode) {
failf(data,"error signaled by ssl ctx callback");
return retcode;
}
}
/* Lets make an SSL structure */ /* Lets make an SSL structure */
conn->ssl.handle = SSL_new (conn->ssl.ctx); conn->ssl.handle = SSL_new (conn->ssl.ctx);

View File

@@ -45,7 +45,6 @@
#endif #endif
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
@@ -84,7 +83,7 @@
#include "arpa_telnet.h" #include "arpa_telnet.h"
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif
@@ -756,7 +755,7 @@ static int check_telnet_options(struct connectdata *conn)
if(conn->bits.user_passwd) if(conn->bits.user_passwd)
{ {
char *buf = malloc(256); char *buf = malloc(256);
sprintf(buf, "USER,%s", data->state.user); sprintf(buf, "USER,%s", conn->user);
tn->telnet_vars = curl_slist_append(tn->telnet_vars, buf); tn->telnet_vars = curl_slist_append(tn->telnet_vars, buf);
tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES; tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;

View File

@@ -46,7 +46,6 @@
#endif #endif
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
@@ -95,12 +94,15 @@
#include "url.h" #include "url.h"
#include "getinfo.h" #include "getinfo.h"
#include "ssluse.h" #include "ssluse.h"
#include "http_digest.h"
#include "http_ntlm.h"
#include "http_negotiate.h"
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif
@@ -284,6 +286,9 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* header line within buffer loop */ /* header line within buffer loop */
do { do {
int hbufp_index; int hbufp_index;
int rest_length;
int full_length;
int writetype;
/* str_start is start of line within buf */ /* str_start is start of line within buf */
k->str_start = k->str; k->str_start = k->str;
@@ -325,22 +330,24 @@ CURLcode Curl_readwrite(struct connectdata *conn,
break; /* read more and try again */ break; /* read more and try again */
} }
/* decrease the size of the remaining buffer */ /* decrease the size of the remaining (supposed) header line */
nread -= (k->end_ptr - k->str)+1; rest_length = (k->end_ptr - k->str)+1;
nread -= rest_length;
k->str = k->end_ptr + 1; /* move past new line */ k->str = k->end_ptr + 1; /* move past new line */
full_length = k->str - k->str_start;
/* /*
* We're about to copy a chunk of data to the end of the * We're about to copy a chunk of data to the end of the
* already received header. We make sure that the full string * already received header. We make sure that the full string
* fit in the allocated header buffer, or else we enlarge * fit in the allocated header buffer, or else we enlarge
* it. * it.
*/ */
if (k->hbuflen + (k->str - k->str_start) >= if (k->hbuflen + full_length >=
data->state.headersize) { data->state.headersize) {
char *newbuff; char *newbuff;
long newsize=MAX((k->hbuflen+ long newsize=MAX((k->hbuflen+full_length)*3/2,
(k->str-k->str_start))*3/2,
data->state.headersize*2); data->state.headersize*2);
hbufp_index = k->hbufp - data->state.headerbuff; hbufp_index = k->hbufp - data->state.headerbuff;
newbuff = (char *)realloc(data->state.headerbuff, newsize); newbuff = (char *)realloc(data->state.headerbuff, newsize);
@@ -354,10 +361,11 @@ CURLcode Curl_readwrite(struct connectdata *conn,
} }
/* copy to end of line */ /* copy to end of line */
strncpy (k->hbufp, k->str_start, k->str - k->str_start); strncpy (k->hbufp, k->str_start, full_length);
k->hbufp += k->str - k->str_start; k->hbufp += full_length;
k->hbuflen += k->str - k->str_start; k->hbuflen += full_length;
*k->hbufp = 0; *k->hbufp = 0;
k->end_ptr = k->hbufp;
k->p = data->state.headerbuff; k->p = data->state.headerbuff;
@@ -371,7 +379,14 @@ CURLcode Curl_readwrite(struct connectdata *conn,
!checkhttpprefix(data, data->state.headerbuff)) { !checkhttpprefix(data, data->state.headerbuff)) {
/* this is not the beginning of a HTTP first header line */ /* this is not the beginning of a HTTP first header line */
k->header = FALSE; k->header = FALSE;
if(nread)
/* since there's more, this is a partial bad header */
k->badheader = HEADER_PARTHEADER; k->badheader = HEADER_PARTHEADER;
else {
/* this was all we read so its all a bad header */
k->badheader = HEADER_ALLBAD;
nread = rest_length;
}
break; break;
} }
} }
@@ -421,13 +436,13 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* now, only output this if the header AND body are requested: /* now, only output this if the header AND body are requested:
*/ */
k->writetype = CLIENTWRITE_HEADER; writetype = CLIENTWRITE_HEADER;
if (data->set.http_include_header) if (data->set.http_include_header)
k->writetype |= CLIENTWRITE_BODY; writetype |= CLIENTWRITE_BODY;
headerlen = k->p - data->state.headerbuff; headerlen = k->p - data->state.headerbuff;
result = Curl_client_write(data, k->writetype, result = Curl_client_write(data, writetype,
data->state.headerbuff, data->state.headerbuff,
headerlen); headerlen);
if(result) if(result)
@@ -445,11 +460,16 @@ CURLcode Curl_readwrite(struct connectdata *conn,
*/ */
if(data->set.no_body) if(data->set.no_body)
stop_reading = TRUE; stop_reading = TRUE;
else if(!conn->bits.close) { else {
/* If this is not the last request before a close, we must /* If we know the expected size of this document, we set the
set the maximum download size to the size of the maximum download size to the size of the expected
expected document or else, we won't know when to stop document or else, we won't know when to stop reading!
reading! */
Note that we set the download maximum even if we read a
"Connection: close" header, to make sure that
"Content-Length: 0" still prevents us from attempting to
read the (missing) response-body.
*/
if(-1 != conn->size) if(-1 != conn->size)
conn->maxdownload = conn->size; conn->maxdownload = conn->size;
} }
@@ -519,7 +539,8 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* If we have been told to fail hard on HTTP-errors, /* If we have been told to fail hard on HTTP-errors,
here is the check for that: */ here is the check for that: */
/* serious error, go home! */ /* serious error, go home! */
failf (data, "The requested file was not found"); failf (data, "The requested URL returned error: %d",
k->httpcode);
return CURLE_HTTP_RETURNED_ERROR; return CURLE_HTTP_RETURNED_ERROR;
} }
@@ -701,9 +722,93 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if(data->set.get_filetime) if(data->set.get_filetime)
data->info.filetime = k->timeofdoc; data->info.filetime = k->timeofdoc;
} }
else if(checkprefix("WWW-Authenticate:", k->p) &&
(401 == k->httpcode)) {
/*
* This page requires authentication
*/
char *start = k->p+strlen("WWW-Authenticate:");
/* pass all white spaces */
while(*start && isspace((int)*start))
start++;
#ifdef GSSAPI
if (checkprefix("GSS-Negotiate", start)) {
if(data->state.authwant == CURLAUTH_GSSNEGOTIATE) {
/* if exactly this is wanted, go */
int neg = Curl_input_negotiate(conn, start);
if (neg == 0)
conn->newurl = strdup(data->change.url);
}
else
if(data->state.authwant & CURLAUTH_GSSNEGOTIATE)
data->state.authavail |= CURLAUTH_GSSNEGOTIATE;
}
else
#endif
#ifdef USE_SSLEAY
/* NTLM support requires the SSL crypto libs */
if(checkprefix("NTLM", start)) {
if(data->state.authwant == CURLAUTH_NTLM) {
/* NTLM authentication is activated */
CURLntlm ntlm =
Curl_input_ntlm(conn, FALSE, start);
if(CURLNTLM_BAD != ntlm)
conn->newurl = strdup(data->change.url); /* clone string */
else
infof(data, "Authentication problem. Ignoring this.\n");
}
else
if(data->state.authwant & CURLAUTH_NTLM)
data->state.authavail |= CURLAUTH_NTLM;
}
else
#endif
if(checkprefix("Digest", start)) {
if(data->state.authwant == CURLAUTH_DIGEST) {
/* Digest authentication is activated */
CURLdigest dig = CURLDIGEST_BAD;
if(data->state.digest.nonce)
infof(data, "Authentication problem. Ignoring this.\n");
else
dig = Curl_input_digest(conn, start);
if(CURLDIGEST_FINE == dig)
/* We act on it. Store our new url, which happens to be
the same one we already use! */
conn->newurl = strdup(data->change.url); /* clone string */
}
else
if(data->state.authwant & CURLAUTH_DIGEST) {
/* We don't know if Digest is what we're gonna use, but we
call this function anyway to store the digest data that
is provided on this line, to skip the extra round-trip
we need to do otherwise. We must sure to free this
data! */
Curl_input_digest(conn, start);
data->state.authavail |= CURLAUTH_DIGEST;
}
}
else if(checkprefix("Basic", start)) {
if((data->state.authwant == CURLAUTH_BASIC) &&
(k->httpcode == 401)) {
/* We asked for Basic authentication but got a 401 back
anyway, which basicly means our name+password isn't
valid. */
data->state.authavail = CURLAUTH_NONE;
infof(data, "Authentication problem. Ignoring this.\n");
}
else if(data->state.authwant & CURLAUTH_BASIC) {
data->state.authavail |= CURLAUTH_BASIC;
}
}
}
else if ((k->httpcode >= 300 && k->httpcode < 400) && else if ((k->httpcode >= 300 && k->httpcode < 400) &&
(data->set.http_follow_location) &&
checkprefix("Location:", k->p)) { checkprefix("Location:", k->p)) {
if(data->set.http_follow_location) {
/* this is the URL that the server advices us to get instead */ /* this is the URL that the server advices us to get instead */
char *ptr; char *ptr;
char *start=k->p; char *start=k->p;
@@ -715,11 +820,17 @@ CURLcode Curl_readwrite(struct connectdata *conn,
white spaces after the "Location:" keyword. */ white spaces after the "Location:" keyword. */
while(*start && isspace((int)*start )) while(*start && isspace((int)*start ))
start++; start++;
ptr = start; /* start scanning here */
/* scan through the string to find the end */ /* Scan through the string from the end to find the last
while(*ptr && !isspace((int)*ptr)) non-space. k->end_ptr points to the actual terminating zero
letter, move pointer one letter back and start from
there. This logic strips off trailing whitespace, but keeps
any embedded whitespace. */
ptr = k->end_ptr-1;
while((ptr>=start) && isspace((int)*ptr))
ptr--;
ptr++; ptr++;
backup = *ptr; /* store the ending letter */ backup = *ptr; /* store the ending letter */
if(ptr != start) { if(ptr != start) {
*ptr = '\0'; /* zero terminate */ *ptr = '\0'; /* zero terminate */
@@ -727,21 +838,28 @@ CURLcode Curl_readwrite(struct connectdata *conn,
*ptr = backup; /* restore ending letter */ *ptr = backup; /* restore ending letter */
} }
} }
#if 0 /* for consideration */
else {
/* This is a Location: but we have not been instructed to
follow it */
infof(data, "We ignore this location header as instructed\n");
}
#endif
}
/* /*
* End of header-checks. Write them to the client. * End of header-checks. Write them to the client.
*/ */
k->writetype = CLIENTWRITE_HEADER; writetype = CLIENTWRITE_HEADER;
if (data->set.http_include_header) if (data->set.http_include_header)
k->writetype |= CLIENTWRITE_BODY; writetype |= CLIENTWRITE_BODY;
if(data->set.verbose) if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN, Curl_debug(data, CURLINFO_HEADER_IN,
k->p, k->hbuflen); k->p, k->hbuflen);
result = Curl_client_write(data, k->writetype, k->p, result = Curl_client_write(data, writetype, k->p, k->hbuflen);
k->hbuflen);
if(result) if(result)
return result; return result;
@@ -774,15 +892,41 @@ CURLcode Curl_readwrite(struct connectdata *conn,
write a piece of the body */ write a piece of the body */
if(conn->protocol&PROT_HTTP) { if(conn->protocol&PROT_HTTP) {
/* HTTP-only checks */ /* HTTP-only checks */
if(data->state.authavail) {
if(data->state.authavail & CURLAUTH_GSSNEGOTIATE)
data->state.authwant = CURLAUTH_GSSNEGOTIATE;
else if(data->state.authavail & CURLAUTH_DIGEST)
data->state.authwant = CURLAUTH_DIGEST;
else if(data->state.authavail & CURLAUTH_NTLM)
data->state.authwant = CURLAUTH_NTLM;
else if(data->state.authavail & CURLAUTH_BASIC)
data->state.authwant = CURLAUTH_BASIC;
else
data->state.authwant = CURLAUTH_NONE; /* none */
if(data->state.authwant)
conn->newurl = strdup(data->change.url); /* clone string */
data->state.authavail = CURLAUTH_NONE; /* clear it here */
}
if (conn->newurl) { if (conn->newurl) {
/* abort after the headers if "follow Location" is set */ if(conn->bits.close) {
infof (data, "Follow to new URL: %s\n", conn->newurl); /* Abort after the headers if "follow Location" is set
and we're set to close anyway. */
k->keepon &= ~KEEP_READ; k->keepon &= ~KEEP_READ;
FD_ZERO(&k->rkeepfd); FD_ZERO(&k->rkeepfd);
*done = TRUE; *done = TRUE;
return CURLE_OK; return CURLE_OK;
} }
else if (conn->resume_from && /* We have a new url to load, but since we want to be able
to re-use this connection properly, we read the full
response in "ignore more" */
k->ignorebody = TRUE;
infof(data, "Ignoring the response-body\n");
}
if (conn->resume_from &&
!k->content_range && !k->content_range &&
(data->set.httpreq==HTTPREQ_GET)) { (data->set.httpreq==HTTPREQ_GET)) {
/* we wanted to resume a download, although the server /* we wanted to resume a download, although the server
@@ -883,7 +1027,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if(!conn->bits.chunk && (nread || k->badheader)) { if(!conn->bits.chunk && (nread || k->badheader)) {
/* If this is chunky transfer, it was already written */ /* If this is chunky transfer, it was already written */
if(k->badheader) { if(k->badheader && !k->ignorebody) {
/* we parsed a piece of data wrongly assuming it was a header /* we parsed a piece of data wrongly assuming it was a header
and now we output it as body instead */ and now we output it as body instead */
result = Curl_client_write(data, CLIENTWRITE_BODY, result = Curl_client_write(data, CLIENTWRITE_BODY,
@@ -904,6 +1048,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
Content-Encoding header. See Curl_readwrite_init; the Content-Encoding header. See Curl_readwrite_init; the
memset() call initializes k->content_encoding to zero. memset() call initializes k->content_encoding to zero.
08/28/02 jhrg */ 08/28/02 jhrg */
if(!k->ignorebody)
result = Curl_client_write(data, CLIENTWRITE_BODY, k->str, result = Curl_client_write(data, CLIENTWRITE_BODY, k->str,
nread); nread);
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
@@ -1186,6 +1331,7 @@ CURLcode Curl_readwrite_init(struct connectdata *conn)
k->maxfd = (conn->sockfd>conn->writesockfd? k->maxfd = (conn->sockfd>conn->writesockfd?
conn->sockfd:conn->writesockfd)+1; conn->sockfd:conn->writesockfd)+1;
k->hbufp = data->state.headerbuff; k->hbufp = data->state.headerbuff;
k->ignorebody=FALSE;
Curl_pgrsTime(data, TIMER_PRETRANSFER); Curl_pgrsTime(data, TIMER_PRETRANSFER);
Curl_speedinit(data); Curl_speedinit(data);
@@ -1355,6 +1501,10 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
data->state.this_is_a_follow = FALSE; /* reset this */ data->state.this_is_a_follow = FALSE; /* reset this */
data->state.errorbuf = FALSE; /* no error has occurred */ data->state.errorbuf = FALSE; /* no error has occurred */
/* set preferred authentication, default to basic */
data->state.authwant = data->set.httpauth?data->set.httpauth:CURLAUTH_BASIC;
data->state.authavail = CURLAUTH_NONE; /* nothing so far */
/* If there was a list of cookie files to read and we haven't done it before, /* If there was a list of cookie files to read and we haven't done it before,
do it now! */ do it now! */
if(data->change.cookielist) { if(data->change.cookielist) {
@@ -1401,6 +1551,60 @@ CURLcode Curl_posttransfer(struct SessionHandle *data)
return CURLE_OK; return CURLE_OK;
} }
static int strlen_url(char *url)
{
char *ptr;
int newlen=0;
bool left=TRUE; /* left side of the ? */
for(ptr=url; *ptr; ptr++) {
switch(*ptr) {
case '?':
left=FALSE;
default:
newlen++;
break;
case ' ':
if(left)
newlen+=3;
else
newlen++;
break;
}
}
return newlen;
}
static void strcpy_url(char *output, char *url)
{
/* we must add this with whitespace-replacing */
bool left=TRUE;
char *iptr;
char *optr = output;
for(iptr = url; /* read from here */
*iptr; /* until zero byte */
iptr++) {
switch(*iptr) {
case '?':
left=FALSE;
default:
*optr++=*iptr;
break;
case ' ':
if(left) {
*optr++='%'; /* add a '%' */
*optr++='2'; /* add a '2' */
*optr++='0'; /* add a '0' */
}
else
*optr++='+'; /* add a '+' here */
break;
}
}
*optr=0; /* zero terminate output buffer */
}
CURLcode Curl_follow(struct SessionHandle *data, CURLcode Curl_follow(struct SessionHandle *data,
char *newurl) /* this 'newurl' is the Location: string, char *newurl) /* this 'newurl' is the Location: string,
and it must be malloc()ed before passed and it must be malloc()ed before passed
@@ -1409,6 +1613,8 @@ CURLcode Curl_follow(struct SessionHandle *data,
/* Location: redirect */ /* Location: redirect */
char prot[16]; /* URL protocol string storage */ char prot[16]; /* URL protocol string storage */
char letter; /* used for a silly sscanf */ char letter; /* used for a silly sscanf */
int newlen;
char *newest;
if (data->set.maxredirs && if (data->set.maxredirs &&
(data->set.followlocation >= data->set.maxredirs)) { (data->set.followlocation >= data->set.maxredirs)) {
@@ -1445,9 +1651,9 @@ CURLcode Curl_follow(struct SessionHandle *data,
*/ */
char *protsep; char *protsep;
char *pathsep; char *pathsep;
char *newest;
char *useurl = newurl; char *useurl = newurl;
int urllen;
/* we must make our own copy of the URL to play with, as it may /* we must make our own copy of the URL to play with, as it may
point to read-only data */ point to read-only data */
@@ -1520,42 +1726,79 @@ CURLcode Curl_follow(struct SessionHandle *data,
*pathsep=0; *pathsep=0;
} }
newest=(char *)malloc( strlen(url_clone) + /* If the new part contains a space, this is a mighty stupid redirect
1 + /* possible slash */ but we still make an effort to do "right". To the left of a '?'
strlen(useurl) + 1/* zero byte */); letter we replace each space with %20 while it is replaced with '+'
on the right side of the '?' letter.
*/
newlen = strlen_url(useurl);
urllen = strlen(url_clone);
newest=(char *)malloc( urllen + 1 + /* possible slash */
newlen + 1 /* zero byte */);
if(!newest) if(!newest)
return CURLE_OUT_OF_MEMORY; /* go out from this */ return CURLE_OUT_OF_MEMORY; /* go out from this */
sprintf(newest, "%s%s%s", url_clone, /* copy over the root url part */
(('/' == useurl[0]) || (protsep && !*protsep))?"":"/", memcpy(newest, url_clone, urllen);
useurl);
/* check if we need to append a slash */
if(('/' == useurl[0]) || (protsep && !*protsep))
;
else
newest[urllen++]='/';
/* then append the new piece on the right side */
strcpy_url(&newest[urllen], useurl);
free(newurl); /* newurl is the allocated pointer */ free(newurl); /* newurl is the allocated pointer */
free(url_clone); free(url_clone);
newurl = newest; newurl = newest;
} }
else else {
/* This is an absolute URL, don't allow the custom port number */ /* This is an absolute URL, don't allow the custom port number */
data->state.allow_port = FALSE; data->state.allow_port = FALSE;
if(strchr(newurl, ' ')) {
/* This new URL contains at least one space, this is a mighty stupid
redirect but we still make an effort to do "right". */
newlen = strlen_url(newurl);
newest = malloc(newlen+1); /* get memory for this */
if(newest) {
strcpy_url(newest, newurl); /* create a space-free URL */
free(newurl); /* that was no good */
newurl = newest; /* use this instead now */
}
}
}
if(data->change.url_alloc) if(data->change.url_alloc)
free(data->change.url); free(data->change.url);
else else
data->change.url_alloc = TRUE; /* the URL is allocated */ data->change.url_alloc = TRUE; /* the URL is allocated */
/* TBD: set the URL with curl_setopt() */
data->change.url = newurl; data->change.url = newurl;
newurl = NULL; /* don't free! */ newurl = NULL; /* don't free! */
infof(data, "Follows Location: to new URL: '%s'\n", data->change.url); infof(data, "Issue another request to this URL: '%s'\n", data->change.url);
/* /*
* We get here when the HTTP code is 300-399. We need to perform * We get here when the HTTP code is 300-399 (and 401). We need to perform
* differently based on exactly what return code there was. * differently based on exactly what return code there was.
* Discussed on the curl mailing list and posted about on the 26th *
* of January 2001. * News from 7.10.6: we can also get here on a 401, in case we act on a
* HTTP authentication scheme other than Basic.
*/ */
switch(data->info.httpcode) { switch(data->info.httpcode) {
case 401:
/* Act on an authentication, we keep on moving and do the Authorization:
XXXX header in the HTTP request code snippet */
break;
case 300: /* Multiple Choices */ case 300: /* Multiple Choices */
case 306: /* Not used */ case 306: /* Not used */
case 307: /* Temporary Redirect */ case 307: /* Temporary Redirect */
@@ -1653,9 +1896,29 @@ CURLcode Curl_perform(struct SessionHandle *data)
* performed after this do-while loop. * performed after this do-while loop.
*/ */
do {
int urlchanged = FALSE;
do { do {
Curl_pgrsTime(data, TIMER_STARTSINGLE); Curl_pgrsTime(data, TIMER_STARTSINGLE);
data->change.url_changed = FALSE;
res = Curl_connect(data, &conn); res = Curl_connect(data, &conn);
/* If a callback (or something) has altered the URL we should use within
the Curl_connect(), we detect it here and act as if we are redirected
to the new URL */
urlchanged = data->change.url_changed;
if ((CURLE_OK == res) && urlchanged) {
char *newurl;
res = Curl_done(conn);
if(CURLE_OK == res) {
newurl = strdup(data->change.url);
res = Curl_follow(data, newurl);
if(res)
free(newurl);
}
}
} while (urlchanged && res == CURLE_OK) ;
if(res == CURLE_OK) { if(res == CURLE_OK) {
res = Curl_do(&conn); res = Curl_do(&conn);

257
lib/url.c
View File

@@ -45,7 +45,6 @@
#endif #endif
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
@@ -107,6 +106,8 @@
#include "strtok.h" #include "strtok.h"
#include "share.h" #include "share.h"
#include "content_encoding.h" #include "content_encoding.h"
#include "http_digest.h"
#include "http_negotiate.h"
/* And now for the protocols */ /* And now for the protocols */
#include "ftp.h" #include "ftp.h"
@@ -133,7 +134,7 @@
#endif #endif
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
#include "memdebug.h" #include "memdebug.h"
#endif #endif
@@ -165,6 +166,11 @@ RETSIGTYPE alarmfunc(int signal)
} }
#endif #endif
void Curl_safefree(void *ptr)
{
if(ptr)
free(ptr);
}
/* /*
* This is the internal function curl_easy_cleanup() calls. This should * This is the internal function curl_easy_cleanup() calls. This should
@@ -192,11 +198,8 @@ CURLcode Curl_close(struct SessionHandle *data)
if(data->change.cookielist) /* clean up list if any */ if(data->change.cookielist) /* clean up list if any */
curl_slist_free_all(data->change.cookielist); curl_slist_free_all(data->change.cookielist);
if(data->state.auth_host) Curl_safefree(data->state.auth_host);
free(data->state.auth_host); Curl_safefree(data->state.scratch);
if(data->state.scratch)
free(data->state.scratch);
if(data->change.proxy_alloc) if(data->change.proxy_alloc)
free(data->change.proxy); free(data->change.proxy);
@@ -207,8 +210,7 @@ CURLcode Curl_close(struct SessionHandle *data)
if(data->change.url_alloc) if(data->change.url_alloc)
free(data->change.url); free(data->change.url);
if(data->state.headerbuff) Curl_safefree(data->state.headerbuff);
free(data->state.headerbuff);
#ifndef CURL_DISABLE_HTTP #ifndef CURL_DISABLE_HTTP
if(data->set.cookiejar) { if(data->set.cookiejar) {
@@ -223,8 +225,9 @@ CURLcode Curl_close(struct SessionHandle *data)
/* free the connection cache */ /* free the connection cache */
free(data->state.connects); free(data->state.connects);
if(data->info.contenttype) Curl_safefree(data->info.contenttype);
free(data->info.contenttype);
Curl_digest_cleanup(data);
free(data); free(data);
return CURLE_OK; return CURLE_OK;
@@ -719,6 +722,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
} }
data->set.set_url = va_arg(param, char *); data->set.set_url = va_arg(param, char *);
data->change.url = data->set.set_url; data->change.url = data->set.set_url;
data->change.url_changed = TRUE;
break; break;
case CURLOPT_PORT: case CURLOPT_PORT:
/* /*
@@ -838,6 +842,26 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
data->set.encoding = (char*)ALL_CONTENT_ENCODINGS; data->set.encoding = (char*)ALL_CONTENT_ENCODINGS;
break; break;
case CURLOPT_HTTPAUTH:
/*
* Set HTTP Authentication type BITMASK.
*/
{
long auth = va_arg(param, long);
/* switch off bits we can't support */
#ifndef USE_SSLEAY
auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
#endif
#ifndef GSSAPI
auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
#endif
if(!auth)
return CURLE_FAILED_INIT; /* no supported types left! */
data->set.httpauth = auth;
}
break;
case CURLOPT_USERPWD: case CURLOPT_USERPWD:
/* /*
* user:password to use in the operation * user:password to use in the operation
@@ -1067,6 +1091,18 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
*/ */
data->set.ssl.verifyhost = va_arg(param, long); data->set.ssl.verifyhost = va_arg(param, long);
break; break;
case CURLOPT_SSL_CTX_FUNCTION:
/*
* Set a SSL_CTX callback
*/
data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
break;
case CURLOPT_SSL_CTX_DATA:
/*
* Set a SSL_CTX callback parameter pointer
*/
data->set.ssl.fsslctxp = va_arg(param, void *);
break;
case CURLOPT_CAINFO: case CURLOPT_CAINFO:
/* /*
* Set CA info for SSL connection. Specify file name of the CA certificate * Set CA info for SSL connection. Specify file name of the CA certificate
@@ -1196,14 +1232,9 @@ CURLcode Curl_disconnect(struct connectdata *conn)
/* This is set if protocol-specific cleanups should be made */ /* This is set if protocol-specific cleanups should be made */
conn->curl_disconnect(conn); conn->curl_disconnect(conn);
if(conn->proto.generic) Curl_safefree(conn->proto.generic);
free(conn->proto.generic); Curl_safefree(conn->newurl);
Curl_safefree(conn->path); /* the URL path part */
if(conn->newurl)
free(conn->newurl);
if(conn->path) /* the URL path part */
free(conn->path);
#ifdef USE_SSLEAY #ifdef USE_SSLEAY
Curl_SSL_Close(conn); Curl_SSL_Close(conn);
@@ -1215,27 +1246,20 @@ CURLcode Curl_disconnect(struct connectdata *conn)
if(-1 != conn->firstsocket) if(-1 != conn->firstsocket)
sclose(conn->firstsocket); sclose(conn->firstsocket);
if(conn->allocptr.proxyuserpwd) Curl_safefree(conn->user);
free(conn->allocptr.proxyuserpwd); Curl_safefree(conn->passwd);
if(conn->allocptr.uagent) Curl_safefree(conn->proxyuser);
free(conn->allocptr.uagent); Curl_safefree(conn->proxypasswd);
if(conn->allocptr.userpwd) Curl_safefree(conn->allocptr.proxyuserpwd);
free(conn->allocptr.userpwd); Curl_safefree(conn->allocptr.uagent);
if(conn->allocptr.accept_encoding) Curl_safefree(conn->allocptr.userpwd);
free(conn->allocptr.accept_encoding); Curl_safefree(conn->allocptr.accept_encoding);
if(conn->allocptr.rangeline) Curl_safefree(conn->allocptr.rangeline);
free(conn->allocptr.rangeline); Curl_safefree(conn->allocptr.ref);
if(conn->allocptr.ref) Curl_safefree(conn->allocptr.cookie);
free(conn->allocptr.ref); Curl_safefree(conn->allocptr.host);
if(conn->allocptr.cookie) Curl_safefree(conn->allocptr.cookiehost);
free(conn->allocptr.cookie); Curl_safefree(conn->proxyhost);
if(conn->allocptr.host)
free(conn->allocptr.host);
if(conn->allocptr.cookiehost)
free(conn->allocptr.cookiehost);
if(conn->proxyhost)
free(conn->proxyhost);
Curl_free_ssl_config(&conn->ssl_config); Curl_free_ssl_config(&conn->ssl_config);
@@ -1318,11 +1342,13 @@ ConnectionExists(struct SessionHandle *data,
continue; continue;
} }
} }
if(needle->protocol & PROT_FTP) { if((needle->protocol & PROT_FTP) ||
/* This is FTP, verify that we're using the same name and ((needle->protocol & PROT_HTTP) &&
password as well */ (needle->data->state.authwant==CURLAUTH_NTLM))) {
if(!strequal(needle->data->state.user, check->proto.ftp->user) || /* This is FTP or HTTP+NTLM, verify that we're using the same name
!strequal(needle->data->state.passwd, check->proto.ftp->passwd)) { and password as well */
if(!strequal(needle->user, check->user) ||
!strequal(needle->passwd, check->passwd)) {
/* one of them was different */ /* one of them was different */
continue; continue;
} }
@@ -1535,7 +1561,7 @@ static int handleSock5Proxy(
return 1; return 1;
} }
if ((socksreq[0] != 5) || /* version */ if ((socksreq[0] != 1) || /* version */
(socksreq[1] != 0)) { /* status */ (socksreq[1] != 0)) { /* status */
failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).", failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).",
socksreq[0], socksreq[1]); socksreq[0], socksreq[1]);
@@ -1678,8 +1704,8 @@ static CURLcode ConnectPlease(struct connectdata *conn,
#endif #endif
if (conn->data->set.proxytype == CURLPROXY_SOCKS5) { if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {
return handleSock5Proxy(conn->data->state.proxyuser, return handleSock5Proxy(conn->proxyuser,
conn->data->state.proxypasswd, conn->proxypasswd,
conn, conn,
conn->firstsocket) ? conn->firstsocket) ?
CURLE_COULDNT_CONNECT : CURLE_OK; CURLE_COULDNT_CONNECT : CURLE_OK;
@@ -1803,6 +1829,11 @@ static CURLcode CreateConnection(struct SessionHandle *data,
unsigned int prev_alarm=0; unsigned int prev_alarm=0;
#endif #endif
char endbracket; char endbracket;
char user[MAX_CURL_USER_LENGTH];
char passwd[MAX_CURL_PASSWORD_LENGTH];
bool passwdgiven=FALSE; /* set TRUE if an application-provided password has
been set */
#ifdef HAVE_SIGACTION #ifdef HAVE_SIGACTION
struct sigaction keep_sigact; /* store the old struct here */ struct sigaction keep_sigact; /* store the old struct here */
@@ -2016,29 +2047,36 @@ static CURLcode CreateConnection(struct SessionHandle *data,
* Take care of proxy authentication stuff * Take care of proxy authentication stuff
*************************************************************/ *************************************************************/
if(conn->bits.proxy_user_passwd) { if(conn->bits.proxy_user_passwd) {
data->state.proxyuser[0] =0; char proxyuser[MAX_CURL_USER_LENGTH]="";
data->state.proxypasswd[0]=0; char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
if(*data->set.proxyuserpwd != ':') { if(*data->set.proxyuserpwd != ':') {
/* the name is given, get user+password */ /* the name is given, get user+password */
sscanf(data->set.proxyuserpwd, "%127[^:]:%127[^\n]", sscanf(data->set.proxyuserpwd, "%127[^:]:%127[^\n]",
data->state.proxyuser, data->state.proxypasswd); proxyuser, proxypasswd);
} }
else else
/* no name given, get the password only */ /* no name given, get the password only */
sscanf(data->set.proxyuserpwd+1, "%127[^\n]", data->state.proxypasswd); sscanf(data->set.proxyuserpwd+1, "%127[^\n]", proxypasswd);
/* check for password, if no ask for one */ /* check for password, if no ask for one */
if( !data->state.proxypasswd[0] ) { if( !proxypasswd[0] ) {
if(data->set.fpasswd( data->set.passwd_client, if(data->set.fpasswd( data->set.passwd_client,
"proxy password:", "proxy password:",
data->state.proxypasswd, proxypasswd,
sizeof(data->state.proxypasswd))) { sizeof(proxypasswd))) {
failf(data, "Bad password from password callback"); failf(data, "Bad password from password callback");
return CURLE_BAD_PASSWORD_ENTERED; return CURLE_BAD_PASSWORD_ENTERED;
} }
} }
conn->proxyuser = strdup(proxyuser);
if(!conn->proxyuser)
return CURLE_OUT_OF_MEMORY;
conn->proxypasswd = strdup(proxypasswd);
if(!conn->proxypasswd)
return CURLE_OUT_OF_MEMORY;
} }
/************************************************************* /*************************************************************
@@ -2048,7 +2086,6 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->ppath = conn->path; conn->ppath = conn->path;
conn->hostname = conn->name; conn->hostname = conn->name;
/************************************************************* /*************************************************************
* Detect what (if any) proxy to use * Detect what (if any) proxy to use
*************************************************************/ *************************************************************/
@@ -2149,6 +2186,45 @@ static CURLcode CreateConnection(struct SessionHandle *data,
if(proxy && *proxy) { if(proxy && *proxy) {
/* we have a proxy here to set */ /* we have a proxy here to set */
char *ptr;
char user[MAX_CURL_USER_LENGTH];
char passwd[MAX_CURL_PASSWORD_LENGTH];
/* skip the possible protocol piece */
ptr=strstr(proxy, "://");
if(ptr)
ptr += 3;
else
ptr = proxy;
/* check for an @-letter */
ptr = strchr(ptr, '@');
if(ptr && (2 == sscanf(proxy, "%" MAX_CURL_USER_LENGTH_TXT"[^:]:"
"%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
user, passwd))) {
/* found user and password, rip them out */
if(conn->proxyuser)
free(conn->proxyuser);
conn->proxyuser = strdup(user);
if(!conn->proxyuser)
return CURLE_OUT_OF_MEMORY;
if(conn->proxypasswd)
free(conn->proxypasswd);
conn->proxypasswd = strdup(passwd);
if(!conn->proxypasswd)
return CURLE_OUT_OF_MEMORY;
conn->bits.proxy_user_passwd = TRUE; /* enable it */
ptr = strdup(ptr+1);
free(proxy); /* free the former data */
proxy = ptr; /* now use this instead */
}
data->change.proxy = proxy; data->change.proxy = proxy;
data->change.proxy_alloc=TRUE; /* this needs to be freed later */ data->change.proxy_alloc=TRUE; /* this needs to be freed later */
conn->bits.httpproxy = TRUE; conn->bits.httpproxy = TRUE;
@@ -2526,8 +2602,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
* *
* Outputs: (almost :- all currently undefined) * Outputs: (almost :- all currently undefined)
* conn->bits.user_passwd - non-zero if non-default passwords exist * conn->bits.user_passwd - non-zero if non-default passwords exist
* conn->state.user - non-zero length if defined * conn->user - non-zero length if defined
* conn->state.passwd - ditto * conn->passwd - ditto
* conn->hostname - remove user name and password * conn->hostname - remove user name and password
*/ */
@@ -2538,8 +2614,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
* We need somewhere to put the embedded details, so do that first. * We need somewhere to put the embedded details, so do that first.
*/ */
data->state.user[0] =0; /* to make everything well-defined */ user[0] =0; /* to make everything well-defined */
data->state.passwd[0]=0; passwd[0]=0;
if (conn->protocol & (PROT_FTP|PROT_HTTP)) { if (conn->protocol & (PROT_FTP|PROT_HTTP)) {
/* This is a FTP or HTTP URL, we will now try to extract the possible /* This is a FTP or HTTP URL, we will now try to extract the possible
@@ -2566,31 +2642,31 @@ static CURLcode CreateConnection(struct SessionHandle *data,
if(*userpass != ':') { if(*userpass != ':') {
/* the name is given, get user+password */ /* the name is given, get user+password */
sscanf(userpass, "%127[^:@]:%127[^@]", sscanf(userpass, "%127[^:@]:%127[^@]",
data->state.user, data->state.passwd); user, passwd);
} }
else else
/* no name given, get the password only */ /* no name given, get the password only */
sscanf(userpass, ":%127[^@]", data->state.passwd); sscanf(userpass, ":%127[^@]", passwd);
if(data->state.user[0]) { if(user[0]) {
char *newname=curl_unescape(data->state.user, 0); char *newname=curl_unescape(user, 0);
if(strlen(newname) < sizeof(data->state.user)) { if(strlen(newname) < sizeof(user)) {
strcpy(data->state.user, newname); strcpy(user, newname);
} }
/* if the new name is longer than accepted, then just use /* if the new name is longer than accepted, then just use
the unconverted name, it'll be wrong but what the heck */ the unconverted name, it'll be wrong but what the heck */
free(newname); free(newname);
} }
if (data->state.passwd[0]) { if (passwd[0]) {
/* we have a password found in the URL, decode it! */ /* we have a password found in the URL, decode it! */
char *newpasswd=curl_unescape(data->state.passwd, 0); char *newpasswd=curl_unescape(passwd, 0);
if(strlen(newpasswd) < sizeof(data->state.passwd)) { if(strlen(newpasswd) < sizeof(passwd)) {
strcpy(data->state.passwd, newpasswd); strcpy(passwd, newpasswd);
} }
free(newpasswd); free(newpasswd);
/* we have set the password */ /* we have set the password */
data->state.passwdgiven = TRUE; passwdgiven = TRUE;
} }
} }
} }
@@ -2609,35 +2685,35 @@ static CURLcode CreateConnection(struct SessionHandle *data,
if(*data->set.userpwd != ':') { if(*data->set.userpwd != ':') {
/* the name is given, get user+password */ /* the name is given, get user+password */
sscanf(data->set.userpwd, "%127[^:]:%127[^\n]", sscanf(data->set.userpwd, "%127[^:]:%127[^\n]",
data->state.user, data->state.passwd); user, passwd);
if(strchr(data->set.userpwd, ':')) if(strchr(data->set.userpwd, ':'))
/* a colon means the password was given, even if blank */ /* a colon means the password was given, even if blank */
data->state.passwdgiven = TRUE; passwdgiven = TRUE;
} }
else else
/* no name given, starts with a colon, get the password only */ /* no name given, starts with a colon, get the password only */
sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd); sscanf(data->set.userpwd+1, "%127[^\n]", passwd);
} }
if ((data->set.use_netrc != CURL_NETRC_IGNORED) && if ((data->set.use_netrc != CURL_NETRC_IGNORED) &&
!data->state.passwdgiven) { /* need passwd */ !passwdgiven) { /* need passwd */
if(Curl_parsenetrc(conn->hostname, if(Curl_parsenetrc(conn->hostname,
data->state.user, user,
data->state.passwd)) { passwd)) {
infof(data, "Couldn't find host %s in the .netrc file, using defaults", infof(data, "Couldn't find host %s in the .netrc file, using defaults",
conn->hostname); conn->hostname);
} }
else { else {
conn->bits.user_passwd = 1; /* enable user+password */ conn->bits.user_passwd = 1; /* enable user+password */
data->state.passwdgiven = TRUE; passwdgiven = TRUE;
} }
} }
/* if we have a user but no password, ask for one */ /* if we have a user but no password, ask for one */
if(conn->bits.user_passwd && !data->state.passwdgiven ) { if(conn->bits.user_passwd && !passwdgiven ) {
if(data->set.fpasswd(data->set.passwd_client, if(data->set.fpasswd(data->set.passwd_client,
"password:", data->state.passwd, "password:", passwd,
sizeof(data->state.passwd))) sizeof(passwd)))
return CURLE_BAD_PASSWORD_ENTERED; return CURLE_BAD_PASSWORD_ENTERED;
} }
@@ -2646,14 +2722,18 @@ static CURLcode CreateConnection(struct SessionHandle *data,
/* If our protocol needs a password and we have none, use the defaults */ /* If our protocol needs a password and we have none, use the defaults */
if ( (conn->protocol & (PROT_FTP|PROT_HTTP)) && if ( (conn->protocol & (PROT_FTP|PROT_HTTP)) &&
!conn->bits.user_passwd && !conn->bits.user_passwd &&
!data->state.passwdgiven) { !passwdgiven) {
strcpy(data->state.user, CURL_DEFAULT_USER); strcpy(user, CURL_DEFAULT_USER);
strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD); strcpy(passwd, CURL_DEFAULT_PASSWORD);
/* This is the default password, so DON'T set conn->bits.user_passwd */ /* This is the default password, so DON'T set conn->bits.user_passwd */
} }
/* store user + password */
conn->user = strdup(user);
conn->passwd = strdup(passwd);
/************************************************************* /*************************************************************
* 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
@@ -2713,6 +2793,9 @@ static CURLcode CreateConnection(struct SessionHandle *data,
otherwise */ otherwise */
conn->maxdownload = -1; /* might have been used previously! */ conn->maxdownload = -1; /* might have been used previously! */
free(old_conn->user);
free(old_conn->passwd);
free(old_conn); /* we don't need this anymore */ free(old_conn); /* we don't need this anymore */
/* /*
@@ -2817,6 +2900,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
if(conn->bits.reuse) { if(conn->bits.reuse) {
/* re-used connection, no resolving is necessary */ /* re-used connection, no resolving is necessary */
hostaddr = NULL; hostaddr = NULL;
conn->connect_addr = NULL; /* we don't connect now so we don't have any
fresh connect_addr struct to point to */
} }
else if(!data->change.proxy || !*data->change.proxy) { else if(!data->change.proxy || !*data->change.proxy) {
/* If not connecting via a proxy, extract the port from the URL, if it is /* If not connecting via a proxy, extract the port from the URL, if it is
@@ -2893,7 +2978,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
if(conn->bits.proxy_user_passwd) { if(conn->bits.proxy_user_passwd) {
char *authorization; char *authorization;
snprintf(data->state.buffer, BUFSIZE, "%s:%s", snprintf(data->state.buffer, BUFSIZE, "%s:%s",
data->state.proxyuser, data->state.proxypasswd); conn->proxyuser, conn->proxypasswd);
if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer), if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
&authorization) >= 0) { &authorization) >= 0) {
if(conn->allocptr.proxyuserpwd) if(conn->allocptr.proxyuserpwd)
@@ -3013,7 +3098,7 @@ CURLcode Curl_done(struct connectdata *conn)
if(conn->connect_addr) if(conn->connect_addr)
Curl_resolv_unlock(conn->data, conn->connect_addr); /* done with this */ Curl_resolv_unlock(conn->data, conn->connect_addr); /* done with this */
#if defined(MALLOCDEBUG) && defined(AGGRESIVE_TEST) #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
/* scan for DNS cache entries still marked as in use */ /* scan for DNS cache entries still marked as in use */
Curl_hash_apply(data->hostcache, Curl_hash_apply(data->hostcache,
NULL, Curl_scan_cache_used); NULL, Curl_scan_cache_used);

View File

@@ -42,4 +42,5 @@ bool Curl_ssl_config_matches(struct ssl_config_data* data,
bool Curl_clone_ssl_config(struct ssl_config_data* source, bool Curl_clone_ssl_config(struct ssl_config_data* source,
struct ssl_config_data* dest); struct ssl_config_data* dest);
void Curl_free_ssl_config(struct ssl_config_data* sslc); void Curl_free_ssl_config(struct ssl_config_data* sslc);
void Curl_safefree(void *ptr);
#endif #endif

View File

@@ -83,7 +83,11 @@
#include "hash.h" #include "hash.h"
#ifdef HAVE_ZLIB_H #ifdef HAVE_ZLIB_H
#include <zlib.h> /* for content-encoding 08/28/02 jhrg */ #include <zlib.h> /* for content-encoding */
#endif
#ifdef GSSAPI
#include <gssapi.h>
#endif #endif
/* Download buffer size, keep it fairly big for speed reasons */ /* Download buffer size, keep it fairly big for speed reasons */
@@ -141,6 +145,8 @@ struct ssl_config_data {
char *egdsocket; /* path to file containing the EGD daemon socket */ char *egdsocket; /* path to file containing the EGD daemon socket */
char *cipher_list; /* list of ciphers to use */ char *cipher_list; /* list of ciphers to use */
long numsessions; /* SSL session id cache size */ long numsessions; /* SSL session id cache size */
curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
void *fsslctxp; /*parameter for call back */
}; };
/* information stored about one single SSL session */ /* information stored about one single SSL session */
@@ -152,6 +158,36 @@ struct curl_ssl_session {
struct ssl_config_data ssl_config; /* setup for this session */ struct ssl_config_data ssl_config; /* setup for this session */
}; };
/* Struct used for Digest challenge-response authentication */
struct digestdata {
char *nonce;
char *cnonce;
char *realm;
int algo;
};
typedef enum {
NTLMSTATE_NONE,
NTLMSTATE_TYPE1,
NTLMSTATE_TYPE2,
NTLMSTATE_TYPE3,
NTLMSTATE_LAST
} curlntlm;
/* Struct used for Digest challenge-response authentication */
struct ntlmdata {
curlntlm state;
unsigned char nonce[8];
};
#ifdef GSSAPI
struct negotiatedata {
OM_uint32 status;
gss_ctx_id_t context;
gss_name_t server_name;
gss_buffer_desc output_token;
};
#endif
/**************************************************************************** /****************************************************************************
* HTTP unique setup * HTTP unique setup
@@ -306,7 +342,6 @@ struct Curl_transfer_keeper {
/* for the low speed checks: */ /* for the low speed checks: */
time_t timeofdoc; time_t timeofdoc;
long bodywrites; long bodywrites;
int writetype;
char *buf; char *buf;
char *uploadbuf; char *uploadbuf;
@@ -325,8 +360,9 @@ struct Curl_transfer_keeper {
bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload
and we're uploading the last chunk */ and we're uploading the last chunk */
};
bool ignorebody; /* we read a response-body but we ignore it! */
};
/* /*
* The connectdata struct contains all fields and variables that should be * The connectdata struct contains all fields and variables that should be
@@ -377,6 +413,12 @@ struct connectdata {
char *proxyhost; /* name of the http proxy host */ char *proxyhost; /* name of the http proxy host */
char *user; /* user name string, allocated */
char *passwd; /* password string, allocated */
char *proxyuser; /* proxy user name string, allocated */
char *proxypasswd; /* proxy password string, allocated */
struct timeval now; /* "current" time */ struct timeval now; /* "current" time */
struct timeval created; /* creation time */ struct timeval created; /* creation time */
int firstsocket; /* the main socket to use */ int firstsocket; /* the main socket to use */
@@ -432,7 +474,7 @@ struct connectdata {
struct dynamically_allocated_data { struct dynamically_allocated_data {
char *proxyuserpwd; /* free later if not NULL! */ char *proxyuserpwd; /* free later if not NULL! */
char *uagent; /* free later if not NULL! */ char *uagent; /* free later if not NULL! */
char *accept_encoding; /* free later if not NULL! 08/28/02 jhrg */ char *accept_encoding; /* free later if not NULL! */
char *userpwd; /* free later if not NULL! */ char *userpwd; /* free later if not NULL! */
char *rangeline; /* free later if not NULL! */ char *rangeline; /* free later if not NULL! */
char *ref; /* free later if not NULL! */ char *ref; /* free later if not NULL! */
@@ -491,9 +533,14 @@ struct connectdata {
curl_read_callback fread; /* function that reads the input */ curl_read_callback fread; /* function that reads the input */
void *fread_in; /* pointer to pass to the fread() above */ void *fread_in; /* pointer to pass to the fread() above */
struct ntlmdata ntlm; /* NTLM differs from other authentication schemes
because it authenticates connections, not
single requests! */
struct ntlmdata proxyntlm; /* NTLM data for proxy */
}; };
/* The end of connectdata. 08/27/02 jhrg */ /* The end of connectdata. */
/* /*
* Struct to keep statistical and informational data. * Struct to keep statistical and informational data.
@@ -501,7 +548,7 @@ struct connectdata {
struct PureInfo { struct PureInfo {
int httpcode; int httpcode;
int httpversion; int httpversion;
long filetime; /* If requested, this is might get set. Set to -1 if time_t filetime; /* If requested, this is might get set. Set to -1 if
the time was unretrievable */ the time was unretrievable */
long header_size; /* size of read header(s) in bytes */ long header_size; /* size of read header(s) in bytes */
long request_size; /* the amount of bytes sent in the request(s) */ long request_size; /* the amount of bytes sent in the request(s) */
@@ -564,6 +611,8 @@ typedef enum {
* Session-data MUST be put in the connectdata struct and here. */ * Session-data MUST be put in the connectdata struct and here. */
#define MAX_CURL_USER_LENGTH 256 #define MAX_CURL_USER_LENGTH 256
#define MAX_CURL_PASSWORD_LENGTH 256 #define MAX_CURL_PASSWORD_LENGTH 256
#define MAX_CURL_USER_LENGTH_TXT "255"
#define MAX_CURL_PASSWORD_LENGTH_TXT "255"
struct UrlState { struct UrlState {
enum { enum {
@@ -573,14 +622,6 @@ struct UrlState {
} used_interface; } used_interface;
/* buffers to store authentication data in, as parsed from input options */ /* buffers to store authentication data in, as parsed from input options */
char user[MAX_CURL_USER_LENGTH];
char passwd[MAX_CURL_PASSWORD_LENGTH];
char proxyuser[MAX_CURL_USER_LENGTH];
char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
bool passwdgiven; /* set TRUE if an application-provided password has been
set */
struct timeval keeps_speed; /* for the progress meter really */ struct timeval keeps_speed; /* for the progress meter really */
/* 'connects' will be an allocated array with pointers. If the pointer is /* 'connects' will be an allocated array with pointers. If the pointer is
@@ -617,6 +658,15 @@ struct UrlState {
#endif #endif
bool allow_port; /* Is set.use_port allowed to take effect or not. This bool allow_port; /* Is set.use_port allowed to take effect or not. This
is always set TRUE when curl_easy_perform() is called. */ is always set TRUE when curl_easy_perform() is called. */
struct digestdata digest;
#ifdef GSSAPI
struct negotiatedata negotiate;
#endif
long authwant; /* inherited from what the user set with CURLOPT_HTTPAUTH */
long authavail; /* what the server reports */
}; };
@@ -630,6 +680,10 @@ struct UrlState {
struct DynamicStatic { struct DynamicStatic {
char *url; /* work URL, copied from UserDefined */ char *url; /* work URL, copied from UserDefined */
bool url_alloc; /* URL string is malloc()'ed */ bool url_alloc; /* URL string is malloc()'ed */
bool url_changed; /* set on CURL_OPT_URL, used to detect if the URL was
changed after the connect phase, as we allow callback
to change it and if so, we reconnect to use the new
URL instead */
char *proxy; /* work proxy, copied from UserDefined */ char *proxy; /* work proxy, copied from UserDefined */
bool proxy_alloc; /* http proxy string is malloc()'ed */ bool proxy_alloc; /* http proxy string is malloc()'ed */
char *referer; /* referer string */ char *referer; /* referer string */
@@ -661,6 +715,7 @@ struct UserDefined {
char *set_proxy; /* proxy to use */ char *set_proxy; /* proxy to use */
long use_port; /* which port to use (when not using default) */ long use_port; /* which port to use (when not using default) */
char *userpwd; /* <user:password>, if used */ char *userpwd; /* <user:password>, if used */
long httpauth; /* what kind of HTTP authentication to use (bitmask) */
char *set_range; /* range, if used. See README for detailed specification char *set_range; /* range, if used. See README for detailed specification
on this syntax. */ on this syntax. */
long followlocation; /* as in HTTP Location: */ long followlocation; /* as in HTTP Location: */

View File

@@ -114,6 +114,10 @@ char *curl_version(void)
sprintf(ptr, " zlib/%s", zlibVersion()); sprintf(ptr, " zlib/%s", zlibVersion());
ptr += strlen(ptr); ptr += strlen(ptr);
#endif #endif
#ifdef GSSAPI
sprintf(ptr, " GSS");
ptr += strlen(ptr);
#endif
return version; return version;
} }
@@ -168,9 +172,16 @@ static curl_version_info_data version_info = {
#endif #endif
#ifdef USE_SSLEAY #ifdef USE_SSLEAY
| CURL_VERSION_SSL | CURL_VERSION_SSL
| CURL_VERSION_NTLM /* since this requires OpenSSL */
#endif #endif
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
| CURL_VERSION_LIBZ | CURL_VERSION_LIBZ
#endif
#ifdef GSSAPI
| CURL_VERSION_GSSNEGOTIATE
#endif
#ifdef CURLDEBUG
| CURL_VERSION_DEBUG
#endif #endif
, ,
NULL, /* ssl_version */ NULL, /* ssl_version */

View File

@@ -134,3 +134,8 @@ echo ""
ls -l $targz $bzip2 $zip ls -l $targz $bzip2 $zip
md5sum $targz $bzip2 $zip md5sum $targz $bzip2 $zip
echo "Run these commands:"
echo "gpg -b -a $targz"
echo "gpg -b -a $bzip2"
echo "gpg -b -a $zip"

2
packages/DOS/.cvsignore Normal file
View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

1
packages/DOS/Makefile.am Normal file
View File

@@ -0,0 +1 @@
EXTRA_DIST = README common.dj

4
packages/DOS/README Normal file
View File

@@ -0,0 +1,4 @@
Gisle Vanem made curl build fine on DOS (and MingW) with djgpp, OpenSSL and his
Watt-32 stack.
'make djgpp' in the root curl dir should build it fine.

56
packages/DOS/common.dj Normal file
View File

@@ -0,0 +1,56 @@
#
# Common defines for curl (djgpp/Watt-32)
#
# Assumes you've unpacked cURL with short-file names
# I.e use "set LFN=n" before untaring on Win9x/XP.
# Requires sed, yacc, rm and the usual stuff.
#
.SUFFIXES: .exe .y
MAKEFILE = Makefile.dj
#
# OpenSSL is available from www.openssl.org and builds okay
# with djgpp/Watt-32. Set to 0 if you don't need https URLs
# (reduces curl.exe with approx 700 kB)
#
USE_SSL = 1
default: all
#
# Root directory for Waterloo tcp/ip. WATT_ROOT should be set
# during Watt-32 install.
#
WATT32_ROOT = $(subst \,/,$(WATT_ROOT))
OPENSSL_ROOT = /net/openssl.098
ZLIB_ROOT = $(DJDIR)/contrib/zlib
CC = gcc
YACC = bison -y
CFLAGS = -g -O2 -I. -I../include -Wall -DHAVE_CONFIG_H
ifeq ($(USE_SSL),1)
CFLAGS += -DUSE_SSLEAY -DHAVE_OPENSSL_ENGINE_H
endif
#
# Generated dependencies; Due to some hacks in gcc 2.95+ and djgpp 2.03
# we must prevent "$(DJDIR)/bin/../include/sys/version.h" from beeing
# included in dependency output (or else this makefile cannot be used on
# another machine). We therefore use a special 'specs' file during
# pre-processing.
#
MM_SPECS = $(TMPDIR)/specs
depend: $(DEPEND_PREREQ)
@echo Generating dependencies..
@copy $(MAKEFILE) Makefile.bak
@echo "*cpp: %(cpp_cpu) %{posix:-D_POSIX_SOURCE} -remap" > $(MM_SPECS)
sed -e "/^# DO NOT DELETE THIS LINE/,$$d" < Makefile.bak > $(MAKEFILE)
echo "# DO NOT DELETE THIS LINE" >> $(MAKEFILE)
$(CC) -MM -specs=$(MM_SPECS) $(CFLAGS) $(SOURCES) >> $(MAKEFILE)
rm -f $(MM_SPECS)

View File

@@ -1,3 +1,3 @@
SUBDIRS = Win32 Linux Solaris EPM SUBDIRS = Win32 Linux Solaris EPM DOS
EXTRA_DIST = README EXTRA_DIST = README

View File

@@ -11,6 +11,14 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/src -I$(top_srcdir)/src
bin_PROGRAMS = curl #memtest bin_PROGRAMS = curl #memtest
if HAVE_LIBZ
# libz available, attempt to compress the help data
MKHELPOPT=-c
else
# no libz, don't try to compress
MKHELPOPT=
endif
#memtest_SOURCES = memtest.c #memtest_SOURCES = memtest.c
#memtest_LDADD = $(top_srcdir)/lib/libcurl.la #memtest_LDADD = $(top_srcdir)/lib/libcurl.la
@@ -24,7 +32,7 @@ BUILT_SOURCES = hugehelp.c
CLEANFILES = hugehelp.c CLEANFILES = hugehelp.c
NROFF=@NROFF@ NROFF=@NROFF@
EXTRA_DIST = mkhelp.pl curlmsg.msg \ EXTRA_DIST = mkhelp.pl curlmsg.msg makefile.dj \
Makefile.vc6 Makefile.b32 Makefile.m32 Makefile.riscos config.h.in \ Makefile.vc6 Makefile.b32 Makefile.m32 Makefile.riscos config.h.in \
macos/curl.mcp.xml.sit.hqx \ macos/curl.mcp.xml.sit.hqx \
macos/MACINSTALL.TXT \ macos/MACINSTALL.TXT \
@@ -38,4 +46,4 @@ MKHELP=$(top_srcdir)/src/mkhelp.pl
# This generates the hugehelp.c file # This generates the hugehelp.c file
hugehelp.c: $(README) $(MANPAGE) mkhelp.pl hugehelp.c: $(README) $(MANPAGE) mkhelp.pl
rm -f hugehelp.c rm -f hugehelp.c
$(NROFF) -man $(MANPAGE) | $(PERL) $(MKHELP) $(README) > hugehelp.c $(NROFF) -man $(MANPAGE) | $(PERL) -s $(MKHELP) $(MKHELPOPT) $(README) > hugehelp.c

View File

@@ -22,7 +22,7 @@ ZLIB_PATH = ../../zlib-1.1.4
######################################################## ########################################################
## Nothing more to do below this line! ## Nothing more to do below this line!
INCLUDES = -I. -I.. -I../include INCLUDES = -I. -I.. -I../include -I$(ZLIB_PATH)
CFLAGS = -g -O2 -DMINGW32 CFLAGS = -g -O2 -DMINGW32
ifdef SSL ifdef SSL
CFLAGS += -DUSE_SSLEAY -DHAVE_OPENSSL_ENGINE_H CFLAGS += -DUSE_SSLEAY -DHAVE_OPENSSL_ENGINE_H
@@ -41,13 +41,10 @@ else
curl_DEPENDENCIES = ../lib/libcurl.a curl_DEPENDENCIES = ../lib/libcurl.a
curl_LDADD = -L../lib -lcurl curl_LDADD = -L../lib -lcurl
endif endif
curl_LDADD += -lwsock32 -lws2_32 -lwinmm curl_LDADD += -lwsock32 -lws2_32 -lwinmm -L$(ZLIB_PATH) -lz
ifdef SSL ifdef SSL
curl_LDADD += -L$(OPENSSL_PATH)/out -leay32 -lssl32 curl_LDADD += -L$(OPENSSL_PATH)/out -leay32 -lssl32
endif endif
ifdef ZLIB
curl_LDADD += -L$(ZLIB_PATH) -lz
endif
PROGRAMS = $(curl_PROGRAMS) PROGRAMS = $(curl_PROGRAMS)
SOURCES = $(curl_SOURCES) SOURCES = $(curl_SOURCES)

View File

@@ -101,3 +101,5 @@ clean:
distrib: clean distrib: clean
-@erase $(PROGRAM_NAME) -@erase $(PROGRAM_NAME)
hugehelp.c: hugehelp.c.cvs
copy hugehelp.c.cvs hugehelp.c

View File

@@ -29,12 +29,17 @@
/* Define if you have the <sys/poll.h> header file */ /* Define if you have the <sys/poll.h> header file */
#undef HAVE_SYS_POLL_H #undef HAVE_SYS_POLL_H
/* Define if you have the `setvbuf' function. */
#undef HAVE_SETVBUF
/* Define if you have the `poll' function. */ /* Define if you have the `poll' function. */
#undef HAVE_POLL #undef HAVE_POLL
/* Define if you can write to argc[] strings */ /* Define if you can write to argc[] strings */
#undef HAVE_WRITABLE_ARGV #undef HAVE_WRITABLE_ARGV
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <time.h> header file. */
#undef HAVE_TIME_H
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME

View File

@@ -50,6 +50,19 @@
#include <winsock.h> #include <winsock.h>
#endif #endif
#ifdef TIME_WITH_SYS_TIME
/* We can include both fine */
#include <sys/time.h>
#include <time.h>
#else
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#else
# include <time.h>
#endif
#endif
#include "version.h" #include "version.h"
#ifdef HAVE_IO_H /* typical win32 habit */ #ifdef HAVE_IO_H /* typical win32 habit */
@@ -78,13 +91,30 @@
#endif #endif
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
/* this is low-level hard-hacking memory leak tracking shit */ /* This is low-level hard-hacking memory leak tracking and similar. Using
the library level code from this client-side is ugly, but we do this
anyway for convenience. */
#include "../lib/memdebug.h" #include "../lib/memdebug.h"
#endif #endif
#define DEFAULT_MAXREDIRS 50L #define DEFAULT_MAXREDIRS 50L
#ifdef __DJGPP__
void *xmalloc(size_t);
char *msdosify(char *);
char *rename_if_dos_device_name(char *);
void xfree(void *);
#include <limits.h>
#include <fcntl.h>
struct pollfd {
int fd;
int events; /* in param: what to poll for */
int revents; /* out param: what events occured */
};
int poll (struct pollfd *, int, int);
#endif /* __DJGPP__ */
#ifndef __cplusplus /* (rabe) */ #ifndef __cplusplus /* (rabe) */
#ifndef typedef_bool #ifndef typedef_bool
typedef char bool; typedef char bool;
@@ -314,7 +344,8 @@ static void helpf(const char *fmt, ...)
vfprintf(stderr, fmt, ap); vfprintf(stderr, fmt, ap);
va_end(ap); va_end(ap);
} }
fprintf(stderr, "curl: try 'curl --help' for more information\n"); fprintf(stderr, "curl: try 'curl --help' or "
"'curl --manual' for more information\n");
} }
/* /*
@@ -338,14 +369,18 @@ static void help(void)
"Options: (H) means HTTP/HTTPS only, (F) means FTP only\n" "Options: (H) means HTTP/HTTPS only, (F) means FTP only\n"
" -a/--append Append to target file when uploading (F)\n" " -a/--append Append to target file when uploading (F)\n"
" -A/--user-agent <string> User-Agent to send to server (H)\n" " -A/--user-agent <string> User-Agent to send to server (H)\n"
" --anyauth Tell curl to choose authentication method (H)\n"
" -b/--cookie <name=string/file> Cookie string or file to read cookies from (H)\n" " -b/--cookie <name=string/file> Cookie string or file to read cookies from (H)\n"
" --basic Enable HTTP Basic Authentication (H)\n"
" -B/--use-ascii Use ASCII/text transfer\n", " -B/--use-ascii Use ASCII/text transfer\n",
curl_version()); curl_version());
puts(" -c/--cookie-jar <file> Write all cookies to this file after operation (H)\n" puts(" -c/--cookie-jar <file> Write all cookies to this file after operation (H)\n"
" -C/--continue-at <offset> Specify absolute resume offset\n" " -C/--continue-at <offset> Specify absolute resume offset\n"
" -d/--data <data> HTTP POST data (H)\n" " -d/--data <data> HTTP POST data (H)\n"
" --data-ascii <data> HTTP POST ASCII data (H)\n" " --data-ascii <data> HTTP POST ASCII data (H)\n"
" --data-binary <data> HTTP POST binary data (H)"); " --data-binary <data> HTTP POST binary data (H)\n"
" --negotiate Enable HTTP Negotiate Authentication (H - req GSS-lib)\n"
" --digest Enable HTTP Digest Authentication (H)");
puts(" --disable-eprt Prevents curl from using EPRT or LPRT (F)\n" puts(" --disable-eprt Prevents curl from using EPRT or LPRT (F)\n"
" --disable-epsv Prevents curl from using EPSV (F)\n" " --disable-epsv Prevents curl from using EPSV (F)\n"
" -D/--dump-header <file> Write the headers to this file\n" " -D/--dump-header <file> Write the headers to this file\n"
@@ -390,7 +425,8 @@ static void help(void)
" -M/--manual Display huge help text\n" " -M/--manual Display huge help text\n"
" -n/--netrc Must read .netrc for user name and password\n" " -n/--netrc Must read .netrc for user name and password\n"
" --netrc-optional Use either .netrc or URL; overrides -n\n" " --netrc-optional Use either .netrc or URL; overrides -n\n"
" -N/--no-buffer Disables the buffering of the output stream"); " --ntlm Enable HTTP NTLM authentication (H)");
puts(" -N/--no-buffer Disables the buffering of the output stream");
puts(" -o/--output <file> Write output to <file> instead of stdout\n" puts(" -o/--output <file> Write output to <file> instead of stdout\n"
" -O/--remote-name Write output to a file named as the remote file\n" " -O/--remote-name Write output to a file named as the remote file\n"
" -p/--proxytunnel Perform non-HTTP services through a HTTP proxy\n" " -p/--proxytunnel Perform non-HTTP services through a HTTP proxy\n"
@@ -412,6 +448,9 @@ static void help(void)
" -U/--proxy-user <user[:password]> Specify Proxy authentication\n" " -U/--proxy-user <user[:password]> Specify Proxy authentication\n"
" -v/--verbose Makes the operation more talkative\n" " -v/--verbose Makes the operation more talkative\n"
" -V/--version Outputs version number then quits"); " -V/--version Outputs version number then quits");
#ifdef __DJGPP__
puts(" --wdebug Turns on WATT-32 debugging under DJGPP");
#endif
puts(" -w/--write-out [format] What to output after completion\n" puts(" -w/--write-out [format] What to output after completion\n"
" -x/--proxy <host[:port]> Use proxy. (Default port is 1080)\n" " -x/--proxy <host[:port]> Use proxy. (Default port is 1080)\n"
" --random-file <file> File to use for reading random data from (SSL)\n" " --random-file <file> File to use for reading random data from (SSL)\n"
@@ -443,6 +482,7 @@ struct Configurable {
char *cookiefile; /* read from this file */ char *cookiefile; /* read from this file */
bool cookiesession; /* new session? */ bool cookiesession; /* new session? */
bool encoding; /* Accept-Encoding please */ bool encoding; /* Accept-Encoding please */
long authtype; /* auth bitmask */
bool use_resume; bool use_resume;
bool resume_from_current; bool resume_from_current;
bool disable_epsv; bool disable_epsv;
@@ -536,6 +576,9 @@ struct Configurable {
size_t lastrecvsize; size_t lastrecvsize;
}; };
/* global variable to hold info about libcurl */
static curl_version_info_data *curlinfo;
static int parseconfig(const char *filename, static int parseconfig(const char *filename,
struct Configurable *config); struct Configurable *config);
static char *my_get_line(FILE *fp); static char *my_get_line(FILE *fp);
@@ -1034,6 +1077,14 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
{"5h", "trace-ascii", TRUE}, {"5h", "trace-ascii", TRUE},
{"5i", "limit-rate", TRUE}, {"5i", "limit-rate", TRUE},
{"5j", "compressed", FALSE}, /* might take an arg someday */ {"5j", "compressed", FALSE}, /* might take an arg someday */
{"5k", "digest", FALSE},
{"5l", "negotiate", FALSE},
{"5m", "ntlm", FALSE},
{"5n", "basic", FALSE},
{"5o", "anyauth", FALSE},
#ifdef __DJGPP__
{"5p", "wdebug", FALSE},
#endif
{"0", "http1.0", FALSE}, {"0", "http1.0", FALSE},
{"1", "tlsv1", FALSE}, {"1", "tlsv1", FALSE},
{"2", "sslv2", FALSE}, {"2", "sslv2", FALSE},
@@ -1258,6 +1309,32 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
config->encoding ^= TRUE; config->encoding ^= TRUE;
break; break;
case 'k': /* --digest */
config->authtype = CURLAUTH_DIGEST;
break;
case 'l': /* --negotiate */
config->authtype = CURLAUTH_GSSNEGOTIATE;
break;
case 'm': /* --ntlm */
config->authtype = CURLAUTH_NTLM;
break;
case 'n': /* --basic for completeness */
config->authtype = CURLAUTH_BASIC;
break;
case 'o': /* --anyauth, let libcurl pick it */
config->authtype = CURLAUTH_ANY;
break;
#ifdef __DJGPP__
case 'p': /* --wdebug */
dbug_init();
break;
#endif
default: /* the URL! */ default: /* the URL! */
{ {
struct getout *url; struct getout *url;
@@ -1673,7 +1750,40 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
config->conf ^= CONF_VERBOSE; /* talk a lot */ config->conf ^= CONF_VERBOSE; /* talk a lot */
break; break;
case 'V': case 'V':
{
const char **proto;
printf(CURL_ID "%s\n", curl_version()); printf(CURL_ID "%s\n", curl_version());
if (curlinfo->protocols) {
printf("Protocols: ");
for (proto=curlinfo->protocols; *proto; ++proto) {
printf("%s ", *proto);
}
puts(""); /* newline */
}
if(curlinfo->features) {
unsigned int i;
struct feat {
const char *name;
int bitmask;
};
struct feat feats[] = {
{"IPv6", CURL_VERSION_IPV6},
{"krb4", CURL_VERSION_KERBEROS4},
{"SSL", CURL_VERSION_SSL},
{"libz", CURL_VERSION_LIBZ},
{"NTLM", CURL_VERSION_NTLM},
{"GSS-Negotiate", CURL_VERSION_GSSNEGOTIATE},
{"Debug", CURL_VERSION_DEBUG}
};
printf("Features: ");
for(i=0; i<sizeof(feats)/sizeof(feats[0]); i++) {
if(curlinfo->features & feats[i].bitmask)
printf("%s ", feats[i].name);
}
puts(""); /* newline */
}
}
return PARAM_HELP_REQUESTED; return PARAM_HELP_REQUESTED;
case 'w': case 'w':
/* get the output string */ /* get the output string */
@@ -1791,7 +1901,7 @@ static int parseconfig(const char *filename,
filename = filebuffer; filename = filebuffer;
} }
free(home); /* we've used it, now free it */ curl_free(home); /* we've used it, now free it */
} }
} }
@@ -1974,6 +2084,7 @@ struct OutStruct {
int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{ {
int rc;
struct OutStruct *out=(struct OutStruct *)stream; struct OutStruct *out=(struct OutStruct *)stream;
struct Configurable *config = out->config; struct Configurable *config = out->config;
if(out && !out->stream) { if(out && !out->stream) {
@@ -1981,12 +2092,6 @@ int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
out->stream=fopen(out->filename, "wb"); out->stream=fopen(out->filename, "wb");
if(!out->stream) if(!out->stream)
return -1; /* failure */ return -1; /* failure */
if(config->nobuffer) {
/* disable output buffering */
#ifdef HAVE_SETVBUF
setvbuf(out->stream, NULL, _IONBF, 0);
#endif
}
} }
if(config->recvpersecond) { if(config->recvpersecond) {
@@ -2009,7 +2114,13 @@ int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
config->lastrecvtime = now; config->lastrecvtime = now;
} }
return fwrite(buffer, size, nmemb, out->stream); rc = fwrite(buffer, size, nmemb, out->stream);
if(config->nobuffer)
/* disable output buffering */
fflush(out->stream);
return rc;
} }
struct InStruct { struct InStruct {
@@ -2058,11 +2169,10 @@ int my_fread(void *buffer, size_t size, size_t nmemb, void *userp)
struct ProgressData { struct ProgressData {
int calls; int calls;
double total;
double prev; double prev;
double point;
int width; int width;
FILE *out; /* where to write everything to */ FILE *out; /* where to write everything to */
int initial_size;
}; };
int myprogress (void *clientp, int myprogress (void *clientp,
@@ -2084,22 +2194,21 @@ int myprogress (void *clientp,
int i; int i;
struct ProgressData *bar = (struct ProgressData *)clientp; struct ProgressData *bar = (struct ProgressData *)clientp;
double total = dltotal + ultotal; double total = dltotal + ultotal + bar->initial_size;
double point = dlnow + ulnow + bar->initial_size; /* we've come this far */
bar->point = dlnow + ulnow; /* we've come this far */
bar->calls++; /* simply count invokes */ bar->calls++; /* simply count invokes */
if(0 == total) { if(0 == total) {
int prevblock = (int)bar->prev / 1024; int prevblock = (int)bar->prev / 1024;
int thisblock = (int)bar->point / 1024; int thisblock = (int)point / 1024;
while ( thisblock > prevblock ) { while ( thisblock > prevblock ) {
fprintf( bar->out, "#" ); fprintf( bar->out, "#" );
prevblock++; prevblock++;
} }
} }
else { else {
frac = bar->point / total; frac = point / total;
percent = frac * 100.0f; percent = frac * 100.0f;
barwidth = bar->width - 7; barwidth = bar->width - 7;
num = (int) (((double)barwidth) * frac); num = (int) (((double)barwidth) * frac);
@@ -2112,7 +2221,7 @@ int myprogress (void *clientp,
sprintf( outline, format, line, percent ); sprintf( outline, format, line, percent );
fprintf( bar->out, "\r%s", outline ); fprintf( bar->out, "\r%s", outline );
} }
bar->prev = bar->point; bar->prev = point;
return 0; return 0;
} }
@@ -2129,6 +2238,12 @@ void progressbarinit(struct ProgressData *bar,
memset(bar, 0, sizeof(struct ProgressData)); memset(bar, 0, sizeof(struct ProgressData));
/* pass this through to progress function so
* it can display progress towards total file
* not just the part that's left. (21-may-03, dbyron) */
if (config->use_resume)
bar->initial_size = config->resume_from;
/* TODO: get terminal width through ansi escapes or something similar. /* TODO: get terminal width through ansi escapes or something similar.
try to update width when xterm is resized... - 19990617 larsa */ try to update width when xterm is resized... - 19990617 larsa */
#ifndef __EMX__ #ifndef __EMX__
@@ -2138,7 +2253,7 @@ void progressbarinit(struct ProgressData *bar,
colp = curl_getenv("COLUMNS"); colp = curl_getenv("COLUMNS");
if (colp != NULL) { if (colp != NULL) {
bar->width = atoi(colp); bar->width = atoi(colp);
free(colp); curl_free(colp);
} }
else else
bar->width = 79; bar->width = 79;
@@ -2313,11 +2428,8 @@ void free_config_fields(struct Configurable *config)
static void FindWin32CACert(struct Configurable *config, static void FindWin32CACert(struct Configurable *config,
const char *bundle_file) const char *bundle_file)
{ {
curl_version_info_data *info;
info = curl_version_info(CURLVERSION_NOW);
/* only check for cert file if "we" support SSL */ /* only check for cert file if "we" support SSL */
if(info->features & CURL_VERSION_SSL) { if(curlinfo->features & CURL_VERSION_SSL) {
DWORD buflen; DWORD buflen;
char *ptr = NULL; char *ptr = NULL;
char *retval = (char *) malloc(sizeof (TCHAR) * (MAX_PATH + 1)); char *retval = (char *) malloc(sizeof (TCHAR) * (MAX_PATH + 1));
@@ -2369,15 +2481,18 @@ operate(struct Configurable *config, int argc, char *argv[])
int i; int i;
char *env; char *env;
#ifdef MALLOCDEBUG #ifdef CURLDEBUG
/* this sends all memory debug messages to a logfile named memdump */ /* this sends all memory debug messages to a logfile named memdump */
env = curl_getenv("CURL_MEMDEBUG"); env = curl_getenv("CURL_MEMDEBUG");
if(env) { if(env) {
free(env); curl_free(env);
curl_memdebug("memdump"); curl_memdebug("memdump");
} }
#endif #endif
/* we get libcurl info right away */
curlinfo = curl_version_info(CURLVERSION_NOW);
errorbuffer[0]=0; /* prevent junk from being output */ errorbuffer[0]=0; /* prevent junk from being output */
main_init(); /* inits */ main_init(); /* inits */
@@ -2488,7 +2603,7 @@ operate(struct Configurable *config, int argc, char *argv[])
env = curl_getenv("CURL_CA_BUNDLE"); env = curl_getenv("CURL_CA_BUNDLE");
if(env) { if(env) {
GetStr(&config->cacert, env); GetStr(&config->cacert, env);
free(env); curl_free(env);
} }
#if defined(WIN32) && !defined(__CYGWIN32__) #if defined(WIN32) && !defined(__CYGWIN32__)
else else
@@ -2562,7 +2677,9 @@ operate(struct Configurable *config, int argc, char *argv[])
if(!config->globoff) { if(!config->globoff) {
/* Unless explicitly shut off, we expand '{...}' and '[...]' expressions /* Unless explicitly shut off, we expand '{...}' and '[...]' expressions
and return total number of URLs in pattern set */ and return total number of URLs in pattern set */
res = glob_url(&urls, url, &urlnum); res = glob_url(&urls, url, &urlnum,
config->showerror?
(config->errors?config->errors:stderr):NULL);
if(res != CURLE_OK) if(res != CURLE_OK)
return res; return res;
} }
@@ -2576,7 +2693,7 @@ operate(struct Configurable *config, int argc, char *argv[])
separator = 1; separator = 1;
} }
for(i = 0; for(i = 0;
(url = urls?next_url(urls):(i?NULL:strdup(url))); (url = urls?glob_next_url(urls):(i?NULL:strdup(url)));
i++) { i++) {
char *outfile; char *outfile;
outfile = outfiles?strdup(outfiles):NULL; outfile = outfiles?strdup(outfiles):NULL;
@@ -2602,11 +2719,21 @@ operate(struct Configurable *config, int argc, char *argv[])
helpf("Remote file name has no length!\n"); helpf("Remote file name has no length!\n");
return CURLE_WRITE_ERROR; return CURLE_WRITE_ERROR;
} }
#if defined(__DJGPP__)
{
/* This is for DOS, and then we do some major replacing of
bad characters in the file name before using it */
char *file1=xmalloc(PATH_MAX);
strcpy(file1, msdosify(outfile));
strcpy(outfile, rename_if_dos_device_name(file1));
xfree(file1);
}
#endif /* __DJGPP__ */
} }
else if(urls) { else if(urls) {
/* fill '#1' ... '#9' terms from URL pattern */ /* fill '#1' ... '#9' terms from URL pattern */
char *storefile = outfile; char *storefile = outfile;
outfile = match_url(storefile, urls); outfile = glob_match_url(storefile, urls);
free(storefile); free(storefile);
} }
@@ -2775,11 +2902,11 @@ operate(struct Configurable *config, int argc, char *argv[])
if(!config->errors) if(!config->errors)
config->errors = stderr; config->errors = stderr;
#if defined(WIN32) && !defined(__CYGWIN32__) #ifdef O_BINARY
if(!outfile && !(config->conf & CONF_GETTEXT)) { if(!outfile && !(config->conf & CONF_GETTEXT)) {
/* We get the output to stdout and we have not got the ASCII/text flag, /* We get the output to stdout and we have not got the ASCII/text flag,
then set stdout to be binary */ then set stdout to be binary */
setmode( 1, O_BINARY ); setmode( fileno(stdout), O_BINARY );
} }
#endif #endif
@@ -2942,6 +3069,10 @@ operate(struct Configurable *config, int argc, char *argv[])
/* disable it */ /* disable it */
curl_easy_setopt(curl, CURLOPT_FTP_USE_EPRT, FALSE); curl_easy_setopt(curl, CURLOPT_FTP_USE_EPRT, FALSE);
/* new in libcurl 7.10.6 (default is Basic) */
if(config->authtype)
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, config->authtype);
/* new in curl 7.9.7 */ /* new in curl 7.9.7 */
if(config->trace_dump) { if(config->trace_dump) {
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace); curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
@@ -3076,7 +3207,6 @@ operate(struct Configurable *config, int argc, char *argv[])
return res; return res;
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int res; int res;
@@ -3207,3 +3337,119 @@ static int create_dir_hierarchy(char *outfile)
return result; /* 0 is fine, -1 is badness */ return result; /* 0 is fine, -1 is badness */
} }
#ifdef __DJGPP__
/* The following functions are taken with modification from the DJGPP
* port of tar 1.12. They use algorithms originally from DJTAR. */
char *
msdosify (char *file_name)
{
static char dos_name[PATH_MAX];
static char illegal_chars_dos[] = ".+, ;=[]|<>\\\":?*";
static char *illegal_chars_w95 = &illegal_chars_dos[8];
int idx, dot_idx;
char *s = file_name, *d = dos_name;
char *illegal_aliens = illegal_chars_dos;
size_t len = sizeof (illegal_chars_dos) - 1;
int lfn = 0;
/* Support for Windows 9X VFAT systems, when available. */
if (_use_lfn (file_name))
lfn = 1;
if (lfn) {
illegal_aliens = illegal_chars_w95;
len -= (illegal_chars_w95 - illegal_chars_dos);
}
/* Get past the drive letter, if any. */
if (s[0] >= 'A' && s[0] <= 'z' && s[1] == ':') {
*d++ = *s++;
*d++ = *s++;
}
for (idx = 0, dot_idx = -1; *s; s++, d++) {
if (memchr (illegal_aliens, *s, len)) {
/* Dots are special: DOS doesn't allow them as the leading character,
and a file name cannot have more than a single dot. We leave the
first non-leading dot alone, unless it comes too close to the
beginning of the name: we want sh.lex.c to become sh_lex.c, not
sh.lex-c. */
if (*s == '.') {
if (idx == 0 && (s[1] == '/' || (s[1] == '.' && s[2] == '/'))) {
/* Copy "./" and "../" verbatim. */
*d++ = *s++;
if (*s == '.')
*d++ = *s++;
*d = *s;
}
else if (idx == 0)
*d = '_';
else if (dot_idx >= 0) {
if (dot_idx < 5) { /* 5 is a heuristic ad-hoc'ery */
d[dot_idx - idx] = '_'; /* replace previous dot */
*d = '.';
}
else
*d = '-';
}
else
*d = '.';
if (*s == '.')
dot_idx = idx;
}
else if (*s == '+' && s[1] == '+') {
if (idx - 2 == dot_idx) { /* .c++, .h++ etc. */
*d++ = 'x';
*d = 'x';
}
else {
/* libg++ etc. */
memcpy (d, "plus", 4);
d += 3;
}
s++;
idx++;
}
else
*d = '_';
}
else
*d = *s;
if (*s == '/') {
idx = 0;
dot_idx = -1;
}
else
idx++;
}
*d = '\0';
return dos_name;
}
char *
rename_if_dos_device_name (char *file_name)
{
/* We could have a file whose name is a device on MS-DOS. Trying to
* retrieve such a file would fail at best and wedge us at worst. We need
* to rename such files. */
extern char *basename (const char *);
char *base;
struct stat st_buf;
char fname[PATH_MAX];
strcpy (fname, file_name);
base = basename (fname);
if (((stat(base, &st_buf)) == 0) && (S_ISCHR(st_buf.st_mode))) {
size_t blen = strlen (base);
/* Prepend a '_'. */
memmove (base + 1, base, blen + 1);
base[0] = '_';
strcpy (file_name, fname);
}
return file_name;
}
#endif /* __DJGPP__ */

48
src/makefile.dj Normal file
View File

@@ -0,0 +1,48 @@
#
# Adapted for djgpp2 / Watt-32 / DOS by
# Gisle Vanem <giva@bgnett.no>
#
DEPEND_PREREQ = config.h
include ../packages/DOS/common.dj
ifeq ($(USE_SSL),1)
EX_LIBS = $(OPENSSL_ROOT)/lib/libssl.a $(OPENSSL_ROOT)/lib/libcrypt.a
endif
EX_LIBS += $(WATT32_ROOT)/lib/libwatt.a $(ZLIB_ROOT)/libz.a
BIN = ../curl.exe
SOURCES = hugehelp.c main.c urlglob.c writeenv.c writeout.c
OBJECTS = $(SOURCES:.c=.o)
all: config.h $(BIN)
$(BIN): $(OBJECTS) ../lib/libcurl.a
$(CC) -o $@ $^ $(EX_LIBS)
config.h:
@echo '#include "../lib/config.dj"' > $@
hugehelp.c: ../docs/curl.1
groff -man $^ | perl mkhelp.pl ../readme > $@
clean:
- rm -f $(OBJECTS) Makefile.bak config.h
vclean: clean
- rm -f $(BIN) hugehelp.c
# DO NOT DELETE THIS LINE
hugehelp.o: hugehelp.c
main.o: main.c setup.h config.h ../lib/config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
../include/curl/mprintf.h urlglob.h writeout.h version.h
urlglob.o: urlglob.c setup.h config.h ../lib/config.dj \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h urlglob.h
writeenv.o: writeenv.c setup.h config.h ../lib/config.dj
writeout.o: writeout.c setup.h config.h ../lib/config.dj \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/mprintf.h writeout.h

View File

@@ -6,10 +6,10 @@
# THEY DON'T FIT ME :-) # THEY DON'T FIT ME :-)
# Get readme file as parameter: # Get readme file as parameter:
$README = $ARGV[0]; my $README = $ARGV[0];
if($README eq "") { if($README eq "") {
print "usage: mkreadme.pl <README>\n"; print "usage: mkreadme.pl [-c] <README> < manpage\n";
exit; exit;
} }
@@ -20,54 +20,163 @@ push @out, " / __| | | | |_) | | \n";
push @out, " | (__| |_| | _ <| |___ \n"; push @out, " | (__| |_| | _ <| |___ \n";
push @out, " \\___|\\___/|_| \\_\\_____|\n"; push @out, " \\___|\\___/|_| \\_\\_____|\n";
$head=0;
loop:
while (<STDIN>) { while (<STDIN>) {
$line = $_; my $line = $_;
# this kind should be removed first: # this should be removed:
$line =~ s/_//g; $line =~ s/(.|_)//g;
# then this: if($line =~ /^([ \t]*\n|curl)/i) {
$line =~ s/.//g; # cut off headers and empty lines
$wline++; # count number of cut off lines
if($line =~ /^curl/i) { next;
# cut off the page headers
$head=1;
next loop;
} }
if($line =~ /^[ \t]*\n/) { my $text = $line;
$wline++; $text =~ s/^\s+//g; # cut off preceeding...
# we only make one empty line max $text =~ s/\s+$//g; # and trailing whitespaces
next loop;
$tlen = length($text);
if($wline && ($olen == $tlen)) {
# if the previous line with contents was exactly as long as
# this line, then we ignore the newlines!
# We do this magic because a header may abort a paragraph at
# any line, but we don't want that to be noticed in the output
# here
$wline=0;
} }
$olen = $tlen;
if($wline) { if($wline) {
# we only make one empty line max
$wline = 0; $wline = 0;
if(!$head) {
push @out, "\n"; push @out, "\n";
} }
$head =0;
}
push @out, $line; push @out, $line;
} }
push @out, "\n"; # just an extra newline push @out, "\n"; # just an extra newline
open(READ, "<$README") || open(READ, "<$README") ||
die "couldn't read the README infile"; die "couldn't read the README infile $README";
while(<READ>) { while(<READ>) {
push @out, $_; push @out, $_;
} }
close(READ); close(READ);
# if compressed
if($c) {
my @test = `gzip --version 2>&1`;
if($test[0] =~ /gzip/) {
open(GZIP, "|gzip -9 >dumpit.gz") ||
die "can't run gzip, try without -c";
binmode GZIP;
for(@out) {
print GZIP $_;
$gzip += length($_);
}
close(GZIP);
print "/* NEVER EVER edit this manually, fix the mkhelp script instead! */\n" open(GZIP, "<dumpit.gz");
binmode GZIP;
while(<GZIP>) {
push @gzip, $_;
$gzipped += length($_);
}
close(GZIP);
unlink("dumpit.gz");
}
else {
# no gzip, no compression!
undef $c;
print STDERR "MEEEP: Couldn't find gzip, disable compression\n";
}
}
$now = localtime;
print <<HEAD
/*
* NEVER EVER edit this manually, fix the mkhelp.pl script instead!
* Generation time: $now
*/
#include <stdio.h>
HEAD
;
if($c) {
print <<HEAD
#include <zlib.h>
static const unsigned char hugehelpgz[] = {
/* This mumbo-jumbo is the huge help text compressed with gzip.
Thanks to this operation, the size of this data shrunk from $gzip
to $gzipped bytes. You can disable the use of compressed help
texts by NOT passing -c to the mkhelp.pl tool. */
HEAD
; ;
print "#include <stdio.h>\n"; my $c=0;
print "void hugehelp(void)\n"; print " ";
print "{\n"; for(@gzip) {
print "puts (\n"; my @all=split(//, $_);
for(@all) {
my $num=ord($_);
printf("0x%02x, ", 0+$num);
if(++$c>11) {
print "\n ";
$c=0;
}
}
}
print "\n};\n";
print <<EOF
/* Decompress and send to stdout a gzip-compressed buffer */
void hugehelp(void)
{
unsigned char buf[0x10000];
int status,headerlen;
z_stream z;
/* Make sure no gzip options are set */
if (hugehelpgz[3] & 0xfe)
return;
headerlen = 10;
z.avail_in = sizeof(hugehelpgz) - headerlen;
z.next_in = (unsigned char *)hugehelpgz + headerlen;
z.zalloc = (alloc_func)Z_NULL;
z.zfree = (free_func)Z_NULL;
z.opaque = 0;
if (inflateInit2(&z, -MAX_WBITS) != Z_OK)
return;
for (;;) {
z.avail_out = (int)sizeof(buf);
z.next_out = buf;
status = inflate(&z, Z_SYNC_FLUSH);
if (status == Z_OK || status == Z_STREAM_END) {
fwrite(buf, sizeof(buf) - z.avail_out, 1, stdout);
if (status == Z_STREAM_END)
break;
} else
break; /* Error */
}
inflateEnd(&z);
}
EOF
;
exit;
}
else {
print <<HEAD
void hugehelp(void)
{
fputs(
HEAD
;
}
$outsize=0; $outsize=0;
for(@out) { for(@out) {
@@ -82,13 +191,13 @@ for(@out) {
# gcc 2.96 claims ISO C89 only is required to support 509 letter strings # gcc 2.96 claims ISO C89 only is required to support 509 letter strings
if($outsize > 500) { if($outsize > 500) {
# terminate and make another puts() call here # terminate and make another fputs() call here
print ");\n puts(\n"; print ", stdout);\n fputs(\n";
$outsize=length($new)+1; $outsize=length($new)+1;
} }
printf("\"%s\\n\"\n", $new); printf("\"%s\\n\"\n", $new);
} }
print " ) ;\n}\n" print ", stdout) ;\n}\n"

View File

@@ -66,7 +66,6 @@ int fileno( FILE *stream);
#endif #endif
#ifdef WIN32 #ifdef WIN32
#define PATH_CHAR ";"
#define DIR_CHAR "\\" #define DIR_CHAR "\\"
#define DOT_CHAR "_" #define DOT_CHAR "_"
#else #else
@@ -74,17 +73,25 @@ int fileno( FILE *stream);
/* 20000318 mgs /* 20000318 mgs
* OS/2 supports leading dots in filenames if the volume is formatted * OS/2 supports leading dots in filenames if the volume is formatted
* with JFS or HPFS. */ * with JFS or HPFS. */
#define PATH_CHAR ";"
#define DIR_CHAR "\\" #define DIR_CHAR "\\"
#define DOT_CHAR "." #define DOT_CHAR "."
#else #else
#define PATH_CHAR ":" #ifdef DJGPP
#include <tcp.h>
#ifdef word
#undef word
#endif
#define DIR_CHAR "/"
#define DOT_CHAR "_"
#else
#define DIR_CHAR "/" #define DIR_CHAR "/"
#define DOT_CHAR "." #define DOT_CHAR "."
#endif #endif /* !DJGPP */
#endif #endif /* !__EMX__ */
#endif /* !WIN32 */
#ifdef __riscos__ #ifdef __riscos__
#define USE_ENVIRONMENT #define USE_ENVIRONMENT

View File

@@ -29,12 +29,18 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <curl/curl.h> #include <curl/curl.h>
#define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */
#include <curl/mprintf.h>
#include "urlglob.h" #include "urlglob.h"
#ifdef MALLOCDEBUG
#ifdef CURLDEBUG
#include "../lib/memdebug.h" #include "../lib/memdebug.h"
#endif #endif
char globerrormsg[80]; /* nasty global error message buffer for globbing */
typedef enum { typedef enum {
GLOB_OK, GLOB_OK,
GLOB_ERROR GLOB_ERROR
@@ -46,12 +52,12 @@ typedef enum {
* Input a full globbed string, set the forth argument to the amount of * Input a full globbed string, set the forth argument to the amount of
* strings we get out of this. Return GlobCode. * strings we get out of this. Return GlobCode.
*/ */
GlobCode glob_word(URLGlob *, /* object anchor */ static GlobCode glob_word(URLGlob *, /* object anchor */
char *, /* globbed string */ char *, /* globbed string */
int, /* position */ int, /* position */
int *); /* returned number of strings */ int *); /* returned number of strings */
GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount) static GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount)
{ {
/* processes a set expression with the point behind the opening '{' /* processes a set expression with the point behind the opening '{'
','-separated elements are collected until the next closing '}' ','-separated elements are collected until the next closing '}'
@@ -70,12 +76,14 @@ GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount)
while (1) { while (1) {
switch (*pattern) { switch (*pattern) {
case '\0': /* URL ended while set was still open */ case '\0': /* URL ended while set was still open */
/*printf("error: unmatched brace at pos %d\n", pos);*/ snprintf(globerrormsg, sizeof(globerrormsg),
"unmatched brace at pos %d\n", pos);
return GLOB_ERROR; return GLOB_ERROR;
case '{': case '{':
case '[': /* no nested expressions at this time */ case '[': /* no nested expressions at this time */
/*printf("error: nested braces not supported %d\n", pos);*/ snprintf(globerrormsg, sizeof(globerrormsg),
"nested braces not supported at pos %d\n", pos);
return GLOB_ERROR; return GLOB_ERROR;
case ',': case ',':
@@ -85,7 +93,7 @@ GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount)
realloc(pat->content.Set.elements, realloc(pat->content.Set.elements,
(pat->content.Set.size + 1) * sizeof(char*)); (pat->content.Set.size + 1) * sizeof(char*));
if (!pat->content.Set.elements) { if (!pat->content.Set.elements) {
/*printf("out of memory in set pattern\n");*/ snprintf(globerrormsg, sizeof(globerrormsg), "out of memory");
return GLOB_ERROR; return GLOB_ERROR;
} }
pat->content.Set.elements[pat->content.Set.size] = pat->content.Set.elements[pat->content.Set.size] =
@@ -110,12 +118,14 @@ GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount)
break; break;
case ']': /* illegal closing bracket */ case ']': /* illegal closing bracket */
/*printf("error: illegal pattern at pos %d\n", pos);*/ snprintf(globerrormsg, sizeof(globerrormsg),
"illegal pattern at pos %d\n", pos);
return GLOB_ERROR; return GLOB_ERROR;
case '\\': /* escaped character, skip '\' */ case '\\': /* escaped character, skip '\' */
if (*(buf+1) == '\0') { /* but no escaping of '\0'! */ if (*(buf+1) == '\0') { /* but no escaping of '\0'! */
/*printf("error: illegal pattern at pos %d\n", pos); */ snprintf(globerrormsg, sizeof(globerrormsg),
"illegal pattern at pos %d\n", pos);
return GLOB_ERROR; return GLOB_ERROR;
} }
++pattern; ++pattern;
@@ -126,10 +136,11 @@ GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount)
++pos; ++pos;
} }
} }
snprintf(globerrormsg, sizeof(globerrormsg), "malformatted pattern");
return GLOB_ERROR; return GLOB_ERROR;
} }
GlobCode glob_range(URLGlob *glob, char *pattern, int pos, int *amount) static GlobCode glob_range(URLGlob *glob, char *pattern, int pos, int *amount)
{ {
/* processes a range expression with the point behind the opening '[' /* processes a range expression with the point behind the opening '['
- char range: e.g. "a-z]", "B-Q]" - char range: e.g. "a-z]", "B-Q]"
@@ -152,10 +163,8 @@ GlobCode glob_range(URLGlob *glob, char *pattern, int pos, int *amount)
pat->content.CharRange.min_c >= pat->content.CharRange.max_c || pat->content.CharRange.min_c >= pat->content.CharRange.max_c ||
pat->content.CharRange.max_c - pat->content.CharRange.min_c > 'z' - 'a') { pat->content.CharRange.max_c - pat->content.CharRange.min_c > 'z' - 'a') {
/* the pattern is not well-formed */ /* the pattern is not well-formed */
#if 0 snprintf(globerrormsg, sizeof(globerrormsg),
printf("error: illegal pattern or range specification after pos %d\n", "illegal pattern or range specification after pos %d\n", pos);
pos);
#endif
return GLOB_ERROR; return GLOB_ERROR;
} }
pat->content.CharRange.ptr_c = pat->content.CharRange.min_c; pat->content.CharRange.ptr_c = pat->content.CharRange.min_c;
@@ -180,10 +189,9 @@ GlobCode glob_range(URLGlob *glob, char *pattern, int pos, int *amount)
&pat->content.NumRange.max_n) != 2 || &pat->content.NumRange.max_n) != 2 ||
pat->content.NumRange.min_n >= pat->content.NumRange.max_n) { pat->content.NumRange.min_n >= pat->content.NumRange.max_n) {
/* the pattern is not well-formed */ /* the pattern is not well-formed */
#if 0 snprintf(globerrormsg, sizeof(globerrormsg),
printf("error: illegal pattern or range specification after pos %d\n", "error: illegal pattern or range specification after pos %d\n",
pos); pos);
#endif
return GLOB_ERROR; return GLOB_ERROR;
} }
if (*pattern == '0') { /* leading zero specified */ if (*pattern == '0') { /* leading zero specified */
@@ -193,7 +201,13 @@ GlobCode glob_range(URLGlob *glob, char *pattern, int pos, int *amount)
instances of this pattern */ instances of this pattern */
} }
pat->content.NumRange.ptr_n = pat->content.NumRange.min_n; pat->content.NumRange.ptr_n = pat->content.NumRange.min_n;
c = (char*)(strchr(pattern, ']') + 1); /* continue after next ']' */ c = (char*)strchr(pattern, ']'); /* continue after next ']' */
if(c)
c++;
else {
snprintf(globerrormsg, sizeof(globerrormsg), "missing ']'");
return GLOB_ERROR; /* missing ']' */
}
/* always check for a literal (may be "") between patterns */ /* always check for a literal (may be "") between patterns */
@@ -206,12 +220,12 @@ GlobCode glob_range(URLGlob *glob, char *pattern, int pos, int *amount)
return GLOB_OK; return GLOB_OK;
} }
/*printf("error: illegal character in range specification at pos %d\n", snprintf(globerrormsg, sizeof(globerrormsg),
pos);*/ "illegal character in range specification at pos %d\n", pos);
return GLOB_ERROR; return GLOB_ERROR;
} }
GlobCode glob_word(URLGlob *glob, char *pattern, int pos, int *amount) static GlobCode glob_word(URLGlob *glob, char *pattern, int pos, int *amount)
{ {
/* processes a literal string component of a URL /* processes a literal string component of a URL
special characters '{' and '[' branch to set/range processing functions special characters '{' and '[' branch to set/range processing functions
@@ -261,7 +275,7 @@ GlobCode glob_word(URLGlob *glob, char *pattern, int pos, int *amount)
return GLOB_ERROR; /* something got wrong */ return GLOB_ERROR; /* something got wrong */
} }
int glob_url(URLGlob** glob, char* url, int *urlnum) int glob_url(URLGlob** glob, char* url, int *urlnum, FILE *error)
{ {
/* /*
* We can deal with any-size, just make a buffer with the same length * We can deal with any-size, just make a buffer with the same length
@@ -271,12 +285,15 @@ int glob_url(URLGlob** glob, char* url, int *urlnum)
int amount; int amount;
char *glob_buffer=(char *)malloc(strlen(url)+1); char *glob_buffer=(char *)malloc(strlen(url)+1);
if(NULL == glob_buffer) if(NULL == glob_buffer) {
snprintf(globerrormsg, sizeof(globerrormsg), "out of memory");
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
}
glob_expand = (URLGlob*)malloc(sizeof(URLGlob)); glob_expand = (URLGlob*)malloc(sizeof(URLGlob));
if(NULL == glob_expand) { if(NULL == glob_expand) {
free(glob_buffer); free(glob_buffer);
snprintf(globerrormsg, sizeof(globerrormsg), "out of memory");
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
glob_expand->size = 0; glob_expand->size = 0;
@@ -291,6 +308,12 @@ int glob_url(URLGlob** glob, char* url, int *urlnum)
free(glob_expand); free(glob_expand);
glob_expand = NULL; glob_expand = NULL;
*urlnum = 1; *urlnum = 1;
if(error && globerrormsg[0]) {
/* send error description to the error-stream */
fprintf(error, "curl: (%d) [globbing] %s\n",
CURLE_URL_MALFORMAT, globerrormsg);
}
return CURLE_URL_MALFORMAT;
} }
*glob = glob_expand; *glob = glob_expand;
@@ -317,7 +340,7 @@ void glob_cleanup(URLGlob* glob)
free(glob); free(glob);
} }
char *next_url(URLGlob *glob) char *glob_next_url(URLGlob *glob)
{ {
char *buf = glob->glob_buffer; char *buf = glob->glob_buffer;
URLPattern *pat; URLPattern *pat;
@@ -393,7 +416,7 @@ char *next_url(URLGlob *glob)
return strdup(glob->glob_buffer); return strdup(glob->glob_buffer);
} }
char *match_url(char *filename, URLGlob *glob) char *glob_match_url(char *filename, URLGlob *glob)
{ {
char *target; char *target;
URLPattern pat; URLPattern pat;

View File

@@ -53,9 +53,9 @@ typedef struct {
char beenhere; char beenhere;
} URLGlob; } URLGlob;
int glob_url(URLGlob**, char*, int *); int glob_url(URLGlob**, char*, int *, FILE *);
char* next_url(URLGlob*); char* glob_next_url(URLGlob*);
char* match_url(char*, URLGlob *); char* glob_match_url(char*, URLGlob *);
void glob_cleanup(URLGlob* glob); void glob_cleanup(URLGlob* glob);
#endif #endif

View File

@@ -1,3 +1,3 @@
#define CURL_NAME "curl" #define CURL_NAME "curl"
#define CURL_VERSION "7.10.5" #define CURL_VERSION "7.10.6"
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") " #define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "

View File

@@ -106,10 +106,30 @@ fi
cd curl cd curl
echo "testcurl: update from CVS" echo "testcurl: update from CVS"
# update quietly to the latest CVS
cvs -Q up -dP 2>&1
cvsstat=$? cvsup() {
# update quietly to the latest CVS
echo "testcurl: run cvs up"
cvs -Q up -dP 2>&1
cvsstat=$?
# return (1 - RETURNVALUE) so that errors return 0 while goodness
# returns 1
return `expr 1 - $cvsstat`
}
att="0"
while cvsup; do
att=`expr $att + 1`
echo "testcurl: failed CVS update attempt number $att."
if [ $att -gt 10 ]; then
cvsstat="111"
break # get out of the loop
fi
sleep 5
done
echo "testcurl: cvs returned: $cvsstat" echo "testcurl: cvs returned: $cvsstat"
if [ "$cvsstat" -ne "0" ]; then if [ "$cvsstat" -ne "0" ]; then

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