Compare commits
	
		
			204 Commits
		
	
	
		
			Curl_easy_
			...
			curl-7_9_1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 329bcf3a71 | ||
|   | 0cb12d7e78 | ||
|   | 3bfa06c9a2 | ||
|   | f34573c8e2 | ||
|   | 4163b86cd2 | ||
|   | 5b948512f9 | ||
|   | 2297a7a70c | ||
|   | dc82f9e6df | ||
|   | e60e7414b9 | ||
|   | c6caa9fd60 | ||
|   | c84ad40ccd | ||
|   | ab7f25ab41 | ||
|   | 6d213e207d | ||
|   | 9b6545c479 | ||
|   | 96fb118251 | ||
|   | 617d6eb7ce | ||
|   | 99888388dc | ||
|   | 7d24ce9651 | ||
|   | cbc35b1fb8 | ||
|   | 027fc719cc | ||
|   | f6b2e9e8a4 | ||
|   | c4f1a9f690 | ||
|   | 542055074b | ||
|   | 7b93348aae | ||
|   | eaf475b538 | ||
|   | 4118c68df1 | ||
|   | 69d5d88259 | ||
|   | 7e6a36ea7b | ||
|   | 6878c0b88f | ||
|   | bbdc9f15e7 | ||
|   | ae4f8243a9 | ||
|   | 1c83dee948 | ||
|   | b66dedc017 | ||
|   | b07e2a08f9 | ||
|   | 64543e09ec | ||
|   | 58936efff6 | ||
|   | dbd32278f8 | ||
|   | 6d35984286 | ||
|   | c046dc904c | ||
|   | bc8375a1e8 | ||
|   | 83877d5ec6 | ||
|   | 3f248dd163 | ||
|   | c9954d1941 | ||
|   | e165332211 | ||
|   | d25310cb6f | ||
|   | fbb9d23a25 | ||
|   | 2d32e8831b | ||
|   | 42a9d96fae | ||
|   | 3edd9b4dfc | ||
|   | 1a8cf79ae0 | ||
|   | b736bdc8e5 | ||
|   | babb985f1a | ||
|   | b22a5f756c | ||
|   | d733061873 | ||
|   | bca0c8d253 | ||
|   | 53ac8004e7 | ||
|   | 7b76499e82 | ||
|   | 9f45190fa1 | ||
|   | f933cb3b75 | ||
|   | c6822f5a7f | ||
|   | 4e276b1b68 | ||
|   | 50e9f8ffd3 | ||
|   | 7d3daa598f | ||
|   | 7349940bdb | ||
|   | 78000dbd5d | ||
|   | b585f411cd | ||
|   | 5ccd6bb842 | ||
|   | 5193894603 | ||
|   | 29b76a52fb | ||
|   | 0436bc22f2 | ||
|   | cd16efa2f2 | ||
|   | 56562bad59 | ||
|   | a26081b555 | ||
|   | aa9c01ad3e | ||
|   | 4e37187e44 | ||
|   | 74d5a6fb3b | ||
|   | 83da58ce91 | ||
|   | 45cc78fdbc | ||
|   | 010044e03c | ||
|   | db0e3cc60c | ||
|   | 8dd6a4e369 | ||
|   | 92abbcef4c | ||
|   | 1e8f0c5771 | ||
|   | 532bca41e5 | ||
|   | b438c46764 | ||
|   | ef48c73783 | ||
|   | 2c5e416591 | ||
|   | 8e91d5de8e | ||
|   | 2f85f3b147 | ||
|   | 20a47acb3a | ||
|   | 6bc85a94f9 | ||
|   | 71bf8a6985 | ||
|   | 59a76e4010 | ||
|   | 65b9c0d44d | ||
|   | f2a25966cf | ||
|   | 51afc3d8c5 | ||
|   | 0c2f60036a | ||
|   | 3dcdcfc572 | ||
|   | 9f8c51cbd8 | ||
|   | de79348a90 | ||
|   | 56bc31e9f9 | ||
|   | a9181f8f00 | ||
|   | 3685f792cb | ||
|   | e227a276ce | ||
|   | 7b5b60d275 | ||
|   | e719f4169c | ||
|   | d8fb2b2e63 | ||
|   | fdeaae678d | ||
|   | f30102f038 | ||
|   | a27ac6f394 | ||
|   | 093c0a098e | ||
|   | c3363f833c | ||
|   | 47def8091c | ||
|   | cfb32ec0cd | ||
|   | 5d9ae88f58 | ||
|   | 9d066935e5 | ||
|   | bc40063e07 | ||
|   | 3c92d45386 | ||
|   | fcf4fccfa4 | ||
|   | eafd2c6bd5 | ||
|   | 64f00454e5 | ||
|   | d678727430 | ||
|   | efc15fb128 | ||
|   | 3d4cd8c9aa | ||
|   | 420259993e | ||
|   | 66087bdac6 | ||
|   | ac70a43452 | ||
|   | 72dbe9da72 | ||
|   | dd02881788 | ||
|   | ced8955325 | ||
|   | 51ca5fcbe0 | ||
|   | 56ff2aa059 | ||
|   | 9f77771ff9 | ||
|   | f0fa858885 | ||
|   | 3298630500 | ||
|   | dc27488c47 | ||
|   | 375e615a6d | ||
|   | 6918427fae | ||
|   | 9d342bbf07 | ||
|   | afc81ada0c | ||
|   | 5cd267b2be | ||
|   | 09da90076f | ||
|   | d0079d9054 | ||
|   | ede5b54edc | ||
|   | c5fdeef41d | ||
|   | 6ca45beaed | ||
|   | 2a07626aa8 | ||
|   | 9127554852 | ||
|   | 9ff28a8237 | ||
|   | e9aa07f660 | ||
|   | 88e21894c7 | ||
|   | 09da2c1767 | ||
|   | ae2ecfc5cb | ||
|   | cc610f0d1f | ||
|   | 8333644c84 | ||
|   | 4d13b2cc64 | ||
|   | 48dc74aecc | ||
|   | 888d39e083 | ||
|   | 7239ecd456 | ||
|   | 598e8dfbfb | ||
|   | 9efdb68035 | ||
|   | 14b898cb05 | ||
|   | 8d16b2b119 | ||
|   | 4d2cb8b32a | ||
|   | d5001a3f0b | ||
|   | 91f5ac4d5c | ||
|   | f9977df50d | ||
|   | 711650b178 | ||
|   | c9adbc9f1c | ||
|   | 611fbfa917 | ||
|   | ecfacfb334 | ||
|   | 645413f5ef | ||
|   | 5becdc38b3 | ||
|   | f36cea67fe | ||
|   | b556d6caee | ||
|   | a17a78c477 | ||
|   | 146413a53c | ||
|   | 437fd064c9 | ||
|   | 28dd4e4f1f | ||
|   | f92dc70beb | ||
|   | 6d8f1328bf | ||
|   | 8d1d93d56d | ||
|   | f8e102c485 | ||
|   | d816fcc965 | ||
|   | e30dcd0501 | ||
|   | 24dc7cffbd | ||
|   | 3bc83926ce | ||
|   | c5cca4d059 | ||
|   | 0db04c4f56 | ||
|   | 5c566c9aa3 | ||
|   | 822f02313d | ||
|   | d934890c1e | ||
|   | 0e25cf41c4 | ||
|   | 5214dbbd02 | ||
|   | 0c716d51ad | ||
|   | 86367d675a | ||
|   | bd8cef5a70 | ||
|   | 708431e2ea | ||
|   | db5c1c61e5 | ||
|   | aa4ff6d8b9 | ||
|   | 6d5b8b50e1 | ||
|   | 600d7b11e6 | ||
|   | afa7648be6 | ||
|   | 5c344fc23a | 
							
								
								
									
										307
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										307
									
								
								CHANGES
									
									
									
									
									
								
							| @@ -6,6 +6,313 @@ | ||||
|  | ||||
|                                History of Changes | ||||
|  | ||||
| Version 7.9.1 | ||||
|  | ||||
| Daniel (4 November 2001) | ||||
| - I've added a number of new test cases the last few days. A few of them since | ||||
|   I got reports that hinted on problems on timeouts, so I added four tests | ||||
|   with timeouts for all sorts of protocols and stuff. I also came to think of | ||||
|   a few other error scenarios that we currently didn't test properly, so I | ||||
|   wrote up tests for a few of those too. | ||||
|  | ||||
| Daniel (2 November 2001) | ||||
| - Replaced read() and write() with recv() and send() for socket operations | ||||
|   even under normal unixes. | ||||
|  | ||||
| Daniel (1 November 2001) | ||||
| - When an FTP transfer was aborted due to a timeout, it wasn't really aware of | ||||
|   how many bytes that had been transferred and the error text always said 0 | ||||
|   bytes. I modified this to output the actually transferred amount! :-) | ||||
|  | ||||
| - The FTP fixes in pre7 didn't compile on IPv6 enabled hosts. Does now. I also | ||||
|   added more comments in the lib/ftp.c source file. | ||||
|  | ||||
| - Minor updates to the FAQ, added a brand new section to the web site about | ||||
|   the name issue (who owns "curl"? will someone sue us? etc etc): | ||||
|   http://curl.haxx.se/legal/thename.html | ||||
|  | ||||
| Version 7.9.1-pre7 | ||||
|  | ||||
| Daniel (31 October 2001) | ||||
| - The curl_easy_getinfo() timers accidentally lost they're subsecond accuracy | ||||
|   as the calculations used longs instead of doubles! Paul Harrington reported. | ||||
|  | ||||
| - The SSL SocketIsDead() checks weren't good enough (as expected really), so I | ||||
|   had to add a generic internal try-it-out system. If the request on a re-used | ||||
|   connection seems to fail, then we go back and get a new (fresh) connection | ||||
|   and re-tries the request on that instead. It kind of makes the | ||||
|   SocketIsDead() check obsolete, but I think it is a quicker way for those | ||||
|   cases where it actually discovers that the connection is dead. | ||||
|  | ||||
| - When fixing the above, I noticed that we did quite a few writes to sockets | ||||
|   in libcurl where we didn't check the return code (that it actually worked to | ||||
|   send the data). With the new "attempted request" system we must detect those | ||||
|   situations so I went over a bunch of functions, changed return types and | ||||
|   added checks for what they actually return. | ||||
|  | ||||
| Version 7.9.1-pre6 | ||||
|  | ||||
| Daniel (31 October 2001) | ||||
| - Paul Harrington detected a problem with persistant SSL connections. Or to be | ||||
|   more exact, we didn't properly detect that the connection was dead and then | ||||
|   a second connection would try to re-use it wrongly. The solution to this | ||||
|   problem is still not very clear and I'm working on it. One OpenSSL insider | ||||
|   said there is no way to know if the SSL connection is alive or not without | ||||
|   actually trying an operation. | ||||
|  | ||||
| Daniel (30 October 2001) | ||||
| - If a cookie was read from a file, it could accidentally strdup() a NULL | ||||
|   pointer. Paul Harrington reported. [http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/curl/curl/lib/cookie.c.diff?r1=1.25&r2=1.26] | ||||
|  | ||||
| - The MANUAL file now documents -t correctly. I also fixed the -T description | ||||
|   in the curl.1 man page. | ||||
|  | ||||
| Daniel (29 October 2001) | ||||
| - John Janssen found out that curl_formadd was missing in the libcurl.def file | ||||
|   and that the docs stated the wrong return type for the function. | ||||
|  | ||||
| - Andr<64>s Garc<72>a found a bug with multiple files in the curl_formadd() function, | ||||
|   that I removed with this patch [http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/curl/curl/lib/formdata.c.diff?r1=1.25&r2=1.26]. | ||||
|  | ||||
| - Kevin Roth brought another patch that moved the cygwin package files to the | ||||
|   packages/Win32/cygwin directory. | ||||
|  | ||||
| - A bug in the connection re-use logic made repeated requests to the same FTP | ||||
|   server (when using name+pasword in the URL) sometimes use more than one | ||||
|   connection. [http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/curl/curl/lib/url.c.diff?r1=1.166&r2=1.167] | ||||
|  | ||||
| - Moonesamy tracked down and fixed a problem with the new 7.9.1 connect | ||||
|   code. This corrected the error Kevin Roth reported on the 7.9.1-pre5 release | ||||
|   (test 19)... | ||||
|   [http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/curl/curl/lib/connect.c.diff?r1=1.13&r2=1.14] | ||||
|  | ||||
| Daniel (26 October 2001) | ||||
| - Added test28 which verifies that "Location:"-following works even if the | ||||
|   contents is separated with more than one space. | ||||
|  | ||||
| Daniel (25 October 2001) | ||||
| - Ramana Mokkapati pointed out that LDAP transfers would 'hang' after the | ||||
|   correct data has been output. | ||||
|  | ||||
| Version 7.9.1-pre5 | ||||
|  | ||||
| Daniel (24 October 2001) | ||||
| - T. Bharath found a memory leak in the cookie engine. When we update a cookie | ||||
|   that we already knew about, we lost a chunk of memory in the progress... The | ||||
|   brand new test case 27 now tests for this occurrence. [http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/curl/curl/lib/cookie.c.diff?r1=1.24&r2=1.25] | ||||
|  | ||||
| Daniel (23 October 2001) | ||||
| - pack_hostent() didn't properly align some pointers, so at least SPARC CPUs | ||||
|   would core. [http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/curl/curl/lib/hostip.c.diff?r1=1.34&r2=1.35] | ||||
|  | ||||
| Daniel (22 October 2001) | ||||
| - Tom Benoist reported that this SGI IRIX compiler didn't handle indented | ||||
|   preprocessor instructions, so they're no longer in the source code! | ||||
|  | ||||
| - Applied Kevin Roth's patches to make it easier to build cygwin packages from | ||||
|   the out-of-the-box curl release archives. | ||||
|  | ||||
| - I forgot to mention it below, but libcurl now closes connections that report | ||||
|   transfer failures. Unconditionally. This could be made more nicely in the | ||||
|   future if we set a flag or something that the connection is still good to be | ||||
|   used for the errors that know that for a fact. We have to close the | ||||
|   connection for the cases where we abort for example a HTTP transfer in the | ||||
|   middle, or otherwise we might re-use that connection later with lots of data | ||||
|   still being sent to us on it. [http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/curl/curl/lib/transfer.c.diff?r1=1.63&r2=1.64] | ||||
|  | ||||
| Daniel (19 October 2001) | ||||
| - CURLE_GOT_NOTHING is now returned when a HTTP server doesn't return | ||||
|   anything, not even a header. test case 37 was added to test for this. | ||||
|  | ||||
| - T. Bharath made curl_easy_duphandle() properly clone the cookie status as | ||||
|   well. | ||||
|  | ||||
| Version 7.9.1-pre4 | ||||
|  | ||||
| Daniel (18 October 2001) | ||||
| - CURLOPT_FAILONERROR, set with "curl --fail" no longer returns an error if | ||||
|   the HTTP return code is below 400. | ||||
|  | ||||
| Daniel (17 October 2001) | ||||
| - The test suite now kills any running test http server when you re-start the | ||||
|   tests. | ||||
|  | ||||
| - We had to remove 'use strict' from two perl scripts, as the cygwin | ||||
|   adjustments didn't play nicely otherwise for some reason. Any perl wizard | ||||
|   out there who can put the scrict back and still make it run good on unix and | ||||
|   cygwin? | ||||
|  | ||||
| - A potential memory leak pointed out to us by Yanick Pelletier was removed. | ||||
|   It would occur when a http file transfer fails. [http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/curl/curl/lib/transfer.c.diff?r1=1.60&r2=1.61] | ||||
|  | ||||
| - The memory debugging system should no longer display anything to stderr | ||||
|   if the curl_memdebug() hasn't been used to explicitly say so. This makes it | ||||
|   easier to use the memory debug system and switch the logging on/off. | ||||
|  | ||||
| Daniel (16 October 2001) | ||||
| - Kevin Roth provided fixes for building curl nicer in cygwin environments. | ||||
|  | ||||
| Daniel (12 October 2001) | ||||
| - Cleaning up the progress meter/info code. The "current speed" is now more | ||||
|   accurate than before as we now use the true time spent between the measures, | ||||
|   and not just "assuming" every-second-update like before. The output should | ||||
|   now also be of the same width at all times, never to show "extra" zeroes on | ||||
|   the right edge. | ||||
|  | ||||
| - After talking about possible Location: bugs on the mailing list, I modified | ||||
|   the "absolute URL" checker in lib/transfer.c to be more strict when checking | ||||
|   if the redirected URL is absolute. | ||||
|  | ||||
| Daniel (11 October 2001) | ||||
| - Kevin Roth provided patches that make the test suite run fine on Windows | ||||
|   2000 running cygwin. | ||||
|  | ||||
| Daniel (10 October 2001) | ||||
| - Setting the -c or the CURLOPT_COOKIEJAR option now enables the cookie parser. | ||||
|   Previously -b or CURLOPT_COOKIEFILE was also required for the jar to work. | ||||
|  | ||||
| Version 7.9.1-pre3 | ||||
|  | ||||
| Daniel (9 October 2001) | ||||
| - Added a new option to the command line client: -0/--http1.0. It uses the new | ||||
|   libcurl option CURLOPT_HTTP_VERSION to request that libcurl uses HTTP 1.0 | ||||
|   requests instead of the default version (1.1). It should only be used if you | ||||
|   really MUST do that because of a silly remote server. | ||||
|  | ||||
| - Renamed the 'TimeCond' typedef in curl/curl.h to use a 'curl_' prefix as | ||||
|   all public curl-symbols should. | ||||
|  | ||||
| - libcurl now explicitly ignores the SIGPIPE signal. | ||||
|  | ||||
| Daniel (8 October 2001) | ||||
| - Kevin Roth's change to the cookie-jar comment (in the stored file) was | ||||
|   applied. | ||||
|  | ||||
| - Lucas Adamski's minor bug in the bind error code failf() was fixed. | ||||
|  | ||||
| Daniel (5 October 2001) | ||||
| - Moonesamy fixed the Curl_connecthost() function to not give compiler errors | ||||
|   on a bunch of compilers, due to the argument named 'socket'. | ||||
|  | ||||
| - Moonesamy also provided updated VC++ makefiles and project files. | ||||
|  | ||||
| Version 7.9.1-pre2 | ||||
|  | ||||
| Daniel (4 October 2001) | ||||
| - Albert Chin provided a configure patch that makes the script detect proper | ||||
|   gethostbyname_r() method without actually running any code, only compiling | ||||
|   is necessary. This also removes the need of having a resolving 'localhost' | ||||
|   name. | ||||
|  | ||||
| - Found and removed memory leakage (name resolve data) in libcurl on | ||||
|   IPv6-enabled hosts. These could sneak through because we didn't have any | ||||
|   resource tracing on the IPv6-related functions. We do now. | ||||
|  | ||||
| Daniel (3 October 2001) | ||||
| - Keith McGuigan patched away a (mainly Windows-) problem with the name | ||||
|   resolver data being kept in the static memory area, which is removed when a | ||||
|   thread is killed. The curl handle itself though perfectly handles being | ||||
|   passed between threads. | ||||
|  | ||||
| - Dirk Eddelbuettel reported an odd bug that turned out to be his proxy that | ||||
|   required an Authorization: header. Now, proxies are not supposed to require | ||||
|   that header, that is for true servers... | ||||
|  | ||||
| - I accidentally ruined Georg's curl_formadd(). Uh, bad me. Corrected now. | ||||
|  | ||||
| Version 7.9.1-pre1 | ||||
|  | ||||
| Daniel (3 October 2001) | ||||
| - Georg Huettenegger once again made an effort beyond the call of duty and not | ||||
|   only improved the curl_formadd() function, but also took care of adjusting | ||||
|   the curl command line client to use this new function instead of the | ||||
|   obsoleted curl_formparse. | ||||
|  | ||||
| Daniel (2 October 2001) | ||||
| - Major fix in how libcurl does TCP connects. It now does non-blocking | ||||
|   connects to enable good timeouts without signals, and it now tries all IP | ||||
|   addresses for any given host (if it resolves more than one and the first | ||||
|   one(s) don't connect). Added a new source file 'connect.c' to deal with all | ||||
|   the TCP connect stuff. | ||||
|  | ||||
| - We now support IPv4-style IP-addresses in rfc2732-format, to better support | ||||
|   people writing scripts without knowing what address there is. | ||||
|  | ||||
| Daniel (28 September 2001) | ||||
| - Cleanups in the FTP source code. Divided the code into even more smaller | ||||
|   functions and generally tried to make the differences between IPv4 and IPv6 | ||||
|   get less noticable in the sources. | ||||
|  | ||||
| - If the remote file time is not readable/accessable/understood by libcurl, | ||||
|   libcurl now returns -1 in the CURLINFO_FILETIME data, not 0 as it previously | ||||
|   did. This should make curl not touch the file data unless there was a known | ||||
|   remote date when -R is used. | ||||
|  | ||||
| Daniel (27 September 2001) | ||||
| - Working on getting non-blocking connects working platform independent. We | ||||
|   will also make curl try all IPs for a given host if the first one should | ||||
|   fail. | ||||
|  | ||||
| Daniel (26 September 2001) | ||||
| - Kevin Roth provided a cookie example that proved the cookie jar | ||||
|   functionality wasn't working properly. I added test case 46 and made it | ||||
|   work. | ||||
|  | ||||
| Daniel (25 September 2001) | ||||
| - J<>rn Hartroth updated the mingw32 makefiles. | ||||
|  | ||||
| Version 7.9 | ||||
|  | ||||
| Daniel (23 September 2001) | ||||
| - Found and removed a 'socket leak' that would occur on IPv6 enabled hosts | ||||
|   when FTP RETR failed. | ||||
|  | ||||
| - Made the FTP upload tests run fine on machines with IPv6 enabled. | ||||
|  | ||||
| Version 7.9-pre8 | ||||
|  | ||||
| Daniel (19 September 2001) | ||||
| - Vojtech Minarik set up a special-purpose test server and provided me with | ||||
|   test certificates in order for me to repeat the bug reports #440068 and | ||||
|   #440373. It turned out we didn't check all the error codes properly. We do | ||||
|   now, and connecting with a unacceptable certificate will make libcurl fail | ||||
|   to connect with an error code returned. | ||||
|  | ||||
| - Ramana Mokkapati found a case when the Location: following code did wrong. | ||||
|   I wrote a test case for this (45). | ||||
|  | ||||
| Version 7.9-pre7 | ||||
|  | ||||
| Daniel (17 September 2001) | ||||
| - Linus Nielsen Feltzing fixed telnet for win32. It makes libcurl require | ||||
|   winsock 2.0. | ||||
|  | ||||
| Version 7.9-pre6 | ||||
|  | ||||
| - libtool 1.4.2 is now in use! | ||||
|  | ||||
| Version 7.9-pre5 | ||||
|  | ||||
| Daniel (14 September 2001) | ||||
| - Added another 14 ftp tests. | ||||
|  | ||||
| Daniel (13 September 2001) | ||||
| - Added curl_easy_duphandle() to the easy.h header file. It has now been | ||||
|   tested and proved to work in a real-world tests by T Bharath. We still need | ||||
|   to write up some docs for this function. | ||||
|  | ||||
| - Added four more ftp tests to the test suite. | ||||
|  | ||||
| Daniel (12 September 2001) | ||||
| - CURLOPT_SSL_CIPHER_LIST was added, and the curl tool option is named | ||||
|   --ciphers. Use them to specify a list of ciphers to use in the SSL | ||||
|   connection. | ||||
|  | ||||
| - T. Bharath found a memory leak in libcurl's windows version. It turned out | ||||
|   to be the new duphandle() that didn't quite work yet. | ||||
|  | ||||
| Version 7.9-pre4 | ||||
|  | ||||
| Daniel (11 September 2001) | ||||
| - Added verbose output for SSL connections that output the server | ||||
|   certificate's start and expire dates. As suggested by Paul Harrington. | ||||
|   | ||||
							
								
								
									
										3
									
								
								MITX.txt
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								MITX.txt
									
									
									
									
									
								
							| @@ -10,8 +10,7 @@ in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, and/or sell copies of the | ||||
| Software, and to permit persons to whom the Software is furnished to do so, | ||||
| provided that the above copyright notice(s) and this permission notice appear | ||||
| in all copies of the Software and that both the above copyright notice(s) and | ||||
| this permission notice appear in supporting documentation. | ||||
| in all copies of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   | ||||
| @@ -67,3 +67,9 @@ pkgadd: | ||||
| 	make install DESTDIR=`/bin/pwd`/packages/Solaris/root ; \ | ||||
| 	cat LEGAL MITX.txt MPL-1.1.txt > $(srcdir)/packages/Solaris/copyright ; \ | ||||
| 	cd $(srcdir)/packages/Solaris && $(MAKE) package | ||||
|  | ||||
| # | ||||
| # Build a cygwin binary tarball installation file | ||||
| # resulting .tar.bz2 file will end up at packages/Win32/cygwin | ||||
| cygwinbin: | ||||
| 	$(MAKE) -C packages/Win32/cygwin cygwinbin | ||||
|   | ||||
							
								
								
									
										1
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								README
									
									
									
									
									
								
							| @@ -26,6 +26,7 @@ README | ||||
|   The official download mirror sites are: | ||||
|  | ||||
|         Sweden    -- ftp://ftp.sunet.se/pub/www/utilities/curl/ | ||||
|         Sweden    -- ftp://cool.haxx.se/curl/ | ||||
|         Germany   -- ftp://ftp.fu-berlin.de/pub/unix/network/curl/ | ||||
|  | ||||
|   To download the very latest source off the CVS server do this: | ||||
|   | ||||
| @@ -54,3 +54,11 @@ | ||||
|  | ||||
| /* Define if you have a working OpenSSL installation */ | ||||
| #undef OPENSSL_ENABLED | ||||
|  | ||||
| /* Define the one correct non-blocking socket method below */ | ||||
| #undef HAVE_FIONBIO | ||||
| #undef HAVE_IOCTLSOCKET | ||||
| #undef HAVE_IOCTLSOCKET_CASE | ||||
| #undef HAVE_O_NONBLOCK | ||||
| #undef HAVE_DISABLED_NONBLOCKING | ||||
|  | ||||
|   | ||||
							
								
								
									
										169
									
								
								acinclude.m4
									
									
									
									
									
								
							
							
						
						
									
										169
									
								
								acinclude.m4
									
									
									
									
									
								
							| @@ -1,3 +1,107 @@ | ||||
| dnl Check for how to set a socket to non-blocking state. There seems to exist | ||||
| dnl four known different ways, with the one used almost everywhere being POSIX | ||||
| dnl and XPG3, while the other different ways for different systems (old BSD, | ||||
| dnl Windows and Amiga). | ||||
| dnl | ||||
| dnl There are two known platforms (AIX 3.x and SunOS 4.1.x) where the | ||||
| dnl O_NONBLOCK define is found but does not work. This condition is attempted | ||||
| dnl to get caught in this script by using an excessive number of #ifdefs... | ||||
| dnl | ||||
| AC_DEFUN(CURL_CHECK_NONBLOCKING_SOCKET, | ||||
| [ | ||||
|   AC_MSG_CHECKING([non-blocking sockets style]) | ||||
|  | ||||
|   AC_TRY_COMPILE([ | ||||
| /* headers for O_NONBLOCK test */ | ||||
| #include <sys/types.h> | ||||
| #include <unistd.h> | ||||
| #include <fcntl.h> | ||||
| ],[ | ||||
| /* try to compile O_NONBLOCK */ | ||||
|  | ||||
| #if defined(sun) || defined(__sun__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) | ||||
| # if defined(__SVR4) || defined(__srv4__) | ||||
| #  define PLATFORM_SOLARIS | ||||
| # else | ||||
| #  define PLATFORM_SUNOS4 | ||||
| # endif | ||||
| #endif | ||||
| #if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX4) | ||||
| # define PLATFORM_AIX_V3 | ||||
| #endif | ||||
|  | ||||
| #if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) | ||||
| #error "O_NONBLOCK does not work on this platform" | ||||
| #endif | ||||
|   int socket; | ||||
|   int flags = fcntl(socket, F_SETFL, flags | O_NONBLOCK); | ||||
| ],[ | ||||
| dnl the O_NONBLOCK test was fine | ||||
| nonblock="O_NONBLOCK" | ||||
| AC_DEFINE(HAVE_O_NONBLOCK) | ||||
| ],[ | ||||
| dnl the code was bad, try a different program now, test 2 | ||||
|  | ||||
|   AC_TRY_COMPILE([ | ||||
| /* headers for FIONBIO test */ | ||||
| #include <unistd.h> | ||||
| #include <stropts.h> | ||||
| ],[ | ||||
| /* FIONBIO source test */ | ||||
|  int flags = ioctl(socket, FIONBIO, &flags); | ||||
| ],[ | ||||
| dnl FIONBIO test was good | ||||
| nonblock="FIONBIO" | ||||
| AC_DEFINE(HAVE_FIONBIO) | ||||
| ],[ | ||||
| dnl FIONBIO test was also bad | ||||
| dnl the code was bad, try a different program now, test 3 | ||||
|  | ||||
|   AC_TRY_COMPILE([ | ||||
| /* headers for ioctlsocket test (cygwin?) */ | ||||
| #include <windows.h> | ||||
| ],[ | ||||
| /* ioctlsocket source code */ | ||||
|  int flags = ioctlsocket(socket, FIONBIO, &flags); | ||||
| ],[ | ||||
| dnl ioctlsocket test was good | ||||
| nonblock="ioctlsocket" | ||||
| AC_DEFINE(HAVE_IOCTLSOCKET) | ||||
| ],[ | ||||
| dnl ioctlsocket didnt compile! | ||||
|  | ||||
|   AC_TRY_COMPILE([ | ||||
| /* headers for IoctlSocket test (Amiga?) */ | ||||
| #include <sys/ioctl.h> | ||||
| ],[ | ||||
| /* IoctlSocket source code */ | ||||
|  int flags = IoctlSocket(socket, FIONBIO, (long)1); | ||||
| ],[ | ||||
| dnl ioctlsocket test was good | ||||
| nonblock="IoctlSocket" | ||||
| AC_DEFINE(HAVE_IOCTLSOCKET_CASE) | ||||
| ],[ | ||||
| dnl ioctlsocket didnt compile! | ||||
| nonblock="nada" | ||||
| AC_DEFINE(HAVE_DISABLED_NONBLOCKING) | ||||
| ]) | ||||
| dnl end of forth test | ||||
|  | ||||
| ]) | ||||
| dnl end of third test | ||||
|  | ||||
| ]) | ||||
| dnl end of second test | ||||
|  | ||||
| ]) | ||||
| dnl end of non-blocking try-compile test | ||||
|   AC_MSG_RESULT($nonblock) | ||||
|  | ||||
|   if test "$nonblock" = "nada"; then | ||||
|     AC_MSG_WARN([non-block sockets disabled]) | ||||
|   fi | ||||
| ]) | ||||
|  | ||||
| dnl Check for socklen_t: historically on BSD it is an int, and in | ||||
| dnl POSIX 1g it is a type of its own, but some platforms use different | ||||
| dnl types for the argument to getsockopt, getpeername, etc.  So we | ||||
| @@ -142,7 +246,6 @@ AC_DEFUN(CURL_CHECK_INET_NTOA_R, | ||||
| 	AC_DEFINE(NEED_REENTRANT) | ||||
| 	AC_MSG_RESULT(yes)], | ||||
| 	AC_MSG_RESULT(no))])]) | ||||
|  | ||||
| ]) | ||||
|  | ||||
| AC_DEFUN(CURL_CHECK_GETHOSTBYADDR_R, | ||||
| @@ -220,8 +323,6 @@ rc = gethostbyaddr_r(address, length, type, &h, | ||||
| 	    ac_cv_gethostbyaddr_args=8],[ | ||||
| 	    AC_MSG_RESULT(no) | ||||
| 	    have_missing_r_funcs="$have_missing_r_funcs gethostbyaddr_r"])])])])]) | ||||
|  | ||||
|  | ||||
| ]) | ||||
|  | ||||
| AC_DEFUN(CURL_CHECK_GETHOSTBYNAME_R, | ||||
| @@ -229,28 +330,21 @@ AC_DEFUN(CURL_CHECK_GETHOSTBYNAME_R, | ||||
|   dnl check for number of arguments to gethostbyname_r. it might take | ||||
|   dnl either 3, 5, or 6 arguments. | ||||
|   AC_CHECK_FUNCS(gethostbyname_r,[ | ||||
|     AC_MSG_CHECKING(if gethostbyname_r takes 3 arguments) | ||||
|     AC_TRY_RUN([ | ||||
|     AC_MSG_CHECKING([if gethostbyname_r takes 3 arguments]) | ||||
|     AC_TRY_COMPILE([ | ||||
| #include <string.h> | ||||
| #include <sys/types.h> | ||||
| #include <netdb.h> | ||||
|  | ||||
| int | ||||
| main () { | ||||
| struct hostent h; | ||||
| struct hostent_data hdata; | ||||
| char *name = "localhost"; | ||||
| int rc; | ||||
| memset(&h, 0, sizeof(struct hostent)); | ||||
| memset(&hdata, 0, sizeof(struct hostent_data)); | ||||
| rc = gethostbyname_r(name, &h, &hdata); | ||||
| exit (rc != 0 ? 1 : 0); }],[ | ||||
| gethostbyname_r(const char *, struct hostent *, struct hostent_data *);],[ | ||||
| gethostbyname_r(NULL, NULL, NULL);],[ | ||||
|       AC_MSG_RESULT(yes) | ||||
|       AC_DEFINE(HAVE_GETHOSTBYNAME_R_3) | ||||
|       ac_cv_gethostbyname_args=3],[ | ||||
|       AC_MSG_RESULT(no) | ||||
|       AC_MSG_CHECKING(if gethostbyname_r with -D_REENTRANT takes 3 arguments) | ||||
|       AC_TRY_RUN([ | ||||
|       AC_MSG_CHECKING([if gethostbyname_r with -D_REENTRANT takes 3 arguments]) | ||||
|       AC_TRY_COMPILE([ | ||||
| #define _REENTRANT | ||||
|  | ||||
| #include <string.h> | ||||
| @@ -258,53 +352,34 @@ exit (rc != 0 ? 1 : 0); }],[ | ||||
| #include <netdb.h> | ||||
|  | ||||
| int | ||||
| main () { | ||||
| struct hostent h; | ||||
| struct hostent_data hdata; | ||||
| char *name = "localhost"; | ||||
| int rc; | ||||
| memset(&h, 0, sizeof(struct hostent)); | ||||
| memset(&hdata, 0, sizeof(struct hostent_data)); | ||||
| rc = gethostbyname_r(name, &h, &hdata); | ||||
| exit (rc != 0 ? 1 : 0); }],[ | ||||
| gethostbyname_r(const char *,struct hostent *, struct hostent_data *);],[ | ||||
| gethostbyname_r(NULL, NULL, NULL);],[ | ||||
| 	AC_MSG_RESULT(yes) | ||||
| 	AC_DEFINE(HAVE_GETHOSTBYNAME_R_3) | ||||
| 	AC_DEFINE(NEED_REENTRANT) | ||||
| 	ac_cv_gethostbyname_args=3],[ | ||||
| 	AC_MSG_RESULT(no) | ||||
| 	AC_MSG_CHECKING(if gethostbyname_r takes 5 arguments) | ||||
| 	AC_TRY_RUN([ | ||||
| 	AC_MSG_CHECKING([if gethostbyname_r takes 5 arguments]) | ||||
| 	AC_TRY_COMPILE([ | ||||
| #include <sys/types.h> | ||||
| #include <netdb.h> | ||||
|  | ||||
| int | ||||
| main () { | ||||
| struct hostent *hp; | ||||
| struct hostent h; | ||||
| char *name = "localhost"; | ||||
| char buffer[8192]; | ||||
| int h_errno; | ||||
| hp = gethostbyname_r(name, &h, buffer, 8192, &h_errno); | ||||
| exit (hp == NULL ? 1 : 0); }],[ | ||||
| struct hostent * | ||||
| gethostbyname_r(const char *, struct hostent *, char *, int, int *);],[ | ||||
| gethostbyname_r(NULL, NULL, NULL, 0, NULL);],[ | ||||
| 	  AC_MSG_RESULT(yes) | ||||
| 	  AC_DEFINE(HAVE_GETHOSTBYNAME_R_5) | ||||
|           ac_cv_gethostbyname_args=5],[ | ||||
| 	  AC_MSG_RESULT(no) | ||||
| 	  AC_MSG_CHECKING(if gethostbyname_r takes 6 arguments) | ||||
| 	  AC_TRY_RUN([ | ||||
| 	  AC_MSG_CHECKING([if gethostbyname_r takes 6 arguments]) | ||||
| 	  AC_TRY_COMPILE([ | ||||
| #include <sys/types.h> | ||||
| #include <netdb.h> | ||||
|  | ||||
| int | ||||
| main () { | ||||
| struct hostent h; | ||||
| struct hostent *hp; | ||||
| char *name = "localhost"; | ||||
| char buf[8192]; | ||||
| int rc; | ||||
| int h_errno; | ||||
| rc = gethostbyname_r(name, &h, buf, 8192, &hp, &h_errno); | ||||
| exit (rc != 0 ? 1 : 0); }],[ | ||||
| gethostbyname_r(const char *, struct hostent *, char *, size_t, | ||||
| struct hostent **, int *);],[ | ||||
| gethostbyname_r(NULL, NULL, NULL, 0, NULL, NULL);],[ | ||||
| 	    AC_MSG_RESULT(yes) | ||||
| 	    AC_DEFINE(HAVE_GETHOSTBYNAME_R_6) | ||||
|             ac_cv_gethostbyname_args=6],[ | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								build_vms.com
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								build_vms.com
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -5,9 +5,7 @@ die(){ | ||||
| 	exit | ||||
| } | ||||
|  | ||||
| MAKEFILES=`find . -name Makefile.am | sed 's/\.am$//'` | ||||
|  | ||||
| automake $MAKEFILES || die "The command 'automake $MAKEFILES' failed" | ||||
| automake          || die "The command 'automake $MAKEFILES' failed" | ||||
| aclocal           || die "The command 'aclocal' failed" | ||||
| autoheader        || die "The command 'autoheader' failed" | ||||
| autoconf          || die "The command 'autoconf' failed" | ||||
|   | ||||
							
								
								
									
										14
									
								
								config.guess
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								config.guess
									
									
									
									
										vendored
									
									
								
							| @@ -3,7 +3,7 @@ | ||||
| #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 | ||||
| #   Free Software Foundation, Inc. | ||||
|  | ||||
| timestamp='2001-08-23' | ||||
| timestamp='2001-09-04' | ||||
|  | ||||
| # This file is free software; you can redistribute it and/or modify it | ||||
| # under the terms of the GNU General Public License as published by | ||||
| @@ -393,6 +393,7 @@ EOF | ||||
| 	echo clipper-intergraph-clix${UNAME_RELEASE} | ||||
| 	exit 0 ;; | ||||
|     mips:*:*:UMIPS | mips:*:*:RISCos) | ||||
| 	eval $set_cc_for_build | ||||
| 	sed 's/^	//' << EOF >$dummy.c | ||||
| #ifdef __cplusplus | ||||
| #include <stdio.h>  /* for printf() prototype */ | ||||
| @@ -414,7 +415,6 @@ EOF | ||||
| 	  exit (-1); | ||||
| 	} | ||||
| EOF | ||||
| 	eval $set_cc_for_build | ||||
| 	$CC_FOR_BUILD $dummy.c -o $dummy \ | ||||
| 	  && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ | ||||
| 	  && rm -f $dummy.c $dummy && exit 0 | ||||
| @@ -484,6 +484,7 @@ EOF | ||||
| 	exit 0 ;; | ||||
|     *:AIX:2:3) | ||||
| 	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then | ||||
| 		eval $set_cc_for_build | ||||
| 		sed 's/^		//' << EOF >$dummy.c | ||||
| 		#include <sys/systemcfg.h> | ||||
|  | ||||
| @@ -495,7 +496,6 @@ EOF | ||||
| 			exit(0); | ||||
| 			} | ||||
| EOF | ||||
| 		eval $set_cc_for_build | ||||
| 		$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 | ||||
| 		rm -f $dummy.c $dummy | ||||
| 		echo rs6000-ibm-aix3.2.5 | ||||
| @@ -563,6 +563,7 @@ EOF | ||||
|                   fi ;; | ||||
|               esac | ||||
|               if [ "${HP_ARCH}" = "" ]; then | ||||
| 	      eval $set_cc_for_build | ||||
|               sed 's/^              //' << EOF >$dummy.c | ||||
|  | ||||
|               #define _HPUX_SOURCE | ||||
| @@ -596,7 +597,6 @@ EOF | ||||
|                   exit (0); | ||||
|               } | ||||
| EOF | ||||
| 	eval $set_cc_for_build | ||||
| 	    (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` | ||||
| 	    if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi | ||||
| 	    rm -f $dummy.c $dummy | ||||
| @@ -609,6 +609,7 @@ EOF | ||||
| 	echo ia64-hp-hpux${HPUX_REV} | ||||
| 	exit 0 ;; | ||||
|     3050*:HI-UX:*:*) | ||||
| 	eval $set_cc_for_build | ||||
| 	sed 's/^	//' << EOF >$dummy.c | ||||
| 	#include <unistd.h> | ||||
| 	int | ||||
| @@ -634,7 +635,6 @@ EOF | ||||
| 	  exit (0); | ||||
| 	} | ||||
| EOF | ||||
| 	eval $set_cc_for_build | ||||
| 	$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 | ||||
| 	rm -f $dummy.c $dummy | ||||
| 	echo unknown-hitachi-hiuxwe2 | ||||
| @@ -851,6 +851,7 @@ EOF | ||||
| 		exit 0 ;; | ||||
| 	esac | ||||
| 	# Determine whether the default compiler is a.out or elf | ||||
| 	eval $set_cc_for_build | ||||
| 	cat >$dummy.c <<EOF | ||||
| #include <features.h> | ||||
| #ifdef __cplusplus | ||||
| @@ -875,7 +876,6 @@ EOF | ||||
|   return 0; | ||||
| } | ||||
| EOF | ||||
| 	eval $set_cc_for_build | ||||
| 	$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0 | ||||
| 	rm -f $dummy.c $dummy | ||||
| 	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 | ||||
| @@ -1122,6 +1122,7 @@ esac | ||||
| #echo '(No uname command or uname output not recognized.)' 1>&2 | ||||
| #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 | ||||
|  | ||||
| eval $set_cc_for_build | ||||
| cat >$dummy.c <<EOF | ||||
| #ifdef _SEQUENT_ | ||||
| # include <sys/types.h> | ||||
| @@ -1236,7 +1237,6 @@ main () | ||||
| } | ||||
| EOF | ||||
|  | ||||
| eval $set_cc_for_build | ||||
| $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 | ||||
| rm -f $dummy.c $dummy | ||||
|  | ||||
|   | ||||
							
								
								
									
										9
									
								
								config.sub
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								config.sub
									
									
									
									
										vendored
									
									
								
							| @@ -3,7 +3,7 @@ | ||||
| #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 | ||||
| #   Free Software Foundation, Inc. | ||||
|  | ||||
| timestamp='2001-08-23' | ||||
| timestamp='2001-09-07' | ||||
|  | ||||
| # This file is (in principle) common to ALL GNU software. | ||||
| # The presence of a machine in this file suggests that SOME GNU software | ||||
| @@ -236,7 +236,8 @@ case $basic_machine in | ||||
| 	| mips16 | mips64 | mips64el | mips64orion | mips64orionel \ | ||||
| 	| mips64vr4100 | mips64vr4100el | mips64vr4300 \ | ||||
| 	| mips64vr4300el | mips64vr5000 | mips64vr5000el \ | ||||
| 	| mipsbe | mipsel | mipsle | mipstx39 | mipstx39el \ | ||||
| 	| mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ | ||||
| 	| mipsisa32 \ | ||||
| 	| mn10200 | mn10300 \ | ||||
| 	| ns16k | ns32k \ | ||||
| 	| openrisc \ | ||||
| @@ -293,8 +294,8 @@ case $basic_machine in | ||||
| 	| m88110-* | m88k-* | mcore-* \ | ||||
| 	| mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ | ||||
| 	| mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ | ||||
| 	| mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipsel-* \ | ||||
| 	| mipsle-* | mipstx39-* | mipstx39el-* \ | ||||
| 	| mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ | ||||
| 	| mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ | ||||
| 	| none-* | np1-* | ns16k-* | ns32k-* \ | ||||
| 	| orion-* \ | ||||
| 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | ||||
|   | ||||
							
								
								
									
										34
									
								
								configure.in
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								configure.in
									
									
									
									
									
								
							| @@ -1,9 +1,16 @@ | ||||
| dnl $Id$ | ||||
| dnl Process this file with autoconf to produce a configure script. | ||||
|  | ||||
| dnl Ensure that this file is processed with autoconf 2.50 or newer | ||||
| dnl Don't even think about removing this check! | ||||
| AC_PREREQ(2.50) | ||||
|  | ||||
| dnl First some basic init macros | ||||
| AC_INIT | ||||
| AC_CONFIG_SRCDIR([lib/urldata.h]) | ||||
| AM_CONFIG_HEADER(config.h src/config.h) | ||||
|  | ||||
| dnl figure out the libcurl version | ||||
| VERSION=`sed -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' ${srcdir}/include/curl/curl.h` | ||||
| AM_INIT_AUTOMAKE(curl,$VERSION) | ||||
|  | ||||
| @@ -38,6 +45,10 @@ AC_PROG_CC | ||||
| dnl check for how to do large files | ||||
| AC_SYS_LARGEFILE | ||||
|  | ||||
| dnl check for cygwin stuff | ||||
| AC_LIBTOOL_WIN32_DLL | ||||
|  | ||||
| dnl libtool setup | ||||
| AM_PROG_LIBTOOL | ||||
|  | ||||
| dnl The install stuff has already been taken care of by the automake stuff | ||||
| @@ -158,6 +169,24 @@ AC_CHECK_FUNC(gethostname, , AC_CHECK_LIB(ucb, gethostname)) | ||||
| dnl dl lib? | ||||
| AC_CHECK_FUNC(dlclose, , AC_CHECK_LIB(dl, dlopen)) | ||||
|  | ||||
| dnl ********************************************************************** | ||||
| dnl Check how non-blocking sockets are set | ||||
| dnl ********************************************************************** | ||||
| AC_ARG_ENABLE(nonblocking, | ||||
| [  --enable-nonblocking  Makes the script detect how to do it | ||||
|   --disable-nonblocking Makes the script disable non-blocking sockets], | ||||
| [ | ||||
|   if test "$enableval" = "no" ; then | ||||
|     AC_MSG_WARN([non-blocking sockets disabled]) | ||||
|     AC_DEFINE(HAVE_DISABLED_NONBLOCKING) | ||||
|   else | ||||
|     CURL_CHECK_NONBLOCKING_SOCKET | ||||
|   fi | ||||
| ], | ||||
| [ | ||||
|   CURL_CHECK_NONBLOCKING_SOCKET | ||||
| ]) | ||||
|  | ||||
| dnl ********************************************************************** | ||||
| dnl Check for the random seed preferences  | ||||
| dnl ********************************************************************** | ||||
| @@ -428,9 +457,6 @@ then | ||||
| Set to explicitly specify we don't want to use thread-safe functions) | ||||
| else | ||||
|  | ||||
|   dnl check that 'localhost' resolves first | ||||
|   CURL_CHECK_WORKING_RESOLVER | ||||
|  | ||||
|   dnl dig around for gethostbyname_r() | ||||
|   CURL_CHECK_GETHOSTBYNAME_R() | ||||
|  | ||||
| @@ -518,7 +544,6 @@ AC_CHECK_FUNCS( socket \ | ||||
|                 strcmpi \ | ||||
|                 gethostname \ | ||||
|                 gethostbyaddr \ | ||||
|                 getservbyname \ | ||||
|                 gettimeofday \ | ||||
|                 inet_addr \ | ||||
|                 inet_ntoa \ | ||||
| @@ -571,6 +596,7 @@ AC_CONFIG_FILES([Makefile \ | ||||
|            tests/data/Makefile \ | ||||
| 	   packages/Makefile \ | ||||
| 	   packages/Win32/Makefile \ | ||||
| 	   packages/Win32/cygwin/Makefile \ | ||||
| 	   packages/Linux/Makefile \ | ||||
| 	   packages/Linux/RPM/Makefile \ | ||||
| 	   packages/Linux/RPM/curl.spec \ | ||||
|   | ||||
							
								
								
									
										32
									
								
								docs/FAQ
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								docs/FAQ
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| Updated: August 23, 2001 (http://curl.haxx.se/docs/faq.shtml) | ||||
| Updated: November 1, 2001 (http://curl.haxx.se/docs/faq.shtml) | ||||
|                                   _   _ ____  _      | ||||
|                               ___| | | |  _ \| |     | ||||
|                              / __| | | | |_) | |     | ||||
| @@ -36,6 +36,7 @@ FAQ | ||||
|   3.9 How do I use curl in PHP, Perl, Tcl, Ruby or Java? | ||||
|   3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP? | ||||
|   3.11 How do I POST with a different Content-Type? | ||||
|   3.12 Why do FTP specific features over HTTP proxy fails? | ||||
|  | ||||
|  4. Running Problems | ||||
|   4.1 Problems connecting to SSL servers. | ||||
| @@ -96,10 +97,9 @@ FAQ | ||||
|  | ||||
|   1.3 What is cURL not? | ||||
|    | ||||
|   Curl is *not*, I repeat, *not* a wget clone even though that is a very | ||||
|   common misconception. Never, during curl's development, have I intended curl | ||||
|   to replace wget or compete on its market. Curl is targeted at single-shot | ||||
|   file transfers. | ||||
|   Curl is *not* a wget clone even though that is a very common misconception. | ||||
|   Never, during curl's development, have we intended curl to replace wget or | ||||
|   compete on its market. Curl is targeted at single-shot file transfers. | ||||
|  | ||||
|   Curl is not a web site mirroring program. If you wanna use curl to mirror | ||||
|   something: fine, go ahead and write a script that wraps around curl to make | ||||
| @@ -134,7 +134,7 @@ FAQ | ||||
|  | ||||
|   * We focus on protocol related issues and improvements. If you wanna do more | ||||
|     magic with the supported protocols than curl currently does, chances are | ||||
|     big I will agree. If you wanna add more protocols, I may very well | ||||
|     big we will agree. If you wanna add more protocols, we may very well | ||||
|     agree. | ||||
|  | ||||
|   * If you want someone else to make all the work while you wait for us to | ||||
| @@ -375,6 +375,18 @@ FAQ | ||||
|  | ||||
|         curl -d "datatopost" -H "Content-Type: text/xml" [URL] | ||||
|  | ||||
|   3.12 Why do FTP specific features over HTTP proxy fail? | ||||
|  | ||||
|   Because when you use a HTTP proxy, the protocol spoken on the network will | ||||
|   be HTTP, even if you specify a FTP URL. This effectively means that you | ||||
|   normally can't use FTP specific features such as ftp upload and ftp quote | ||||
|   etc. | ||||
|  | ||||
|   There is one exception to this rule, and that is if you can "tunnel through" | ||||
|   the given HTTP proxy. Proxy tunneling is enabled with a special option (-P) | ||||
|   and is generally not available as proxy admins usuable disable tunneling to | ||||
|   other ports than 443 (which is used for HTTPS access through proxies). | ||||
|  | ||||
| 4. Running Problems | ||||
|  | ||||
|   4.1. Problems connecting to SSL servers. | ||||
| @@ -573,13 +585,7 @@ FAQ | ||||
|  | ||||
|   5.4 Does libcurl do Winsock initialization on win32 systems? | ||||
|  | ||||
|   No. | ||||
|  | ||||
|   On win32 systems, you need to init the winsock stuff manually, libcurl will | ||||
|   not do that for you. WSAStartup() and WSACleanup() should be used | ||||
|   accordingly. The reason for this is of course that a single application may | ||||
|   use several different libraries and parts, and there's no reason for every | ||||
|   single library to do this. | ||||
|   Yes (since 7.8.1) if told to in the curl_global_init() call. | ||||
|  | ||||
|   5.5 Does CURLOPT_FILE and CURLOPT_INFILE work on win32 ? | ||||
|  | ||||
|   | ||||
							
								
								
									
										58
									
								
								docs/INSTALL
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								docs/INSTALL
									
									
									
									
									
								
							| @@ -8,9 +8,12 @@ | ||||
|  | ||||
| Curl has been compiled and built on numerous different operating systems. | ||||
|  | ||||
| If you're using Windows (95/98/NT/ME/2000 or whatever), VMS, RISC OS or OS/2, | ||||
| you should continue reading from one the paragraphs further down. All other | ||||
| systems should be capable of being installed as described below. | ||||
| Most systems build curl the same way (unix-style). Continue reading below for | ||||
| more details if you're one of them. | ||||
|  | ||||
| If you're using Windows (95/98/NT/ME/2000/XP or similar), VMS, RISC OS or OS/2 | ||||
| or cross-compile, you should continue reading from one the paragraphs further | ||||
| down. | ||||
|  | ||||
| UNIX | ||||
| ==== | ||||
| @@ -325,13 +328,50 @@ VMS | ||||
|    13-jul-2001 | ||||
|    N. Baggus | ||||
|  | ||||
| CROSS COMPILE | ||||
| ============= | ||||
|  | ||||
|    (This section was graciously brought to us by Jim Duey, 23-oct-2001) | ||||
|  | ||||
|    Download and unpack the cURL package.  Version should be 7.9.1 or later. | ||||
|  | ||||
|    'cd' to the new directory. (ie. curl-7.9.1-pre4) | ||||
|  | ||||
|    Set environment variables to point to the cross-compile toolchain and call | ||||
|    configure with any options you need.  Be sure and specify the '--host' and | ||||
|    '--build' parameters at configuration time.  The following script is an | ||||
|    example of cross-compiling for the IBM 405GP PowerPC processor using the | ||||
|    toolchain from MonteVista for Hardhat Linux. | ||||
|  | ||||
|    (begin script) | ||||
|  | ||||
|    #! /bin/sh | ||||
|  | ||||
|    export PATH=$PATH:/opt/hardhat/devkit/ppc/405/bin | ||||
|    export CPPFLAGS="-I/opt/hardhat/devkit/ppc/405/target/usr/include" | ||||
|    export AR=ppc_405-ar | ||||
|    export AS=ppc_405-as | ||||
|    export LD=ppc_405-ld | ||||
|    export RANLIB=ppc_405-ranlib | ||||
|    export CC=ppc_405-gcc | ||||
|    export NM=ppc_405-nm | ||||
|  | ||||
|    configure --target=powerpc-hardhat-linux \ | ||||
| 	--host=powerpc-hardhat-linux \ | ||||
| 	--build=i586-pc-linux-gnu \ | ||||
| 	--prefix=/opt/hardhat/devkit/ppc/405/target/usr/local \ | ||||
| 	--exec-prefix=/usr/local | ||||
|  | ||||
|    (end script) | ||||
|  | ||||
|    The '--prefix' parameter specifies where cURL will be installed.  If | ||||
|    'configure' completes successfully, do 'make' and 'make install' as usual. | ||||
|  | ||||
| PORTS | ||||
| ===== | ||||
|    This is a probably incomplete list of known hardware and operating systems | ||||
|    that curl has been compiled for: | ||||
|  | ||||
|         - Ultrix 4.3a | ||||
|         - SINIX-Z v5 | ||||
|         - Alpha DEC OSF 4 | ||||
|         - Alpha Digital UNIX v3.2 | ||||
|         - Alpha FreeBSD 4.1 | ||||
| @@ -344,9 +384,14 @@ PORTS | ||||
|         - PowerPC Darwin 1.0 | ||||
|         - PowerPC Linux | ||||
|         - PowerPC Mac OS X | ||||
|         - SINIX-Z v5 | ||||
|         - Sparc Linux | ||||
|         - Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7, 8 | ||||
|         - Sparc SunOS 4.1.X | ||||
|         - StrongARM (and other ARM) RISC OS 3.1, 4.02 | ||||
|         - StrongARM Linux 2.4 | ||||
|         - StrongARM NetBSD 1.4.1 | ||||
|         - Ultrix 4.3a | ||||
|         - i386 BeOS | ||||
|         - i386 FreeBSD | ||||
|         - i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4 | ||||
| @@ -359,8 +404,7 @@ PORTS | ||||
|         - ia64 Linux 2.3.99 | ||||
|         - m68k AmigaOS 3 | ||||
|         - m68k OpenBSD | ||||
|         - StrongARM NetBSD 1.4.1 | ||||
|         - StrongARM (and other ARM) RISC OS 3.1, 4.02 | ||||
|         - s390 Linux  | ||||
|  | ||||
| OpenSSL | ||||
| ======= | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
|                                        Updated for curl 7.8 on May 29, 2001 | ||||
|                                     Updated for curl 7.9.1 on November 2, 2001 | ||||
|                                   _   _ ____  _      | ||||
|                               ___| | | |  _ \| |     | ||||
|                              / __| | | | |_) | |     | ||||
| @@ -78,15 +78,15 @@ Library | ||||
|  makes sure we stay absolutely platform independent. | ||||
|  | ||||
|  curl_easy_init() allocates an internal struct and makes some initializations. | ||||
|  The returned handle does not reveal internals. This is the 'UrlData' struct | ||||
|  which works as a global "anchor" struct. All connections performed will get | ||||
|  connect-specific data allocated that should be used for things related to | ||||
|  particular connections/requests. | ||||
|  The returned handle does not reveal internals. This is the 'SessionHandle' | ||||
|  struct which works as an "anchor" struct for all curl_easy functions. All | ||||
|  connections performed will get connect-specific data allocated that should be | ||||
|  used for things related to particular connections/requests. | ||||
|  | ||||
|  curl_easy_setopt() takes three arguments, where the option stuff must be | ||||
|  passed in pairs: the parameter-ID and the parameter-value. The list of | ||||
|  options is documented in the man page. This function mainly sets things in | ||||
|  the 'UrlData' struct. | ||||
|  the 'SessionHandle' struct. | ||||
|  | ||||
|  curl_easy_perform() does a whole lot of things: | ||||
|  | ||||
| @@ -106,7 +106,7 @@ Library | ||||
|    This function makes sure there's an allocated and initiated 'connectdata' | ||||
|    struct that is used for this particular connection only (although there may | ||||
|    be several requests performed on the same connect). A bunch of things are | ||||
|    inited/inherited from the UrlData struct. | ||||
|    inited/inherited from the SessionHandle struct. | ||||
|  | ||||
|  o Curl_do() | ||||
|  | ||||
| @@ -123,6 +123,13 @@ Library | ||||
|    Curl_Transfer() function (in lib/transfer.c) to setup the transfer and | ||||
|    returns. | ||||
|  | ||||
|    Starting in 7.9.1, if this DO function fails and the connection is being | ||||
|    re-used, libcurl will then close this connection, setup a new connection | ||||
|    and re-issue the DO request on that. This is because there is no way to be | ||||
|    perfectly sure that we have discovered a dead connection before the DO | ||||
|    function and thus we might wrongly be re-using a connection that was closed | ||||
|    by the remote peer. | ||||
|  | ||||
|  o Transfer() | ||||
|  | ||||
|    Curl_perform() then calls Transfer() in lib/transfer.c that performs | ||||
| @@ -144,7 +151,7 @@ Library | ||||
|  o Curl_disconnect() | ||||
|  | ||||
|    When doing normal connections and transfers, no one ever tries to close any | ||||
|    connection so this is not normally called when curl_easy_perform() is | ||||
|    connections so this is not normally called when curl_easy_perform() is | ||||
|    used. This function is only used when we are certain that no more transfers | ||||
|    is going to be made on the connection. It can be also closed by force, or | ||||
|    it can be called to make sure that libcurl doesn't keep too many | ||||
| @@ -258,12 +265,12 @@ Persistent Connections | ||||
|  The persistent connection support in libcurl requires some considerations on | ||||
|  how to do things inside of the library. | ||||
|  | ||||
|  o The 'UrlData' struct returned in the curl_easy_init() call must never | ||||
|    hold connection-oriented data. It is meant to hold the root data as well | ||||
|    as all the options etc that the library-user may choose. | ||||
|  o The 'UrlData' struct holds the "connection cache" (an array of pointers to | ||||
|    'connectdata' structs). There's one connectdata struct allocated for each | ||||
|    connection that libcurl knows about. | ||||
|  o The 'SessionHandle' struct returned in the curl_easy_init() call must never | ||||
|    hold connection-oriented data. It is meant to hold the root data as well as | ||||
|    all the options etc that the library-user may choose. | ||||
|  o The 'SessionHandle' struct holds the "connection cache" (an array of | ||||
|    pointers to 'connectdata' structs). There's one connectdata struct | ||||
|    allocated for each connection that libcurl knows about. | ||||
|  o This also enables the 'curl handle' to be reused on subsequent transfers, | ||||
|    something that was illegal before libcurl 7.7. | ||||
|  o When we are about to perform a transfer with curl_easy_perform(), we first | ||||
|   | ||||
							
								
								
									
										15
									
								
								docs/MANUAL
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								docs/MANUAL
									
									
									
									
									
								
							| @@ -132,7 +132,7 @@ UPLOADING | ||||
|  | ||||
|   Upload all data on stdin to a specified ftp site: | ||||
|  | ||||
|         curl -t ftp://ftp.upload.com/myfile | ||||
|         curl -T - ftp://ftp.upload.com/myfile | ||||
|  | ||||
|   Upload data from a specified file, login with user and password: | ||||
|  | ||||
| @@ -157,7 +157,7 @@ UPLOADING | ||||
|  | ||||
|   Upload all data on stdin to a specified http site: | ||||
|  | ||||
|         curl -t http://www.upload.com/myfile | ||||
|         curl -T - http://www.upload.com/myfile | ||||
|  | ||||
|   Note that the http server must've been configured to accept PUT before this | ||||
|   can be done successfully. | ||||
| @@ -756,6 +756,17 @@ TELNET | ||||
|   You might want the -N/--no-buffer option to switch off the buffered output | ||||
|   for slow connections or similar. | ||||
|  | ||||
|   Pass options to the telnet protocol negotiation, by using the -t option. To | ||||
|   tell the server we use a vt100 terminal, try something like: | ||||
|  | ||||
|         curl -tTTYPE=vt100 telnet://remote.server.com | ||||
|  | ||||
|   Other interesting options for it -t include: | ||||
|  | ||||
|    - XDISPLOC=<X display> Sets the X display location. | ||||
|  | ||||
|    - NEW_ENV=<var,val> Sets an environment variable. | ||||
|  | ||||
|   NOTE: the telnet protocol does not specify any way to login with a specified | ||||
|   user and password so curl can't do that automatically. To do that, you need | ||||
|   to track when the login prompt is received and send the username and | ||||
|   | ||||
| @@ -12,6 +12,7 @@ man_MANS = \ | ||||
| 	curl_easy_init.3 \ | ||||
| 	curl_easy_perform.3 \ | ||||
| 	curl_easy_setopt.3 \ | ||||
| 	curl_easy_duphandle.3 \ | ||||
| 	curl_formparse.3 \ | ||||
| 	curl_formadd.3 \ | ||||
| 	curl_formfree.3 \ | ||||
| @@ -39,6 +40,7 @@ HTMLPAGES = \ | ||||
| 	curl_easy_init.html \ | ||||
| 	curl_easy_perform.html \ | ||||
| 	curl_easy_setopt.html \ | ||||
| 	curl_easy_duphandle.html \ | ||||
| 	curl_formadd.html \ | ||||
| 	curl_formparse.html \ | ||||
| 	curl_formfree.html \ | ||||
|   | ||||
							
								
								
									
										99
									
								
								docs/TODO
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								docs/TODO
									
									
									
									
									
								
							| @@ -10,26 +10,42 @@ TODO | ||||
|  send me patches that improve things! Also check the http://curl.haxx.se/dev | ||||
|  web section for various development notes. | ||||
|  | ||||
| To do in a future release (random order): | ||||
|  | ||||
|  * FTP ASCII upload does not follow RFC959 section 3.1.1.1:  | ||||
|     "The sender converts the data from an internal character representation to | ||||
|     the standard 8-bit NVT-ASCII representation (see the Telnet | ||||
|     specification).  The receiver will convert the data from the standard form | ||||
|     to his own internal form." | ||||
|  | ||||
|  * Make the connect non-blocking so that timeouts work for connect in  | ||||
|    multi-threaded programs  | ||||
|  LIBCURL | ||||
|  | ||||
|  * Consider an interface to libcurl that allows applications to easier get to | ||||
|    know what cookies that are sent back in the response headers. | ||||
|  | ||||
|  * HTTP PUT for files passed on stdin. Requires libcurl to send the file | ||||
|    with chunked content encoding. http://curl.haxx.se/dev/HTTP-PUT-stdin.txt | ||||
|  * Make content encoding/decoding internally be made using a filter system. | ||||
|  | ||||
|  * The new 'multi' interface is being designed. Work out the details, start | ||||
|    implementing and write test applications! | ||||
|    [http://curl.haxx.se/dev/multi.h] | ||||
|  | ||||
|  * Add a name resolve cache to libcurl to make repeated fetches to the same | ||||
|    host name (when persitancy isn't available) faster. | ||||
|  | ||||
|  * Introduce another callback interface for upload/download that makes one | ||||
|    less copy of data and thus a faster operation. | ||||
|    http://curl.haxx.se/dev/no_copy_callbacks.txt | ||||
|    [http://curl.haxx.se/dev/no_copy_callbacks.txt] | ||||
|  | ||||
|  * Add configure options that disables certain protocols in libcurl to | ||||
|    decrease footprint.  '--disable-[protocol]' where protocol is http, ftp, | ||||
|    telnet, ldap, dict or file. | ||||
|  | ||||
|  * Add asynchronous name resolving. http://curl.haxx.se/dev/async-resolver.txt | ||||
|  | ||||
|  DOCUMENTATION | ||||
|  | ||||
|  * Document all CURLcode error codes, why they happen and what most likely | ||||
|    will make them not happen again. | ||||
|  | ||||
|  FTP | ||||
|  | ||||
|  * FTP ASCII upload does not follow RFC959 section 3.1.1.1: "The sender | ||||
|    converts the data from an internal character representation to the standard | ||||
|    8-bit NVT-ASCII representation (see the Telnet specification).  The | ||||
|    receiver will convert the data from the standard form to his own internal | ||||
|    form." | ||||
|  | ||||
|  * 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 | ||||
| @@ -38,33 +54,25 @@ To do in a future release (random order): | ||||
|  | ||||
|  * Suggested on the mailing list: CURLOPT_FTP_MKDIR...! | ||||
|  | ||||
|  * Add configure options that disables certain protocols in libcurl to | ||||
|    decrease footprint.  '--disable-[protocol]' where protocol is http, ftp, | ||||
|    telnet, ldap, dict or file. | ||||
|  * Always use the FTP SIZE command before downloading, as that makes it more | ||||
|    likely that we know the size when downloading. Some sites support SIZE but | ||||
|    don't show the size in the RETR response! | ||||
|  | ||||
|  * Extend the test suite to include telnet. The telnet could just do ftp or | ||||
|    http operations (for which we have test servers). | ||||
|  * Make FTP PASV work with IPv6 support. RFC 2428 "FTP Extensions for IPv6 and | ||||
|    NATs" is interesting. | ||||
|  | ||||
|  * Make TELNET work on windows! | ||||
|  HTTP | ||||
|  | ||||
|  * Make curl's SSL layer option capable of using other free SSL libraries. | ||||
|    Such as the Mozilla Security Services | ||||
|    (http://www.mozilla.org/projects/security/pki/nss/) and GNUTLS | ||||
|    (http://gnutls.hellug.gr/) | ||||
|  | ||||
|  * Add asynchronous name resolving, as this enables full timeout support for | ||||
|    fork() systems. http://curl.haxx.se/dev/async-resolver.txt | ||||
|  | ||||
|  * Move non-URL related functions that are used by both the lib and the curl | ||||
|    application to a separate "portability lib". | ||||
|  | ||||
|  * Add libcurl support/interfaces for more languages. C++ wrapper perhaps? | ||||
|  * HTTP PUT for files passed on stdin *OR* when the --crlf option is | ||||
|    used. Requires libcurl to send the file with chunked content | ||||
|    encoding. [http://curl.haxx.se/dev/HTTP-PUT-stdin.txt] When the filter | ||||
|    system mentioned above gets real, it'll be a piece of cake to add. | ||||
|  | ||||
|  * "Content-Encoding: compress/gzip/zlib" HTTP 1.1 clearly defines how to get | ||||
|    and decode compressed documents. There is the zlib that is pretty good at | ||||
|    decompressing stuff. This work was started in October 1999 but halted again | ||||
|    since it proved more work than we thought. It is still a good idea to | ||||
|    implement though. | ||||
|    implement though. This requires the filter system mentioned above. | ||||
|  | ||||
|  * Authentication: NTLM. Support for that MS crap called NTLM | ||||
|    authentication. MS proxies and servers sometime require that. Since that | ||||
| @@ -87,10 +95,27 @@ To do in a future release (random order): | ||||
|    sends the password in cleartext over the network, this "Digest" method uses | ||||
|    a challange-response protocol which increases security quite a lot. | ||||
|  | ||||
|  * Other proxies | ||||
|    Ftp-kind proxy, Socks5, whatever kind of proxies are there? | ||||
|  TELNET | ||||
|  | ||||
|  * Full IPv6 Awareness and support. (This is partly done.)  RFC 2428 "FTP | ||||
|    Extensions for IPv6 and NATs" is interesting. PORT should be replaced with | ||||
|    EPRT for IPv6 (done), and EPSV instead of PASV. | ||||
|  * Make TELNET work on windows98! | ||||
|  | ||||
|  SSL | ||||
|  | ||||
|  * Make curl's SSL layer option capable of using other free SSL libraries. | ||||
|    Such as the Mozilla Security Services | ||||
|    (http://www.mozilla.org/projects/security/pki/nss/) and GNUTLS | ||||
|    (http://gnutls.hellug.gr/) | ||||
|  | ||||
|  LDAP | ||||
|  | ||||
|  * Multiple URL requests don't work. [http://sourceforge.net/tracker/index.php?func=detail&aid=475407&group_id=976&atid=100976] | ||||
|  | ||||
|  TEST SUITE | ||||
|  | ||||
|  * Extend the test suite to include more protocols. The telnet could just do | ||||
|    ftp or http operations (for which we have test servers). | ||||
|  | ||||
|  * Make the test suite work on more platforms. OpenBSD and Mac OS. Remove | ||||
|    fork()s and it should become even more portable. | ||||
|  | ||||
|  * Introduce a test suite that tests libcurl better and more explicitly. | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| Online:  http://curl.haxx.se/docs/httpscripting.shtml | ||||
| Author:  Daniel Stenberg <daniel@haxx.se> | ||||
| Date:    August 20, 2001 | ||||
| Version: 0.4 | ||||
| Date:    October 31, 2001 | ||||
| Version: 0.5 | ||||
|  | ||||
|                 The Art Of Scripting HTTP Requests Using Curl | ||||
|                 ============================================= | ||||
| @@ -48,7 +48,7 @@ Version: 0.4 | ||||
| 2. URL | ||||
|  | ||||
|  The Uniform Resource Locator format is how you specify the address of a | ||||
|  particular resource on the internet. You know these, you've seen URLs like | ||||
|  particular resource on the Internet. You know these, you've seen URLs like | ||||
|  http://curl.haxx.se or https://yourbank.com a million times. | ||||
|  | ||||
| 3. GET a page | ||||
| @@ -56,7 +56,7 @@ Version: 0.4 | ||||
|  The simplest and most common request/operation made using HTTP is to get a | ||||
|  URL. The URL could itself refer to a web page, an image or a file. The client | ||||
|  issues a GET request to the server and receives the document it asked for. | ||||
|  If you isse the command line | ||||
|  If you issue the command line | ||||
|  | ||||
|         curl http://curl.haxx.se | ||||
|  | ||||
| @@ -89,7 +89,7 @@ Version: 0.4 | ||||
|           <input type=submit name=press value="OK"> | ||||
|         </form> | ||||
|  | ||||
|   In your favourite browser, this form will appear with a text box to fill in | ||||
|   In your favorite browser, this form will appear with a text box to fill in | ||||
|   and a press-button labeled "OK". If you fill in '1905' and press the OK | ||||
|   button, your browser will then create a new URL to get for you. The URL will | ||||
|   get "junk.cgi?birthyear=1905&press=OK" appended to the path part of the | ||||
| @@ -136,8 +136,8 @@ Version: 0.4 | ||||
|  4.3 FILE UPLOAD POST | ||||
|  | ||||
|   Back in late 1995 they defined a new way to post data over HTTP. It was | ||||
|   documented in the RFC 1867, why this method sometimes is refered to as | ||||
|   a rfc1867-posting. | ||||
|   documented in the RFC 1867, why this method sometimes is referred to as | ||||
|   a RFC1867-posting. | ||||
|  | ||||
|   This method is mainly designed to better support file uploads. A form that | ||||
|   allows a user to upload a file could be written like this in HTML: | ||||
| @@ -182,7 +182,7 @@ Version: 0.4 | ||||
|   way your browser does. | ||||
|  | ||||
|   An easy way to get to see this, is to save the HTML page with the form on | ||||
|   your local disk, mofidy the 'method' to a GET, and press the submit button | ||||
|   your local disk, modify the 'method' to a GET, and press the submit button | ||||
|   (you could also change the action URL if you want to). | ||||
|  | ||||
|   You will then clearly see the data get appended to the URL, separated with a | ||||
| @@ -214,7 +214,7 @@ Version: 0.4 | ||||
|  Sometimes your HTTP access is only available through the use of a HTTP | ||||
|  proxy. This seems to be especially common at various companies. A HTTP proxy | ||||
|  may require its own user and password to allow the client to get through to | ||||
|  the internet. To specify those with curl, run something like: | ||||
|  the Internet. To specify those with curl, run something like: | ||||
|  | ||||
|         curl -U proxyuser:proxypassword curl.haxx.se | ||||
|  | ||||
| @@ -294,7 +294,7 @@ Version: 0.4 | ||||
|  contents to the server, unless of course they are expired. | ||||
|  | ||||
|  Many applications and servers use this method to connect a series of requests | ||||
|  into a single logical session. To be able to use curl in such occations, we | ||||
|  into a single logical session. To be able to use curl in such occasions, we | ||||
|  must be able to record and send back cookies the way the web application | ||||
|  expects them. The same way browsers deal with them. | ||||
|  | ||||
| @@ -325,6 +325,15 @@ Version: 0.4 | ||||
|  | ||||
|         curl -b nada -L www.cookiesite.com | ||||
|  | ||||
|  Curl has the ability to read and write cookie files that use the same file | ||||
|  format that Netscape and Mozilla do. It is a convenient way to share cookies | ||||
|  between browsers and automatic scripts. The -b switch automatically detects | ||||
|  if a given file is such a cookie file and parses it, and by using the | ||||
|  -c/--cookie-jar option you'll make curl write a new cookie file at the end of | ||||
|  an operation: | ||||
|  | ||||
|         curl -b cookies.txt -c newcookies.txt www.cookiesite.com | ||||
|  | ||||
| 11. HTTPS | ||||
|  | ||||
|  There are a few ways to do secure HTTP transfers. The by far most common | ||||
| @@ -349,7 +358,7 @@ Version: 0.4 | ||||
|   you need to enter the unlock-code before the certificate can be used by | ||||
|   curl. The PIN-code can be specified on the command line or if not, entered | ||||
|   interactively when curl queries for it. Use a certificate with curl on a | ||||
|   https server like: | ||||
|   HTTPS server like: | ||||
|  | ||||
|         curl -E mycert.pem https://that.secure.server.com | ||||
|  | ||||
| @@ -358,10 +367,12 @@ Version: 0.4 | ||||
|  RFC 2616 is a must to read if you want in-depth understanding of the HTTP | ||||
|  protocol. | ||||
|  | ||||
|  RFC 2396 explains the URL syntax | ||||
|  RFC 2396 explains the URL syntax. | ||||
|  | ||||
|  RFC 2109 defines how cookies are supposed to work. | ||||
|  | ||||
|  RFC 1867 defines the HTTP post upload format. | ||||
|  | ||||
|  http://www.openssl.org is the home of the OpenSSL project | ||||
|  | ||||
|  http://curl.haxx.se is the home of the cURL project | ||||
|   | ||||
							
								
								
									
										27
									
								
								docs/curl.1
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								docs/curl.1
									
									
									
									
									
								
							| @@ -2,7 +2,7 @@ | ||||
| .\" nroff -man curl.1 | ||||
| .\" Written by Daniel Stenberg | ||||
| .\" | ||||
| .TH curl 1 "12 Sep 2001" "Curl 7.9" "Curl Manual" | ||||
| .TH curl 1 "30 Oct 2001" "Curl 7.9.1" "Curl Manual" | ||||
| .SH NAME | ||||
| curl \- get a URL with FTP, TELNET, LDAP, GOPHER, DICT, FILE, HTTP or | ||||
| HTTPS syntax. | ||||
| @@ -485,14 +485,15 @@ XDISPLOC=<X display> Sets the X display location. | ||||
|  | ||||
| NEW_ENV=<var,val> Sets an environment variable. | ||||
| .IP "-T/--upload-file <file>" | ||||
| Like -t, but this transfers the specified local file. If there is no | ||||
| file part in the specified URL, Curl will append the local file | ||||
| name. NOTE that you must use a trailing / on the last directory to | ||||
| really prove to Curl that there is no file name or curl will | ||||
| think that your last directory name is the remote file name to | ||||
| use. That will most likely cause the upload operation to fail. If | ||||
| This transfers the specified local file to the remote URL. If there is no file | ||||
| part in the specified URL, Curl will append the local file name. NOTE that you | ||||
| must use a trailing / on the last directory to really prove to Curl that there | ||||
| is no file name or curl will think that your last directory name is the remote | ||||
| file name to use. That will most likely cause the upload operation to fail. If | ||||
| this is used on a http(s) server, the PUT command will be used. | ||||
|  | ||||
| Use the file name "-" (a single dash) to use stdin instead of a given file. | ||||
|  | ||||
| If this option is used several times, the last one will be used. | ||||
| .IP "-u/--user <user:password>" | ||||
| Specify user and password to use when fetching. See README.curl for detailed | ||||
| @@ -589,8 +590,13 @@ The average upload speed that curl measured for the complete upload. | ||||
|  | ||||
| If this option is used several times, the last one will be used. | ||||
| .IP "-x/--proxy <proxyhost[:port]>" | ||||
| Use specified proxy. If the port number is not specified, it is assumed at | ||||
| port 1080. | ||||
| Use specified HTTP proxy. If the port number is not specified, it is assumed | ||||
| at port 1080. | ||||
|  | ||||
| \fBNote\fP that all operations that are performed over a HTTP proxy will | ||||
| transparantly be converted to HTTP. It means that certain protocol specific | ||||
| operations might not be available. This is not the case if you can tunnel | ||||
| through the proxy, as done with the \fI-p/--proxytunnel\fP option. | ||||
|  | ||||
| If this option is used several times, the last one will be used. | ||||
| .IP "-X/--request <command>" | ||||
| @@ -638,6 +644,9 @@ Forces curl to use SSL version 3 when negotiating with a remote SSL server. | ||||
| .IP "-2/--sslv2" | ||||
| (HTTPS) | ||||
| Forces curl to use SSL version 2 when negotiating with a remote SSL server. | ||||
| .IP "-0/--http1.0" | ||||
| (HTTP) Forces curl to issue its requests using HTTP 1.0 instead of using its | ||||
| internally preferred: HTTP 1.1. | ||||
| .IP "-#/--progress-bar" | ||||
| Make curl display progress information as a progress bar instead of the | ||||
| default statistics. | ||||
|   | ||||
							
								
								
									
										37
									
								
								docs/curl_easy_duphandle.3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								docs/curl_easy_duphandle.3
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| .\" You can view this file with: | ||||
| .\" nroff -man [file] | ||||
| .\" $Id$ | ||||
| .\" | ||||
| .TH curl_easy_duphandle 3 "18 September 2001" "libcurl 7.9" "libcurl Manual" | ||||
| .SH NAME | ||||
| curl_easy_duphandle - Clone a libcurl session handle | ||||
| .SH SYNOPSIS | ||||
| .B #include <curl/curl.h> | ||||
| .sp | ||||
| .BI "CURL *curl_easy_duphandle(CURL *"handle ");" | ||||
| .ad | ||||
| .SH DESCRIPTION | ||||
| This function will return a new curl handle, a duplicate, using all the | ||||
| options previously set in the input curl \fIhandle\fP. Both handles can | ||||
| subsequently be used independently and they must both be freed with | ||||
| \fIcurl_easy_cleanup()\fP. | ||||
|  | ||||
| All strings that the input handle has been told to point to (as opposed to | ||||
| copy) with previous calls to \fIcurl_easy_setopt\fP using char * inputs, will | ||||
| be pointed to by the new handle as well. You must therefore make sure to keep | ||||
| the data around until both handles have been cleaned up. | ||||
|  | ||||
| The new handle will \fBnot\fP inherit any state information, no connections, | ||||
| no SSL sessions and no cookies. | ||||
|  | ||||
| \fBNote\fP that even in multi-threaded programs, this function must be called | ||||
| in a synchronous way, the input handle may not be in use when cloned. | ||||
|  | ||||
| This function was added in libcurl 7.9. | ||||
| .SH RETURN VALUE | ||||
| If this function returns NULL, something went wrong and no valid handle was | ||||
| returned. | ||||
| .SH "SEE ALSO" | ||||
| .BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_global_init "(3) | ||||
| .SH BUGS | ||||
| Surely there are some, you tell me! | ||||
| @@ -2,83 +2,84 @@ | ||||
| .\" nroff -man [file] | ||||
| .\" $Id$ | ||||
| .\" | ||||
| .TH curl_easy_setopt 3 "12 Sep 2001" "libcurl 7.9" "libcurl Manual" | ||||
| .TH curl_easy_setopt 3 "11 Oct 2001" "libcurl 7.9.1" "libcurl Manual" | ||||
| .SH NAME | ||||
| curl_easy_setopt - Set curl easy-session options | ||||
| .SH SYNOPSIS | ||||
| .B #include <curl/curl.h> | ||||
| .sp | ||||
| .BI "CURLcode curl_easy_setopt(CURL *" handle ", CURLoption "option ", ...);" | ||||
| #include <curl/curl.h> | ||||
|  | ||||
| CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter); | ||||
| .ad | ||||
| .SH DESCRIPTION | ||||
| curl_easy_setopt() is called to tell libcurl how to behave in a number of | ||||
| ways. Most operations in libcurl have default actions, and by using the | ||||
| appropriate options you can make them behave differently (as documented).  All | ||||
| options are set with the | ||||
| .I option | ||||
| followed by a parameter. That parameter can be a long, a function pointer or | ||||
| an object pointer, all depending on what the option in question expects. Read | ||||
| this manual carefully as bad input values may cause libcurl to behave badly! | ||||
| You can only set one option in each function call. A typical application uses | ||||
| many curl_easy_setopt() calls in the setup phase. | ||||
| curl_easy_setopt() is used to tell libcurl how to behave. Most operations in | ||||
| libcurl have default actions, and by using the appropriate options to | ||||
| \fIcurl_easy_setopt\fP, you can change them.  All options are set with the | ||||
| \fIoption\fP followed by a \fIparameter\fP. That parameter can be a long, a | ||||
| function pointer or an object pointer, all depending on what the specific | ||||
| option expects. Read this manual carefully as bad input values may cause | ||||
| libcurl to behave badly!  You can only set one option in each function call. A | ||||
| typical application uses many curl_easy_setopt() calls in the setup phase. | ||||
|  | ||||
| NOTE: strings passed to libcurl as 'char *' arguments, will not be copied by | ||||
| the library. Instead you should keep them available until libcurl no longer | ||||
| needs them. Failing to do so will cause very odd behaviour or even crashes. | ||||
| \fBNOTE:\fP strings passed to libcurl as 'char *' arguments, will not be | ||||
| copied by the library. Instead you should keep them available until libcurl no | ||||
| longer needs them. Failing to do so will cause very odd behavior or even | ||||
| crashes. | ||||
|  | ||||
| More note: the options set with this function call are valid for the | ||||
| forthcoming data transfers that are performed when you invoke | ||||
| .I curl_easy_perform . | ||||
| \fBNOTE2:\fP options set with this function call are valid for the forthcoming | ||||
| data transfers that are performed when you invoke \fIcurl_easy_perform\fP. | ||||
| The options are not in any way reset between transfers, so if you want | ||||
| subsequent transfers with different options, you must change them between the | ||||
| transfers. | ||||
|  | ||||
| The | ||||
| .I "handle" | ||||
| is the return code from the | ||||
| .I "curl_easy_init" | ||||
| call. | ||||
| The \fIhandle\fP is the return code from a \fIcurl_easy_init(3)\fP or | ||||
| \fIcurl_easy_duphandle(3)\fP call. | ||||
| .SH OPTIONS | ||||
| These options are in a bit of random order, but you'll figure it out! | ||||
| The options are listed in a sort of random order, but you'll figure it out! | ||||
| .TP 0.8i | ||||
| .B CURLOPT_FILE | ||||
| Data pointer to pass to file write function. Note that if you specify the | ||||
| .I CURLOPT_WRITEFUNCTION | ||||
| , this is the pointer you'll get as input. If you don't use a callback, you | ||||
| must pass a 'FILE *' as libcurl passes it to fwrite() when writing data. | ||||
| Data pointer to pass to the file write function. Note that if you specify the | ||||
| \fICURLOPT_WRITEFUNCTION\fP, this is the pointer you'll get as input. If you | ||||
| don't use a callback, you must pass a 'FILE *' as libcurl will pass this to | ||||
| fwrite() when writing data. | ||||
|  | ||||
| NOTE: If you're using libcurl as a win32 DLL, you MUST use the | ||||
| \fICURLOPT_WRITEFUNCTION\fP if you set this option. | ||||
| \fBNOTE:\fP If you're using libcurl as a win32 DLL, you MUST use the | ||||
| \fICURLOPT_WRITEFUNCTION\fP if you set this option or you will experience | ||||
| crashes. | ||||
| .TP | ||||
| .B CURLOPT_WRITEFUNCTION | ||||
| Function pointer that should match the following prototype: | ||||
| .BI "size_t function( void *ptr, size_t size, size_t nmemb, void *stream);" | ||||
| This function gets called by libcurl as soon as there is received data that | ||||
| needs to be written down. The size of the data pointed to by \fIptr\fP is | ||||
| \fIsize\fP multiplied with \fInmemb\fP.  Return the number of bytes actually | ||||
| written or return -1 to signal error to the library (it will cause it to abort | ||||
| the transfer with CURLE_WRITE_ERROR). | ||||
| Function pointer that should match the following prototype: \fBsize_t | ||||
| function( void *ptr, size_t size, size_t nmemb, void *stream);\fP This | ||||
| function gets called by libcurl as soon as there is data available to pass | ||||
| available that needs to be saved. The size of the data pointed to by \fIptr\fP | ||||
| is \fIsize\fP multiplied with \fInmemb\fP.  Return the number of bytes | ||||
| actually taken care of. If that amount differs from the amount passed to your | ||||
| function, it'll signal an error to the library and it will abort the transfer | ||||
| and return \fICURLE_WRITE_ERROR\fP. | ||||
|  | ||||
| Set the \fIstream\fP argument with the \fBCURLOPT_FILE\fP option. | ||||
|  | ||||
| \fBNOTE:\fP you will be passed as much data as possible in all invokes, but | ||||
| you cannot possibly make any assumptions. It may be one byte, it may be | ||||
| thousands. | ||||
| .TP | ||||
| .B CURLOPT_INFILE | ||||
| Data pointer to pass to the file read function. Note that if you specify the | ||||
| \fICURLOPT_READFUNCTION\fP, this is the pointer you'll get as input. If you | ||||
| don't specify a read callback, this must be a valid FILE *. | ||||
|  | ||||
| NOTE: If you're using libcurl as a win32 DLL, you MUST use a | ||||
| \fBNOTE:\fP If you're using libcurl as a win32 DLL, you MUST use a | ||||
| \fICURLOPT_READFUNCTION\fP if you set this option. | ||||
| .TP | ||||
| .B CURLOPT_READFUNCTION | ||||
| Function pointer that should match the following prototype: | ||||
| .BI "size_t function( void *ptr, size_t size, size_t nmemb, void *stream);" | ||||
| This function gets called by libcurl as soon as it needs to read data in order | ||||
| to send it to the peer. The data area pointed at by the pointer \fIptr\fP may | ||||
| be filled with at most \fIsize\fP multiplied with \fInmemb\fP number of | ||||
| Function pointer that should match the following prototype: \fBsize_t | ||||
| function( void *ptr, size_t size, size_t nmemb, void *stream);\fP This | ||||
| function gets called by libcurl as soon as it needs to read data in order to | ||||
| send it to the peer. The data area pointed at by the pointer \fIptr\fP may be | ||||
| filled with at most \fIsize\fP multiplied with \fInmemb\fP number of | ||||
| bytes. Your function must return the actual number of bytes that you stored in | ||||
| that memory area. Returning -1 will signal an error to the library and cause | ||||
| it to abort the current transfer immediately (with a CURLE_READ_ERROR return | ||||
| code). | ||||
| it to abort the current transfer immediately (with a \fICURLE_READ_ERROR\fP | ||||
| return code). | ||||
| .TP | ||||
| .B CURLOPT_INFILESIZE | ||||
| When uploading a file to a remote site, this option should be used to tell | ||||
| @@ -87,49 +88,67 @@ libcurl what the expected size of the infile is. | ||||
| .B CURLOPT_URL | ||||
| The actual URL to deal with. The parameter should be a char * to a zero | ||||
| terminated string. The string must remain present until curl no longer needs | ||||
| it, as it doesn't copy the string. NOTE: this option is required to be set | ||||
| before curl_easy_perform() is called. | ||||
| it, as it doesn't copy the string. | ||||
|  | ||||
| \fBNOTE:\fP this option is (the only one) required to be set before | ||||
| \fIcurl_easy_perform(3)\fP is called. | ||||
| .TP | ||||
| .B CURLOPT_PROXY | ||||
| If you need libcurl to use a http proxy to access the outside world, set the | ||||
| proxy string with this option. The parameter should be a char * to a zero | ||||
| terminated string. To specify port number in this string, append :[port] to | ||||
| the end of the host name. The proxy string may be prefixed with | ||||
| [protocol]:// since any such prefix will be ignored. | ||||
| Set HTTP proxy to use. The parameter should be a char * to a zero terminated | ||||
| string holding the host name or dotted IP address. To specify port number in | ||||
| this string, append :[port] to the end of the host name. The proxy string may | ||||
| be prefixed with [protocol]:// since any such prefix will be ignored. The | ||||
| proxy's port number may optionally be specified with the separate option | ||||
| \fICURLOPT_PROXYPORT\fP. | ||||
|  | ||||
| \fBNOTE:\fP when you tell the library to use a HTTP proxy, libcurl will | ||||
| transparently convert operations to HTTP even if you specify a FTP URL | ||||
| etc. This may have an impact on what other features of the library you can | ||||
| use, such as CURLOPT_QUOTE and similar FTP specifics that don't work unless | ||||
| you tunnel through the HTTP proxy. Such tunneling is activated with | ||||
| \fICURLOPT_HTTPPROXYTUNNEL\fP. | ||||
|  | ||||
| \fBNOTE2:\fP libcurl respects the environment variables \fBhttp_proxy\fP, | ||||
| \fBftp_proxy\fP, \fBall_proxy\fP etc, if any of those is set. | ||||
| .TP | ||||
| .B CURLOPT_PROXYPORT | ||||
| Set this long with this option to set the proxy port to use unless it is | ||||
| specified in the proxy string CURLOPT_PROXY. | ||||
| Pass a long with this option to set the proxy port to connect to unless it is | ||||
| specified in the proxy string \fICURLOPT_PROXY\fP. | ||||
| .TP | ||||
| .B CURLOPT_HTTPPROXYTUNNEL | ||||
| Set the parameter to non-zero to get the library to tunnel all non-HTTP | ||||
| operations through the given HTTP proxy. Do note that there is a big | ||||
| difference to use a proxy and to tunnel through it. If you don't know what | ||||
| this means, you probably don't want this tunnel option. (Added in libcurl 7.3) | ||||
| Set the parameter to non-zero to get the library to tunnel all operations | ||||
| through a given HTTP proxy. Note that there is a big difference between using | ||||
| a proxy and to tunnel through it. If you don't know what this means, you | ||||
| probably don't want this tunneling option. (Added in libcurl 7.3) | ||||
| .TP | ||||
| .B CURLOPT_VERBOSE | ||||
| Set the parameter to non-zero to get the library to display a lot of verbose | ||||
| information about its operations. Very useful for libcurl and/or protocl | ||||
| information about its operations. Very useful for libcurl and/or protocol | ||||
| debugging and understanding. | ||||
|  | ||||
| You hardly ever want this set in production use, you will almost always want | ||||
| this when you debug/report problems. | ||||
| .TP | ||||
| .B CURLOPT_HEADER | ||||
| A non-zero parameter tells the library to include the header in the | ||||
| output. This is only relevant for protocols that actually has a header | ||||
| preceeding the data (like HTTP). | ||||
| A non-zero parameter tells the library to include the header in the body | ||||
| output. This is only relevant for protocols that actually have headers | ||||
| preceding the data (like HTTP). | ||||
| .TP | ||||
| .B CURLOPT_NOPROGRESS | ||||
| A non-zero parameter tells the library to shut of the built-in progress meter | ||||
| completely. (NOTE: future versions of the lib is likely to not have any | ||||
| built-in progress meter at all). | ||||
| completely. | ||||
|  | ||||
| \fBNOTE:\fP future versions of libcurl is likely to not have any built-in | ||||
| progress meter at all. | ||||
| .TP | ||||
| .B CURLOPT_NOBODY | ||||
| A non-zero parameter tells the library to not include the body-part in the | ||||
| output. This is only relevant for protocols that have a separate header and | ||||
| body part. | ||||
| output. This is only relevant for protocols that have separate header and body | ||||
| parts. | ||||
| .TP | ||||
| .B CURLOPT_FAILONERROR | ||||
| A non-zero parameter tells the library to fail silently if the HTTP code | ||||
| returned is equal or larger than 300. The default action would be to return | ||||
| returned is equal to or larger than 300. The default action would be to return | ||||
| the page normally, ignoring that code. | ||||
| .TP | ||||
| .B CURLOPT_UPLOAD | ||||
| @@ -146,7 +165,7 @@ will imply this option. | ||||
| .TP | ||||
| .B CURLOPT_FTPLISTONLY | ||||
| A non-zero parameter tells the library to just list the names of an ftp | ||||
| directory, instead of doing a full directory listin that would include file | ||||
| directory, instead of doing a full directory listing that would include file | ||||
| sizes, dates etc. | ||||
| .TP | ||||
| .B CURLOPT_FTPAPPEND | ||||
| @@ -154,91 +173,108 @@ A non-zero parameter tells the library to append to the remote file instead of | ||||
| overwrite it. This is only useful when uploading to a ftp site. | ||||
| .TP | ||||
| .B CURLOPT_NETRC | ||||
| A non-zero parameter tells the library to scan your | ||||
| .I ~/.netrc | ||||
| file to find user name and password for the remote site you are about to | ||||
| access. Do note that curl does not verify that the file has the correct | ||||
| properties set (as the standard unix ftp client does), and that only machine | ||||
| name, user name and password is taken into account (init macros and similar | ||||
| things aren't supported). | ||||
| A non-zero parameter tells the library to scan your \fI~/.netrc\fP file to | ||||
| find user name and password for the remote site you are about to access. Only | ||||
| machine name, user name and password is taken into account (init macros and | ||||
| similar things aren't supported). | ||||
|  | ||||
| \fBNote:\fP libcurl does not verify that the file has the correct properties | ||||
| set (as the standard Unix ftp client does). It should only be readable by | ||||
| user. | ||||
| .TP | ||||
| .B CURLOPT_FOLLOWLOCATION | ||||
| A non-zero parameter tells the library to follow any Location: header that the | ||||
| server sends as part of a HTTP header. NOTE that this means that the library | ||||
| will resend the same request on the new location and follow new Location: | ||||
| headers all the way until no more such headers are returned. | ||||
| server sends as part of a HTTP header. | ||||
|  | ||||
| \fBNOTE:\fP this means that the library will re-send the same request on the | ||||
| new location and follow new Location: headers all the way until no more such | ||||
| headers are returned. \fICURLOPT_MAXREDIRS\fP can be used to limit the number | ||||
| of redirects libcurl will follow. | ||||
| .TP | ||||
| .B CURLOPT_TRANSFERTEXT | ||||
| A non-zero parameter tells the library to use ASCII mode for ftp transfers, | ||||
| instead of the default binary transfer. For LDAP transfers it gets the data in | ||||
| plain text instead of HTML and for win32 systems it does not set the stdout to | ||||
| binary mode. This option can be useable when transfering text data between | ||||
| system with different views on certain characters, such as newlines or | ||||
| binary mode. This option can be usable when transferring text data between | ||||
| systems with different views on certain characters, such as newlines or | ||||
| similar. | ||||
| .TP | ||||
| .B CURLOPT_PUT | ||||
| A non-zero parameter tells the library to use HTTP PUT a file. The file to put | ||||
| must be set with CURLOPT_INFILE and CURLOPT_INFILESIZE. | ||||
| A non-zero parameter tells the library to use HTTP PUT to transfer data. The | ||||
| data should be set with CURLOPT_INFILE and CURLOPT_INFILESIZE. | ||||
| .TP | ||||
| .B CURLOPT_USERPWD | ||||
| Pass a char * as parameter, which should be [username]:[password] to use for | ||||
| Pass a char * as parameter, which should be [user name]:[password] to use for | ||||
| the connection. If the password is left out, you will be prompted for it. | ||||
| \fICURLOPT_PASSWDFUNCTION\fP can be used to set your own prompt function. | ||||
| .TP | ||||
| .B CURLOPT_PROXYUSERPWD | ||||
| Pass a char * as parameter, which should be [username]:[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 | ||||
| prompted for it. | ||||
| prompted for it. \fICURLOPT_PASSWDFUNCTION\fP can be used to set your own | ||||
| prompt function. | ||||
| .TP | ||||
| .B CURLOPT_RANGE | ||||
| Pass a char * as parameter, which should contain the specified range you | ||||
| want. It should be in the format "X-Y", where X or Y may be left out. HTTP | ||||
| transfers also support several intervals, separated with commas as in | ||||
| .I "X-Y,N-M" | ||||
| . Using this kind of multiple intervals will cause the HTTP server to send the | ||||
| response document in pieces. | ||||
| \fI"X-Y,N-M"\fP. Using this kind of multiple intervals will cause the HTTP | ||||
| server to send the response document in pieces (using standard MIME separation | ||||
| techniques). | ||||
| .TP | ||||
| .B CURLOPT_ERRORBUFFER | ||||
| Pass a char * to a buffer that the libcurl may store human readable error | ||||
| messages in. This may be more helpful than just the return code from the | ||||
| library. The buffer must be at least CURL_ERROR_SIZE big. | ||||
|  | ||||
| \fBNote:\fP if the library does not return an error, the buffer may not have | ||||
| been touched. Do not rely on the contents in those cases. | ||||
| .TP | ||||
| .B CURLOPT_TIMEOUT | ||||
| Pass a long as parameter containing the maximum time in seconds that you allow | ||||
| the libcurl transfer operation to take. Normally, name lookups can take a | ||||
| considerable time and limiting operations to less than a few minutes risk | ||||
| aborting perfectly normal operations. This option will cause curl to use the | ||||
| SIGALRM to enable timeouting system calls. | ||||
| .B NOTE | ||||
| that this does not work in multi-threaded programs! | ||||
| SIGALRM to enable time-outing system calls. | ||||
|  | ||||
| \fBNOTE:\fP this does not work in Unix multi-threaded programs, as it uses | ||||
| signals. | ||||
| .TP | ||||
| .B CURLOPT_POSTFIELDS | ||||
| Pass a char * as parameter, which should be the full data to post in a HTTP | ||||
| post operation. See also the CURLOPT_POST. Since 7.8, using CURLOPT_POSTFIELDS | ||||
| implies CURLOPT_POST. | ||||
| post operation. This is a normal application/x-www-form-urlencoded kind, which | ||||
| is the most commonly used one by HTML forms. See also the CURLOPT_POST. Since | ||||
| 7.8, using CURLOPT_POSTFIELDS implies CURLOPT_POST. | ||||
|  | ||||
| \fBNote:\fP to make multipart/formdata posts (aka rfc1867-posts), check out | ||||
| the \fICURLOPT_HTTPPOST\fP option. | ||||
| .TP | ||||
| .B CURLOPT_POSTFIELDSIZE | ||||
| If you want to post data to the server without letting libcurl do a strlen() | ||||
| to measure the data size, this option must be used. Also, when this option is | ||||
| used, you can post fully binary data which otherwise is likely to fail. If | ||||
| this size is set to zero, the library will use strlen() to get the data | ||||
| size. (Added in libcurl 7.2) | ||||
| to measure the data size, this option must be used. When this option is used | ||||
| you can post fully binary data, which otherwise is likely to fail. If this | ||||
| size is set to zero, the library will use strlen() to get the size. (Added in | ||||
| libcurl 7.2) | ||||
| .TP | ||||
| .B CURLOPT_REFERER | ||||
| Pass a pointer to a zero terminated string as parameter. It will be used to | ||||
| set the referer: header in the http request sent to the remote server. This | ||||
| can be used to fool servers or scripts. | ||||
| set the Referer: header in the http request sent to the remote server. This | ||||
| can be used to fool servers or scripts. You can also set any custom header | ||||
| with \fICURLOPT_HTTPHEADER\fP. | ||||
| .TP | ||||
| .B CURLOPT_USERAGENT | ||||
| Pass a pointer to a zero terminated string as parameter. It will be used to | ||||
| set the user-agent: header in the http request sent to the remote server. This | ||||
| can be used to fool servers or scripts. | ||||
| set the User-Agent: header in the http request sent to the remote server. This | ||||
| can be used to fool servers or scripts. You can also set any custom header | ||||
| with \fICURLOPT_HTTPHEADER\fP. | ||||
| .TP | ||||
| .B CURLOPT_FTPPORT | ||||
| Pass a pointer to a zero terminated string as parameter. It will be used to | ||||
| get the IP address to use for the ftp PORT instruction. The PORT instruction | ||||
| tells the remote server to connect to our specified IP address. The string may | ||||
| be a plain IP address, a host name, an network interface name (under unix) or | ||||
| just a '-' letter to let the library use your systems default IP address. | ||||
| be a plain IP address, a host name, an network interface name (under Unix) or | ||||
| just a '-' letter to let the library use your systems default IP | ||||
| address. Default FTP operations are passive, and thus won't use PORT. | ||||
| .TP | ||||
| .B CURLOPT_LOW_SPEED_LIMIT | ||||
| Pass a long as parameter. It contains the transfer speed in bytes per second | ||||
| @@ -261,82 +297,71 @@ set a cookie in the http request. The format of the string should be | ||||
| .TP | ||||
| .B CURLOPT_HTTPHEADER | ||||
| Pass a pointer to a linked list of HTTP headers to pass to the server in your | ||||
| HTTP request. The linked list should be a fully valid list of 'struct | ||||
| curl_slist' structs properly filled in. Use | ||||
| .I curl_slist_append(3) | ||||
| to create the list and | ||||
| .I curl_slist_free_all(3) | ||||
| to clean up an entire list. If you add a header that is otherwise generated | ||||
| and used by libcurl internally, your added one will be used instead. If you | ||||
| add a header with no contents as in 'Accept:', the internally used header will | ||||
| just get disabled. Thus, using this option you can add new headers, replace | ||||
| internal headers and remove internal headers. | ||||
| HTTP request. The linked list should be a fully valid list of \fBstruct | ||||
| curl_slist\fP structs properly filled in. Use \fIcurl_slist_append(3)\fP to | ||||
| create the list and \fIcurl_slist_free_all(3)\fP to clean up an entire | ||||
| list. If you add a header that is otherwise generated and used by libcurl | ||||
| internally, your added one will be used instead. If you add a header with no | ||||
| contents as in 'Accept:' (no data on the right side of the colon), the | ||||
| internally used header will get disabled. Thus, using this option you can add | ||||
| new headers, replace internal headers and remove internal headers. | ||||
|  | ||||
| \fBNOTE:\fPThe most commonly replaced headers have "shortcuts" in the options | ||||
| CURLOPT_COOKIE, CURLOPT_USERAGENT and CURLOPT_REFERER. | ||||
| .TP | ||||
| .B CURLOPT_HTTPPOST | ||||
| Tells libcurl you want a multipart/formdata HTTP POST to be made and you | ||||
| instruct what data to pass on to the server.  Pass a pointer to a linked list | ||||
| of HTTP post structs as parameter.  The linked list should be a fully valid | ||||
| list of 'struct HttpPost' structs properly filled in. The best and most | ||||
| elegant way to do this, is to use | ||||
| .I curl_formadd(3) | ||||
| as documented. The data in this list must remained intact until you close this | ||||
| curl handle again with curl_easy_cleanup(). | ||||
| elegant way to do this, is to use \fIcurl_formadd(3)\fP as documented. The | ||||
| data in this list must remained intact until you close this curl handle again | ||||
| with \fIcurl_easy_cleanup(3)\fP. | ||||
| .TP | ||||
| .B CURLOPT_SSLCERT | ||||
| Pass a pointer to a zero terminated string as parameter. The string should be | ||||
| the file name of your certficicate in PEM format. | ||||
| the file name of your certificate in PEM format. | ||||
| .TP | ||||
| .B CURLOPT_SSLCERTPASSWD | ||||
| Pass a pointer to a zero terminated string as parameter. It will be used as | ||||
| the password required to use the CURLOPT_SSLCERT certificate. If the password | ||||
| is not supplied, you will be prompted for it. | ||||
| is not supplied, you will be prompted for it. \fICURLOPT_PASSWDFUNCTION\fP can | ||||
| be used to set your own prompt function. | ||||
| .TP | ||||
| .B CURLOPT_CRLF | ||||
| Convert unix newlines to CRLF newlines on FTP uploads. | ||||
| Convert Unix newlines to CRLF newlines on FTP uploads. | ||||
| .TP | ||||
| .B CURLOPT_QUOTE | ||||
| Pass a pointer to a linked list of FTP commands to pass to the server prior to | ||||
| your ftp request. The linked list should be a fully valid list of 'struct | ||||
| curl_slist' structs properly filled in. Use | ||||
| .I curl_slist_append(3) | ||||
| to append strings (commands) to the list, and clear the entire list afterwards | ||||
| with | ||||
| .I curl_slist_free_all(3) | ||||
| curl_slist' structs properly filled in. Use \fIcurl_slist_append(3)\fP to | ||||
| append strings (commands) to the list, and clear the entire list afterwards | ||||
| with \fIcurl_slist_free_all(3)\fP. | ||||
| .TP | ||||
| .B CURLOPT_POSTQUOTE | ||||
| Pass a pointer to a linked list of FTP commands to pass to the server after | ||||
| your ftp transfer request. The linked list should be a fully valid list of | ||||
| struct curl_slist structs properly filled in as described for | ||||
| .I "CURLOPT_QUOTE" | ||||
| \fICURLOPT_QUOTE\fP. | ||||
| .TP | ||||
| .B CURLOPT_WRITEHEADER | ||||
| Pass a pointer to be used to write the header part of the received data to. If | ||||
| you don't use a callback to take care of the writing, this must be a FILE | ||||
| *. The headers are guaranteed to be written one-by-one and only complete lines | ||||
| are written. Parsing headers should be easy enough using this. See also the | ||||
| \fICURLOPT_HEADERFUNCTION\fP option. | ||||
| you don't use your own callback to take care of the writing, this must be a | ||||
| valid FILE *. See also the \fICURLOPT_HEADERFUNCTION\fP option below on how to set a | ||||
| custom get-all-headers callback. | ||||
| .TP | ||||
| .B CURLOPT_HEADERFUNCTION | ||||
| Function pointer that should match the following prototype: | ||||
| .BI "size_t function( void *ptr, size_t size, size_t nmemb, void *stream);" | ||||
| This function gets called by libcurl as soon as there is received header data | ||||
| that needs to be written down. The function will be called once for each | ||||
| header with a complete header line in each invoke. The size of the data | ||||
| pointed to by | ||||
| .I ptr  | ||||
| is | ||||
| .I size | ||||
| multiplied with | ||||
| .I nmemb. | ||||
| The pointer named | ||||
| .I stream | ||||
| will be the one you passed to libcurl with the | ||||
| .I CURLOPT_WRITEHEADER | ||||
| option. | ||||
| Return the number of bytes actually written or return -1 to signal error to | ||||
| the library (it will cause it to abort the transfer with a | ||||
| .I CURLE_WRITE_ERROR | ||||
| return code). (Added in libcurl 7.7.2) | ||||
| Function pointer that should match the following prototype: \fIsize_t | ||||
| function( void *ptr, size_t size, size_t nmemb, void *stream);\fP. This | ||||
| function gets called by libcurl as soon as there is received header data that | ||||
| needs to be written down. The headers are guaranteed to be written one-by-one | ||||
| and only complete lines are written. Parsing headers should be easy enough | ||||
| using this. The size of the data pointed to by \fIptr\fP is \fIsize\fP | ||||
| multiplied with \fInmemb\fP.  The pointer named \fIstream\fP will be the one | ||||
| you passed to libcurl with the \fICURLOPT_WRITEHEADER\fP option.  Return the | ||||
| number of bytes actually written or return -1 to signal error to the library | ||||
| (it will cause it to abort the transfer with a \fICURLE_WRITE_ERROR\fP return | ||||
| code). (Added in libcurl 7.7.2) | ||||
| .TP | ||||
| .B CURLOPT_COOKIEFILE | ||||
| Pass a pointer to a zero terminated string as parameter. It should contain the | ||||
| @@ -347,12 +372,12 @@ file. | ||||
| .B CURLOPT_SSLVERSION | ||||
| Pass a long as parameter. Set what version of SSL to attempt to use, 2 or | ||||
| 3. By default, the SSL library will try to solve this by itself although some | ||||
| servers make this difficult why you at times will have to use this option. | ||||
| servers make this difficult why you at times may have to use this option. | ||||
| .TP | ||||
| .B CURLOPT_TIMECONDITION | ||||
| Pass a long as parameter. This defines how the CURLOPT_TIMEVALUE time value is | ||||
| treated. You can set this parameter to TIMECOND_IFMODSINCE or | ||||
| TIMECOND_IFUNMODSINCE. This is aa HTTP-only feature. (TBD) | ||||
| TIMECOND_IFUNMODSINCE. This is a HTTP-only feature. (TBD) | ||||
| .TP | ||||
| .B CURLOPT_TIMEVALUE | ||||
| Pass a long as parameter. This should be the time in seconds since 1 jan 1970, | ||||
| @@ -362,8 +387,8 @@ isn't used, it will be TIMECOND_IFMODSINCE by default. | ||||
| .B CURLOPT_CUSTOMREQUEST | ||||
| 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 | ||||
| DELETE or other more obscure HTTP requests. Don't do this at will, make sure | ||||
| your server supports the command first. | ||||
| DELETE or other more or less obscure HTTP requests. Don't do this at will, | ||||
| make sure your server supports the command first. | ||||
| .TP | ||||
| .B CURLOPT_STDERR | ||||
| Pass a FILE * as parameter. This is the stream to use instead of stderr | ||||
| @@ -381,29 +406,18 @@ krb4 awareness.  This is a string, 'clear', 'safe', 'confidential' or | ||||
| will be used. Set the string to NULL to disable kerberos4. The kerberos | ||||
| support only works for FTP. (Added in libcurl 7.3) | ||||
| .TP | ||||
| .B CURLOPT_WRITEINFO | ||||
| (NOT PRESENT IN 7.4 or later!) | ||||
| Pass a pointer to a zero terminated string as parameter. It will be used to | ||||
| report information after a successful request. This string may contain | ||||
| variables that will be substituted by their contents when output. Described | ||||
| elsewhere. | ||||
| .TP | ||||
| .B CURLOPT_PROGRESSFUNCTION | ||||
| Function pointer that should match the | ||||
| .BI curl_progress_callback | ||||
| prototype found in | ||||
| .I <curl/curl.h> | ||||
| This function gets called by libcurl instead of its internal | ||||
| equivalent. Unknown/unused argument values will be set to zero (like if you | ||||
| only download data, the upload size will remain 0). Returning a non-zero value | ||||
| from this callback will cause libcurl to abort the transfer and return | ||||
| CURLE_ABORTED_BY_CALLBACK. | ||||
| Function pointer that should match the \fIcurl_progress_callback\fP prototype | ||||
| found in \fI<curl/curl.h>\fP. This function gets called by libcurl instead of | ||||
| its internal equivalent with a frequent interval during data transfer. | ||||
| Unknown/unused argument values will be set to zero (like if you only download | ||||
| data, the upload size will remain 0). Returning a non-zero value from this | ||||
| callback will cause libcurl to abort the transfer and return | ||||
| \fICURLE_ABORTED_BY_CALLBACK\fP. | ||||
| .TP | ||||
| .B CURLOPT_PROGRESSDATA | ||||
| Pass a pointer that will be untouched by libcurl and passed as the first | ||||
| argument in the progress callback set with | ||||
| .I CURLOPT_PROGRESSFUNCTION | ||||
|  . | ||||
| argument in the progress callback set with \fICURLOPT_PROGRESSFUNCTION\fP. | ||||
| .TP | ||||
| .B CURLOPT_SSL_VERIFYPEER | ||||
| Pass a long that is set to a non-zero value to make curl verify the peer's | ||||
| @@ -416,67 +430,66 @@ verify the peer with. This only makes sense when used in combination with the | ||||
| CURLOPT_SSL_VERIFYPEER option. (Added in 7.4.2) | ||||
| .TP | ||||
| .B CURLOPT_PASSWDFUNCTION | ||||
| Pass a pointer to a curl_passwd_callback function that will then be called | ||||
| Pass a pointer to a \fIcurl_passwd_callback\fP function that will be called | ||||
| instead of the internal one if libcurl requests a password. The function must | ||||
| match this prototype: | ||||
| .BI "int my_getpass(void *client, char *prompt, char* buffer, int buflen );" | ||||
| If set to NULL, it equals to making the function always fail. If the function | ||||
| returns a non-zero value, it will abort the operation and an error | ||||
| (CURLE_BAD_PASSWORD_ENTERED) will be returned. | ||||
| .I client | ||||
| is a generic pointer, see CURLOPT_PASSWDDATA. | ||||
| .I prompt | ||||
| match this prototype: \fBint my_getpass(void *client, char *prompt, char* | ||||
| buffer, int buflen );\fP.  If set to NULL, it equals to making the function | ||||
| always fail. If the function returns a non-zero value, it will abort the | ||||
| operation and an error (CURLE_BAD_PASSWORD_ENTERED) will be returned. | ||||
| \fIclient\fP is a generic pointer, see \fICURLOPT_PASSWDDATA\fP.  \fIprompt\fP | ||||
| is a zero-terminated string that is text that prefixes the input request. | ||||
| .I buffer | ||||
| is a pointer to data where the entered password should be stored and | ||||
| .I buflen | ||||
| is the maximum number of bytes that may be written in the buffer. | ||||
| (Added in 7.4.2) | ||||
| \fIbuffer\fP is a pointer to data where the entered password should be stored | ||||
| and \fIbuflen\fP is the maximum number of bytes that may be written in the | ||||
| buffer.  (Added in 7.4.2) | ||||
| .TP | ||||
| .B CURLOPT_PASSWDDATA | ||||
| Pass a void * to whatever data you want. The passed pointer will be the first | ||||
| argument sent to the specifed CURLOPT_PASSWDFUNCTION function. (Added in | ||||
| argument sent to the specifed \fICURLOPT_PASSWDFUNCTION\fP function. (Added in | ||||
| 7.4.2) | ||||
| .TP | ||||
| .B CURLOPT_FILETIME | ||||
| Pass a long. If it is a non-zero value, libcurl will attempt to get the | ||||
| modification date of the remote document in this operation. This requires that | ||||
| the remote server sends the time or replies to a time querying command. The | ||||
| curl_easy_getinfo() function with the CURLINFO_FILETIME argument can be used | ||||
| after a transfer to extract the received time (if any). (Added in 7.5) | ||||
| \fIcurl_easy_getinfo(3)\fP function with the \fICURLINFO_FILETIME\fP argument | ||||
| can be used after a transfer to extract the received time (if any). (Added in | ||||
| 7.5) | ||||
| .TP | ||||
| .B CURLOPT_MAXREDIRS | ||||
| Pass a long. The set number will be the redirection limit. If that many | ||||
| redirections have been followed, the next redirect will cause an error. This | ||||
| option only makes sense if the CURLOPT_FOLLOWLOCATION is used at the same | ||||
| time. (Added in 7.5) | ||||
| redirections have been followed, the next redirect will cause an error | ||||
| (\fICURLE_TOO_MANY_REDIRECTS\fP). This option only makes sense if the | ||||
| \fICURLOPT_FOLLOWLOCATION\fP is used at the same time. (Added in 7.5) | ||||
| .TP | ||||
| .B CURLOPT_MAXCONNECTS | ||||
| Pass a long. The set number will be the persistant connection cache size. The | ||||
| set amount will be the maximum amount of simultaneous connections that libcurl | ||||
| may cache between file transfers. Default is 5, and there isn't much point in | ||||
| changing this value unless you are perfectly aware of how this work and | ||||
| changes libcurl's behaviour. Note: if you have already performed transfers | ||||
| with this curl handle, setting a smaller MAXCONNECTS than before may cause | ||||
| open connections to unnecessarily get closed. (Added in 7.7) | ||||
| changes libcurl's behaviour. | ||||
|  | ||||
| \fBNOTE:\fP if you already have performed transfers with this curl handle, | ||||
| setting a smaller MAXCONNECTS than before may cause open connections to get | ||||
| closed unnecessarily. (Added in 7.7) | ||||
| .TP | ||||
| .B CURLOPT_CLOSEPOLICY | ||||
| Pass a long. This option sets what policy libcurl should use when the | ||||
| connection cache is filled and one of the open connections has to be closed to | ||||
| make room for a new connection. This must be one of the CURLCLOSEPOLICY_* | ||||
| defines. Use CURLCLOSEPOLICY_LEAST_RECENTLY_USED to make libcurl close the | ||||
| connection that was least recently used, that connection is also least likely | ||||
| to be capable of re-use. Use CURLCLOSEPOLICY_OLDEST to make libcurl close the | ||||
| oldest connection, the one that was created first among the ones in the | ||||
| connection cache. The other close policies are not support yet. (Added in 7.7) | ||||
| defines. Use \fICURLCLOSEPOLICY_LEAST_RECENTLY_USED\fP to make libcurl close | ||||
| the connection that was least recently used, that connection is also least | ||||
| likely to be capable of re-use. Use \fICURLCLOSEPOLICY_OLDEST\fP to make | ||||
| libcurl close the oldest connection, the one that was created first among the | ||||
| ones in the connection cache. The other close policies are not support | ||||
| yet. (Added in 7.7) | ||||
| .TP | ||||
| .B CURLOPT_FRESH_CONNECT | ||||
| Pass a long. Set to non-zero to make the next transfer use a new connection by | ||||
| force. If the connection cache is full before this connection, one of the | ||||
| existinf connections will be closed as according to the set policy. This | ||||
| option should be used with caution and only if you understand what it | ||||
| does. Set to 0 to have libcurl attempt re-use of an existing connection. | ||||
| (Added in 7.7) | ||||
| Pass a long. Set to non-zero to make the next transfer use a new (fresh) | ||||
| connection by force. If the connection cache is full before this connection, | ||||
| one of the existing connections will be closed as according to the selected or | ||||
| default policy. This option should be used with caution and only if you | ||||
| understand what it does. Set this to 0 to have libcurl attempt re-using an | ||||
| existing connection (default behavior).  (Added in 7.7) | ||||
| .TP | ||||
| .B CURLOPT_FORBID_REUSE | ||||
| Pass a long. Set to non-zero to make the next transfer explicitly close the | ||||
| @@ -484,7 +497,7 @@ connection when done. Normally, libcurl keep all connections alive when done | ||||
| with one transfer in case there comes a succeeding one that can re-use them. | ||||
| This option should be used with caution and only if you understand what it | ||||
| does. Set to 0 to have libcurl keep the connection open for possibly later | ||||
| re-use. (Added in 7.7) | ||||
| re-use (default behavior). (Added in 7.7) | ||||
| .TP | ||||
| .B CURLOPT_RANDOM_FILE | ||||
| Pass a char * to a zero terminated file name. The file will be used to read | ||||
| @@ -500,11 +513,10 @@ Pass a long. It should contain the maximum time in seconds that you allow the | ||||
| connection to the server to take.  This only limits the connection phase, once | ||||
| it has connected, this option is of no more use. Set to zero to disable | ||||
| connection timeout (it will then only timeout on the system's internal | ||||
| timeouts). See also the | ||||
| .I CURLOPT_TIMEOUT | ||||
| option. | ||||
| .B NOTE | ||||
| that this does not work in multi-threaded programs! | ||||
| timeouts). See also the \fICURLOPT_TIMEOUT\fP option. | ||||
|  | ||||
| \fBNOTE:\fP this does not work in unix multi-threaded programs, as it uses | ||||
| signals. | ||||
| .TP | ||||
| .B CURLOPT_HTTPGET | ||||
| Pass a long. If the long is non-zero, this forces the HTTP request to get back | ||||
| @@ -518,8 +530,8 @@ the provided hostname. (Added in 7.8.1) | ||||
| .TP | ||||
| .B CURLOPT_COOKIEJAR | ||||
| Pass a file name as char *, zero terminated. This will make libcurl dump all | ||||
| internally known cookies to the specified file when curl_easy_cleanup() is | ||||
| called. If no cookies are known, no file will be created. Specify "-" to | ||||
| internally known cookies to the specified file when \fIcurl_easy_cleanup(3)\fP | ||||
| is called. If no cookies are known, no file will be created. Specify "-" to | ||||
| instead have the cookies written to stdout. | ||||
| .TP | ||||
| .B CURLOPT_SSL_CIPHER_LIST | ||||
| @@ -531,14 +543,15 @@ be used as operators. Valid examples of cipher lists include 'RC4-SHA', | ||||
| \'SHA1+DES\', 'TLSv1' and 'DEFAULT'. The default list is normally set when you | ||||
| compile OpenSSL. | ||||
|  | ||||
| You'll find all details about cipher lists on this URL: | ||||
| .I http://www.openssl.org/docs/apps/ciphers.html | ||||
| You'll find more details about cipher lists on this URL: | ||||
| \fIhttp://www.openssl.org/docs/apps/ciphers.html\fP | ||||
| .PP | ||||
| .SH RETURN VALUE | ||||
| 0 means the option was set properly, non-zero means an error as | ||||
| .I <curl/curl.h> | ||||
| defines | ||||
| CURLE_OK (zero) means that the option was set properly, non-zero means an | ||||
| error occurred as \fI<curl/curl.h>\fP defines. | ||||
| .SH "SEE ALSO" | ||||
| .BR curl_easy_init "(3), " curl_easy_cleanup "(3), " | ||||
| .SH BUGS | ||||
| Surely there are some, you tell me! | ||||
| If you find any bugs, or just have questions, subscribe to one of the mailing | ||||
| lists and post. We won't bite. | ||||
|  | ||||
|   | ||||
| @@ -2,13 +2,13 @@ | ||||
| .\" nroff -man [file] | ||||
| .\" $Id$ | ||||
| .\" | ||||
| .TH curl_formadd 3 "27 August 2001" "libcurl 7.9" "libcurl Manual" | ||||
| .TH curl_formadd 3 "29 October 2001" "libcurl 7.9.1" "libcurl Manual" | ||||
| .SH NAME | ||||
| curl_formadd - add a section to a multipart/formdata HTTP POST | ||||
| .SH SYNOPSIS | ||||
| .B #include <curl/curl.h> | ||||
| .sp | ||||
| .BI "CURLcode curl_formadd(struct HttpPost ** " firstitem, | ||||
| .BI "int curl_formadd(struct HttpPost ** " firstitem, | ||||
| .BI "struct HttpPost ** " lastitem, " ...);" | ||||
| .ad | ||||
| .SH DESCRIPTION | ||||
| @@ -17,49 +17,62 @@ HTTP POST (sometimes refered to as rfc1867-style posts). Append one section at | ||||
| a time until you've added all the sections you want included and then you pass | ||||
| the \fIfirstitem\fP pointer as parameter to \fBCURLOPT_HTTPPOST\fP. | ||||
| \fIlastitem\fP is set after each call and on repeated invokes it should be | ||||
| left as set to allow repeated invokes to find the end of the list in a faster | ||||
| way. | ||||
| left as set to allow repeated invokes to find the end of the list faster. | ||||
|  | ||||
| After \fIlastitem\fP follow the real arguments that constitute the | ||||
| new section (if the following description confuses you jump directly | ||||
| to the examples): | ||||
| After the \fIlastitem\fP pointer follow the real arguments. (If the following | ||||
| description confuses you, jump directly to the examples): | ||||
|  | ||||
| CURLFORM_COPYNAME or CURLFORM_PTRNAME followed by a string is used for | ||||
| the name of the section. Optionally one may use CURLFORM_NAMELENGTH to | ||||
| specify the length of the name (allowing null characters within the name). | ||||
| \fBCURLFORM_COPYNAME\fP or \fBCURLFORM_PTRNAME\fP followed by a string is used | ||||
| for the name of the section. Optionally one may use \fBCURLFORM_NAMELENGTH\fP | ||||
| to specify the length of the name (allowing null characters within the | ||||
| name). All options that use the word COPY in their names copy the given | ||||
| contents, while the ones with PTR in their names simply points to the (static) | ||||
| data you must make sure remain until curl no longer needs it. | ||||
|  | ||||
| The three options for providing values are: CURLFORM_COPYCONTENTS, | ||||
| CURLFORM_PTRCONTENTS, or CURLFORM_FILE, followed by a char or void | ||||
| pointer (allowed for PTRCONTENTS). | ||||
| The four options for providing values are: \fBCURLFORM_COPYCONTENTS\fP, | ||||
| \fBCURLFORM_PTRCONTENTS\fP, \fBCURLFORM_FILE\fP, or \fBCURLFORM_FILECONTENT\fP | ||||
| followed by a char or void pointer (allowed for PTRCONTENTS). | ||||
|  | ||||
| Other arguments may be CURLFORM_CONTENTTYPE if the | ||||
| user wishes to specify one (for FILE if no type is given the library | ||||
| tries to provide the correct one; for CONTENTS no Content-Type is sent | ||||
| in this case) | ||||
| \fBCURLFORM_FILECONTENT\fP does a normal post like \fBCURLFORM_COPYCONTENTS\fP | ||||
| but the actual value is read from the filename given as a string. | ||||
|  | ||||
| For CURLFORM_PTRCONTENTS or CURLFORM_COPYNAME the user may also add | ||||
| CURLFORM_CONTENTSLENGTH followed by the length as a long (if not given | ||||
| the library will use strlen to determine the length). | ||||
| Other arguments may be \fBCURLFORM_CONTENTTYPE\fP if the user wishes to | ||||
| specify one (for FILE if no type is given the library tries to provide the | ||||
| correct one; for CONTENTS no Content-Type is sent in this case). | ||||
|  | ||||
| For CURLFORM_FILE the user may send multiple files in one section by | ||||
| providing multiple CURLFORM_FILE arguments each followed by the filename | ||||
| For \fBCURLFORM_PTRCONTENTS\fP or \fBCURLFORM_COPYNAME\fP the user may also | ||||
| add \fBCURLFORM_CONTENTSLENGTH\fP followed by the length as a long (if not | ||||
| given the library will use strlen to determine the length). | ||||
|  | ||||
| For \fBCURLFORM_FILE\fP the user may send multiple files in one section by | ||||
| providing multiple \fBCURLFORM_FILE\fP arguments each followed by the filename | ||||
| (and each FILE is allowed to have a CONTENTTYPE). | ||||
|  | ||||
| The last argument always is CURLFORM_END. | ||||
| Another possibility to send single or multiple files in one section is to use | ||||
| \fBCURLFORM_ARRAY\fP that gets a struct curl_forms array pointer as its | ||||
| value. Each structure element has a CURLformoption and a char pointer. For the | ||||
| options only \fBCURLFORM_FILE\fP, \fBCURLFORM_CONTENTTYPE\fP, and | ||||
| \fBCURLFORM_END\fP (that is used to determine the end of the array and thus | ||||
| must be the option of the last and no other element of the curl_forms array) | ||||
| are allowed. The effect of this parameter is the same as giving multiple | ||||
| \fBCURLFORM_FILE\fP options possibly with \fBCURLFORM_CONTENTTYPE\fP after or | ||||
| before each \fBCURLFORM_FILE\fP option. | ||||
|  | ||||
| The last argument in such an array must always be \fBCURLFORM_END\fP. | ||||
|  | ||||
| The pointers \fI*firstitem\fP and \fI*lastitem\fP should both be pointing to | ||||
| NULL in the first call to this function. All list-data will be allocated by | ||||
| the function itself. You must call \fIcurl_formfree\fP after the form post has | ||||
| been done to free the resources again. | ||||
|  | ||||
| This function will copy all input data except the data pointed to by | ||||
| the arguments after CURLFORM_PTRNAME and CURLFORM_PTRCONTENTS and keep | ||||
| This function will copy all input data except the data pointed to by the | ||||
| arguments after \fBCURLFORM_PTRNAME\fP and \fBCURLFORM_PTRCONTENTS\fP and keep | ||||
| its own version of it allocated until you call \fIcurl_formfree\fP. When | ||||
| you've passed the pointer to \fIcurl_easy_setopt\fP, you must not free | ||||
| the list until after you've called \fIcurl_easy_cleanup\fP for the | ||||
| curl handle. If you provide a pointer as an arguments after | ||||
| CURLFORM_PTRNAME or CURLFORM_PTRCONTENTS you must ensure that the pointer | ||||
| stays valid until you call \fIcurl_form_free\fP and \fIcurl_easy_cleanup\fP. | ||||
| you've passed the pointer to \fIcurl_easy_setopt\fP, you must not free the | ||||
| list until after you've called \fIcurl_easy_cleanup\fP for the curl handle. If | ||||
| you provide a pointer as an arguments after \fBCURLFORM_PTRNAME\fP or | ||||
| \fBCURLFORM_PTRCONTENTS\fP you must ensure that the pointer stays valid until | ||||
| you call \fIcurl_form_free\fP and \fIcurl_easy_cleanup\fP. | ||||
|  | ||||
| See example below. | ||||
| .SH RETURN VALUE | ||||
| @@ -74,6 +87,9 @@ Returns non-zero if an error occurs. | ||||
|  char buffer[] = "test buffer"; | ||||
|  char htmlbuffer[] = "<HTML>test buffer</HTML>"; | ||||
|  long htmlbufferlength = strlen(htmlbuffer); | ||||
|  struct curl_forms forms[3]; | ||||
|  char file1[] = "my-face.jpg"; | ||||
|  char file2[] = "your-face.jpg"; | ||||
|  /* add null character into htmlbuffer, to demonstrate that | ||||
|     transfers of buffers containing null characters actually work | ||||
|  */ | ||||
| @@ -82,40 +98,61 @@ Returns non-zero if an error occurs. | ||||
|  /* Add simple name/content section */ | ||||
|  curl_formadd(&post, &last, CURLFORM_COPYNAME, "name", | ||||
|               CURLFORM_COPYCONTENTS, "content", CURLFORM_END);  | ||||
|  | ||||
|  /* Add simple name/content/contenttype section */ | ||||
|  curl_formadd(&post, &last, CURLFORM_COPYNAME, "htmlcode", | ||||
|               CURLFORM_COPYCONTENTS, "<HTML></HTML>", | ||||
|               CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END); | ||||
|  | ||||
|  /* Add name/ptrcontent section */ | ||||
|  curl_formadd(&post, &last, CURLFORM_COPYNAME, "name_for_ptrcontent", | ||||
|               CURLFORM_PTRCONTENTS, buffer, CURLFORM_END); | ||||
|  | ||||
|  /* Add ptrname/ptrcontent section */ | ||||
|  curl_formadd(&post, &last, CURLFORM_PTRNAME, namebuffer, | ||||
| 	      CURLFORM_PTRCONTENTS, buffer, CURLFORM_NAMELENGTH, | ||||
| 	      namelength, CURLFORM_END); | ||||
|  | ||||
|  /* Add name/ptrcontent/contenttype section */ | ||||
|  curl_formadd(&post, &last, CURLFORM_COPYNAME, "html_code_with_hole", | ||||
|               CURLFORM_PTRCONTENTS, htmlbuffer, | ||||
|               CURLFORM_CONTENTSLENGTH, htmlbufferlength, | ||||
|               CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END); | ||||
|  | ||||
|  /* Add simple file section */ | ||||
|  curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture", | ||||
|               CURLFORM_FILE, "my-face.jpg", CURLFORM_END); | ||||
|  | ||||
|  /* Add file/contenttype section */ | ||||
|  curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture", | ||||
|               CURLFORM_FILE, "my-face.jpg", | ||||
|               CURLFORM_CONTENTTYPE, "image/jpeg", CURLFORM_END); | ||||
|  | ||||
|  /* Add two file section */ | ||||
|  curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures", | ||||
|               CURLFORM_FILE, "my-face.jpg", | ||||
|               CURLFORM_FILE, "your-face.jpg", CURLFORM_END); | ||||
|  | ||||
|  /* Add two file section using CURLFORM_ARRAY */ | ||||
|  forms[0].option = CURLFORM_FILE; | ||||
|  forms[0].value  = file1; | ||||
|  forms[1].option = CURLFORM_FILE; | ||||
|  forms[1].value  = file2; | ||||
|  forms[2].option  = CURLFORM_END; | ||||
|  | ||||
|  /* no option needed for the end marker */ | ||||
|  curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures", | ||||
|               CURLFORM_ARRAY, forms, CURLFORM_END); | ||||
|  /* Add the content of a file as a normal post text value */ | ||||
|  curl_formadd(&post, &last, CURLFORM_COPYNAME, "filecontent", | ||||
|               CURLFORM_FILECONTENT, ".bashrc", CURLFORM_END); | ||||
|  /* Set the form info */ | ||||
|  curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); | ||||
|  | ||||
| .SH "SEE ALSO" | ||||
| .BR curl_easy_setopt "(3), " | ||||
| .BR curl_formparse "(3) [deprecated], " | ||||
| .BR curl_formfree "(3) | ||||
| .BR curl_formfree "(3)" | ||||
| .SH BUGS | ||||
| Surely there are some, you tell me! | ||||
|  | ||||
|   | ||||
| @@ -6,7 +6,7 @@ AUTOMAKE_OPTIONS = foreign no-dependencies | ||||
|  | ||||
| EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit.c postit2.c \ | ||||
| 	     win32sockets.c persistant.c ftpget.c Makefile.example \ | ||||
| 	     multithread.c getinmemory.c ftpupload.c | ||||
| 	     multithread.c getinmemory.c ftpupload.c httpput.c | ||||
|  | ||||
| all: | ||||
| 	@echo "done" | ||||
|   | ||||
							
								
								
									
										100
									
								
								docs/examples/httpput.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								docs/examples/httpput.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | ||||
| /***************************************************************************** | ||||
|  *                                  _   _ ____  _      | ||||
|  *  Project                     ___| | | |  _ \| |     | ||||
|  *                             / __| | | | |_) | |     | ||||
|  *                            | (__| |_| |  _ <| |___  | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * $Id$ | ||||
|  */ | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <fcntl.h> | ||||
| #include <sys/stat.h> | ||||
|  | ||||
| #include <curl/curl.h> | ||||
|  | ||||
| /* | ||||
|  * This example shows a HTTP PUT operation. PUTs a file given as a command | ||||
|  * line argument to the URL also given on the command line. | ||||
|  * | ||||
|  * This example also uses its own read callback. | ||||
|  */ | ||||
|  | ||||
| size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream) | ||||
| { | ||||
|   size_t retcode; | ||||
|  | ||||
|   /* in real-world cases, this would probably get this data differently | ||||
|      as this fread() stuff is exactly what the library already would do | ||||
|      by default internally */ | ||||
|   retcode = fread(ptr, size, nmemb, stream); | ||||
|  | ||||
|   fprintf(stderr, "*** We read %d bytes from file\n", retcode); | ||||
|  | ||||
|   return retcode; | ||||
| } | ||||
|  | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
|   CURL *curl; | ||||
|   CURLcode res; | ||||
|   FILE *ftpfile; | ||||
|   FILE * hd_src ; | ||||
|   int hd ; | ||||
|   struct stat file_info; | ||||
|  | ||||
|   char *file; | ||||
|   char *url; | ||||
|  | ||||
|   if(argc < 3) | ||||
|     return 1; | ||||
|   | ||||
|   file= argv[1]; | ||||
|   url = argv[2]; | ||||
|    | ||||
|   /* get the file size of the local file */ | ||||
|   hd = open(file, O_RDONLY) ; | ||||
|   fstat(hd, &file_info); | ||||
|   close(hd) ; | ||||
|  | ||||
|   /* get a FILE * of the same file, could also be made with | ||||
|      fdopen() from the previous descriptor, but hey this is just  | ||||
|      an example! */ | ||||
|   hd_src = fopen(file, "rb"); | ||||
|  | ||||
|   /* In windows, this will init the winsock stuff */ | ||||
|   curl_global_init(CURL_GLOBAL_ALL); | ||||
|  | ||||
|   /* get a curl handle */ | ||||
|   curl = curl_easy_init(); | ||||
|   if(curl) { | ||||
|     /* we want to use our own read function */ | ||||
|     curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); | ||||
|  | ||||
|     /* enable uploading */ | ||||
|     curl_easy_setopt(curl, CURLOPT_UPLOAD, TRUE) ; | ||||
|  | ||||
|     /* HTTP PUT please */ | ||||
|     curl_easy_setopt(curl, CURLOPT_PUT, TRUE); | ||||
|  | ||||
|     /* specify target */ | ||||
|     curl_easy_setopt(curl,CURLOPT_URL, url); | ||||
|  | ||||
|     /* now specify which file to upload */ | ||||
|     curl_easy_setopt(curl, CURLOPT_INFILE, hd_src); | ||||
|  | ||||
|     /* and give the size of the upload (optional) */ | ||||
|     curl_easy_setopt(curl, CURLOPT_INFILESIZE, file_info.st_size); | ||||
|  | ||||
|     /* Now run off and do what you've been told! */ | ||||
|     res = curl_easy_perform(curl); | ||||
|  | ||||
|     /* always cleanup */ | ||||
|     curl_easy_cleanup(curl); | ||||
|   } | ||||
|   fclose(hd_src); /* close the local file */ | ||||
|  | ||||
|   curl_global_cleanup(); | ||||
|   return 0; | ||||
| } | ||||
| @@ -7,7 +7,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___  | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * In order to be useful for every potential user, curl and libcurl are | ||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||
| @@ -154,6 +154,7 @@ typedef enum { | ||||
|   CURLE_TELNET_OPTION_SYNTAX ,   /* 49 - Malformed telnet option */ | ||||
|   CURLE_OBSOLETE,	         /* 50 - removed after 7.7.3 */ | ||||
|   CURLE_SSL_PEER_CERTIFICATE,    /* 51 - peer's certificate wasn't ok */ | ||||
|   CURLE_GOT_NOTHING,             /* 52 - when this is a specific error */ | ||||
|    | ||||
|   CURL_LAST /* never use! */ | ||||
| } CURLcode; | ||||
| @@ -461,9 +462,25 @@ typedef enum { | ||||
|   /* Specify which SSL ciphers to use */ | ||||
|   CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83), | ||||
|  | ||||
|   /* Specify which HTTP version to use! This must be set to one of the | ||||
|      CURL_HTTP_VERSION* enums set below. */ | ||||
|   CINIT(HTTP_VERSION, LONG, 84), | ||||
|    | ||||
|   CURLOPT_LASTENTRY /* the last unusued */ | ||||
| } CURLoption; | ||||
|  | ||||
|   /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ | ||||
| enum { | ||||
|   CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd | ||||
|                              like the library to choose the best possible | ||||
|                              for us! */ | ||||
|   CURL_HTTP_VERSION_1_0,  /* please use HTTP 1.0 in the request */ | ||||
|   CURL_HTTP_VERSION_1_1,  /* please use HTTP 1.1 in the request */ | ||||
|    | ||||
|   CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ | ||||
| }; | ||||
|  | ||||
|  | ||||
| typedef enum { | ||||
|   TIMECOND_NONE, | ||||
|  | ||||
| @@ -472,7 +489,7 @@ typedef enum { | ||||
|   TIMECOND_LASTMOD, | ||||
|  | ||||
|   TIMECOND_LAST | ||||
| } TimeCond; | ||||
| } curl_TimeCond; | ||||
|  | ||||
| #ifdef __BEOS__ | ||||
| #include <support/SupportDefs.h> | ||||
| @@ -512,13 +529,23 @@ typedef enum { | ||||
|   CFINIT(COPYCONTENTS), | ||||
|   CFINIT(PTRCONTENTS), | ||||
|   CFINIT(CONTENTSLENGTH), | ||||
|   CFINIT(FILECONTENT), | ||||
|   CFINIT(ARRAY), | ||||
|   CFINIT(ARRAY_START), /* below are the options allowed within a array */ | ||||
|   CFINIT(FILE), | ||||
|   CFINIT(CONTENTTYPE), | ||||
|   CFINIT(END), | ||||
|   CFINIT(ARRAY_END),   /* up are the options allowed within a array */ | ||||
|  | ||||
|   CURLFORM_LASTENTRY /* the last unusued */ | ||||
| } CURLformoption; | ||||
|  | ||||
| /* structure to be used as parameter for CURLFORM_ARRAY */ | ||||
| struct curl_forms { | ||||
| 	CURLformoption		option; | ||||
| 	const char		*value; | ||||
| }; | ||||
|  | ||||
| /* new external form function */ | ||||
| int curl_formadd(struct HttpPost **httppost, | ||||
|                  struct HttpPost **last_post, | ||||
| @@ -548,8 +575,8 @@ CURLcode curl_global_init(long flags); | ||||
| void curl_global_cleanup(void); | ||||
|  | ||||
| /* This is the version number */ | ||||
| #define LIBCURL_VERSION "7.8.2-pre1" | ||||
| #define LIBCURL_VERSION_NUM 0x070802 | ||||
| #define LIBCURL_VERSION "7.9.1" | ||||
| #define LIBCURL_VERSION_NUM 0x070901 | ||||
|  | ||||
| /* linked-list structure for the CURLOPT_QUOTE option (and other) */ | ||||
| struct curl_slist { | ||||
|   | ||||
| @@ -46,6 +46,21 @@ void curl_easy_cleanup(CURL *curl); | ||||
|  */ | ||||
| CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * NAME curl_easy_duphandle() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * Creates a new curl session handle with the same options set for the handle | ||||
|  * passed in. Duplicating a handle could only be a matter of cloning data and | ||||
|  * options, internal state info and things like persistant connections cannot | ||||
|  * be transfered. It is useful in multithreaded applications when you can run | ||||
|  * curl_easy_duphandle() for each new thread to avoid a series of identical | ||||
|  * curl_easy_setopt() invokes in every thread. | ||||
|  */ | ||||
| CURL* curl_easy_duphandle(CURL *curl); | ||||
|  | ||||
| #ifdef  __cplusplus | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -1,134 +0,0 @@ | ||||
| /** | ||||
|  * The curl class is a JNI wrapper for libcurl. Please bear with me, I'm no | ||||
|  * true java dude (yet). Improve what you think is bad and send me the | ||||
|  * updates! | ||||
|  * daniel@haxx.se | ||||
|  * | ||||
|  * This is meant as a raw, crude and low-level interface to libcurl. If you | ||||
|  * want fancy stuff, build upon this. | ||||
|  */ | ||||
|  | ||||
| public class CurlGlue | ||||
| { | ||||
|   // start of imported generated list, make a new list with | ||||
|   // define2java.pl on demand | ||||
|   public static final int CURLOPT_NOTHING  = 0; | ||||
|   public static final int CURLOPT_FILE  = 10001; | ||||
|   public static final int CURLOPT_URL  = 10002; | ||||
|   public static final int CURLOPT_PORT  = 3; | ||||
|   public static final int CURLOPT_PROXY  = 10004; | ||||
|   public static final int CURLOPT_USERPWD  = 10005; | ||||
|   public static final int CURLOPT_PROXYUSERPWD  = 10006; | ||||
|   public static final int CURLOPT_RANGE  = 10007; | ||||
|   public static final int CURLOPT_INFILE  = 10009; | ||||
|   public static final int CURLOPT_ERRORBUFFER  = 10010; | ||||
|   public static final int CURLOPT_WRITEFUNCTION  = 20011; | ||||
|   public static final int CURLOPT_READFUNCTION  = 20012; | ||||
|   public static final int CURLOPT_TIMEOUT  = 13; | ||||
|   public static final int CURLOPT_INFILESIZE  = 14; | ||||
|   public static final int CURLOPT_POSTFIELDS  = 10015; | ||||
|   public static final int CURLOPT_REFERER  = 10016; | ||||
|   public static final int CURLOPT_FTPPORT  = 10017; | ||||
|   public static final int CURLOPT_USERAGENT  = 10018; | ||||
|   public static final int CURLOPT_LOW_SPEED_LIMIT  = 19; | ||||
|   public static final int CURLOPT_LOW_SPEED_TIME  = 20; | ||||
|   public static final int CURLOPT_RESUME_FROM  = 21; | ||||
|   public static final int CURLOPT_COOKIE  = 10022; | ||||
|   public static final int CURLOPT_HTTPHEADER  = 10023; | ||||
|   public static final int CURLOPT_HTTPPOST  = 10024; | ||||
|   public static final int CURLOPT_SSLCERT  = 10025; | ||||
|   public static final int CURLOPT_SSLCERTPASSWD  = 10026; | ||||
|   public static final int CURLOPT_CRLF  = 27; | ||||
|   public static final int CURLOPT_QUOTE  = 10028; | ||||
|   public static final int CURLOPT_WRITEHEADER  = 10029; | ||||
|   public static final int CURLOPT_COOKIEFILE  = 10031; | ||||
|   public static final int CURLOPT_SSLVERSION  = 32; | ||||
|   public static final int CURLOPT_TIMECONDITION  = 33; | ||||
|   public static final int CURLOPT_TIMEVALUE  = 34; | ||||
|   public static final int CURLOPT_HTTPREQUEST  = 10035; | ||||
|   public static final int CURLOPT_CUSTOMREQUEST  = 10036; | ||||
|   public static final int CURLOPT_STDERR  = 10037; | ||||
|   public static final int CURLOPT_POSTQUOTE  = 10039; | ||||
|   public static final int CURLOPT_WRITEINFO  = 10040; | ||||
|   public static final int CURLOPT_VERBOSE  = 41; | ||||
|   public static final int CURLOPT_HEADER  = 42; | ||||
|   public static final int CURLOPT_NOPROGRESS  = 43; | ||||
|   public static final int CURLOPT_NOBODY  = 44; | ||||
|   public static final int CURLOPT_FAILONERROR  = 45; | ||||
|   public static final int CURLOPT_UPLOAD  = 46; | ||||
|   public static final int CURLOPT_POST  = 47; | ||||
|   public static final int CURLOPT_FTPLISTONLY  = 48; | ||||
|   public static final int CURLOPT_FTPAPPEND  = 50; | ||||
|   public static final int CURLOPT_NETRC  = 51; | ||||
|   public static final int CURLOPT_FOLLOWLOCATION  = 52; | ||||
|   public static final int CURLOPT_FTPASCII  = 53; | ||||
|   public static final int CURLOPT_TRANSFERTEXT  = 53; | ||||
|   public static final int CURLOPT_PUT  = 54; | ||||
|   public static final int CURLOPT_MUTE  = 55; | ||||
|   public static final int CURLOPT_PROGRESSFUNCTION  = 20056; | ||||
|   public static final int CURLOPT_PROGRESSDATA  = 10057; | ||||
|   public static final int CURLOPT_AUTOREFERER  = 58; | ||||
|   public static final int CURLOPT_PROXYPORT  = 59; | ||||
|   public static final int CURLOPT_POSTFIELDSIZE  = 60; | ||||
|   public static final int CURLOPT_HTTPPROXYTUNNEL  = 61; | ||||
|   public static final int CURLOPT_INTERFACE  = 10062; | ||||
|   public static final int CURLOPT_KRB4LEVEL  = 10063; | ||||
|   public static final int CURLOPT_SSL_VERIFYPEER  = 64; | ||||
|   public static final int CURLOPT_CAINFO  = 10065; | ||||
|   public static final int CURLOPT_PASSWDFUNCTION  = 20066; | ||||
|   public static final int CURLOPT_PASSWDDATA  = 10067; | ||||
|   public static final int CURLOPT_MAXREDIRS  = 68; | ||||
|   public static final int CURLOPT_FILETIME  = 10069; | ||||
|   public static final int CURLOPT_TELNETOPTIONS  = 10070; | ||||
|   public static final int CURLOPT_MAXCONNECTS  = 71; | ||||
|   public static final int CURLOPT_CLOSEPOLICY  = 72; | ||||
|   public static final int CURLOPT_CLOSEFUNCTION  = 20073; | ||||
|   public static final int CURLOPT_FRESH_CONNECT  = 74; | ||||
|   public static final int CURLOPT_FORBID_REUSE  = 75; | ||||
|   public static final int CURLOPT_RANDOM_FILE  = 10076; | ||||
|   public static final int CURLOPT_EGDSOCKET  = 10077; | ||||
|   public static final int CURLOPT_CONNECTTIMEOUT  = 78; | ||||
|   public static final int CURLOPT_HEADERFUNCTION  = 20079; | ||||
|   // end of generated list | ||||
|  | ||||
|   public CurlGlue() { | ||||
|     javacurl_handle = jni_init(); | ||||
|   } | ||||
|  | ||||
|   public void finalize() { | ||||
|     jni_cleanup(javacurl_handle); | ||||
|   } | ||||
|  | ||||
|   private int javacurl_handle; | ||||
|  | ||||
|   /* constructor and destructor for the libcurl handle */ | ||||
|   private native int jni_init(); | ||||
|   private native void jni_cleanup(int javacurl_handle); | ||||
|   private native synchronized int jni_perform(int javacurl_handle); | ||||
|    | ||||
|     // Instead of varargs, we have different functions for each | ||||
|   // kind of type setopt() can take | ||||
|   private native int jni_setopt(int libcurl, int option, String value); | ||||
|   private native int jni_setopt(int libcurl, int option, int value); | ||||
|   private native int jni_setopt(int libcurl, int option, CurlWrite value); | ||||
|  | ||||
|   public native int getinfo(); | ||||
|    | ||||
|   public int perform() { | ||||
|     return jni_perform(javacurl_handle); | ||||
|   } | ||||
|   public int setopt(int option, int value) { | ||||
|     return jni_setopt(javacurl_handle, option, value); | ||||
|   } | ||||
|   public int setopt(int option, String value) { | ||||
|     return jni_setopt(javacurl_handle, option, value); | ||||
|   } | ||||
|   public int setopt(int option, CurlWrite value) { | ||||
|     return jni_setopt(javacurl_handle, option, value); | ||||
|   } | ||||
|  | ||||
|   static { | ||||
|     System.loadLibrary("javacurl"); | ||||
|   } | ||||
|    | ||||
| } | ||||
| @@ -1,9 +0,0 @@ | ||||
| public interface CurlWrite | ||||
| { | ||||
|   /** | ||||
|    * handleString gets called by libcurl on each chunk of data | ||||
|    * we receive from the remote server | ||||
|    */ | ||||
|   public int handleString(byte s[]); | ||||
| } | ||||
|  | ||||
| @@ -1,8 +0,0 @@ | ||||
| CurlGlue.java | ||||
| CurlWrite.java | ||||
| define2java.pl | ||||
| javacurl.c | ||||
| Makefile | ||||
| README | ||||
| test.java | ||||
| MANIFEST | ||||
| @@ -1,35 +0,0 @@ | ||||
|  | ||||
| TARGET = libjavacurl.so | ||||
|  | ||||
| OBJS = javacurl.o | ||||
|  | ||||
| CC = gcc | ||||
| CFLAGS = -c | ||||
| CPPFLAGS = -I/usr/j2se/include -I/usr/local/include -I/usr/j2se/include/solaris | ||||
|  | ||||
| # Linux might use -shared -Wl,-soname,libnative.so instead of -G | ||||
| LDFLAGS = -G -lcurl -ldl -L/usr/local/ssl/lib -lssl -lcrypto | ||||
|  | ||||
| all: CurlGlue.h CurlGlue.class javacurl.o $(TARGET) test.class | ||||
|  | ||||
| test: | ||||
| 	java test | ||||
|  | ||||
| javacurl.o: javacurl.c CurlGlue.h | ||||
| 	$(CC) $(CPPFLAGS) $(CFLAGS) $< | ||||
|  | ||||
| CurlGlue.h: CurlGlue.java CurlGlue.class | ||||
| 	javah CurlGlue | ||||
| 	touch CurlGlue.h | ||||
|  | ||||
| test.class: CurlGlue.class javacurl.o | ||||
| 	javac test.java | ||||
|  | ||||
| CurlGlue.class: CurlGlue.java | ||||
| 	javac $< | ||||
|  | ||||
| $(TARGET): $(OBJS) | ||||
| 	$(CC) -o $(TARGET) $(LDFLAGS) $(OBJS) | ||||
|  | ||||
| clean: | ||||
| 	rm -f javacurl.o CurlGlue.h CurlGlue.class | ||||
							
								
								
									
										17
									
								
								java/README
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								java/README
									
									
									
									
									
								
							| @@ -1,17 +0,0 @@ | ||||
|                                   _   _ ____  _      | ||||
|                               ___| | | |  _ \| |     | ||||
|                              / __| | | | |_) | |     | ||||
|                             | (__| |_| |  _ <| |___  | ||||
|                              \___|\___/|_| \_\_____| | ||||
|  | ||||
|                                 Java Interface | ||||
|  | ||||
|  This is not a complete implementation of a libcurl interface. I've made the | ||||
| core work and it needs additional code to be added to get the rest of the | ||||
| stuff supported. | ||||
|  | ||||
|  The interface is not set yet, bring your suggestions! | ||||
|  | ||||
|  Feel free to grab the source files in here and help out! | ||||
|  | ||||
|  The 'test.java' is the actual program that uses the curl stuff. | ||||
| @@ -1,22 +0,0 @@ | ||||
| #!/usr/bin/perl | ||||
|  | ||||
| open(GCC, "gcc -E ../include/curl/curl.h|"); | ||||
|  | ||||
| while(<GCC>) { | ||||
|     if($_ =~ /(CURLOPT_(.*)) += (.*)/) { | ||||
|         $var= $1; | ||||
|         $expr = $3; | ||||
|         $f=$3; | ||||
|         if($expr =~ / *(\d+) *\+ *(\d+)/) { | ||||
|             $expr = $1+$2; | ||||
|         } | ||||
|  | ||||
|         # nah, keep the CURL prefix to make them look like other | ||||
|         # languages' defines | ||||
|         # $var =~ s/^CURL//g; | ||||
|  | ||||
|         print "  public static final int $var = $expr;\n"; | ||||
|     } | ||||
| } | ||||
|  | ||||
| close(GCC); | ||||
							
								
								
									
										218
									
								
								java/javacurl.c
									
									
									
									
									
								
							
							
						
						
									
										218
									
								
								java/javacurl.c
									
									
									
									
									
								
							| @@ -1,218 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  *                                  _   _ ____  _      | ||||
|  *  Project                     ___| | | |  _ \| |     | ||||
|  *                             / __| | | | |_) | |     | ||||
|  *                            | (__| |_| |  _ <| |___  | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * In order to be useful for every potential user, curl and libcurl are | ||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||
|  * | ||||
|  * You may opt to use, copy, modify, merge, publish, distribute and/or sell | ||||
|  * copies of the Software, and permit persons to whom the Software is | ||||
|  * furnished to do so, under the terms of the MPL or the MIT/X-derivate | ||||
|  * licenses. You may pick one of these licenses. | ||||
|  * | ||||
|  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||||
|  * KIND, either express or implied. | ||||
|  * | ||||
|  * $Id$ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| #include <curl/curl.h> /* libcurl header */ | ||||
| #include "CurlGlue.h"  /* the JNI-generated glue header file */ | ||||
|  | ||||
| /* | ||||
|  * This is a private struct allocated for every 'CurlGlue' object. | ||||
|  */ | ||||
| struct javacurl { | ||||
|   void *libcurl; | ||||
|   void *whatever; | ||||
|   struct writecallback { | ||||
|     jmethodID mid; | ||||
|     JNIEnv *java; | ||||
|     jclass cls; /* global reference */ | ||||
|     jobject object; | ||||
|   } write; | ||||
| }; | ||||
|  | ||||
| JNIEXPORT jint JNICALL Java_CurlGlue_jni_1init(JNIEnv *java, | ||||
|                                                jobject myself) | ||||
| { | ||||
|   void *libhandle; | ||||
|   struct javacurl *jcurl=NULL; | ||||
|  | ||||
|   libhandle = curl_easy_init(); | ||||
|  | ||||
|   if(libhandle) { | ||||
|     jcurl=(struct javacurl *)malloc(sizeof(struct javacurl)); | ||||
|     if(jcurl) { | ||||
|       memset(jcurl, 0, sizeof(struct javacurl)); | ||||
|       jcurl->libcurl = libhandle; | ||||
|  | ||||
|     } | ||||
|     else { | ||||
|       curl_easy_cleanup(libhandle); | ||||
|       return (jint)0; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return (jint) jcurl; /* nasty typecast */ | ||||
| } | ||||
|  | ||||
| JNIEXPORT void JNICALL Java_CurlGlue_jni_1cleanup(JNIEnv *java, | ||||
|                                                   jobject myself, | ||||
|                                                   jint jcurl) | ||||
| { | ||||
|  | ||||
|   struct javacurl *curl = (struct javacurl*)jcurl; | ||||
|  | ||||
|   if(curl->write.cls) { | ||||
|     /* a global reference we must delete */ | ||||
|     (*java)->DeleteGlobalRef(java, curl->write.cls); | ||||
|     (*java)->DeleteGlobalRef(java, curl->write.object); | ||||
|   } | ||||
|  | ||||
|   curl_easy_cleanup(curl->libcurl); /* cleanup libcurl stuff */ | ||||
|  | ||||
|   free((void *)curl); /* free the struct too */ | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * setopt() int + string | ||||
|  */ | ||||
| JNIEXPORT jint JNICALL Java_CurlGlue_jni_1setopt__IILjava_lang_String_2 | ||||
|   (JNIEnv *java, jobject myself, jint jcurl, jint option, jstring value) | ||||
| { | ||||
|   /* get the actual string C-style */ | ||||
|   const char *str = (*java)->GetStringUTFChars(java, value, 0); | ||||
|  | ||||
|   void *handle = (void *)((struct javacurl*)jcurl)->libcurl; | ||||
|  | ||||
|   puts("setopt int + string"); | ||||
|    | ||||
|   return (jint)curl_easy_setopt(handle, (CURLoption)option, str); | ||||
|  | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * setopt() int + int  | ||||
|  */ | ||||
| JNIEXPORT jint JNICALL Java_CurlGlue_jni_1setopt__III | ||||
|   (JNIEnv *java, jobject myself, jint jcurl, jint option, jint value) | ||||
| { | ||||
|   void *handle = (void *)((struct javacurl*)jcurl)->libcurl; | ||||
|   CURLoption opt = (CURLoption)option; | ||||
|  | ||||
|   puts("setopt int + int"); | ||||
|  | ||||
|   switch(opt) { | ||||
|   case CURLOPT_FILE: | ||||
|     /* silently ignored, we don't need user-specified callback data when | ||||
|        we have an object, and besides the CURLOPT_FILE is not exported | ||||
|        to the java interface */ | ||||
|     return 0; | ||||
|   } | ||||
|  | ||||
|   return (jint)curl_easy_setopt(handle, (CURLoption)option, value); | ||||
| } | ||||
|  | ||||
| static int javacurl_write_callback(void *ptr, | ||||
|                                    size_t size, | ||||
|                                    size_t nmemb, | ||||
|                                    FILE  *stream) | ||||
| { | ||||
|   struct javacurl *curl = (struct javacurl *)stream; | ||||
|   size_t realsize = size * nmemb; | ||||
|   JNIEnv *java = curl->write.java; | ||||
|   jbyteArray jb=NULL; | ||||
|   int ret=0; | ||||
|  | ||||
|   fprintf(stderr, "%d bytes data received in callback:\n" | ||||
|           "ptr=%p, java=%p cls=%p\n", | ||||
|           realsize, curl, java, curl->write.cls); | ||||
|  | ||||
|   jb=(*java)->NewByteArray(java, realsize); | ||||
|   (*java)->SetByteArrayRegion(java, jb, 0,  | ||||
|                               realsize, (jbyte *)ptr); | ||||
|  | ||||
|   fprintf(stderr, "created byte-array\n"); | ||||
|  | ||||
|   ret = (*java)->CallIntMethod(java, | ||||
|                                curl->write.object, | ||||
|                                curl->write.mid, | ||||
|                                jb); | ||||
|  | ||||
|   fprintf(stderr, "java-method returned %d\n", ret); | ||||
|  | ||||
|   return realsize; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * setopt() int + object | ||||
|  */ | ||||
|  | ||||
| JNIEXPORT jint JNICALL Java_CurlGlue_jni_1setopt__IILCurlWrite_2 | ||||
|   (JNIEnv *java, jobject myself, jint jcurl, jint option, jobject object) | ||||
| { | ||||
|   jclass cls_local = (*java)->GetObjectClass(java, object); | ||||
|   jmethodID mid; | ||||
|   struct javacurl *curl = (struct javacurl *)jcurl; | ||||
|   jclass cls; | ||||
|   jobject obj_global; | ||||
|  | ||||
|   switch(option) { | ||||
|   case CURLOPT_WRITEFUNCTION: | ||||
|     /* this makes a reference that'll be alive until we kill it! */ | ||||
|     cls = (*java)->NewGlobalRef(java, cls_local); | ||||
|  | ||||
|     printf("setopt int + object, option = %d cls= %p\n", | ||||
|            option, cls); | ||||
|  | ||||
|     if(!cls) { | ||||
|       puts("couldn't make local reference global"); | ||||
|       return 0; | ||||
|     } | ||||
|  | ||||
|     /* this is the write callback */ | ||||
|     mid = (*java)->GetMethodID(java, cls, "handleString", "([B)I"); | ||||
|     if(!mid) { | ||||
|       puts("no callback method found"); | ||||
|       return 0; | ||||
|     } | ||||
|  | ||||
|     obj_global = (*java)->NewGlobalRef(java, object); | ||||
|  | ||||
|     curl->write.mid = mid; | ||||
|     curl->write.cls = cls; | ||||
|     curl->write.object = obj_global; | ||||
|     /*curl->write.java = java; stored on perform */ | ||||
|  | ||||
|     fprintf(stderr, "setopt write callback and write file pointer %p, java = %p\n", | ||||
|             curl, java); | ||||
|  | ||||
|     curl_easy_setopt(curl->libcurl, CURLOPT_WRITEFUNCTION, | ||||
|                      javacurl_write_callback); | ||||
|     curl_easy_setopt(curl->libcurl, CURLOPT_FILE, | ||||
|                      curl); | ||||
|  | ||||
|     break; | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| JNIEXPORT jint JNICALL Java_CurlGlue_getinfo | ||||
|   (JNIEnv *java, jobject value) | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| JNIEXPORT jint JNICALL Java_CurlGlue_jni_1perform | ||||
|   (JNIEnv *java, jobject myself, jint jcurl) | ||||
| { | ||||
|   struct javacurl *curl=(struct javacurl*)jcurl; | ||||
|   curl->write.java = java; | ||||
|   return (jint)curl_easy_perform(curl->libcurl); | ||||
| } | ||||
| @@ -1,27 +0,0 @@ | ||||
| import CurlGlue; | ||||
| import CurlWrite; | ||||
|  | ||||
| class test implements CurlWrite { | ||||
|     public int handleString(byte s[]) | ||||
|     { | ||||
|         /* output everything */ | ||||
|         System.out.println("IIIIIIIIIII -------------- OOOOOOOOOOOOOOOOOOO"); | ||||
|         try { | ||||
|           System.out.write(s); | ||||
|         } | ||||
|         catch (java.io.IOException moo) { | ||||
|           // nothing | ||||
|         } | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     public static void main(String[] args) | ||||
|     { | ||||
|         CurlGlue cg = new CurlGlue(); | ||||
|         test cw = new test(); | ||||
|         cg.setopt(CurlGlue.CURLOPT_URL, "http://www.contactor.se/"); | ||||
|         cg.setopt(CurlGlue.CURLOPT_WRITEFUNCTION, cw); | ||||
|         cg.perform(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -16,7 +16,7 @@ lib_LTLIBRARIES = libcurl.la | ||||
| INCLUDES = -I$(top_srcdir)/include | ||||
|  | ||||
|  | ||||
| libcurl_la_LDFLAGS = -version-info 2:2:0 | ||||
| libcurl_la_LDFLAGS = -no-undefined -version-info 2:2:0 | ||||
| # This flag accepts an argument of the form current[:revision[:age]]. So, | ||||
| # passing -version-info 3:12:1 sets current to 3, revision to 12, and age to | ||||
| # 1. | ||||
| @@ -59,7 +59,7 @@ escape.c       mprintf.c      telnet.c       \ | ||||
| escape.h       getpass.c      netrc.c        telnet.h       \ | ||||
| getinfo.c getinfo.h transfer.c strequal.c strequal.h easy.c \ | ||||
| security.h security.c krb4.c krb4.h memdebug.c memdebug.h inet_ntoa_r.h \ | ||||
| http_chunks.c http_chunks.h strtok.c strtok.h | ||||
| http_chunks.c http_chunks.h strtok.c strtok.h connect.c connect.h | ||||
|  | ||||
| noinst_HEADERS = setup.h transfer.h | ||||
|  | ||||
|   | ||||
| @@ -58,7 +58,8 @@ SOURCES	   = \ | ||||
| 	version.c \ | ||||
| 	easy.c \ | ||||
| 	strequal.c \ | ||||
| 	strtok.c | ||||
| 	strtok.c \ | ||||
| 	connect.c | ||||
|  | ||||
| OBJECTS = $(SOURCES:.c=.obj) | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| ############################################################# | ||||
| # $Id$ | ||||
| # | ||||
| ## Makefile for building libcurl.a with MingW32 (GCC-2.95) and | ||||
| ## optionally OpenSSL (0.9.6) | ||||
| @@ -12,7 +11,7 @@ CC = gcc | ||||
| AR = ar | ||||
| RANLIB = ranlib | ||||
| STRIP = strip -g | ||||
| OPENSSL_PATH = ../../openssl-0.9.6 | ||||
| OPENSSL_PATH = ../../openssl-0.9.6b | ||||
|  | ||||
| ######################################################## | ||||
| ## Nothing more to do below this line! | ||||
| @@ -36,14 +35,14 @@ libcurl_a_SOURCES = arpa_telnet.h file.c getpass.h netrc.h timeval.c base64.c \ | ||||
| 	ldap.h ssluse.h escape.c getenv.h mprintf.c telnet.c escape.h getpass.c netrc.c	\ | ||||
| 	telnet.h getinfo.c strequal.c strequal.h easy.c security.h		\ | ||||
| 	security.c krb4.h krb4.c memdebug.h memdebug.c inet_ntoa_r.h http_chunks.h http_chunks.c \ | ||||
| 	strtok.c | ||||
| 	strtok.c connect.c | ||||
|  | ||||
| libcurl_a_OBJECTS =  file.o timeval.o base64.o hostip.o progress.o \ | ||||
| 	formdata.o cookie.o http.o sendf.o ftp.o url.o dict.o if2ip.o \ | ||||
| 	speedcheck.o getdate.o transfer.o ldap.o ssluse.o version.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 \ | ||||
| 	strtok.o | ||||
| 	strtok.o connect.o | ||||
|  | ||||
| LIBRARIES =  $(libcurl_a_LIBRARIES) | ||||
| SOURCES = $(libcurl_a_SOURCES) | ||||
| @@ -62,7 +61,7 @@ libcurl.a: $(libcurl_a_OBJECTS) $(libcurl_a_DEPENDENCIES) | ||||
|  | ||||
| libcurl.dll libcurldll.a: libcurl.a libcurl.def dllinit.o | ||||
| 	-@erase $@ | ||||
| 	dllwrap --dllname $@ --output-lib libcurldll.a --export-all --def libcurl.def $(libcurl_a_LIBRARIES) dllinit.o -L$(OPENSSL_PATH)/out $(DLL_LIBS) -lwsock32 | ||||
| 	dllwrap --dllname $@ --output-lib libcurldll.a --export-all --def libcurl.def $(libcurl_a_LIBRARIES) dllinit.o -L$(OPENSSL_PATH)/out $(DLL_LIBS) -lwsock32 -lws2_32 | ||||
| 	$(STRIP) $@ | ||||
|  | ||||
| # remove the last line above to keep debug info | ||||
|   | ||||
| @@ -29,7 +29,7 @@ LINKRS = link.exe -lib /out:$(PROGRAM_NAME) /LIBPATH:$(OPENSSL_PATH)/out32dll | ||||
|  | ||||
| CFLAGS = /I "../include" /nologo /W3 /GX /D "WIN32" /D "VC6" /D "_MBCS" /D "_LIB" /YX /FD /c /D "MSDOS" | ||||
| LFLAGS = /nologo | ||||
| LINKLIBS = wsock32.lib | ||||
| LINKLIBS = ws2_32.lib | ||||
| LINKSLIBS = libeay32.lib ssleay32.lib RSAglue.lib | ||||
|  | ||||
| RELEASE_OBJS= \ | ||||
| @@ -62,7 +62,8 @@ RELEASE_OBJS= \ | ||||
| 	versionr.obj \ | ||||
| 	easyr.obj \ | ||||
| 	strequalr.obj \ | ||||
| 	strtokr.obj | ||||
| 	strtokr.obj \ | ||||
| 	connectr.obj | ||||
|  | ||||
| DEBUG_OBJS= \ | ||||
| 	base64d.obj \ | ||||
| @@ -94,7 +95,8 @@ DEBUG_OBJS= \ | ||||
| 	versiond.obj  \ | ||||
| 	easyd.obj \ | ||||
| 	strequald.obj \ | ||||
| 	strtokd.obj | ||||
| 	strtokd.obj \ | ||||
| 	connectd.obj | ||||
|  | ||||
| RELEASE_SSL_OBJS= \ | ||||
| 	base64rs.obj \ | ||||
| @@ -126,7 +128,8 @@ RELEASE_SSL_OBJS= \ | ||||
| 	versionrs.obj \ | ||||
| 	easyrs.obj \ | ||||
| 	strequalrs.obj \ | ||||
| 	strtokrs.obj | ||||
| 	strtokrs.obj \ | ||||
| 	connectrs.obj | ||||
|  | ||||
| LINK_OBJS= \ | ||||
| 	base64.obj \ | ||||
| @@ -158,7 +161,8 @@ LINK_OBJS= \ | ||||
| 	version.obj \ | ||||
| 	easy.obj \ | ||||
| 	strequal.obj \ | ||||
| 	strtok.obj | ||||
| 	strtok.obj \ | ||||
| 	connect.obj | ||||
|  | ||||
| all : release | ||||
|  | ||||
| @@ -232,6 +236,8 @@ strequalr.obj: strequal.c | ||||
| 	$(CCR) $(CFLAGS) strequal.c | ||||
| strtokr.obj:strtok.c | ||||
| 	$(CCR) $(CFLAGS) strtok.c | ||||
| connectr.obj:connect.c | ||||
| 	$(CCR) $(CFLAGS) connect.c | ||||
|  | ||||
| ## Debug | ||||
| base64d.obj: base64.c | ||||
| @@ -294,6 +300,8 @@ strequald.obj: strequal.c | ||||
| 	$(CCD) $(CFLAGS) strequal.c | ||||
| strtokd.obj:strtok.c | ||||
| 	$(CCD) $(CFLAGS) strtok.c | ||||
| connectd.obj:connect.c | ||||
| 	$(CCR) $(CFLAGS) connect.c | ||||
|  | ||||
| ## Release SSL | ||||
| base64rs.obj: base64.c | ||||
| @@ -356,7 +364,8 @@ strequalrs.obj: strequal.c | ||||
| 	$(CCRS) $(CFLAGS) strequal.c | ||||
| strtokrs.obj:strtok.c | ||||
| 	$(CCRS) $(CFLAGS) strtok.c | ||||
|  | ||||
| connectrs.obj:connect.c | ||||
| 	$(CCR) $(CFLAGS) connect.c | ||||
|  | ||||
| clean: | ||||
| 	-@erase *.obj | ||||
|   | ||||
| @@ -265,6 +265,6 @@ void *suck(int *lenptr) { | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
							
								
								
									
										562
									
								
								lib/connect.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										562
									
								
								lib/connect.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,562 @@ | ||||
| /***************************************************************************** | ||||
|  *                                  _   _ ____  _      | ||||
|  *  Project                     ___| | | |  _ \| |     | ||||
|  *                             / __| | | | |_) | |     | ||||
|  *                            | (__| |_| |  _ <| |___  | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * In order to be useful for every potential user, curl and libcurl are | ||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||
|  * | ||||
|  * You may opt to use, copy, modify, merge, publish, distribute and/or sell | ||||
|  * copies of the Software, and permit persons to whom the Software is | ||||
|  * furnished to do so, under the terms of the MPL or the MIT/X-derivate | ||||
|  * licenses. You may pick one of these licenses. | ||||
|  * | ||||
|  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||||
|  * KIND, either express or implied. | ||||
|  * | ||||
|  * $Id$ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| #include "setup.h" | ||||
|  | ||||
| #ifndef WIN32 | ||||
| /* headers for non-win32 */ | ||||
| #include <sys/time.h> | ||||
| #include <sys/socket.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/ioctl.h> | ||||
| #ifdef HAVE_UNISTD_H | ||||
| #include <unistd.h> | ||||
| #endif | ||||
| #ifdef HAVE_NETDB_H | ||||
| #include <netdb.h> | ||||
| #endif | ||||
| #ifdef HAVE_FCNTL_H | ||||
| #include <fcntl.h> | ||||
| #endif | ||||
| #ifdef HAVE_NETINET_IN_H | ||||
| #include <netinet/in.h> | ||||
| #endif | ||||
| #ifdef HAVE_ARPA_INET_H | ||||
| #include <arpa/inet.h> | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
| #include <stdio.h> | ||||
| #include <errno.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #ifndef TRUE | ||||
| #define TRUE 1 | ||||
| #define FALSE 0 | ||||
| #endif | ||||
|  | ||||
| #ifdef WIN32 | ||||
| #define HAVE_IOCTLSOCKET | ||||
| #include <windows.h> | ||||
| #include <winsock.h> | ||||
| #define EINPROGRESS WSAEINPROGRESS | ||||
| #define EWOULDBLOCK WSAEWOULDBLOCK | ||||
| #endif | ||||
|  | ||||
| #include "urldata.h" | ||||
| #include "sendf.h" | ||||
| #include "if2ip.h" | ||||
|  | ||||
| /* The last #include file should be: */ | ||||
| #ifdef MALLOCDEBUG | ||||
| #include "memdebug.h" | ||||
| #endif | ||||
|  | ||||
| static | ||||
| int geterrno(void) | ||||
| { | ||||
| #ifdef WIN32 | ||||
|   return (int)GetLastError(); | ||||
| #else | ||||
|   return errno; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| /************************************************************************* | ||||
|  * Curl_nonblock | ||||
|  * | ||||
|  * Description: | ||||
|  *  Set the socket to either blocking or non-blocking mode. | ||||
|  */ | ||||
|  | ||||
| int Curl_nonblock(int socket,    /* operate on this */ | ||||
|                   int nonblock   /* TRUE or FALSE */) | ||||
| { | ||||
| #undef SETBLOCK | ||||
| #ifdef HAVE_O_NONBLOCK | ||||
|   int flags; | ||||
|  | ||||
|   flags = fcntl(socket, F_GETFL, 0); | ||||
|   if (TRUE == nonblock) | ||||
|     return fcntl(socket, F_SETFL, flags | O_NONBLOCK); | ||||
|   else | ||||
|     return fcntl(socket, F_SETFL, flags & (~O_NONBLOCK)); | ||||
| #define SETBLOCK 1 | ||||
| #endif | ||||
|  | ||||
| #ifdef HAVE_FIONBIO | ||||
|   int flags; | ||||
|  | ||||
|   flags = nonblock; | ||||
|   return ioctl(socket, FIONBIO, &flags); | ||||
| #define SETBLOCK 2 | ||||
| #endif | ||||
|  | ||||
| #ifdef HAVE_IOCTLSOCKET | ||||
|   int flags; | ||||
|   flags = nonblock; | ||||
|   return ioctlsocket(socket, FIONBIO, &flags); | ||||
| #define SETBLOCK 3 | ||||
| #endif | ||||
|  | ||||
| #ifdef HAVE_IOCTLSOCKET_CASE | ||||
|   return IoctlSocket(socket, FIONBIO, (long)nonblock); | ||||
| #define SETBLOCK 4 | ||||
| #endif | ||||
|  | ||||
| #ifdef HAVE_DISABLED_NONBLOCKING | ||||
|   return 0; /* returns success */ | ||||
| #define SETBLOCK 5 | ||||
| #endif | ||||
|  | ||||
| #ifndef SETBLOCK | ||||
| #error "no non-blocking method was found/used/set" | ||||
| #endif | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Return 0 on fine connect, -1 on error and 1 on timeout. | ||||
|  */ | ||||
| static | ||||
| int waitconnect(int sockfd, /* socket */ | ||||
|                 int timeout_msec) | ||||
| { | ||||
|   fd_set fd; | ||||
|   fd_set errfd; | ||||
|   struct timeval interval; | ||||
|   int rc; | ||||
|  | ||||
|   /* now select() until we get connect or timeout */ | ||||
|   FD_ZERO(&fd); | ||||
|   FD_SET(sockfd, &fd); | ||||
|  | ||||
|   FD_ZERO(&errfd); | ||||
|   FD_SET(sockfd, &errfd); | ||||
|  | ||||
|   interval.tv_sec = timeout_msec/1000; | ||||
|   timeout_msec -= interval.tv_sec*1000; | ||||
|  | ||||
|   interval.tv_usec = timeout_msec*1000; | ||||
|  | ||||
|   rc = select(sockfd+1, NULL, &fd, &errfd, &interval); | ||||
|   if(-1 == rc) | ||||
|     /* error, no connect here, try next */ | ||||
|     return -1; | ||||
|    | ||||
|   else if(0 == rc) | ||||
|     /* timeout, no connect today */ | ||||
|     return 1; | ||||
|  | ||||
|   if(FD_ISSET(sockfd, &errfd)) { | ||||
|     /* error condition caught */ | ||||
|     return 2; | ||||
|   } | ||||
|  | ||||
|   /* we have a connect! */ | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| #ifndef ENABLE_IPV6 | ||||
| static CURLcode bindlocal(struct connectdata *conn, | ||||
|                           int sockfd) | ||||
| { | ||||
| #if !defined(WIN32)||defined(__CYGWIN32__) | ||||
|   /* We don't generally like checking for OS-versions, we should make this | ||||
|      HAVE_XXXX based, although at the moment I don't have a decent test for | ||||
|      this! */ | ||||
|  | ||||
| #ifdef HAVE_INET_NTOA | ||||
|  | ||||
| #ifndef INADDR_NONE | ||||
| #define INADDR_NONE (unsigned long) ~0 | ||||
| #endif | ||||
|  | ||||
|   struct SessionHandle *data = conn->data; | ||||
|  | ||||
|   /************************************************************* | ||||
|    * Select device to bind socket to | ||||
|    *************************************************************/ | ||||
|   if (strlen(data->set.device)<255) { | ||||
|     struct sockaddr_in sa; | ||||
|     struct hostent *h=NULL; | ||||
|     char *hostdataptr=NULL; | ||||
|     size_t size; | ||||
|     char myhost[256] = ""; | ||||
|     unsigned long in; | ||||
|  | ||||
|     if(Curl_if2ip(data->set.device, myhost, sizeof(myhost))) { | ||||
|       h = Curl_getaddrinfo(data, myhost, 0, &hostdataptr); | ||||
|     } | ||||
|     else { | ||||
|       if(strlen(data->set.device)>1) { | ||||
|         h = Curl_getaddrinfo(data, data->set.device, 0, &hostdataptr); | ||||
|       } | ||||
|       if(h) { | ||||
|         /* we know data->set.device is shorter than the myhost array */ | ||||
|         strcpy(myhost, data->set.device); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if(! *myhost) { | ||||
|       /* need to fix this | ||||
|          h=Curl_gethost(data, | ||||
|          getmyhost(*myhost,sizeof(myhost)), | ||||
|          hostent_buf, | ||||
|          sizeof(hostent_buf)); | ||||
|       */ | ||||
|       if(hostdataptr) | ||||
|         free(hostdataptr); /* allocated by Curl_getaddrinfo() */ | ||||
|       return CURLE_HTTP_PORT_FAILED; | ||||
|     } | ||||
|  | ||||
|     infof(data, "We bind local end to %s\n", myhost); | ||||
|  | ||||
|     if ( (in=inet_addr(myhost)) != INADDR_NONE ) { | ||||
|  | ||||
|       if ( h ) { | ||||
|         memset((char *)&sa, 0, sizeof(sa)); | ||||
|         memcpy((char *)&sa.sin_addr, | ||||
|                h->h_addr, | ||||
|                h->h_length); | ||||
|         sa.sin_family = AF_INET; | ||||
|         sa.sin_addr.s_addr = in; | ||||
|         sa.sin_port = 0; /* get any port */ | ||||
| 	 | ||||
|         if( bind(sockfd, (struct sockaddr *)&sa, sizeof(sa)) >= 0) { | ||||
|           /* we succeeded to bind */ | ||||
|           struct sockaddr_in add; | ||||
| 	 | ||||
|           size = sizeof(add); | ||||
|           if(getsockname(sockfd, (struct sockaddr *) &add, | ||||
|                          (socklen_t *)&size)<0) { | ||||
|             failf(data, "getsockname() failed"); | ||||
|             return CURLE_HTTP_PORT_FAILED; | ||||
|           } | ||||
|         } | ||||
|         else { | ||||
|           switch(errno) { | ||||
|           case EBADF: | ||||
|             failf(data, "Invalid descriptor: %d", errno); | ||||
|             break; | ||||
|           case EINVAL: | ||||
|             failf(data, "Invalid request: %d", errno); | ||||
|             break; | ||||
|           case EACCES: | ||||
|             failf(data, "Address is protected, user not superuser: %d", errno); | ||||
|             break; | ||||
|           case ENOTSOCK: | ||||
|             failf(data, | ||||
|                   "Argument is a descriptor for a file, not a socket: %d", | ||||
|                   errno); | ||||
|             break; | ||||
|           case EFAULT: | ||||
|             failf(data, "Inaccessable memory error: %d", errno); | ||||
|             break; | ||||
|           case ENAMETOOLONG: | ||||
|             failf(data, "Address too long: %d", errno); | ||||
|             break; | ||||
|           case ENOMEM: | ||||
|             failf(data, "Insufficient kernel memory was available: %d", errno); | ||||
|             break; | ||||
|           default: | ||||
|             failf(data, "errno %d\n", errno); | ||||
|             break; | ||||
|           } /* end of switch(errno) */ | ||||
| 	 | ||||
|           return CURLE_HTTP_PORT_FAILED; | ||||
|         } /* end of else */ | ||||
| 	 | ||||
|       } /* end of if  h */ | ||||
|       else { | ||||
| 	failf(data,"could't find my own IP address (%s)", myhost); | ||||
| 	return CURLE_HTTP_PORT_FAILED; | ||||
|       } | ||||
|     } /* end of inet_addr */ | ||||
|  | ||||
|     else { | ||||
|       failf(data, "could't find my own IP address (%s)", myhost); | ||||
|       return CURLE_HTTP_PORT_FAILED; | ||||
|     } | ||||
|  | ||||
|     if(hostdataptr) | ||||
|       free(hostdataptr); /* allocated by Curl_getaddrinfo() */ | ||||
|  | ||||
|     return CURLE_OK; | ||||
|  | ||||
|   } /* end of device selection support */ | ||||
| #endif /* end of HAVE_INET_NTOA */ | ||||
| #endif /* end of not WIN32 */ | ||||
|  | ||||
|   return CURLE_HTTP_PORT_FAILED; | ||||
| } | ||||
| #else /* end of ipv4-specific section */ | ||||
|  | ||||
| /* we only use socketerror() on IPv6-enabled machines */ | ||||
| static | ||||
| int socketerror(int sockfd) | ||||
| { | ||||
|   int err = 0; | ||||
|   socklen_t errSize = sizeof(err); | ||||
|  | ||||
|   if( -1 == getsockopt(sockfd, SOL_SOCKET, SO_ERROR, | ||||
|                        (void *)&err, &errSize)) | ||||
|     err = geterrno(); | ||||
|    | ||||
|   return err; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * TCP connect to the given host with timeout, proxy or remote doesn't matter. | ||||
|  * There might be more than one IP address to try out. Fill in the passed | ||||
|  * pointer with the connected socket. | ||||
|  */ | ||||
|  | ||||
| CURLcode Curl_connecthost(struct connectdata *conn,  /* context */ | ||||
|                           Curl_addrinfo *remotehost, /* use one in here */ | ||||
|                           int port,                  /* connect to this */ | ||||
|                           int *sockconn,             /* the connected socket */ | ||||
|                           Curl_ipconnect **addr)     /* the one we used */ | ||||
| { | ||||
|   struct SessionHandle *data = conn->data; | ||||
|   int rc; | ||||
|   int sockfd=-1; | ||||
|   int aliasindex=0; | ||||
|  | ||||
|   struct timeval after; | ||||
|   struct timeval before = Curl_tvnow(); | ||||
|  | ||||
|   /************************************************************* | ||||
|    * Figure out what maximum time we have left | ||||
|    *************************************************************/ | ||||
|   long timeout_ms=300000; /* milliseconds, default to five minutes */ | ||||
|   if(data->set.timeout || data->set.connecttimeout) { | ||||
|     double has_passed; | ||||
|  | ||||
|     /* Evaluate in milliseconds how much time that has passed */ | ||||
|     has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start); | ||||
|  | ||||
| #ifndef min | ||||
| #define min(a, b)   ((a) < (b) ? (a) : (b)) | ||||
| #endif | ||||
|  | ||||
|     /* get the most strict timeout of the ones converted to milliseconds */ | ||||
|     if(data->set.timeout && | ||||
|        (data->set.timeout>data->set.connecttimeout)) | ||||
|       timeout_ms = data->set.timeout*1000; | ||||
|     else | ||||
|       timeout_ms = data->set.connecttimeout*1000; | ||||
|  | ||||
|     /* subtract the passed time */ | ||||
|     timeout_ms -= (long)has_passed; | ||||
|  | ||||
|     if(timeout_ms < 0) | ||||
|       /* a precaution, no need to continue if time already is up */ | ||||
|       return CURLE_OPERATION_TIMEOUTED; | ||||
|   } | ||||
|  | ||||
| #ifdef ENABLE_IPV6 | ||||
|   /* | ||||
|    * Connecting with IPv6 support is so much easier and cleanly done | ||||
|    */ | ||||
|   { | ||||
|     struct addrinfo *ai; | ||||
|     port =0; /* prevent compiler warning */ | ||||
|  | ||||
|     for (ai = remotehost; ai; ai = ai->ai_next, aliasindex++) { | ||||
|       sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); | ||||
|       if (sockfd < 0) | ||||
|         continue; | ||||
|  | ||||
|       /* set socket non-blocking */ | ||||
|       Curl_nonblock(sockfd, TRUE); | ||||
|  | ||||
|       rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen); | ||||
|  | ||||
|       if(-1 == rc) { | ||||
|         int error=geterrno(); | ||||
|  | ||||
|         switch (error) { | ||||
|         case EINPROGRESS: | ||||
|         case EWOULDBLOCK: | ||||
| #if defined(EAGAIN) && EAGAIN != EWOULDBLOCK | ||||
|           /* On some platforms EAGAIN and EWOULDBLOCK are the | ||||
|            * same value, and on others they are different, hence | ||||
|            * the odd #if | ||||
|            */ | ||||
|         case EAGAIN: | ||||
| #endif | ||||
|         case EINTR: | ||||
|  | ||||
|           /* asynchronous connect, wait for connect or timeout */ | ||||
|           rc = waitconnect(sockfd, timeout_ms); | ||||
|           break; | ||||
|         case ECONNREFUSED: /* no one listening */ | ||||
|         default: | ||||
|           /* unknown error, fallthrough and try another address! */ | ||||
|           failf(data, "Failed to connect"); | ||||
|           break; | ||||
|         } | ||||
|       } | ||||
|       if(0 == rc) { | ||||
|         /* we might be connected, if the socket says it is OK! Ask it! */ | ||||
|         int err; | ||||
|  | ||||
|         err = socketerror(sockfd); | ||||
|         if ((0 == err) || (EISCONN == err)) { | ||||
|           /* we are connected, awesome! */ | ||||
|           break; | ||||
| 	} | ||||
|         /* we are _not_ connected, it was a false alert, continue please */ | ||||
|       } | ||||
|  | ||||
|       /* connect failed or timed out */ | ||||
|       sclose(sockfd); | ||||
|       sockfd = -1; | ||||
|  | ||||
|       /* get a new timeout for next attempt */ | ||||
|       after = Curl_tvnow(); | ||||
|       timeout_ms -= Curl_tvdiff(after, before); | ||||
|       if(timeout_ms < 0) { | ||||
|         failf(data, "connect() timed out!"); | ||||
|         return CURLE_OPERATION_TIMEOUTED; | ||||
|       } | ||||
|       before = after; | ||||
|       continue; | ||||
|     } | ||||
|     if (sockfd < 0) { | ||||
|       failf(data, "connect() failed"); | ||||
|       return CURLE_COULDNT_CONNECT; | ||||
|     } | ||||
|  | ||||
|     /* now disable the non-blocking mode again */ | ||||
|     Curl_nonblock(sockfd, FALSE); | ||||
|  | ||||
|     if(addr) | ||||
|       *addr = ai; /* the address we ended up connected to */ | ||||
|   } | ||||
| #else | ||||
|   /* | ||||
|    * Connecting with IPv4-only support | ||||
|    */ | ||||
|   if(!remotehost->h_addr_list[0]) { | ||||
|     /* If there is no addresses in the address list, then we return | ||||
|        error right away */ | ||||
|     failf(data, "no address available"); | ||||
|     return CURLE_COULDNT_CONNECT; | ||||
|   } | ||||
|   /* create an IPv4 TCP socket */ | ||||
|   sockfd = socket(AF_INET, SOCK_STREAM, 0); | ||||
|   if(-1 == sockfd) { | ||||
|     failf(data, "couldn't create socket"); | ||||
|     return CURLE_COULDNT_CONNECT; /* big time error */ | ||||
|   } | ||||
|    | ||||
|   if(conn->data->set.device) { | ||||
|     /* user selected to bind the outgoing socket to a specified "device" | ||||
|        before doing connect */ | ||||
|     CURLcode res = bindlocal(conn, sockfd); | ||||
|     if(res) | ||||
|       return res; | ||||
|   } | ||||
|  | ||||
|   /* Convert socket to non-blocking type */ | ||||
|   Curl_nonblock(sockfd, TRUE); | ||||
|  | ||||
|   /* This is the loop that attempts to connect to all IP-addresses we | ||||
|      know for the given host. One by one. */ | ||||
|   for(rc=-1, aliasindex=0; | ||||
|       rc && (struct in_addr *)remotehost->h_addr_list[aliasindex]; | ||||
|       aliasindex++) { | ||||
|     struct sockaddr_in serv_addr; | ||||
|  | ||||
|     /* do this nasty work to do the connect */ | ||||
|     memset((char *) &serv_addr, '\0', sizeof(serv_addr)); | ||||
|     memcpy((char *)&(serv_addr.sin_addr), | ||||
|            (struct in_addr *)remotehost->h_addr_list[aliasindex], | ||||
|            sizeof(struct in_addr)); | ||||
|     serv_addr.sin_family = remotehost->h_addrtype; | ||||
|     serv_addr.sin_port = htons(port); | ||||
|    | ||||
|     rc = connect(sockfd, (struct sockaddr *)&serv_addr, | ||||
|                  sizeof(serv_addr)); | ||||
|  | ||||
|     if(-1 == rc) { | ||||
|       int error=geterrno(); | ||||
|  | ||||
|       switch (error) { | ||||
|       case EINPROGRESS: | ||||
|       case EWOULDBLOCK: | ||||
| #if defined(EAGAIN) && EAGAIN != EWOULDBLOCK | ||||
|         /* On some platforms EAGAIN and EWOULDBLOCK are the | ||||
|          * same value, and on others they are different, hence | ||||
|          * the odd #if | ||||
|          */ | ||||
|       case EAGAIN: | ||||
| #endif | ||||
|  | ||||
|         /* asynchronous connect, wait for connect or timeout */ | ||||
|         rc = waitconnect(sockfd, timeout_ms); | ||||
|         break; | ||||
|       default: | ||||
|         /* unknown error, fallthrough and try another address! */ | ||||
|         failf(data, "Failed to connect to IP number %d", aliasindex+1); | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if(0 != rc) { | ||||
|       /* get a new timeout for next attempt */ | ||||
|       after = Curl_tvnow(); | ||||
|       timeout_ms -= Curl_tvdiff(after, before); | ||||
|       if(timeout_ms < 0) { | ||||
|         failf(data, "Connect timeout on IP number %d", aliasindex+1); | ||||
|         break; | ||||
|       } | ||||
|       before = after; | ||||
|       continue; /* try next address */ | ||||
|     } | ||||
|     break; | ||||
|   } | ||||
|   if(0 != rc) { | ||||
|     /* no good connect was made */ | ||||
|     sclose(sockfd); | ||||
|     *sockconn = -1; | ||||
|     return CURLE_COULDNT_CONNECT; | ||||
|   } | ||||
|    | ||||
|   /* now disable the non-blocking mode again */ | ||||
|   Curl_nonblock(sockfd, FALSE); | ||||
|  | ||||
|   if(addr) | ||||
|     /* this is the address we've connected to */ | ||||
|     *addr = (struct in_addr *)remotehost->h_addr_list[aliasindex]; | ||||
| #endif | ||||
|  | ||||
|   /* allow NULL-pointers to get passed in */ | ||||
|   if(sockconn) | ||||
|     *sockconn = sockfd;    /* the socket descriptor we've connected */ | ||||
|  | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
							
								
								
									
										35
									
								
								lib/connect.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								lib/connect.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| #ifndef __CONNECT_H | ||||
| #define __CONNECT_H | ||||
| /***************************************************************************** | ||||
|  *                                  _   _ ____  _      | ||||
|  *  Project                     ___| | | |  _ \| |     | ||||
|  *                             / __| | | | |_) | |     | ||||
|  *                            | (__| |_| |  _ <| |___  | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * In order to be useful for every potential user, curl and libcurl are | ||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||
|  * | ||||
|  * You may opt to use, copy, modify, merge, publish, distribute and/or sell | ||||
|  * copies of the Software, and permit persons to whom the Software is | ||||
|  * furnished to do so, under the terms of the MPL or the MIT/X-derivate | ||||
|  * licenses. You may pick one of these licenses. | ||||
|  * | ||||
|  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||||
|  * KIND, either express or implied. | ||||
|  * | ||||
|  * $Id$ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| int Curl_nonblock(int socket,    /* operate on this */ | ||||
|                   int nonblock   /* TRUE or FALSE */); | ||||
|  | ||||
| CURLcode Curl_connecthost(struct connectdata *conn, | ||||
|                           Curl_addrinfo *host, /* connect to this */ | ||||
|                           long port,      /* connect to this port number */ | ||||
|                           int *sockconn,  /* not set if error is returned */ | ||||
|                           Curl_ipconnect **addr /* the one we used */ | ||||
|                           ); /*  index we used */ | ||||
| #endif | ||||
							
								
								
									
										26
									
								
								lib/cookie.c
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								lib/cookie.c
									
									
									
									
									
								
							| @@ -104,7 +104,8 @@ Example set of cookies: | ||||
| struct Cookie * | ||||
| Curl_cookie_add(struct CookieInfo *c, | ||||
|                 bool httpheader, /* TRUE if HTTP header-style line */ | ||||
|                 char *lineptr) /* first non-space of the line */ | ||||
|                 char *lineptr,   /* first non-space of the line */ | ||||
|                 char *domain)    /* default domain */ | ||||
| { | ||||
|   struct Cookie *clist; | ||||
|   char what[MAX_COOKIE_LINE]; | ||||
| @@ -194,6 +195,10 @@ Curl_cookie_add(struct CookieInfo *c, | ||||
|         ptr++; | ||||
|       semiptr=strchr(ptr, ';'); /* now, find the next semicolon */ | ||||
|     } while(semiptr); | ||||
|  | ||||
|     if(NULL == co->domain) | ||||
|       /* no domain given in the header line, set the default now */ | ||||
|       co->domain=domain?strdup(domain):NULL; | ||||
|   } | ||||
|   else { | ||||
|     /* This line is NOT a HTTP header style line, we do offer support for | ||||
| @@ -369,6 +374,9 @@ Curl_cookie_add(struct CookieInfo *c, | ||||
|           free(clist->maxage); | ||||
|  | ||||
|         *clist = *co;  /* then store all the new data */ | ||||
|  | ||||
|         free(co);   /* free the newly alloced memory */ | ||||
|         co = clist; /* point to the previous struct instead */ | ||||
|       } | ||||
|  | ||||
|     } | ||||
| @@ -418,7 +426,7 @@ struct CookieInfo *Curl_cookie_init(char *file, struct CookieInfo *inc) | ||||
|   } | ||||
|   c->running = FALSE; /* this is not running, this is init */ | ||||
|  | ||||
|   if(strequal(file, "-")) { | ||||
|   if(file && strequal(file, "-")) { | ||||
|     fp = stdin; | ||||
|     fromfile=FALSE; | ||||
|   } | ||||
| @@ -441,7 +449,7 @@ struct CookieInfo *Curl_cookie_init(char *file, struct CookieInfo *inc) | ||||
|       while(*lineptr && isspace((int)*lineptr)) | ||||
|         lineptr++; | ||||
|  | ||||
|       Curl_cookie_add(c, headerline, lineptr); | ||||
|       Curl_cookie_add(c, headerline, lineptr, NULL); | ||||
|     } | ||||
|     if(fromfile) | ||||
|       fclose(fp); | ||||
| @@ -619,7 +627,7 @@ int Curl_cookie_output(struct CookieInfo *c, char *dumphere) | ||||
|   if(c) { | ||||
|     fputs("# Netscape HTTP Cookie File\n" | ||||
|           "# http://www.netscape.com/newsref/std/cookie_spec.html\n" | ||||
|           "# This is generated by libcurl! Edit on your own risk.\n\n", | ||||
|           "# This file was generated by libcurl! Edit at your own risk.\n\n", | ||||
|           out); | ||||
|     co = c->cookies; | ||||
|       | ||||
| @@ -632,13 +640,13 @@ int Curl_cookie_output(struct CookieInfo *c, char *dumphere) | ||||
|               "%u\t" /* expires */ | ||||
|               "%s\t" /* name */ | ||||
|               "%s\n", /* value */ | ||||
|               co->domain, | ||||
|               co->domain?co->domain:"unknown", | ||||
|               co->field1==2?"TRUE":"FALSE", | ||||
|               co->path, | ||||
|               co->path?co->path:"/", | ||||
|               co->secure?"TRUE":"FALSE", | ||||
|               (unsigned int)co->expires, | ||||
|               co->name, | ||||
|               co->value); | ||||
|               co->value?co->value:""); | ||||
|  | ||||
|       co=co->next; | ||||
|     } | ||||
| @@ -681,6 +689,6 @@ int main(int argc, char **argv) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -68,7 +68,13 @@ struct CookieInfo { | ||||
| #define MAX_NAME 256 | ||||
| #define MAX_NAME_TXT "255" | ||||
|  | ||||
| struct Cookie *Curl_cookie_add(struct CookieInfo *, bool, char *); | ||||
| /* | ||||
|  * Add a cookie to the internal list of cookies. The domain argument is only | ||||
|  * used if the header boolean is TRUE. | ||||
|  */ | ||||
| struct Cookie *Curl_cookie_add(struct CookieInfo *, bool header, char *line, | ||||
|                                char *domain); | ||||
|  | ||||
| struct CookieInfo *Curl_cookie_init(char *, struct CookieInfo *); | ||||
| struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool); | ||||
| void Curl_cookie_freelist(struct Cookie *); | ||||
|   | ||||
| @@ -54,7 +54,7 @@ BSC32=bscmake.exe | ||||
| # ADD BSC32 /nologo | ||||
| LINK32=link.exe | ||||
| # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 | ||||
| # ADD LINK32 kernel32.lib wsock32.lib /nologo /dll /map /debug /machine:I386 /out:"Release/libcurl.dll" | ||||
| # ADD LINK32 kernel32.lib ws2_32.lib /nologo /dll /map /debug /machine:I386 /out:"Release/libcurl.dll" | ||||
|  | ||||
| !ELSEIF  "$(CFG)" == "curllib - Win32 Debug" | ||||
|  | ||||
| @@ -81,7 +81,7 @@ BSC32=bscmake.exe | ||||
| # ADD BSC32 /nologo | ||||
| LINK32=link.exe | ||||
| # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept | ||||
| # ADD LINK32 kernel32.lib wsock32.lib /nologo /dll /incremental:no /map /debug /machine:I386 /out:"Debug/libcurl.dll" /pdbtype:sept | ||||
| # ADD LINK32 kernel32.lib ws2_32.lib /nologo /dll /incremental:no /map /debug /machine:I386 /out:"Debug/libcurl.dll" /pdbtype:sept | ||||
| # SUBTRACT LINK32 /nodefaultlib | ||||
|  | ||||
| !ENDIF  | ||||
| @@ -99,6 +99,10 @@ SOURCE=.\base64.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\connect.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\cookie.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
| @@ -247,6 +251,10 @@ SOURCE=.\base64.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\connect.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\cookie.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|   | ||||
							
								
								
									
										33
									
								
								lib/dict.c
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								lib/dict.c
									
									
									
									
									
								
							| @@ -136,7 +136,7 @@ CURLcode Curl_dict(struct connectdata *conn) | ||||
|       nth = atoi(nthdef); | ||||
|     } | ||||
|        | ||||
|     Curl_sendf(conn->firstsocket, conn, | ||||
|     result = Curl_sendf(conn->firstsocket, conn, | ||||
|                         "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" | ||||
|                         "MATCH " | ||||
|                         "%s "    /* database */ | ||||
| @@ -148,13 +148,13 @@ CURLcode Curl_dict(struct connectdata *conn) | ||||
|                         strategy, | ||||
|                         word | ||||
|                         ); | ||||
|      | ||||
|     if(result) | ||||
|       failf(data, "Failed sending DICT request"); | ||||
|     else | ||||
|       result = Curl_Transfer(conn, conn->firstsocket, -1, FALSE, bytecount, | ||||
|                              -1, NULL); /* no upload */       | ||||
|        | ||||
|     if(result) | ||||
|       return result; | ||||
|      | ||||
|   } | ||||
|   else if (strnequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) || | ||||
|            strnequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) || | ||||
| @@ -186,17 +186,17 @@ CURLcode Curl_dict(struct connectdata *conn) | ||||
|       nth = atoi(nthdef); | ||||
|     } | ||||
|        | ||||
|     Curl_sendf(conn->firstsocket, conn, | ||||
|     result = Curl_sendf(conn->firstsocket, conn, | ||||
|                         "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" | ||||
|                         "DEFINE " | ||||
|                         "%s "     /* database */ | ||||
|                         "%s\n"    /* word */ | ||||
|                         "QUIT\n", | ||||
|                 | ||||
|                         database, | ||||
|                word | ||||
|                ); | ||||
|      | ||||
|                         word); | ||||
|     if(result) | ||||
|       failf(data, "Failed sending DICT request"); | ||||
|     else | ||||
|       result = Curl_Transfer(conn, conn->firstsocket, -1, FALSE, bytecount, | ||||
|                              -1, NULL); /* no upload */ | ||||
|      | ||||
| @@ -215,18 +215,17 @@ CURLcode Curl_dict(struct connectdata *conn) | ||||
|         if (ppath[i] == ':') | ||||
|           ppath[i] = ' '; | ||||
|       } | ||||
|       Curl_sendf(conn->firstsocket, conn, | ||||
|       result = Curl_sendf(conn->firstsocket, conn, | ||||
|                           "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" | ||||
|                           "%s\n" | ||||
|                  "QUIT\n", | ||||
|                  ppath); | ||||
|        | ||||
|                           "QUIT\n", ppath); | ||||
|       if(result) | ||||
|         failf(data, "Failed sending DICT request"); | ||||
|       else | ||||
|         result = Curl_Transfer(conn, conn->firstsocket, -1, FALSE, bytecount, | ||||
|                                -1, NULL); | ||||
|        | ||||
|       if(result) | ||||
|         return result; | ||||
|        | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -237,6 +236,6 @@ CURLcode Curl_dict(struct connectdata *conn) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -87,6 +87,6 @@ DllMain ( | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
							
								
								
									
										22
									
								
								lib/easy.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								lib/easy.c
									
									
									
									
									
								
							| @@ -94,7 +94,7 @@ static CURLcode win32_init(void) | ||||
|   WORD wVersionRequested;   | ||||
|   WSADATA wsaData;  | ||||
|   int err;  | ||||
|   wVersionRequested = MAKEWORD(1, 1);  | ||||
|   wVersionRequested = MAKEWORD(2, 0);  | ||||
|      | ||||
|   err = WSAStartup(wVersionRequested, &wsaData);  | ||||
|      | ||||
| @@ -103,14 +103,14 @@ static CURLcode win32_init(void) | ||||
|     /* winsock.dll.     */  | ||||
|     return CURLE_FAILED_INIT;  | ||||
|      | ||||
|   /* Confirm that the Windows Sockets DLL supports 1.1.*/  | ||||
|   /* Confirm that the Windows Sockets DLL supports 2.0.*/  | ||||
|   /* Note that if the DLL supports versions greater */  | ||||
|   /* than 1.1 in addition to 1.1, it will still return */  | ||||
|   /* 1.1 in wVersion since that is the version we */  | ||||
|   /* than 2.0 in addition to 2.0, it will still return */  | ||||
|   /* 2.0 in wVersion since that is the version we */  | ||||
|   /* requested. */  | ||||
|      | ||||
|   if ( LOBYTE( wsaData.wVersion ) != 1 ||  | ||||
|        HIBYTE( wsaData.wVersion ) != 1 ) {  | ||||
|   if ( LOBYTE( wsaData.wVersion ) != 2 ||  | ||||
|        HIBYTE( wsaData.wVersion ) != 0 ) {  | ||||
|     /* Tell the user that we couldn't find a useable */  | ||||
|  | ||||
|     /* winsock.dll. */  | ||||
| @@ -293,6 +293,12 @@ CURL *curl_easy_duphandle(CURL *incurl) | ||||
|   outcurl->progress.flags    = data->progress.flags; | ||||
|   outcurl->progress.callback = data->progress.callback; | ||||
|  | ||||
|   if(data->cookies) | ||||
|     /* If cookies are enabled in the parent handle, we enable them | ||||
|        in the clone as well! */ | ||||
|     outcurl->cookies = Curl_cookie_init(data->cookies->filename, | ||||
|                                         outcurl->cookies); | ||||
|  | ||||
|   /* duplicate all values in 'change' */ | ||||
|   if(data->change.url) { | ||||
|     outcurl->change.url = strdup(data->change.url); | ||||
| @@ -314,6 +320,6 @@ CURL *curl_easy_duphandle(CURL *incurl) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -115,6 +115,6 @@ char *curl_unescape(const char *string, int length) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -201,6 +201,6 @@ CURLcode Curl_file(struct connectdata *conn) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
							
								
								
									
										391
									
								
								lib/formdata.c
									
									
									
									
									
								
							
							
						
						
									
										391
									
								
								lib/formdata.c
									
									
									
									
									
								
							| @@ -80,6 +80,23 @@ Content-Disposition: attachment; filename="inet_ntoa_r.h" | ||||
| Content-Type: text/plain | ||||
| ... | ||||
|  | ||||
|  | ||||
| Content-Disposition: form-data; name="ARRAY: FILE1_+_FILE2_+_FILE3" | ||||
| Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1 | ||||
| ... | ||||
| Content-Disposition: attachment; filename="inet_ntoa_r.h" | ||||
| Content-Type: text/plain | ||||
| ... | ||||
| Content-Disposition: attachment; filename="Makefile.b32.resp" | ||||
| Content-Type: text/plain | ||||
| ... | ||||
| Content-Disposition: attachment; filename="inet_ntoa_r.h" | ||||
| Content-Type: text/plain | ||||
| ... | ||||
|  | ||||
| Content-Disposition: form-data; name="FILECONTENT" | ||||
| ... | ||||
|  | ||||
|   For the old FormParse used by curl_formparse use: | ||||
|  | ||||
|   gcc -DHAVE_CONFIG_H -I../ -g -D_OLD_FORM_DEBUG -o formdata -I../include formdata.c strequal.c | ||||
| @@ -394,7 +411,7 @@ static struct HttpPost * AddHttpPost (char * name, | ||||
|   if(post) { | ||||
|     memset(post, 0, sizeof(struct HttpPost)); | ||||
|     post->name = name; | ||||
|     post->namelength = namelength; | ||||
|     post->namelength = name?(namelength?namelength:(long)strlen(name)):0; | ||||
|     post->contents = value; | ||||
|     post->contentslength = contentslength; | ||||
|     post->contenttype = contenttype; | ||||
| @@ -432,7 +449,7 @@ static struct HttpPost * AddHttpPost (char * name, | ||||
|  * parent_form_info is NULL. | ||||
|  * | ||||
|  ***************************************************************************/ | ||||
| static FormInfo * AddFormInfo (char *value, | ||||
| static FormInfo * AddFormInfo(char *value, | ||||
|                               char *contenttype, | ||||
|                               FormInfo *parent_form_info) | ||||
| { | ||||
| @@ -472,7 +489,7 @@ static FormInfo * AddFormInfo (char *value, | ||||
|  * Returns some valid contenttype for filename. | ||||
|  * | ||||
|  ***************************************************************************/ | ||||
| static const char * ContentTypeForFilename (char *filename, | ||||
| static const char * ContentTypeForFilename (const char *filename, | ||||
| 					    const char *prevtype) | ||||
| { | ||||
|   const char *contenttype = NULL; | ||||
| @@ -528,16 +545,21 @@ static const char * ContentTypeForFilename (char *filename, | ||||
|  ***************************************************************************/ | ||||
| static int AllocAndCopy (char **buffer, int buffer_length) | ||||
| { | ||||
|   char *src = *buffer; | ||||
|   int length; | ||||
|   const char *src = *buffer; | ||||
|   int length, add = 0; | ||||
|   if (buffer_length) | ||||
|     length = buffer_length; | ||||
|   else | ||||
|   else { | ||||
|     length = strlen(*buffer); | ||||
|   *buffer = (char*)malloc(length); | ||||
|     add = 1; | ||||
|   } | ||||
|   *buffer = (char*)malloc(length+add); | ||||
|   if (!*buffer) | ||||
|     return 1; | ||||
|   memcpy(*buffer, src, length); | ||||
|   /* if length unknown do null termination */ | ||||
|   if (add) | ||||
|     (*buffer)[length] = '\0'; | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| @@ -561,11 +583,11 @@ static int AllocAndCopy (char **buffer, int buffer_length) | ||||
|  * | ||||
|  * Simple name/value pair with copied contents: | ||||
|  * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", | ||||
|  * CURLFORM_COPYCONTENTS, "value"); | ||||
|  * CURLFORM_COPYCONTENTS, "value", CURLFORM_END); | ||||
|  * | ||||
|  * name/value pair where only the content pointer is remembered: | ||||
|  * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", | ||||
|  * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10); | ||||
|  * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10, CURLFORM_END); | ||||
|  * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used) | ||||
|  * | ||||
|  * storing a filename (CONTENTTYPE is optional!): | ||||
| @@ -577,204 +599,301 @@ static int AllocAndCopy (char **buffer, int buffer_length) | ||||
|  * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", | ||||
|  * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END); | ||||
|  * | ||||
|  * Returns 0 on success, 1 if the FormInfo allocation fails, 2 if one | ||||
|  * option is given twice for one Form, 3 if a null pointer was given for | ||||
|  * a char *, 4 if the allocation of a FormInfo struct failed, 5 if an | ||||
|  * unknown option was used, 6 if the some FormInfo is not complete (or | ||||
|  * has an error), 7 if a HttpPost struct cannot be allocated, and 8 | ||||
|  * if some allocation for string copying failed. | ||||
|  * Returns: | ||||
|  * FORMADD_OK             on success | ||||
|  * FORMADD_MEMORY         if the FormInfo allocation fails | ||||
|  * FORMADD_OPTION_TWICE   if one option is given twice for one Form | ||||
|  * FORMADD_NULL           if a null pointer was given for a char | ||||
|  * FORMADD_MEMORY         if the allocation of a FormInfo struct failed | ||||
|  * FORMADD_UNKNOWN_OPTION if an unknown option was used | ||||
|  * FORMADD_INCOMPLETE     if the some FormInfo is not complete (or an error) | ||||
|  * FORMADD_MEMORY         if a HttpPost struct cannot be allocated | ||||
|  * FORMADD_MEMORY         if some allocation for string copying failed. | ||||
|  * FORMADD_ILLEGAL_ARRAY  if an illegal option is used in an array | ||||
|  * | ||||
|  ***************************************************************************/ | ||||
|  | ||||
| typedef enum { | ||||
|   FORMADD_OK, /* first, no error */ | ||||
|  | ||||
|   FORMADD_MEMORY, | ||||
|   FORMADD_OPTION_TWICE, | ||||
|   FORMADD_NULL, | ||||
|   FORMADD_UNKNOWN_OPTION, | ||||
|   FORMADD_INCOMPLETE, | ||||
|   FORMADD_ILLEGAL_ARRAY, | ||||
|  | ||||
|   FORMADD_LAST /* last */ | ||||
| } FORMcode; | ||||
|  | ||||
| static | ||||
| int FormAdd(struct HttpPost **httppost, | ||||
| FORMcode FormAdd(struct HttpPost **httppost, | ||||
|                  struct HttpPost **last_post, | ||||
|                  va_list params) | ||||
| { | ||||
|   FormInfo *first_form_info, *current_form_info, *form_info; | ||||
|   int return_value = 0; | ||||
|   FormInfo *first_form, *current_form, *form; | ||||
|   FORMcode return_value = FORMADD_OK; | ||||
|   const char *prevtype = NULL; | ||||
|   struct HttpPost *post = NULL; | ||||
|   CURLformoption next_option; | ||||
|   CURLformoption option; | ||||
|   struct curl_forms *forms = NULL; | ||||
|   const char *array_value; /* value read from an array */ | ||||
|  | ||||
|   first_form_info = (FormInfo *)malloc(sizeof(struct FormInfo)); | ||||
|   if(first_form_info) { | ||||
|     memset(first_form_info, 0, sizeof(FormInfo)); | ||||
|     current_form_info = first_form_info; | ||||
|   /* This is a state variable, that if TRUE means that we're parsing an | ||||
|      array that we got passed to us. If FALSE we're parsing the input | ||||
|      va_list arguments. */ | ||||
|   bool array_state = FALSE; | ||||
|  | ||||
|   /* | ||||
|    * We need to allocate the first struct to fill in. | ||||
|    */ | ||||
|   first_form = (FormInfo *)malloc(sizeof(struct FormInfo)); | ||||
|   if(first_form) { | ||||
|     memset(first_form, 0, sizeof(FormInfo)); | ||||
|     current_form = first_form; | ||||
|   } | ||||
|   else | ||||
|     return 1; | ||||
|     return FORMADD_MEMORY; | ||||
|  | ||||
|   /** TODO: first check whether char * is not NULL | ||||
|       TODO: transfer.c | ||||
|   /* | ||||
|    * Loop through all the options set. | ||||
|    */ | ||||
|   while ( ((next_option = va_arg(params, CURLformoption)) != CURLFORM_END) && | ||||
|           (return_value == 0) ) | ||||
|   { | ||||
|     switch (next_option) | ||||
|     { | ||||
|       case CURLFORM_PTRNAME: | ||||
|         current_form_info->flags |= HTTPPOST_PTRNAME; /* fall through */ | ||||
|       case CURLFORM_COPYNAME: | ||||
|         if (current_form_info->name) | ||||
|           return_value = 2; | ||||
|   while (1) { | ||||
|  | ||||
|     /* break if we have an error to report */ | ||||
|     if (return_value != FORMADD_OK) | ||||
|       break; | ||||
|  | ||||
|     /* first see if we have more parts of the array param */ | ||||
|     if ( array_state ) { | ||||
|       /* get the upcoming option from the given array */ | ||||
|       option = forms->option; | ||||
|       array_value = forms->value; | ||||
|  | ||||
|       forms++; /* advance this to next entry */ | ||||
|       if (CURLFORM_END == option) { | ||||
|         /* end of array state */ | ||||
|         array_state = FALSE; | ||||
|         continue; | ||||
|       } | ||||
|       else { | ||||
|           if (next_option == CURLFORM_PTRNAME) | ||||
|             current_form_info->name = va_arg(params, char *); | ||||
|         /* check that the option is OK in an array */ | ||||
|  | ||||
|         /* Daniel's note: do we really need to do this? */ | ||||
|         if ( (option <= CURLFORM_ARRAY_START) || | ||||
|              (option >= CURLFORM_ARRAY_END) ) { | ||||
|           return_value = FORMADD_ILLEGAL_ARRAY; | ||||
|           break; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     else { | ||||
|       /* This is not array-state, get next option */ | ||||
|       option = va_arg(params, CURLformoption); | ||||
|       if (CURLFORM_END == option) | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     switch (option) { | ||||
|     case CURLFORM_ARRAY: | ||||
|       forms = va_arg(params, struct curl_forms *); | ||||
|       if (forms) | ||||
|         array_state = TRUE; | ||||
|       else | ||||
|         return_value = FORMADD_NULL; | ||||
|       break; | ||||
|  | ||||
|       /* | ||||
|        * Set the Name property. | ||||
|        */ | ||||
|     case CURLFORM_PTRNAME: | ||||
|       current_form->flags |= HTTPPOST_PTRNAME; /* fall through */ | ||||
|     case CURLFORM_COPYNAME: | ||||
|       if (current_form->name) | ||||
|         return_value = FORMADD_OPTION_TWICE; | ||||
|       else { | ||||
|         char *name = va_arg(params, char *); | ||||
|         if (name) | ||||
| 	      current_form_info->name = name; /* store for the moment */ | ||||
|           current_form->name = name; /* store for the moment */ | ||||
|         else | ||||
| 	      return_value = 3; | ||||
| 	  } | ||||
|           return_value = FORMADD_NULL; | ||||
|       } | ||||
|       break; | ||||
|     case CURLFORM_NAMELENGTH: | ||||
|         if (current_form_info->namelength) | ||||
|           return_value = 2; | ||||
|       if (current_form->namelength) | ||||
|         return_value = FORMADD_OPTION_TWICE; | ||||
|       else | ||||
|           current_form_info->namelength = va_arg(params, long); | ||||
|         current_form->namelength = va_arg(params, long); | ||||
|       break; | ||||
|  | ||||
|       /* | ||||
|        * Set the contents property. | ||||
|        */ | ||||
|     case CURLFORM_PTRCONTENTS: | ||||
|         current_form_info->flags |= HTTPPOST_PTRCONTENTS; /* fall through */ | ||||
|       current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */ | ||||
|     case CURLFORM_COPYCONTENTS: | ||||
|         if (current_form_info->value) | ||||
|           return_value = 2; | ||||
|         else { | ||||
|           if (next_option == CURLFORM_PTRCONTENTS) | ||||
|             current_form_info->value = va_arg(params, char *); | ||||
|       if (current_form->value) | ||||
|         return_value = FORMADD_OPTION_TWICE; | ||||
|       else { | ||||
|         char *value = va_arg(params, char *); | ||||
|         if (value) | ||||
| 	      current_form_info->value = value; /* store for the moment */ | ||||
|           current_form->value = value; /* store for the moment */ | ||||
|         else | ||||
| 	      return_value = 3; | ||||
| 	  } | ||||
|           return_value = FORMADD_NULL; | ||||
|       } | ||||
|       break; | ||||
|     case CURLFORM_CONTENTSLENGTH: | ||||
|         if (current_form_info->contentslength) | ||||
|           return_value = 2; | ||||
|       if (current_form->contentslength) | ||||
|         return_value = FORMADD_OPTION_TWICE; | ||||
|       else | ||||
|           current_form_info->contentslength = va_arg(params, long); | ||||
|         current_form->contentslength = va_arg(params, long); | ||||
|       break; | ||||
|       case CURLFORM_FILE: { | ||||
|  | ||||
|       /* Get contents from a given file name */ | ||||
|     case CURLFORM_FILECONTENT: | ||||
|       if (current_form->flags != 0) | ||||
|         return_value = FORMADD_OPTION_TWICE; | ||||
|       else { | ||||
|         char *filename = va_arg(params, char *); | ||||
| 	if (current_form_info->value) { | ||||
|           if (current_form_info->flags & HTTPPOST_FILENAME) { | ||||
|         if (filename) { | ||||
| 	      if (!(current_form_info = AddFormInfo (strdup(filename), | ||||
| 						     NULL, current_form_info))) | ||||
| 		return_value = 4; | ||||
|           current_form->value = strdup(filename); | ||||
|           current_form->flags |= HTTPPOST_READFILE; | ||||
|         } | ||||
|         else | ||||
| 	      return_value = 3; | ||||
|           return_value = FORMADD_NULL; | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|       /* We upload a file */ | ||||
|     case CURLFORM_FILE: | ||||
|       { | ||||
|         const char *filename = NULL; | ||||
|         if (array_state) | ||||
|           filename = array_value; | ||||
|         else | ||||
|           filename = va_arg(params, const char *); | ||||
|         if (current_form->value) { | ||||
|           if (current_form->flags & HTTPPOST_FILENAME) { | ||||
|             if (filename) { | ||||
|               if (!(current_form = AddFormInfo(strdup(filename), | ||||
|                                                NULL, current_form))) | ||||
|                 return_value = FORMADD_MEMORY; | ||||
|             } | ||||
|             else | ||||
|             return_value = 2; | ||||
|               return_value = FORMADD_NULL; | ||||
|           } | ||||
|           else | ||||
|             return_value = FORMADD_OPTION_TWICE; | ||||
|         } | ||||
|         else { | ||||
|           if (filename) | ||||
| 	    current_form_info->value = strdup(filename); | ||||
|             current_form->value = strdup(filename); | ||||
|           else | ||||
| 	    return_value = 3; | ||||
|           current_form_info->flags |= HTTPPOST_FILENAME; | ||||
|             return_value = FORMADD_NULL; | ||||
|           current_form->flags |= HTTPPOST_FILENAME; | ||||
|         } | ||||
|         break; | ||||
|       } | ||||
|       case CURLFORM_CONTENTTYPE: { | ||||
| 	char *contenttype = va_arg(params, char *); | ||||
|         if (current_form_info->contenttype) { | ||||
|           if (current_form_info->flags & HTTPPOST_FILENAME) { | ||||
|     case CURLFORM_CONTENTTYPE: | ||||
|       { | ||||
| 	const char *contenttype = NULL; | ||||
|         if (array_state) | ||||
|           contenttype = array_value; | ||||
|         else | ||||
|           contenttype = va_arg(params, const char *); | ||||
|         if (current_form->contenttype) { | ||||
|           if (current_form->flags & HTTPPOST_FILENAME) { | ||||
|             if (contenttype) { | ||||
|               if (!(current_form_info = AddFormInfo (NULL, | ||||
|               if (!(current_form = AddFormInfo(NULL, | ||||
|                                                strdup(contenttype), | ||||
|                                                      current_form_info))) | ||||
|                 return_value = 4; | ||||
|                                                current_form))) | ||||
|                 return_value = FORMADD_MEMORY; | ||||
|             } | ||||
| 	    else | ||||
| 	      return_value = 3; | ||||
| 	      return_value = FORMADD_NULL; | ||||
|           } | ||||
|           else | ||||
|             return_value = 2; | ||||
|             return_value = FORMADD_OPTION_TWICE; | ||||
|         } | ||||
|         else { | ||||
| 	  if (contenttype) | ||||
| 	    current_form_info->contenttype = strdup(contenttype); | ||||
| 	    current_form->contenttype = strdup(contenttype); | ||||
| 	  else | ||||
| 	    return_value = 3; | ||||
| 	    return_value = FORMADD_NULL; | ||||
| 	} | ||||
|         break; | ||||
|       } | ||||
|     default: | ||||
|         fprintf (stderr, "got unknown CURLFORM_OPTION: %d\n", next_option); | ||||
|         return_value = 5; | ||||
|     }; | ||||
|   }; | ||||
|       fprintf (stderr, "got unknown CURLFORM_OPTION: %d\n", option); | ||||
|       return_value = FORMADD_UNKNOWN_OPTION; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if(FORMADD_OK == return_value) { | ||||
|     /* go through the list, check for copleteness and if everything is | ||||
|      * alright add the HttpPost item otherwise set return_value accordingly */ | ||||
|   form_info = first_form_info; | ||||
|   while (form_info != NULL) | ||||
|   { | ||||
|     if ( (!first_form_info->name) || | ||||
|          (!form_info->value) || | ||||
|          ( (!form_info->namelength) && | ||||
|            (form_info->flags & HTTPPOST_PTRNAME) ) || | ||||
| 	 ( (form_info->contentslength) && | ||||
| 	   (form_info->flags & HTTPPOST_FILENAME) ) || | ||||
| 	 ( (form_info->flags & HTTPPOST_FILENAME) && | ||||
| 	   (form_info->flags & HTTPPOST_PTRCONTENTS) ) | ||||
|      | ||||
|     post = NULL; | ||||
|     for(form = first_form; | ||||
|         form != NULL; | ||||
|         form = form->more) { | ||||
|       if ( ((!form->name || !form->value) && !post) || | ||||
|            ( (form->contentslength) && | ||||
|              (form->flags & HTTPPOST_FILENAME) ) || | ||||
|            ( (form->flags & HTTPPOST_FILENAME) && | ||||
|              (form->flags & HTTPPOST_PTRCONTENTS) ) || | ||||
|            ( (form->flags & HTTPPOST_READFILE) && | ||||
|              (form->flags & HTTPPOST_PTRCONTENTS) ) | ||||
|            ) { | ||||
|       return_value = 6; | ||||
|         return_value = FORMADD_INCOMPLETE; | ||||
|         break; | ||||
|       } | ||||
|       else { | ||||
|       if ( (form_info->flags & HTTPPOST_FILENAME) && | ||||
| 	   (!form_info->contenttype) ) { | ||||
|         if ( (form->flags & HTTPPOST_FILENAME) && | ||||
|              !form->contenttype ) { | ||||
|           /* our contenttype is missing */ | ||||
| 	form_info->contenttype | ||||
| 	  = strdup(ContentTypeForFilename(form_info->value, prevtype)); | ||||
|           form->contenttype | ||||
|             = strdup(ContentTypeForFilename(form->value, prevtype)); | ||||
|         } | ||||
|       if ( !(form_info->flags & HTTPPOST_PTRNAME) && | ||||
| 	   (form_info == first_form_info) ) { | ||||
|         if ( !(form->flags & HTTPPOST_PTRNAME) && | ||||
|              (form == first_form) ) { | ||||
|           /* copy name (without strdup; possibly contains null characters) */ | ||||
| 	if (AllocAndCopy(&form_info->name, form_info->namelength)) { | ||||
| 	  return_value = 8; | ||||
|           if (AllocAndCopy(&form->name, form->namelength)) { | ||||
|             return_value = FORMADD_MEMORY; | ||||
|             break; | ||||
|           } | ||||
|         } | ||||
|       if ( !(form_info->flags & HTTPPOST_FILENAME) && | ||||
| 	   !(form_info->flags & HTTPPOST_PTRCONTENTS) ) { | ||||
|         if ( !(form->flags & HTTPPOST_FILENAME) && | ||||
|              !(form->flags & HTTPPOST_READFILE) &&  | ||||
|              !(form->flags & HTTPPOST_PTRCONTENTS) ) { | ||||
|           /* copy value (without strdup; possibly contains null characters) */ | ||||
| 	if (AllocAndCopy(&form_info->value, form_info->contentslength)) { | ||||
| 	  return_value = 8; | ||||
|           if (AllocAndCopy(&form->value, form->contentslength)) { | ||||
|             return_value = FORMADD_MEMORY; | ||||
|             break; | ||||
|           } | ||||
|         } | ||||
|       if ( (post = AddHttpPost (form_info->name, form_info->namelength, | ||||
|                                 form_info->value, form_info->contentslength, | ||||
|                                 form_info->contenttype, form_info->flags, | ||||
|         if ( (post = AddHttpPost(form->name, form->namelength, | ||||
|                                  form->value, form->contentslength, | ||||
|                                  form->contenttype, form->flags, | ||||
|                                  post, httppost, | ||||
|                                  last_post)) == NULL) { | ||||
|         return_value = 7; | ||||
|           return_value = FORMADD_MEMORY; | ||||
|         } | ||||
|         if (form->contenttype) | ||||
|           prevtype = form->contenttype; | ||||
|       } | ||||
|     } | ||||
|       if (form_info->contenttype) | ||||
| 	prevtype = form_info->contenttype; | ||||
|   } | ||||
|     form_info = form_info->more; | ||||
|   }; | ||||
|  | ||||
|   /* and finally delete the allocated memory */ | ||||
|   form_info = first_form_info; | ||||
|   while (form_info != NULL) { | ||||
|     FormInfo *delete_form_info; | ||||
|   /* always delete the allocated memory before returning */ | ||||
|   form = first_form; | ||||
|   while (form != NULL) { | ||||
|     FormInfo *delete_form; | ||||
|      | ||||
|     delete_form_info = form_info; | ||||
|     form_info = form_info->more; | ||||
|     free (delete_form_info); | ||||
|   }; | ||||
|     delete_form = form; | ||||
|     form = form->more; | ||||
|     free (delete_form); | ||||
|   } | ||||
|  | ||||
|   return return_value; | ||||
| } | ||||
| @@ -1169,6 +1288,8 @@ int main() | ||||
|   char name7[] = "FILE1_+_CONTENTTYPE"; | ||||
|   char name8[] = "FILE1_+_FILE2"; | ||||
|   char name9[] = "FILE1_+_FILE2_+_FILE3"; | ||||
|   char name10[] = "ARRAY: FILE1_+_FILE2_+_FILE3"; | ||||
|   char name11[] = "FILECONTENT"; | ||||
|   char value1[] = "value for simple COPYCONTENTS"; | ||||
|   char value2[] = "value for COPYCONTENTS + CONTENTTYPE"; | ||||
|   char value3[] = "value for PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH"; | ||||
| @@ -1190,6 +1311,7 @@ int main() | ||||
|   char buffer[4096]; | ||||
|   struct HttpPost *httppost=NULL; | ||||
|   struct HttpPost *last_post=NULL; | ||||
|   struct curl_forms forms[4]; | ||||
|  | ||||
|   struct FormData *form; | ||||
|   struct Form formread; | ||||
| @@ -1244,6 +1366,21 @@ int main() | ||||
|                   CURLFORM_COPYNAME, name9, CURLFORM_FILE, value7, | ||||
|                   CURLFORM_FILE, value8, CURLFORM_FILE, value7, CURLFORM_END)) | ||||
|     ++errors; | ||||
|   forms[0].option = CURLFORM_FILE; | ||||
|   forms[0].value  = value7; | ||||
|   forms[1].option = CURLFORM_FILE; | ||||
|   forms[1].value  = value8; | ||||
|   forms[2].option = CURLFORM_FILE; | ||||
|   forms[2].value  = value7; | ||||
|   forms[3].option  = CURLFORM_END; | ||||
|   if (FormAddTest("FILE1 + FILE2 + FILE3 ARRAY test", &httppost, &last_post, | ||||
|                   CURLFORM_COPYNAME, name10, CURLFORM_ARRAY, forms, | ||||
|                   CURLFORM_END)) | ||||
|     ++errors; | ||||
|   if (FormAddTest("FILECONTENT test", &httppost, &last_post, | ||||
|                   CURLFORM_COPYNAME, name11, CURLFORM_FILECONTENT, value7, | ||||
|                   CURLFORM_END)) | ||||
|     ++errors; | ||||
|  | ||||
|   form=Curl_getFormData(httppost, &size); | ||||
|  | ||||
| @@ -1255,12 +1392,12 @@ int main() | ||||
|  | ||||
|     if(-1 == nread) | ||||
|       break; | ||||
|     fwrite(buffer, nread, 1, stderr); | ||||
|     fwrite(buffer, nread, 1, stdout); | ||||
|   } while(1); | ||||
|  | ||||
|   fprintf(stderr, "size: %d\n", size); | ||||
|   fprintf(stdout, "size: %d\n", size); | ||||
|   if (errors) | ||||
|     fprintf(stderr, "\n==> %d Test(s) failed!\n", errors); | ||||
|     fprintf(stdout, "\n==> %d Test(s) failed!\n", errors); | ||||
|   else | ||||
|     fprintf(stdout, "\nAll Tests seem to have worked (please check output)\n"); | ||||
|  | ||||
| @@ -1327,6 +1464,6 @@ int main(int argc, char **argv) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -28,11 +28,10 @@ CURLcode Curl_ftp_done(struct connectdata *conn); | ||||
| CURLcode Curl_ftp_connect(struct connectdata *conn); | ||||
| CURLcode Curl_ftp_disconnect(struct connectdata *conn); | ||||
|  | ||||
| size_t Curl_ftpsendf(int fd, struct connectdata *, const char *fmt, ...); | ||||
| size_t Curl_ftpsendf(struct connectdata *, const char *fmt, ...); | ||||
|  | ||||
| /* The kerberos stuff needs this: */ | ||||
| int Curl_GetFTPResponse(int sockfd, char *buf, | ||||
|                         struct connectdata *conn, | ||||
| int Curl_GetFTPResponse(char *buf, struct connectdata *conn, | ||||
|                         int *ftpcode); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -2131,6 +2131,6 @@ main (ac, av) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -71,6 +71,6 @@ char *curl_getenv(const char *v) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -46,7 +46,7 @@ CURLcode Curl_initinfo(struct SessionHandle *data) | ||||
|  | ||||
|   info->httpcode = 0; | ||||
|   info->httpversion=0; | ||||
|   info->filetime=0; | ||||
|   info->filetime=-1; /* -1 is an illegal time and thus means unknown */ | ||||
|  | ||||
|   return CURLE_OK; | ||||
| } | ||||
| @@ -138,6 +138,6 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -249,6 +249,6 @@ char *getpass(const char *prompt) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
							
								
								
									
										201
									
								
								lib/hostip.c
									
									
									
									
									
								
							
							
						
						
									
										201
									
								
								lib/hostip.c
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___  | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * In order to be useful for every potential user, curl and libcurl are | ||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||
| @@ -55,6 +55,7 @@ | ||||
|  | ||||
| #include "urldata.h" | ||||
| #include "sendf.h" | ||||
| #include "hostip.h" | ||||
|  | ||||
| #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) | ||||
| #include "inet_ntoa_r.h" | ||||
| @@ -65,8 +66,168 @@ | ||||
| #include "memdebug.h" | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * This is a wrapper function for freeing name information in a protocol | ||||
|  * independent way. This takes care of using the appropriate underlaying | ||||
|  * proper function. | ||||
|  */ | ||||
| void Curl_freeaddrinfo(void *freethis) | ||||
| { | ||||
| #ifdef ENABLE_IPV6 | ||||
|   freeaddrinfo(freethis); | ||||
| #else | ||||
|   free(freethis); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| /* --- resolve name or IP-number --- */ | ||||
|  | ||||
| #ifdef ENABLE_IPV6 | ||||
|  | ||||
| #ifdef MALLOCDEBUG | ||||
| /* 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 | ||||
|  * here since they require a bunch of struct types I didn't wanna include | ||||
|  * in memdebug.c | ||||
|  */ | ||||
| int curl_getaddrinfo(char *hostname, char *service, | ||||
|                      struct addrinfo *hints, | ||||
|                      struct addrinfo **result, | ||||
|                      int line, const char *source) | ||||
| { | ||||
|   int res=(getaddrinfo)(hostname, service, hints, result); | ||||
|   if(0 == res) { | ||||
|     /* success */ | ||||
|     if(logfile) | ||||
|       fprintf(logfile, "ADDR %s:%d getaddrinfo() = %p\n", | ||||
|               source, line, *result); | ||||
|   } | ||||
|   else { | ||||
|     if(logfile) | ||||
|       fprintf(logfile, "ADDR %s:%d getaddrinfo() failed\n", | ||||
|               source, line); | ||||
|   } | ||||
|   return res; | ||||
| } | ||||
|  | ||||
| void curl_freeaddrinfo(struct addrinfo *freethis, | ||||
|                        int line, const char *source) | ||||
| { | ||||
|   (freeaddrinfo)(freethis); | ||||
|   if(logfile) | ||||
|     fprintf(logfile, "ADDR %s:%d freeaddrinfo(%p)\n", | ||||
|             source, line, freethis); | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * Return name information about the given hostname and port number. If | ||||
|  * successful, the 'addrinfo' is returned and the forth argument will point to | ||||
|  * memory we need to free after use. That meory *MUST* be freed with | ||||
|  * Curl_freeaddrinfo(), nothing else. | ||||
|  */ | ||||
| Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | ||||
|                                 char *hostname, | ||||
|                                 int port, | ||||
|                                 char **bufp) | ||||
| { | ||||
|   struct addrinfo hints, *res; | ||||
|   int error; | ||||
|   char sbuf[NI_MAXSERV]; | ||||
|  | ||||
|   memset(&hints, 0, sizeof(hints)); | ||||
|   hints.ai_family = PF_UNSPEC; | ||||
|   hints.ai_socktype = SOCK_STREAM; | ||||
|   hints.ai_flags = AI_CANONNAME; | ||||
|   snprintf(sbuf, sizeof(sbuf), "%d", port); | ||||
|   error = getaddrinfo(hostname, sbuf, &hints, &res); | ||||
|   if (error) { | ||||
|     infof(data, "getaddrinfo(3) failed for %s\n", hostname);     | ||||
|     return NULL; | ||||
|   } | ||||
|   *bufp=(char *)res; /* make it point to the result struct */ | ||||
|  | ||||
|   return res; | ||||
| } | ||||
| #else /* following code is IPv4-only */ | ||||
|  | ||||
| #ifndef HAVE_GETHOSTBYNAME_R | ||||
| /** | ||||
|  * Performs a "deep" copy of a hostent into a buffer (returns a pointer to the | ||||
|  * copy). Make absolutely sure the destination buffer is big enough! | ||||
|  * | ||||
|  * Keith McGuigan  | ||||
|  * 10/3/2001 */ | ||||
| static struct hostent* pack_hostent(char* buf, struct hostent* orig) | ||||
| { | ||||
|   char* bufptr; | ||||
|   struct hostent* copy; | ||||
|  | ||||
|   int i; | ||||
|   char* str; | ||||
|   int len; | ||||
|  | ||||
|   bufptr = buf; | ||||
|   copy = (struct hostent*)bufptr; | ||||
|  | ||||
|   bufptr += sizeof(struct hostent); | ||||
|   copy->h_name = bufptr; | ||||
|   len = strlen(orig->h_name) + 1; | ||||
|   strncpy(bufptr, orig->h_name, len); | ||||
|   bufptr += len; | ||||
|  | ||||
|   /* we align on even 64bit boundaries for safety */ | ||||
| #define MEMALIGN(x) (((unsigned long)(x)&0xfffffff8)+8) | ||||
|  | ||||
|   /* This must be aligned properly to work on many CPU architectures! */ | ||||
|   copy->h_aliases = (char**)MEMALIGN(bufptr); | ||||
|  | ||||
|   /* Figure out how many aliases there are */ | ||||
|   for (i = 0; orig->h_aliases[i] != NULL; ++i); | ||||
|  | ||||
|   /* Reserve room for the array */ | ||||
|   bufptr += (i + 1) * sizeof(char*); | ||||
|  | ||||
|   /* Clone all known aliases */ | ||||
|   for(i = 0; (str = orig->h_aliases[i]); i++) { | ||||
|     len = strlen(str) + 1; | ||||
|     strncpy(bufptr, str, len); | ||||
|     copy->h_aliases[i] = bufptr; | ||||
|     bufptr += len; | ||||
|   } | ||||
|   /* Terminate the alias list with a NULL */ | ||||
|   copy->h_aliases[i] = NULL; | ||||
|  | ||||
|   copy->h_addrtype = orig->h_addrtype; | ||||
|   copy->h_length = orig->h_length; | ||||
|      | ||||
|   /* align it for (at least) 32bit accesses */ | ||||
|   bufptr = (char *)MEMALIGN(bufptr); | ||||
|  | ||||
|   copy->h_addr_list = (char**)bufptr; | ||||
|  | ||||
|   /* Figure out how many addresses there are */ | ||||
|   for (i = 0; orig->h_addr_list[i] != NULL; ++i); | ||||
|  | ||||
|   /* Reserve room for the array */ | ||||
|   bufptr += (i + 1) * sizeof(char*); | ||||
|  | ||||
|   i = 0; | ||||
|   len = orig->h_length; | ||||
|   str = orig->h_addr_list[i]; | ||||
|   while (str != NULL) { | ||||
|     memcpy(bufptr, str, len); | ||||
|     copy->h_addr_list[i] = bufptr; | ||||
|     bufptr += len; | ||||
|     str = orig->h_addr_list[++i]; | ||||
|   } | ||||
|   copy->h_addr_list[i] = NULL; | ||||
|  | ||||
|   return copy; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static char *MakeIP(unsigned long num,char *addr, int addr_len) | ||||
| { | ||||
| #if defined(HAVE_INET_NTOA) || defined(HAVE_INET_NTOA_R) | ||||
| @@ -88,29 +249,6 @@ static char *MakeIP(unsigned long num,char *addr, int addr_len) | ||||
|   return (addr); | ||||
| } | ||||
|  | ||||
| #ifdef ENABLE_IPV6 | ||||
| struct addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | ||||
| 			       char *hostname, | ||||
| 			       int port) | ||||
| { | ||||
|   struct addrinfo hints, *res; | ||||
|   int error; | ||||
|   char sbuf[NI_MAXSERV]; | ||||
|  | ||||
|   memset(&hints, 0, sizeof(hints)); | ||||
|   hints.ai_family = PF_UNSPEC; | ||||
|   hints.ai_socktype = SOCK_STREAM; | ||||
|   hints.ai_flags = AI_CANONNAME; | ||||
|   snprintf(sbuf, sizeof(sbuf), "%d", port); | ||||
|   error = getaddrinfo(hostname, sbuf, &hints, &res); | ||||
|   if (error) { | ||||
|     infof(data, "getaddrinfo(3) failed for %s\n", hostname); | ||||
|     return NULL; | ||||
|   } | ||||
|   return res; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| /* The original code to this function was once stolen from the Dancer source | ||||
|    code, written by Bjorn Reese, it has since been patched and modified | ||||
|    considerably. */ | ||||
| @@ -119,8 +257,9 @@ struct addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | ||||
| #define INADDR_NONE (unsigned long) ~0 | ||||
| #endif | ||||
|  | ||||
| struct hostent *Curl_gethost(struct SessionHandle *data, | ||||
| Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | ||||
|                                 char *hostname, | ||||
|                                 int port, | ||||
|                                 char **bufp) | ||||
| { | ||||
|   struct hostent *h = NULL; | ||||
| @@ -137,6 +276,7 @@ struct hostent *Curl_gethost(struct SessionHandle *data, | ||||
|     return NULL; /* major failure */ | ||||
|   *bufp = buf; | ||||
|  | ||||
|   port=0; /* unused in IPv4 code */ | ||||
|   ret = 0; /* to prevent the compiler warning */ | ||||
|  | ||||
|   if ( (in=inet_addr(hostname)) != INADDR_NONE ) { | ||||
| @@ -211,15 +351,22 @@ struct hostent *Curl_gethost(struct SessionHandle *data, | ||||
|       free(buf); | ||||
|       *bufp=NULL; | ||||
|     } | ||||
|     else  | ||||
|       /* we make a copy of the hostent right now, right here, as the | ||||
|          static one we got a pointer to might get removed when we don't | ||||
|          want/expect that */ | ||||
|       h = pack_hostent(buf, h); | ||||
| #endif | ||||
|   } | ||||
|   return (h); | ||||
| } | ||||
|  | ||||
| #endif /* end of IPv4-specific code */ | ||||
|  | ||||
| /* | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
							
								
								
									
										20
									
								
								lib/hostip.h
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								lib/hostip.h
									
									
									
									
									
								
							| @@ -24,12 +24,24 @@ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| struct addrinfo; | ||||
| struct addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | ||||
|                              char *hostname, | ||||
|                              int port); | ||||
| struct hostent; | ||||
| struct SessionHandle; | ||||
|  | ||||
| struct hostent *Curl_gethost(struct SessionHandle *data, | ||||
| /* Get name info */ | ||||
| Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | ||||
|                                 char *hostname, | ||||
|                                 int port, | ||||
|                                 char **bufp); | ||||
| /* free name info */ | ||||
| void Curl_freeaddrinfo(void *freethis); | ||||
|  | ||||
| #ifdef MALLOCDEBUG | ||||
| void curl_freeaddrinfo(struct addrinfo *freethis, | ||||
|                        int line, const char *source); | ||||
| int curl_getaddrinfo(char *hostname, char *service, | ||||
|                      struct addrinfo *hints, | ||||
|                      struct addrinfo **result, | ||||
|                      int line, const char *source); | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										90
									
								
								lib/http.c
									
									
									
									
									
								
							
							
						
						
									
										90
									
								
								lib/http.c
									
									
									
									
									
								
							| @@ -125,22 +125,27 @@ send_buffer *add_buffer_init(void) | ||||
|  * add_buffer_send() sends a buffer and frees all associated memory. | ||||
|  */ | ||||
| static | ||||
| size_t add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in) | ||||
| CURLcode add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in, | ||||
|                          long *bytes_written) | ||||
| { | ||||
|   size_t amount; | ||||
|   CURLcode result; | ||||
|  | ||||
|   if(conn->data->set.verbose) { | ||||
|     fputs("> ", conn->data->set.err); | ||||
|     /* this data _may_ contain binary stuff */ | ||||
|     fwrite(in->buffer, in->size_used, 1, conn->data->set.err); | ||||
|   } | ||||
|  | ||||
|   Curl_write(conn, sockfd, in->buffer, in->size_used, &amount); | ||||
|   result = Curl_write(conn, sockfd, in->buffer, in->size_used, &amount); | ||||
|  | ||||
|   if(in->buffer) | ||||
|     free(in->buffer); | ||||
|   free(in); | ||||
|  | ||||
|   return amount; | ||||
|   *bytes_written = amount; | ||||
|  | ||||
|   return result; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -204,31 +209,18 @@ CURLcode add_buffer(send_buffer *in, const void *inptr, size_t size) | ||||
|  */ | ||||
|  | ||||
| static | ||||
| int GetLine(int sockfd, char *buf, struct connectdata *conn) | ||||
| int GetLine(int sockfd, char *ptr, struct connectdata *conn) | ||||
| { | ||||
|   ssize_t nread; | ||||
|   int read_rc=1; | ||||
|   char *ptr; | ||||
|   struct SessionHandle *data=conn->data; | ||||
|  | ||||
|   ptr=buf; | ||||
|  | ||||
|   /* get us a full line, terminated with a newline */ | ||||
|   for(nread=0; | ||||
|       (nread<BUFSIZE) && read_rc; | ||||
|       nread++, ptr++) { | ||||
|   for(nread=0; (nread<BUFSIZE); nread++, ptr++) { | ||||
|     if((CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &nread)) || | ||||
|        (nread <= 0) || | ||||
|        (*ptr == '\n')) | ||||
|        (nread <= 0) || (*ptr == '\n')) | ||||
|       break; | ||||
|   } | ||||
|   *ptr=0; /* zero terminate */ | ||||
|    | ||||
|   if(data->set.verbose) { | ||||
|     fputs("< ", data->set.err); | ||||
|     fwrite(buf, 1, nread, data->set.err); | ||||
|     fputs("\n", data->set.err); | ||||
|   } | ||||
|   return nread>0?nread:0; | ||||
| } | ||||
|  | ||||
| @@ -264,10 +256,12 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, | ||||
|   int httperror=0; | ||||
|   int subversion=0; | ||||
|   struct SessionHandle *data=conn->data; | ||||
|   CURLcode result; | ||||
|  | ||||
|   infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port); | ||||
|  | ||||
|   /* OK, now send the connect request to the proxy */ | ||||
|   result = | ||||
|     Curl_sendf(tunnelsocket, conn, | ||||
|                "CONNECT %s:%d HTTP/1.0\015\012" | ||||
|                "%s" | ||||
| @@ -277,11 +271,18 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, | ||||
|                (conn->bits.proxy_user_passwd)?conn->allocptr.proxyuserpwd:"", | ||||
|                (data->set.useragent?conn->allocptr.uagent:"") | ||||
|                ); | ||||
|   if(result) { | ||||
|     failf(data, "Failed sending CONNECT to proxy"); | ||||
|     return result; | ||||
|   } | ||||
|  | ||||
|   /* wait for the proxy to send us a HTTP/1.0 200 OK header */ | ||||
|   while(GetLine(tunnelsocket, data->state.buffer, conn)) { | ||||
|     if('\r' == data->state.buffer[0]) | ||||
|       break; /* end of headers */ | ||||
|     if(data->set.verbose) | ||||
|       fprintf(data->set.err, "< %s\n", data->state.buffer); | ||||
|  | ||||
|     if(2 == sscanf(data->state.buffer, "HTTP/1.%d %d", | ||||
|                    &subversion, | ||||
|                    &httperror)) { | ||||
| @@ -341,15 +342,6 @@ CURLcode Curl_http_connect(struct connectdata *conn) | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
| /* called from curl_close() when this struct is about to get wasted, free | ||||
|    protocol-specific resources */ | ||||
| CURLcode Curl_http_close(struct connectdata *conn) | ||||
| { | ||||
|   if(conn->data->state.auth_host) | ||||
|     free(conn->data->state.auth_host); | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
| CURLcode Curl_http_done(struct connectdata *conn) | ||||
| { | ||||
|   struct SessionHandle *data; | ||||
| @@ -371,6 +363,13 @@ CURLcode Curl_http_done(struct connectdata *conn) | ||||
|     *bytecount = http->readbytecount + http->writebytecount; | ||||
|   } | ||||
|  | ||||
|   if(0 == (http->readbytecount + conn->headerbytecount)) { | ||||
|     /* nothing was read from the HTTP server, this can't be right | ||||
|        so we return an error here */ | ||||
|     failf(data, "Empty reply from server\n"); | ||||
|     return CURLE_GOT_NOTHING; | ||||
|   } | ||||
|  | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
| @@ -574,6 +573,10 @@ CURLcode Curl_http(struct connectdata *conn) | ||||
|   } | ||||
|  | ||||
|   do { | ||||
|     /* Use 1.1 unless the use specificly asked for 1.0 */ | ||||
|     const char *httpstring= | ||||
|       data->set.httpversion==CURL_HTTP_VERSION_1_0?"1.0":"1.1"; | ||||
|  | ||||
|     send_buffer *req_buffer; | ||||
|     struct curl_slist *headers=data->set.headers; | ||||
|  | ||||
| @@ -583,7 +586,7 @@ CURLcode Curl_http(struct connectdata *conn) | ||||
|     /* add the main request stuff */ | ||||
|     add_bufferf(req_buffer, | ||||
|                 "%s " /* GET/HEAD/POST/PUT */ | ||||
|                 "%s HTTP/1.1\r\n" /* path */ | ||||
|                 "%s HTTP/%s\r\n" /* path */ | ||||
|                 "%s" /* proxyuserpwd */ | ||||
|                 "%s" /* userpwd */ | ||||
|                 "%s" /* range */ | ||||
| @@ -599,7 +602,7 @@ CURLcode Curl_http(struct connectdata *conn) | ||||
|                  ((HTTPREQ_POST == data->set.httpreq) || | ||||
|                   (HTTPREQ_POST_FORM == data->set.httpreq))?"POST": | ||||
|                  (HTTPREQ_PUT == data->set.httpreq)?"PUT":"GET"), | ||||
|                 ppath, | ||||
|                 ppath, httpstring, | ||||
|                 (conn->bits.proxy_user_passwd && | ||||
|                  conn->allocptr.proxyuserpwd)?conn->allocptr.proxyuserpwd:"", | ||||
|                 (conn->bits.user_passwd && conn->allocptr.userpwd)? | ||||
| @@ -748,9 +751,11 @@ CURLcode Curl_http(struct connectdata *conn) | ||||
|       Curl_pgrsSetUploadSize(data, http->postsize); | ||||
|  | ||||
|       /* fire away the whole request to the server */ | ||||
|       data->info.request_size =  | ||||
|         add_buffer_send(conn->firstsocket, conn, req_buffer); | ||||
|  | ||||
|       result = add_buffer_send(conn->firstsocket, conn, req_buffer, | ||||
|                                &data->info.request_size); | ||||
|       if(result) | ||||
|         failf(data, "Failed sending POST request"); | ||||
|       else | ||||
|         /* setup variables for the upcoming transfer */ | ||||
|         result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE, | ||||
|                                &http->readbytecount, | ||||
| @@ -776,9 +781,11 @@ CURLcode Curl_http(struct connectdata *conn) | ||||
|       Curl_pgrsSetUploadSize(data, data->set.infilesize); | ||||
|  | ||||
|       /* this sends the buffer and frees all the buffer resources */ | ||||
|       data->info.request_size =  | ||||
|         add_buffer_send(conn->firstsocket, conn, req_buffer); | ||||
|  | ||||
|       result = add_buffer_send(conn->firstsocket, conn, req_buffer, | ||||
|                                &data->info.request_size); | ||||
|       if(result) | ||||
|         failf(data, "Faied sending POST request"); | ||||
|       else | ||||
|         /* prepare for transfer */ | ||||
|         result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE, | ||||
|                                &http->readbytecount, | ||||
| @@ -833,9 +840,12 @@ CURLcode Curl_http(struct connectdata *conn) | ||||
|         add_buffer(req_buffer, "\r\n", 2); | ||||
|  | ||||
|       /* issue the request */ | ||||
|       data->info.request_size =  | ||||
|         add_buffer_send(conn->firstsocket, conn, req_buffer); | ||||
|       result = add_buffer_send(conn->firstsocket, conn, req_buffer, | ||||
|                                &data->info.request_size); | ||||
|  | ||||
|       if(result) | ||||
|         failf(data, "Failed sending HTTP request"); | ||||
|       else | ||||
|         /* HTTP GET/HEAD download: */ | ||||
|         result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE, bytecount, | ||||
|                                -1, NULL); /* nothing to upload */ | ||||
| @@ -853,6 +863,6 @@ CURLcode Curl_http(struct connectdata *conn) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -33,7 +33,6 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, | ||||
| CURLcode Curl_http(struct connectdata *conn); | ||||
| CURLcode Curl_http_done(struct connectdata *conn); | ||||
| CURLcode Curl_http_connect(struct connectdata *conn); | ||||
| CURLcode Curl_http_close(struct connectdata *conn); | ||||
|  | ||||
| /* The following functions are defined in http_chunks.c */ | ||||
| void Curl_httpchunk_init(struct connectdata *conn); | ||||
|   | ||||
| @@ -225,6 +225,6 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -129,6 +129,6 @@ char *Curl_if2ip(char *interface, char *buf, int buf_size) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
							
								
								
									
										28
									
								
								lib/krb4.c
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								lib/krb4.c
									
									
									
									
									
								
							| @@ -194,7 +194,7 @@ krb4_auth(void *app_data, struct connectdata *conn) | ||||
|   u_int32_t cs; | ||||
|   struct krb4_data *d = app_data; | ||||
|   struct sockaddr_in *localaddr  = (struct sockaddr_in *)LOCAL_ADDR; | ||||
|   char *host = conn->hp->h_name; | ||||
|   char *host = conn->hostaddr->h_name; | ||||
|   ssize_t nread; | ||||
|   int l = sizeof(conn->local_addr); | ||||
|  | ||||
| @@ -245,12 +245,12 @@ krb4_auth(void *app_data, struct connectdata *conn) | ||||
|     return AUTH_CONTINUE; | ||||
|   } | ||||
|  | ||||
|   Curl_ftpsendf(conn->firstsocket, conn, "ADAT %s", p); | ||||
|   if(Curl_ftpsendf(conn, "ADAT %s", p)) | ||||
|     return -2; | ||||
|  | ||||
|   nread = Curl_GetFTPResponse(conn->firstsocket, | ||||
|                               conn->data->state.buffer, conn, NULL); | ||||
|   nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, NULL); | ||||
|   if(nread < 0) | ||||
|     return /*CURLE_OPERATION_TIMEOUTED*/-1; | ||||
|     return -1; | ||||
|   free(p); | ||||
|  | ||||
|   if(/*ret != COMPLETE*/conn->data->state.buffer[0] != '2'){ | ||||
| @@ -313,10 +313,10 @@ void Curl_krb_kauth(struct connectdata *conn) | ||||
|  | ||||
|   save = Curl_set_command_prot(conn, prot_private); | ||||
|  | ||||
|   Curl_ftpsendf(conn->firstsocket, conn, | ||||
|                 "SITE KAUTH %s", conn->data->state.user); | ||||
|   if(Curl_ftpsendf(conn, "SITE KAUTH %s", conn->data->state.user)) | ||||
|     return; | ||||
|  | ||||
|   nread = Curl_GetFTPResponse(conn->firstsocket, conn->data->state.buffer, | ||||
|   nread = Curl_GetFTPResponse(conn->data->state.buffer, | ||||
|                               conn, NULL); | ||||
|   if(nread < 0) | ||||
|     return /*CURLE_OPERATION_TIMEOUTED*/; | ||||
| @@ -363,7 +363,7 @@ void Curl_krb_kauth(struct connectdata *conn) | ||||
|   if (strcmp ((char*)tktcopy.dat + 8, | ||||
|               KRB_TICKET_GRANTING_TICKET) != 0) { | ||||
|     afs_string_to_key (passwd, | ||||
|                        krb_realmofhost(/*hostname*/conn->hp->h_name), | ||||
|                        krb_realmofhost(conn->hostaddr->h_name), | ||||
|                        &key); | ||||
|     des_key_sched (&key, schedule); | ||||
|     des_pcbc_encrypt((des_cblock*)tkt.dat, (des_cblock*)tktcopy.dat, | ||||
| @@ -380,10 +380,10 @@ void Curl_krb_kauth(struct connectdata *conn) | ||||
|   } | ||||
|   memset (tktcopy.dat, 0, tktcopy.length); | ||||
|  | ||||
|   Curl_ftpsendf(conn->firstsocket, conn, | ||||
|                 "SITE KAUTH %s %s", name, p); | ||||
|   if(Curl_ftpsendf(conn, "SITE KAUTH %s %s", name, p)) | ||||
|     return; | ||||
|  | ||||
|   nread = Curl_GetFTPResponse(conn->firstsocket, conn->data->state.buffer, | ||||
|   nread = Curl_GetFTPResponse(conn->data->state.buffer, | ||||
|                               conn, NULL); | ||||
|   if(nread < 0) | ||||
|     return /*CURLE_OPERATION_TIMEOUTED*/; | ||||
| @@ -397,6 +397,6 @@ void Curl_krb_kauth(struct connectdata *conn) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
							
								
								
									
										10
									
								
								lib/ldap.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								lib/ldap.c
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___  | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * In order to be useful for every potential user, curl and libcurl are | ||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||
| @@ -47,6 +47,7 @@ | ||||
| #include <curl/curl.h> | ||||
| #include "sendf.h" | ||||
| #include "escape.h" | ||||
| #include "transfer.h" | ||||
|  | ||||
| #define _MPRINTF_REPLACE /* use our functions only */ | ||||
| #include <curl/mprintf.h> | ||||
| @@ -211,6 +212,9 @@ CURLcode Curl_ldap(struct connectdata *conn) | ||||
|   } | ||||
|   DynaClose(); | ||||
|  | ||||
|   /* no data to transfer */ | ||||
|   Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); | ||||
|    | ||||
|   return status; | ||||
| } | ||||
|  | ||||
| @@ -218,6 +222,6 @@ CURLcode Curl_ldap(struct connectdata *conn) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -31,4 +31,6 @@ EXPORTS | ||||
|  	curl_mvfprintf @ 22 ; | ||||
| 	curl_strequal @ 23 ; | ||||
| 	curl_strnequal @ 24 ; | ||||
|         curl_easy_duphandle @ 25 ; | ||||
|         curl_formadd @ 26 ; | ||||
|  | ||||
|   | ||||
| @@ -60,14 +60,18 @@ FILE *logfile; | ||||
| /* this sets the log file name */ | ||||
| void curl_memdebug(const char *logname) | ||||
| { | ||||
|   if(logname) | ||||
|     logfile = fopen(logname, "w"); | ||||
|   else | ||||
|     logfile = stderr; | ||||
| } | ||||
|  | ||||
|  | ||||
| void *curl_domalloc(size_t size, int line, const char *source) | ||||
| { | ||||
|   void *mem=(malloc)(size); | ||||
|   fprintf(logfile?logfile:stderr, "MEM %s:%d malloc(%d) = %p\n", | ||||
|   if(logfile) | ||||
|     fprintf(logfile, "MEM %s:%d malloc(%d) = %p\n", | ||||
|             source, line, size, mem); | ||||
|   return mem; | ||||
| } | ||||
| @@ -85,7 +89,8 @@ char *curl_dostrdup(const char *str, int line, const char *source) | ||||
|  | ||||
|   mem=(strdup)(str); | ||||
|   len=strlen(str)+1; | ||||
|   fprintf(logfile?logfile:stderr, "MEM %s:%d strdup(%p) (%d) = %p\n", | ||||
|   if(logfile) | ||||
|     fprintf(logfile, "MEM %s:%d strdup(%p) (%d) = %p\n", | ||||
|             source, line, str, len, mem); | ||||
|   return mem; | ||||
| } | ||||
| @@ -93,7 +98,8 @@ char *curl_dostrdup(const char *str, int line, const char *source) | ||||
| void *curl_dorealloc(void *ptr, size_t size, int line, const char *source) | ||||
| { | ||||
|   void *mem=(realloc)(ptr, size); | ||||
|   fprintf(logfile?logfile:stderr, "MEM %s:%d realloc(%p, %d) = %p\n", | ||||
|   if(logfile) | ||||
|     fprintf(logfile, "MEM %s:%d realloc(%p, %d) = %p\n", | ||||
|             source, line, ptr, size, mem); | ||||
|   return mem; | ||||
| } | ||||
| @@ -108,14 +114,15 @@ void curl_dofree(void *ptr, int line, const char *source) | ||||
|  | ||||
|   (free)(ptr); | ||||
|  | ||||
|   fprintf(logfile?logfile:stderr, "MEM %s:%d free(%p)\n", | ||||
|           source, line, ptr); | ||||
|   if(logfile) | ||||
|     fprintf(logfile, "MEM %s:%d free(%p)\n", source, line, ptr); | ||||
| } | ||||
|  | ||||
| int curl_socket(int domain, int type, int protocol, int line, char *source) | ||||
| { | ||||
|   int sockfd=(socket)(domain, type, protocol); | ||||
|   fprintf(logfile?logfile:stderr, "FD %s:%d socket() = %d\n", | ||||
|   if(logfile) | ||||
|     fprintf(logfile, "FD %s:%d socket() = %d\n", | ||||
|             source, line, sockfd); | ||||
|   return sockfd; | ||||
| } | ||||
| @@ -124,7 +131,8 @@ int curl_accept(int s, struct sockaddr *addr, socklen_t *addrlen, | ||||
|                 int line, const char *source) | ||||
| { | ||||
|   int sockfd=(accept)(s, addr, addrlen); | ||||
|   fprintf(logfile?logfile:stderr, "FD %s:%d accept() = %d\n", | ||||
|   if(logfile) | ||||
|     fprintf(logfile, "FD %s:%d accept() = %d\n", | ||||
|             source, line, sockfd); | ||||
|   return sockfd; | ||||
| } | ||||
| @@ -133,7 +141,8 @@ int curl_accept(int s, struct sockaddr *addr, socklen_t *addrlen, | ||||
| int curl_sclose(int sockfd, int line, char *source) | ||||
| { | ||||
|   int res=sclose(sockfd); | ||||
|   fprintf(logfile?logfile:stderr, "FD %s:%d sclose(%d)\n", | ||||
|   if(logfile) | ||||
|     fprintf(logfile, "FD %s:%d sclose(%d)\n", | ||||
|             source, line, sockfd); | ||||
|   return res; | ||||
| } | ||||
| @@ -142,7 +151,8 @@ FILE *curl_fopen(const char *file, const char *mode, | ||||
|                  int line, const char *source) | ||||
| { | ||||
|   FILE *res=(fopen)(file, mode); | ||||
|   fprintf(logfile?logfile:stderr, "FILE %s:%d fopen(\"%s\") = %p\n", | ||||
|   if(logfile) | ||||
|     fprintf(logfile, "FILE %s:%d fopen(\"%s\") = %p\n", | ||||
|             source, line, file, res); | ||||
|   return res; | ||||
| } | ||||
| @@ -150,7 +160,8 @@ FILE *curl_fopen(const char *file, const char *mode, | ||||
| int curl_fclose(FILE *file, int line, const char *source) | ||||
| { | ||||
|   int res=(fclose)(file); | ||||
|   fprintf(logfile?logfile:stderr, "FILE %s:%d fclose(%p)\n", | ||||
|   if(logfile) | ||||
|     fprintf(logfile, "FILE %s:%d fclose(%p)\n", | ||||
|             source, line, file); | ||||
|   return res; | ||||
| } | ||||
| @@ -161,6 +172,6 @@ int curl_fclose(FILE *file, int line, const char *source) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -6,6 +6,8 @@ | ||||
| #include <memory.h> | ||||
| #endif | ||||
|  | ||||
| extern FILE *logfile; | ||||
|  | ||||
| /* memory functions */ | ||||
| void *curl_domalloc(size_t size, int line, const char *source); | ||||
| void *curl_dorealloc(void *ptr, size_t size, int line, const char *source); | ||||
| @@ -35,6 +37,11 @@ int curl_fclose(FILE *file, int line, const char *source); | ||||
| #define accept(sock,addr,len)\ | ||||
|  curl_accept(sock,addr,len,__LINE__,__FILE__) | ||||
|  | ||||
| #define getaddrinfo(host,serv,hint,res) \ | ||||
|   curl_getaddrinfo(host,serv,hint,res,__LINE__,__FILE__) | ||||
| #define freeaddrinfo(data) \ | ||||
|   curl_freeaddrinfo(data,__LINE__,__FILE__) | ||||
|  | ||||
| /* sclose is probably already defined, redefine it! */ | ||||
| #undef sclose | ||||
| #define sclose(sockfd) curl_sclose(sockfd,__LINE__,__FILE__) | ||||
|   | ||||
| @@ -1237,6 +1237,6 @@ int main() | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -206,6 +206,6 @@ int main(int argc, char **argv) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___  | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * In order to be useful for every potential user, curl and libcurl are | ||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||
| @@ -70,7 +70,7 @@ static char *max5data(double bytes, char *max5) | ||||
|   } | ||||
|   if(bytes < (100*ONE_MEGABYTE)) { | ||||
|     /* 'XX.XM' is good as long as we're less than 100 megs */ | ||||
|     sprintf(max5, "%2.1fM", bytes/ONE_MEGABYTE); | ||||
|     sprintf(max5, "%4.1fM", bytes/ONE_MEGABYTE); | ||||
|     return max5; | ||||
|   } | ||||
|   sprintf(max5, "%4dM", (int)bytes/ONE_MEGABYTE); | ||||
| @@ -118,16 +118,16 @@ void Curl_pgrsTime(struct SessionHandle *data, timerid timer) | ||||
|     break; | ||||
|  | ||||
|   case TIMER_NAMELOOKUP: | ||||
|     data->progress.t_nslookup += Curl_tvdiff(Curl_tvnow(), | ||||
|                                         data->progress.t_startsingle); | ||||
|     data->progress.t_nslookup += | ||||
|       (double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000; | ||||
|     break; | ||||
|   case TIMER_CONNECT: | ||||
|     data->progress.t_connect += Curl_tvdiff(Curl_tvnow(), | ||||
|                                        data->progress.t_startsingle); | ||||
|     data->progress.t_connect += | ||||
|       (double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000; | ||||
|     break; | ||||
|   case TIMER_PRETRANSFER: | ||||
|     data->progress.t_pretransfer += Curl_tvdiff(Curl_tvnow(), | ||||
|                                            data->progress.t_startsingle); | ||||
|     data->progress.t_pretransfer += | ||||
|       (double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000; | ||||
|     break; | ||||
|   case TIMER_POSTRANSFER: | ||||
|     /* this is the normal end-of-transfer thing */ | ||||
| @@ -187,12 +187,14 @@ int Curl_pgrsUpdate(struct connectdata *conn) | ||||
|  | ||||
|   double total_transfer; | ||||
|   double total_expected_transfer; | ||||
|   double timespent; | ||||
|  | ||||
|   struct SessionHandle *data = conn->data; | ||||
|  | ||||
|   int nowindex = data->progress.speeder_c% CURR_TIME; | ||||
|   int checkindex; | ||||
|   int count; | ||||
|  | ||||
|   int countindex; /* amount of seconds stored in the speeder array */ | ||||
|  | ||||
|   char time_left[10]; | ||||
|   char time_total[10]; | ||||
| @@ -222,14 +224,18 @@ int Curl_pgrsUpdate(struct connectdata *conn) | ||||
|  | ||||
|   now = Curl_tvnow(); /* what time is it */ | ||||
|  | ||||
|   /* The exact time spent so far */ | ||||
|   data->progress.timespent = Curl_tvdiff (now, data->progress.start); | ||||
|   /* The exact time spent so far (from the start) */ | ||||
|   timespent = (double)Curl_tvdiff (now, data->progress.start)/1000; | ||||
|  | ||||
|   data->progress.timespent = (long)timespent; | ||||
|  | ||||
|   /* The average download speed this far */ | ||||
|   data->progress.dlspeed = data->progress.downloaded/(data->progress.timespent!=0.0?data->progress.timespent:1.0); | ||||
|   data->progress.dlspeed = | ||||
|     data->progress.downloaded/(timespent>0.01?timespent:1); | ||||
|  | ||||
|   /* The average upload speed this far */ | ||||
|   data->progress.ulspeed = data->progress.uploaded/(data->progress.timespent!=0.0?data->progress.timespent:1.0); | ||||
|   data->progress.ulspeed = | ||||
|     data->progress.uploaded/(timespent>0.01?timespent:1); | ||||
|  | ||||
|   if(data->progress.lastshow == Curl_tvlong(now)) | ||||
|     return 0; /* never update this more than once a second if the end isn't  | ||||
| @@ -237,24 +243,56 @@ int Curl_pgrsUpdate(struct connectdata *conn) | ||||
|   data->progress.lastshow = now.tv_sec; | ||||
|  | ||||
|   /* Let's do the "current speed" thing, which should use the fastest | ||||
|          of the dl/ul speeds */ | ||||
|      of the dl/ul speeds. Store the fasted speed at entry 'nowindex'. */ | ||||
|   data->progress.speeder[ nowindex ] = | ||||
|     data->progress.downloaded>data->progress.uploaded? | ||||
|     data->progress.downloaded:data->progress.uploaded; | ||||
|   data->progress.speeder_c++; /* increase */ | ||||
|   count = ((data->progress.speeder_c>=CURR_TIME)? | ||||
|  | ||||
|   /* remember the exact time for this moment */ | ||||
|   data->progress.speeder_time [ nowindex ] = now; | ||||
|  | ||||
|   /* advance our speeder_c counter, which is increased every time we get | ||||
|      here and we expect it to never wrap as 2^32 is a lot of seconds! */ | ||||
|   data->progress.speeder_c++; | ||||
|  | ||||
|   /* figure out how many index entries of data we have stored in our speeder | ||||
|      array. With N_ENTRIES filled in, we have about N_ENTRIES-1 seconds of | ||||
|      transfer. Imagine, after one second we have filled in two entries, | ||||
|      after two seconds we've filled in three entries etc. */ | ||||
|   countindex = ((data->progress.speeder_c>=CURR_TIME)? | ||||
|                 CURR_TIME:data->progress.speeder_c) - 1; | ||||
|  | ||||
|   /* first of all, we don't do this if there's no counted seconds yet */ | ||||
|   if(countindex) { | ||||
|     long span_ms; | ||||
|  | ||||
|     /* Get the index position to compare with the 'nowindex' position. | ||||
|        Get the oldest entry possible. While we have less than CURR_TIME | ||||
|        entries, the first entry will remain the oldest. */ | ||||
|     checkindex = (data->progress.speeder_c>=CURR_TIME)? | ||||
|       data->progress.speeder_c%CURR_TIME:0; | ||||
|  | ||||
|   /* find out the average speed the last CURR_TIME seconds */ | ||||
|     /* Figure out the exact time for the time span */ | ||||
|     span_ms = Curl_tvdiff(now, | ||||
|                           data->progress.speeder_time[checkindex]); | ||||
|  | ||||
|     /* Calculate the average speed the last 'countindex' seconds */ | ||||
|     data->progress.current_speed = | ||||
|       (data->progress.speeder[nowindex]- | ||||
|      data->progress.speeder[checkindex])/(count?count:1); | ||||
|        data->progress.speeder[checkindex])/((double)span_ms/1000); | ||||
|   } | ||||
|   else | ||||
|     /* the first second we use the main average */ | ||||
|     data->progress.current_speed = | ||||
|       (data->progress.ulspeed>data->progress.dlspeed)? | ||||
|       data->progress.ulspeed:data->progress.dlspeed; | ||||
|  | ||||
|   if(data->progress.flags & PGRS_HIDE) | ||||
|     return 0; | ||||
|  | ||||
|   else if(data->set.fprogress) { | ||||
|     /* There's a callback set, so we call that instead of writing | ||||
|        anything ourselves. This really is the way to go. */ | ||||
|     result= data->set.fprogress(data->set.progress_client, | ||||
|                                 data->progress.size_dl, | ||||
|                                 data->progress.downloaded, | ||||
| @@ -337,6 +375,6 @@ int Curl_pgrsUpdate(struct connectdata *conn) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -413,33 +413,34 @@ sec_prot_internal(struct connectdata *conn, int level) | ||||
|   } | ||||
|  | ||||
|   if(level){ | ||||
|     Curl_ftpsendf(conn->firstsocket, conn, | ||||
|                   "PBSZ %u", s); | ||||
|     /* wait for feedback */ | ||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, | ||||
|                                 conn->data->state.buffer, conn, NULL); | ||||
|     if(Curl_ftpsendf(conn, "PBSZ %u", s)) | ||||
|       return -1; | ||||
|  | ||||
|     nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, NULL); | ||||
|     if(nread < 0) | ||||
|       return /*CURLE_OPERATION_TIMEOUTED*/-1; | ||||
|     if(/*ret != COMPLETE*/conn->data->state.buffer[0] != '2'){ | ||||
|       return -1; | ||||
|  | ||||
|     if(conn->data->state.buffer[0] != '2'){ | ||||
|       failf(conn->data, "Failed to set protection buffer size.\n"); | ||||
|       return -1; | ||||
|     } | ||||
|     conn->buffer_size = s; | ||||
|     p = strstr(/*reply_string*/conn->data->state.buffer, "PBSZ="); | ||||
|  | ||||
|     p = strstr(conn->data->state.buffer, "PBSZ="); | ||||
|     if(p) | ||||
|       sscanf(p, "PBSZ=%u", &s); | ||||
|     if(s < conn->buffer_size) | ||||
|       conn->buffer_size = s; | ||||
|   } | ||||
|  | ||||
|   Curl_ftpsendf(conn->firstsocket, conn, | ||||
|                 "PROT %c", level["CSEP"]); | ||||
|   /* wait for feedback */ | ||||
|   nread = Curl_GetFTPResponse(conn->firstsocket, | ||||
|                               conn->data->state.buffer, conn, NULL); | ||||
|   if(Curl_ftpsendf(conn, "PROT %c", level["CSEP"])) | ||||
|     return -1; | ||||
|  | ||||
|   nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, NULL); | ||||
|   if(nread < 0) | ||||
|     return /*CURLE_OPERATION_TIMEOUTED*/-1; | ||||
|   if(/*ret != COMPLETE*/conn->data->state.buffer[0] != '2'){ | ||||
|     return -1; | ||||
|  | ||||
|   if(conn->data->state.buffer[0] != '2'){ | ||||
|     failf(conn->data, "Failed to set protection level.\n"); | ||||
|     return -1; | ||||
|   } | ||||
| @@ -473,6 +474,7 @@ Curl_sec_login(struct connectdata *conn) | ||||
|   struct Curl_sec_client_mech **m; | ||||
|   ssize_t nread; | ||||
|   struct SessionHandle *data=conn->data; | ||||
|   int ftpcode; | ||||
|  | ||||
|   for(m = mechs; *m && (*m)->name; m++) { | ||||
|     void *tmp; | ||||
| @@ -489,31 +491,35 @@ Curl_sec_login(struct connectdata *conn) | ||||
|       continue; | ||||
|     } | ||||
|     infof(data, "Trying %s...\n", (*m)->name); | ||||
|     /*ret = command("AUTH %s", (*m)->name);***/ | ||||
|     Curl_ftpsendf(conn->firstsocket, conn, | ||||
|                   "AUTH %s", (*m)->name); | ||||
|     /* wait for feedback */ | ||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, | ||||
|                                 conn->data->state.buffer, conn, NULL); | ||||
|  | ||||
|     if(Curl_ftpsendf(conn, "AUTH %s", (*m)->name)) | ||||
|       return -1; | ||||
|  | ||||
|     nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, &ftpcode); | ||||
|     if(nread < 0) | ||||
|       return /*CURLE_OPERATION_TIMEOUTED*/-1; | ||||
|     if(/*ret != CONTINUE*/conn->data->state.buffer[0] != '3'){ | ||||
|       if(/*code == 504*/strncmp(conn->data->state.buffer,"504",3) == 0) { | ||||
|       return -1; | ||||
|  | ||||
|     if(conn->data->state.buffer[0] != '3'){ | ||||
|       switch(ftpcode) { | ||||
|       case 504: | ||||
|         infof(data, | ||||
|               "%s is not supported by the server.\n", (*m)->name); | ||||
|       } | ||||
|       else if(/*code == 534*/strncmp(conn->data->state.buffer,"534",3) == 0) { | ||||
|         break; | ||||
|       case 534: | ||||
|         infof(data, "%s rejected as security mechanism.\n", (*m)->name); | ||||
|       } | ||||
|       else if(/*ret == ERROR*/conn->data->state.buffer[0] == '5') { | ||||
|         break; | ||||
|       default: | ||||
|         if(conn->data->state.buffer[0] == '5') { | ||||
|           infof(data, "The server doesn't support the FTP " | ||||
|                 "security extensions.\n"); | ||||
|           return -1; | ||||
|         } | ||||
|         break; | ||||
|       } | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     ret = (*(*m)->auth)(conn->app_data, /*host***/conn); | ||||
|     ret = (*(*m)->auth)(conn->app_data, conn); | ||||
| 	 | ||||
|     if(ret == AUTH_CONTINUE) | ||||
|       continue; | ||||
| @@ -551,6 +557,6 @@ Curl_sec_end(struct connectdata *conn) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
							
								
								
									
										17
									
								
								lib/sendf.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								lib/sendf.c
									
									
									
									
									
								
							| @@ -140,17 +140,20 @@ void Curl_failf(struct SessionHandle *data, const char *fmt, ...) | ||||
| { | ||||
|   va_list ap; | ||||
|   va_start(ap, fmt); | ||||
|   if(data->set.errorbuffer) | ||||
|   if(data->set.errorbuffer && !data->state.errorbuf) { | ||||
|     vsnprintf(data->set.errorbuffer, CURL_ERROR_SIZE, fmt, ap); | ||||
|     data->state.errorbuf = TRUE; /* wrote error string */ | ||||
|   } | ||||
|   va_end(ap); | ||||
| } | ||||
|  | ||||
| /* Curl_sendf() sends formated data to the server */ | ||||
| size_t Curl_sendf(int sockfd, struct connectdata *conn, | ||||
| CURLcode Curl_sendf(int sockfd, struct connectdata *conn, | ||||
|                     const char *fmt, ...) | ||||
| { | ||||
|   struct SessionHandle *data = conn->data; | ||||
|   size_t bytes_written; | ||||
|   CURLcode result; | ||||
|   char *s; | ||||
|   va_list ap; | ||||
|   va_start(ap, fmt); | ||||
| @@ -162,11 +165,11 @@ size_t Curl_sendf(int sockfd, struct connectdata *conn, | ||||
|     fprintf(data->set.err, "> %s", s); | ||||
|  | ||||
|   /* Write the buffer to the socket */ | ||||
|   Curl_write(conn, sockfd, s, strlen(s), &bytes_written); | ||||
|   result = Curl_write(conn, sockfd, s, strlen(s), &bytes_written); | ||||
|  | ||||
|   free(s); /* free the output string */ | ||||
|  | ||||
|   return bytes_written; | ||||
|   return result; | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -211,7 +214,7 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd, | ||||
| #endif | ||||
|  | ||||
|   *written = bytes_written; | ||||
|   return CURLE_OK; | ||||
|   return (bytes_written==len)?CURLE_OK:CURLE_WRITE_ERROR; | ||||
| } | ||||
|  | ||||
| /* client_write() sends data to the write callback(s) | ||||
| @@ -296,6 +299,6 @@ CURLcode Curl_read(struct connectdata *conn, int sockfd, | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -23,7 +23,7 @@ | ||||
|  * $Id$ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| size_t Curl_sendf(int fd, struct connectdata *, const char *fmt, ...); | ||||
| CURLcode Curl_sendf(int fd, struct connectdata *, const char *fmt, ...); | ||||
| void Curl_infof(struct SessionHandle *, const char *fmt, ...); | ||||
| void Curl_failf(struct SessionHandle *, const char *fmt, ...); | ||||
|  | ||||
|   | ||||
							
								
								
									
										19
									
								
								lib/setup.h
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								lib/setup.h
									
									
									
									
									
								
							| @@ -125,8 +125,8 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO) | ||||
|  | ||||
| #else | ||||
| #define sclose(x) close(x) | ||||
| #define sread(x,y,z) read(x,y,z) | ||||
| #define swrite(x,y,z) write(x,y,z) | ||||
| #define sread(x,y,z) recv(x,y,z,0) | ||||
| #define swrite(x,y,z) send(x,y,z,0) | ||||
| #define myalarm(x) alarm(x) | ||||
|  | ||||
| #define PATH_CHAR     ":" | ||||
| @@ -144,4 +144,19 @@ int fileno( FILE *stream); | ||||
|  | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * Curl_addrinfo MUST be used for name resolving information. | ||||
|  * Information regarding a single IP witin a Curl_addrinfo MUST be stored in | ||||
|  * a Curl_ipconnect struct. | ||||
|  */ | ||||
| #ifdef ENABLE_IPV6 | ||||
| typedef struct addrinfo Curl_addrinfo; | ||||
| typedef struct addrinfo Curl_ipconnect; | ||||
| #else | ||||
| typedef struct hostent Curl_addrinfo; | ||||
| typedef struct in_addr Curl_ipconnect; | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| #endif /* __CONFIG_H */ | ||||
|   | ||||
| @@ -51,7 +51,8 @@ CURLcode Curl_speedcheck(struct SessionHandle *data, | ||||
|        for "low speed time" seconds we consider that enough reason | ||||
|        to abort the download. */ | ||||
|      | ||||
|     if( Curl_tvdiff(now, data->state.keeps_speed) > data->set.low_speed_time) { | ||||
|     if( (Curl_tvdiff(now, data->state.keeps_speed)/1000) > | ||||
|         data->set.low_speed_time) { | ||||
|       /* we have been this slow for long enough, now die */ | ||||
|       failf(data, | ||||
| 	    "Operation too slow. " | ||||
| @@ -72,6 +73,6 @@ CURLcode Curl_speedcheck(struct SessionHandle *data, | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
							
								
								
									
										13
									
								
								lib/ssluse.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								lib/ssluse.c
									
									
									
									
									
								
							| @@ -200,7 +200,7 @@ int cert_stuff(struct connectdata *conn, | ||||
|  | ||||
|     if (SSL_CTX_use_certificate_file(conn->ssl.ctx, | ||||
| 				     cert_file, | ||||
| 				     SSL_FILETYPE_PEM) <= 0) { | ||||
| 				     SSL_FILETYPE_PEM) != 1) { | ||||
|       failf(data, "unable to set certificate file (wrong password?)\n"); | ||||
|       return(0); | ||||
|     } | ||||
| @@ -209,7 +209,7 @@ int cert_stuff(struct connectdata *conn, | ||||
|  | ||||
|     if (SSL_CTX_use_PrivateKey_file(conn->ssl.ctx, | ||||
| 				    key_file, | ||||
| 				    SSL_FILETYPE_PEM) <= 0) { | ||||
| 				    SSL_FILETYPE_PEM) != 1) { | ||||
|       failf(data, "unable to set public key file\n"); | ||||
|       return(0); | ||||
|     } | ||||
| @@ -612,7 +612,10 @@ Curl_SSLConnect(struct connectdata *conn) | ||||
|   SSL_set_fd (conn->ssl.handle, conn->firstsocket); | ||||
|   err = SSL_connect (conn->ssl.handle); | ||||
|  | ||||
|   if (-1 == err) { | ||||
|   /* 1  is fine | ||||
|      0  is "not successful but was shut down controlled" | ||||
|      <0 is "handshake was not successful, because a fatal error occurred" */ | ||||
|   if (err <= 0) { | ||||
|     err = ERR_get_error();  | ||||
|     failf(data, "SSL: %s", ERR_error_string(err, NULL)); | ||||
|     return CURLE_SSL_CONNECT_ERROR; | ||||
| @@ -722,6 +725,6 @@ Curl_SSLConnect(struct connectdata *conn) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -112,6 +112,6 @@ size_t Curl_strlcat(char *dst, const char *src, size_t siz) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -69,6 +69,6 @@ Curl_strtok_r(char *ptr, const char *sep, char **end) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
							
								
								
									
										106
									
								
								lib/telnet.c
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								lib/telnet.c
									
									
									
									
									
								
							| @@ -35,7 +35,7 @@ | ||||
| #include <errno.h> | ||||
|  | ||||
| #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) | ||||
| #include <winsock.h> | ||||
| #include <winsock2.h> | ||||
| #include <time.h> | ||||
| #include <io.h> | ||||
| #else | ||||
| @@ -152,8 +152,8 @@ struct TELNET { | ||||
|   int him[256];  | ||||
|   int himq[256];  | ||||
|   int him_preferred[256];  | ||||
|   char *subopt_ttype;             /* Set with suboption TTYPE */ | ||||
|   char *subopt_xdisploc;          /* Set with suboption XDISPLOC */ | ||||
|   char subopt_ttype[32];             /* Set with suboption TTYPE */ | ||||
|   char subopt_xdisploc[128];          /* Set with suboption XDISPLOC */ | ||||
|   struct curl_slist *telnet_vars; /* Environment variables */ | ||||
|  | ||||
|   /* suboptions */ | ||||
| @@ -765,14 +765,16 @@ static int check_telnet_options(struct connectdata *conn) | ||||
|  | ||||
|       /* Terminal type */ | ||||
|       if(strequal(option_keyword, "TTYPE")) { | ||||
|         tn->subopt_ttype = option_arg; | ||||
|         strncpy(tn->subopt_ttype, option_arg, 31); | ||||
|         tn->subopt_ttype[31] = 0; /* String termination */ | ||||
|         tn->us_preferred[TELOPT_TTYPE] = YES; | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       /* Display variable */ | ||||
|       if(strequal(option_keyword, "XDISPLOC")) { | ||||
|         tn->subopt_xdisploc = option_arg; | ||||
|         strncpy(tn->subopt_xdisploc, option_arg, 127); | ||||
|         tn->subopt_xdisploc[127] = 0; /* String termination */ | ||||
|         tn->us_preferred[TELOPT_XDISPLOC] = YES; | ||||
|         continue; | ||||
|       } | ||||
| @@ -1033,9 +1035,16 @@ CURLcode Curl_telnet(struct connectdata *conn) | ||||
|   CURLcode code; | ||||
|   struct SessionHandle *data = conn->data; | ||||
|   int sockfd = conn->firstsocket; | ||||
| #ifdef WIN32 | ||||
|   WSAEVENT event_handle; | ||||
|   WSANETWORKEVENTS events; | ||||
|   HANDLE stdin_handle; | ||||
|   HANDLE objs[2]; | ||||
|   DWORD waitret; | ||||
| #else | ||||
|   fd_set readfd; | ||||
|   fd_set keepfd; | ||||
|  | ||||
| #endif | ||||
|   bool keepon = TRUE; | ||||
|   char *buf = data->state.buffer; | ||||
|   ssize_t nread; | ||||
| @@ -1051,6 +1060,86 @@ CURLcode Curl_telnet(struct connectdata *conn) | ||||
|   if(code) | ||||
|     return code; | ||||
|  | ||||
| #ifdef WIN32 | ||||
|   /* We want to wait for both stdin and the socket. Since | ||||
|   ** the select() function in winsock only works on sockets | ||||
|   ** we have to use the WaitForMultipleObjects() call. | ||||
|   */ | ||||
|  | ||||
|   /* First, create a sockets event object */ | ||||
|   event_handle = WSACreateEvent(); | ||||
|  | ||||
|   /* The get the Windows file handle for stdin */ | ||||
|   stdin_handle = GetStdHandle(STD_INPUT_HANDLE); | ||||
|  | ||||
|   /* Create the list of objects to wait for */ | ||||
|   objs[0] = stdin_handle; | ||||
|   objs[1] = event_handle; | ||||
|  | ||||
|   /* Tell winsock what events we want to listen to */ | ||||
|   if(WSAEventSelect(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) { | ||||
|     return 0; | ||||
|   } | ||||
|  | ||||
|   /* Keep on listening and act on events */ | ||||
|   while(keepon) { | ||||
|     waitret = WaitForMultipleObjects(2, objs, FALSE, INFINITE); | ||||
|     switch(waitret - WAIT_OBJECT_0) | ||||
|     { | ||||
|       case 0: | ||||
|       { | ||||
|         unsigned char outbuf[2]; | ||||
|         int out_count = 0; | ||||
|         size_t bytes_written; | ||||
|         char *buffer = buf; | ||||
|                | ||||
|         if(!ReadFile(stdin_handle, buf, 255, &nread, NULL)) { | ||||
|           keepon = FALSE; | ||||
|           break; | ||||
|         } | ||||
|          | ||||
|         while(nread--) { | ||||
|           outbuf[0] = *buffer++; | ||||
|           out_count = 1; | ||||
|           if(outbuf[0] == IAC) | ||||
|             outbuf[out_count++] = IAC; | ||||
|            | ||||
|           Curl_write(conn, conn->firstsocket, outbuf, | ||||
|                      out_count, &bytes_written); | ||||
|         } | ||||
|       } | ||||
|       break; | ||||
|        | ||||
|       case 1: | ||||
|         if(WSAEnumNetworkEvents(sockfd, event_handle, &events) | ||||
|            != SOCKET_ERROR) | ||||
|         { | ||||
|           if(events.lNetworkEvents & FD_READ) | ||||
|           { | ||||
|             Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); | ||||
|              | ||||
|             telrcv(conn, (unsigned char *)buf, nread); | ||||
|              | ||||
|             fflush(stdout); | ||||
|              | ||||
|             /* Negotiate if the peer has started negotiating, | ||||
|                otherwise don't. We don't want to speak telnet with | ||||
|                non-telnet servers, like POP or SMTP. */ | ||||
|             if(tn->please_negotiate && !tn->already_negotiated) { | ||||
|               negotiate(conn); | ||||
|               tn->already_negotiated = 1; | ||||
|             } | ||||
|           } | ||||
|            | ||||
|           if(events.lNetworkEvents & FD_CLOSE) | ||||
|           { | ||||
|             keepon = FALSE; | ||||
|           } | ||||
|         } | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
| #else | ||||
|   FD_ZERO (&readfd);		/* clear it */ | ||||
|   FD_SET (sockfd, &readfd); | ||||
|   FD_SET (1, &readfd); | ||||
| @@ -1108,6 +1197,7 @@ CURLcode Curl_telnet(struct connectdata *conn) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| #endif | ||||
|   /* mark this as "no further transfer wanted" */ | ||||
|   return Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); | ||||
| } | ||||
| @@ -1116,6 +1206,6 @@ CURLcode Curl_telnet(struct connectdata *conn) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -65,9 +65,14 @@ struct timeval Curl_tvnow (void) | ||||
|  return now; | ||||
| } | ||||
|  | ||||
| double Curl_tvdiff (struct timeval t1, struct timeval t2) | ||||
| /* | ||||
|  * Make sure that the first argument is the more recent time, as otherwise | ||||
|  * we'll get a weird negative time-diff back... | ||||
|  */ | ||||
| long Curl_tvdiff (struct timeval t1, struct timeval t2) | ||||
| { | ||||
|  return (double)(t1.tv_sec - t2.tv_sec) + ((t1.tv_usec-t2.tv_usec)/1000000.0); | ||||
|   return (t1.tv_sec*1000 + t1.tv_usec/1000)- | ||||
|     (t2.tv_sec*1000 + t2.tv_usec/1000); | ||||
| } | ||||
|  | ||||
| long Curl_tvlong (struct timeval t1) | ||||
| @@ -79,6 +84,6 @@ long Curl_tvlong (struct timeval t1) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -43,7 +43,10 @@ struct timeval { | ||||
| #endif | ||||
|  | ||||
| struct timeval Curl_tvnow (); | ||||
| double Curl_tvdiff (struct timeval t1, struct timeval t2); | ||||
|  | ||||
| /* the diff is from now on returned in number of milliseconds! */ | ||||
| long Curl_tvdiff (struct timeval t1, struct timeval t2); | ||||
|  | ||||
| long Curl_tvlong (struct timeval t1); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___  | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * In order to be useful for every potential user, curl and libcurl are | ||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||
| @@ -220,8 +220,6 @@ Transfer(struct connectdata *c_conn) | ||||
|  | ||||
|   hbufp = data->state.headerbuff; | ||||
|  | ||||
|   myalarm (0);			/* switch off the alarm-style timeout */ | ||||
|  | ||||
|   now = Curl_tvnow(); | ||||
|   start = now; | ||||
|  | ||||
| @@ -452,12 +450,14 @@ Transfer(struct connectdata *c_conn) | ||||
|                 if (data->set.http_include_header) | ||||
|                   writetype |= CLIENTWRITE_BODY; | ||||
|  | ||||
|                 urg = Curl_client_write(data, writetype, data->state.headerbuff, | ||||
|                 urg = Curl_client_write(data, writetype, | ||||
|                                         data->state.headerbuff, | ||||
|                                         p - data->state.headerbuff); | ||||
|                 if(urg) | ||||
|                   return urg; | ||||
|  | ||||
|                 data->info.header_size += p - data->state.headerbuff; | ||||
|                 conn->headerbytecount += p - data->state.headerbuff; | ||||
|  | ||||
|                 if(!header) { | ||||
|                   /* | ||||
| @@ -520,13 +520,8 @@ Transfer(struct connectdata *c_conn) | ||||
|                   data->info.httpversion = httpversion; | ||||
|  | ||||
|                   /* 404 -> URL not found! */ | ||||
|                   if ( | ||||
|                       ( ((data->set.http_follow_location) && | ||||
|                          (httpcode >= 400)) | ||||
|                         || | ||||
|                         (!data->set.http_follow_location && | ||||
|                          (httpcode >= 300))) | ||||
|                       && (data->set.http_fail_on_error)) { | ||||
|                   if (data->set.http_fail_on_error && | ||||
|                       (httpcode >= 400)) { | ||||
|                     /* If we have been told to fail hard on HTTP-errors, | ||||
|                        here is the check for that: */ | ||||
|                     /* serious error, go home! */ | ||||
| @@ -620,14 +615,14 @@ Transfer(struct connectdata *c_conn) | ||||
|               } | ||||
|               else if(data->cookies && | ||||
|                       strnequal("Set-Cookie:", p, 11)) { | ||||
|                 Curl_cookie_add(data->cookies, TRUE, &p[12]); | ||||
|                 Curl_cookie_add(data->cookies, TRUE, &p[12], conn->name); | ||||
|               } | ||||
|               else if(strnequal("Last-Modified:", p, | ||||
|                                 strlen("Last-Modified:")) && | ||||
|                       (data->set.timecondition || data->set.get_filetime) ) { | ||||
|                 time_t secs=time(NULL); | ||||
|                 timeofdoc = curl_getdate(p+strlen("Last-Modified:"), &secs); | ||||
|                 if(data->set.get_filetime) | ||||
|                 if(data->set.get_filetime>=0) | ||||
|                   data->info.filetime = timeofdoc; | ||||
|               } | ||||
|               else if ((httpcode >= 300 && httpcode < 400) && | ||||
| @@ -844,6 +839,12 @@ Transfer(struct connectdata *c_conn) | ||||
|         break; | ||||
|       } | ||||
|  | ||||
|       /* Update read/write counters */ | ||||
|       if(conn->bytecountp) | ||||
|         *conn->bytecountp = bytecount; /* read count */ | ||||
|       if(conn->writebytecountp) | ||||
|         *conn->writebytecountp = writebytecount; /* write count */ | ||||
|  | ||||
|       now = Curl_tvnow(); | ||||
|       if(Curl_pgrsUpdate(conn)) | ||||
|         urg = CURLE_ABORTED_BY_CALLBACK; | ||||
| @@ -861,11 +862,13 @@ Transfer(struct connectdata *c_conn) | ||||
|         conn->upload_bufsize=(long)min(data->progress.ulspeed, BUFSIZE); | ||||
|       } | ||||
|  | ||||
|       if (data->set.timeout && (Curl_tvdiff (now, start) > data->set.timeout)) { | ||||
|       if (data->set.timeout && | ||||
|           ((Curl_tvdiff(now, start)/1000) >= data->set.timeout)) { | ||||
| 	failf (data, "Operation timed out with %d out of %d bytes received", | ||||
| 	       bytecount, conn->size); | ||||
| 	return CURLE_OPERATION_TIMEOUTED; | ||||
|       } | ||||
|  | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -888,11 +891,6 @@ Transfer(struct connectdata *c_conn) | ||||
|   if(Curl_pgrsUpdate(conn)) | ||||
|     return CURLE_ABORTED_BY_CALLBACK; | ||||
|  | ||||
|   if(conn->bytecountp) | ||||
|     *conn->bytecountp = bytecount; /* read count */ | ||||
|   if(conn->writebytecountp) | ||||
|     *conn->writebytecountp = writebytecount; /* write count */ | ||||
|  | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
| @@ -916,6 +914,7 @@ CURLcode Curl_perform(struct SessionHandle *data) | ||||
|  | ||||
|   data->set.followlocation=0; /* reset the location-follow counter */ | ||||
|   data->state.this_is_a_follow = FALSE; /* reset this */ | ||||
|   data->state.errorbuf = FALSE; /* no error has occurred */ | ||||
|  | ||||
|   Curl_initinfo(data); /* reset session-specific information "variables" */ | ||||
|  | ||||
| @@ -926,7 +925,31 @@ CURLcode Curl_perform(struct SessionHandle *data) | ||||
|     res = Curl_connect(data, &conn, port); | ||||
|     if(res == CURLE_OK) { | ||||
|       res = Curl_do(conn); | ||||
|  | ||||
|       if((CURLE_WRITE_ERROR == res) && conn->bits.reuse) { | ||||
|         /* This was a re-use of a connection and we got a write error in the | ||||
|          * DO-phase. Then we DISCONNECT this connection and have another | ||||
|          * attempt to CONNECT and then DO again! The retry cannot possibly | ||||
|          * find another connection to re-use, since we only keep one possible | ||||
|          * connection for each. | ||||
|          */ | ||||
|  | ||||
|         infof(data, "The re-used connection seems dead, get a new one\n"); | ||||
|  | ||||
|         conn->bits.close = TRUE; /* enforce close of this connetion */ | ||||
|         res = Curl_done(conn);   /* we are so done with this */ | ||||
|         if(CURLE_OK == res) { | ||||
|           /* Now, redo the connect */ | ||||
|           res = Curl_connect(data, &conn, port); | ||||
|           if(CURLE_OK == res) | ||||
|             /* ... finally back to actually retry the DO phase */ | ||||
|             res = Curl_do(conn); | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       if(res == CURLE_OK) { | ||||
|         CURLcode res2; /* just a local extra result container */ | ||||
|  | ||||
|         if(conn->protocol&PROT_FTPS) | ||||
|           /* FTPS, disable ssl while transfering data */ | ||||
|           conn->ssl.use = FALSE; | ||||
| @@ -935,15 +958,24 @@ CURLcode Curl_perform(struct SessionHandle *data) | ||||
|           /* FTPS, enable ssl again after havving transferred data */ | ||||
|           conn->ssl.use = TRUE; | ||||
|  | ||||
|         if(res == CURLE_OK) { | ||||
|         if(res == CURLE_OK) | ||||
|           /* | ||||
|            * We must duplicate the new URL here as the connection data | ||||
|            * may be free()ed in the Curl_done() function. | ||||
|            */ | ||||
|           newurl = conn->newurl?strdup(conn->newurl):NULL; | ||||
|         else | ||||
|           /* The transfer phase returned error, we mark the connection to get | ||||
|            * closed to prevent being re-used. This is becasue we can't | ||||
|            * possibly know if the connection is in a good shape or not now. */ | ||||
|           conn->bits.close = TRUE; | ||||
|  | ||||
|           res = Curl_done(conn); | ||||
|         } | ||||
|         /* Always run Curl_done(), even if some of the previous calls | ||||
|            failed, but return the previous (original) error code */ | ||||
|         res2 = Curl_done(conn); | ||||
|  | ||||
|         if(CURLE_OK == res) | ||||
|           res = res2; | ||||
|       } | ||||
|  | ||||
|       /* | ||||
| @@ -986,7 +1018,7 @@ CURLcode Curl_perform(struct SessionHandle *data) | ||||
|           data->change.referer_alloc = TRUE; /* yes, free this later */ | ||||
|         } | ||||
|  | ||||
|         if(2 != sscanf(newurl, "%15[^:]://%c", prot, &letter)) { | ||||
|         if(2 != sscanf(newurl, "%15[^?&/:]://%c", prot, &letter)) { | ||||
|           /*** | ||||
|            *DANG* this is an RFC 2068 violation. The URL is supposed | ||||
|            to be absolute and this doesn't seem to be that! | ||||
| @@ -1127,7 +1159,7 @@ CURLcode Curl_perform(struct SessionHandle *data) | ||||
|   if(newurl) | ||||
|     free(newurl); | ||||
|  | ||||
|   /* make sure the alarm is switched off! */ | ||||
|   /* make absolutely sure the alarm is switched off! */ | ||||
|   if(data->set.timeout || data->set.connecttimeout) | ||||
|     myalarm(0); | ||||
|  | ||||
| @@ -1166,6 +1198,6 @@ Curl_Transfer(struct connectdata *c_conn, /* connection data */ | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
							
								
								
									
										442
									
								
								lib/url.c
									
									
									
									
									
								
							
							
						
						
									
										442
									
								
								lib/url.c
									
									
									
									
									
								
							| @@ -107,6 +107,7 @@ | ||||
| #include "file.h" | ||||
| #include "ldap.h" | ||||
| #include "url.h" | ||||
| #include "connect.h" | ||||
|  | ||||
| #include <curl/types.h> | ||||
|  | ||||
| @@ -153,17 +154,21 @@ CURLcode Curl_close(struct SessionHandle *data) | ||||
|   Curl_SSL_Close_All(data); | ||||
| #endif | ||||
|  | ||||
|   if(data->state.auth_host) | ||||
|     free(data->state.auth_host); | ||||
|  | ||||
|   if(data->change.proxy_alloc) | ||||
|     free(data->change.proxy); | ||||
|  | ||||
|   if(data->change.referer_alloc) | ||||
|     free(data->change.referer); | ||||
|  | ||||
|   if(data->change.url_alloc) | ||||
|     free(data->change.url); | ||||
|  | ||||
|   if(data->state.headerbuff) | ||||
|     free(data->state.headerbuff); | ||||
|  | ||||
|  | ||||
|   if(data->set.cookiejar) | ||||
|     /* we have a "destination" for all the cookies to get dumped to */ | ||||
|     Curl_cookie_output(data->cookies, data->set.cookiejar); | ||||
| @@ -201,7 +206,10 @@ CURLcode Curl_open(struct SessionHandle **curl) | ||||
|  | ||||
|   /* Very simple start-up: alloc the struct, init it with zeroes and return */ | ||||
|   data = (struct SessionHandle *)malloc(sizeof(struct SessionHandle)); | ||||
|   if(data) { | ||||
|   if(!data) | ||||
|     /* this is a very serious error */ | ||||
|     return CURLE_OUT_OF_MEMORY; | ||||
|    | ||||
|   memset(data, 0, sizeof(struct SessionHandle)); | ||||
|  | ||||
|   /* We do some initial setup here, all those fields that can't be just 0 */ | ||||
| @@ -256,7 +264,7 @@ CURLcode Curl_open(struct SessionHandle **curl) | ||||
|   *curl = data; | ||||
|  | ||||
|   /************************************************************* | ||||
|      * Set signal handler | ||||
|    * Set signal handler to catch SIGALRM | ||||
|    *************************************************************/ | ||||
| #ifdef HAVE_SIGACTION | ||||
|   sigaction(SIGALRM, NULL, &sigact); | ||||
| @@ -270,15 +278,17 @@ CURLcode Curl_open(struct SessionHandle **curl) | ||||
|   /* no sigaction(), revert to the much lamer signal() */ | ||||
| #ifdef HAVE_SIGNAL | ||||
|   signal(SIGALRM, alarmfunc); | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
|   /************************************************************* | ||||
|    * Tell signal handler to ignore SIGPIPE | ||||
|    *************************************************************/ | ||||
| #if defined(HAVE_SIGNAL) && defined(SIGPIPE) | ||||
|   (void) signal(SIGPIPE, SIG_IGN); | ||||
| #endif | ||||
|    | ||||
|   return CURLE_OK; | ||||
|   } | ||||
|  | ||||
|   /* this is a very serious error */ | ||||
|   return CURLE_OUT_OF_MEMORY; | ||||
| } | ||||
|  | ||||
| CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) | ||||
| @@ -434,6 +444,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) | ||||
|      */ | ||||
|     data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE; | ||||
|     break; | ||||
|   case CURLOPT_HTTP_VERSION: | ||||
|     /* | ||||
|      * This sets a requested HTTP version to be used. The value is one of | ||||
|      * the listed enums in curl/curl.h. | ||||
|      */ | ||||
|     data->set.httpversion = va_arg(param, long); | ||||
|     break; | ||||
|   case CURLOPT_TRANSFERTEXT: | ||||
|     /* | ||||
|      * This option was previously named 'FTPASCII'. Renamed to work with | ||||
| @@ -451,15 +468,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) | ||||
|     if(va_arg(param, long)) | ||||
|       data->set.httpreq = HTTPREQ_PUT; | ||||
|     break; | ||||
| #if 0 | ||||
|     /* obsolete stuff, kept here a while for informational purposes */ | ||||
|   case CURLOPT_MUTE: | ||||
|     /* | ||||
|      * Stay absolutely quiet. | ||||
|      */ | ||||
|     data->set.mute = va_arg(param, long)?TRUE:FALSE; | ||||
|     break; | ||||
| #endif | ||||
|   case CURLOPT_TIMECONDITION: | ||||
|     /* | ||||
|      * Set HTTP time condition. This must be one of the defines in the | ||||
| @@ -495,7 +503,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) | ||||
|     /* | ||||
|      * Set cookie file name to dump all cookies to when we're done. | ||||
|      */ | ||||
|     data->set.cookiejar = cookiefile = (char *)va_arg(param, void *); | ||||
|     data->set.cookiejar = (char *)va_arg(param, void *); | ||||
|  | ||||
|     /* | ||||
|      * Activate the cookie parser. This may or may not already | ||||
|      * have been made. | ||||
|      */ | ||||
|     data->cookies = Curl_cookie_init(NULL, data->cookies); | ||||
|     break; | ||||
|   case CURLOPT_WRITEHEADER: | ||||
|     /* | ||||
| @@ -863,7 +877,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) | ||||
|  | ||||
|   if(-1 != conn->connectindex) { | ||||
|     /* unlink ourselves! */ | ||||
|     infof(conn->data, "Closing live connection (#%d)\n", conn->connectindex); | ||||
|     infof(conn->data, "Closing connection #%d\n", conn->connectindex); | ||||
|     conn->data->state.connects[conn->connectindex] = NULL; | ||||
|   } | ||||
|  | ||||
| @@ -874,13 +888,8 @@ CURLcode Curl_disconnect(struct connectdata *conn) | ||||
|   if(conn->proto.generic) | ||||
|     free(conn->proto.generic); | ||||
|  | ||||
| #ifdef ENABLE_IPV6 | ||||
|   if(conn->hp) /* host name info */ | ||||
|     freeaddrinfo(conn->hp); | ||||
| #else | ||||
|   if(conn->hostent_buf) /* host name info */ | ||||
|     free(conn->hostent_buf); | ||||
| #endif | ||||
|     Curl_freeaddrinfo(conn->hostent_buf); | ||||
|  | ||||
|   if(conn->newurl) | ||||
|     free(conn->newurl); | ||||
| @@ -987,10 +996,20 @@ ConnectionExists(struct SessionHandle *data, | ||||
|         } | ||||
|         dead = SocketIsDead(check->firstsocket); | ||||
|         if(dead) { | ||||
|           /* | ||||
|            * Even though the connection seems to have passed away, we could | ||||
|            * still make an effort to get the name information, as we intend to | ||||
|            * connect to the same host again. | ||||
|            * | ||||
|            * This is now subject to discussion. What do you think? | ||||
|            */ | ||||
|           infof(data, "Connection %d seems to be dead!\n", i); | ||||
|           Curl_disconnect(check); /* disconnect resources */ | ||||
|           data->state.connects[i]=NULL; /* nothing here */ | ||||
|           continue; /* try another one now */ | ||||
|  | ||||
|           /* There's no need to continue search, because we only store | ||||
|              one connection for each unique set of identifiers */ | ||||
|           return FALSE; | ||||
|         } | ||||
|  | ||||
|         *usethis = check; | ||||
| @@ -1046,14 +1065,14 @@ ConnectionKillOne(struct SessionHandle *data) | ||||
|        * Set higher score for the age passed since the connection | ||||
|        * was used. | ||||
|        */ | ||||
|       score = Curl_tvlong(now) - Curl_tvlong(conn->now); | ||||
|       score = Curl_tvdiff(now, conn->now); | ||||
|       break; | ||||
|     case CURLCLOSEPOLICY_OLDEST: | ||||
|       /* | ||||
|        * Set higher score for the age passed since the connection | ||||
|        * was created. | ||||
|        */ | ||||
|       score = Curl_tvlong(now) - Curl_tvlong(conn->created); | ||||
|       score = Curl_tvdiff(now, conn->created); | ||||
|       break; | ||||
|     } | ||||
|  | ||||
| @@ -1108,255 +1127,40 @@ ConnectionStore(struct SessionHandle *data, | ||||
|   return i; | ||||
| } | ||||
|  | ||||
| static CURLcode ConnectPlease(struct SessionHandle *data, | ||||
|                               struct connectdata *conn) | ||||
| static CURLcode ConnectPlease(struct connectdata *conn) | ||||
| { | ||||
| #if defined(WIN32) | ||||
|   unsigned long nonblock = 0; | ||||
|   fd_set connectfd; | ||||
|   struct timeval conntimeout; | ||||
| #endif | ||||
|  | ||||
| #ifndef ENABLE_IPV6 | ||||
|   conn->firstsocket = socket(AF_INET, SOCK_STREAM, 0); | ||||
|  | ||||
|   memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr)); | ||||
|   memcpy((char *)&(conn->serv_addr.sin_addr), | ||||
|          conn->hp->h_addr, conn->hp->h_length); | ||||
|   conn->serv_addr.sin_family = conn->hp->h_addrtype; | ||||
|   conn->serv_addr.sin_port = htons(conn->port); | ||||
| #else | ||||
|   /* IPv6-style */ | ||||
|   struct addrinfo *ai; | ||||
| #endif | ||||
|  | ||||
| #if !defined(WIN32)||defined(__CYGWIN32__) | ||||
|   /* We don't generally like checking for OS-versions, we should make this | ||||
|      HAVE_XXXX based, although at the moment I don't have a decent test for | ||||
|      this! */ | ||||
|  | ||||
| #ifdef HAVE_INET_NTOA | ||||
|  | ||||
| #ifndef INADDR_NONE | ||||
| #define INADDR_NONE (unsigned long) ~0 | ||||
| #endif | ||||
|  | ||||
| #ifndef ENABLE_IPV6 | ||||
|   /************************************************************* | ||||
|    * Select device to bind socket to | ||||
|    *************************************************************/ | ||||
|   if (data->set.device && (strlen(data->set.device)<255)) { | ||||
|     struct sockaddr_in sa; | ||||
|     struct hostent *h=NULL; | ||||
|     char *hostdataptr=NULL; | ||||
|     size_t size; | ||||
|     char myhost[256] = ""; | ||||
|     unsigned long in; | ||||
|  | ||||
|     if(Curl_if2ip(data->set.device, myhost, sizeof(myhost))) { | ||||
|       h = Curl_gethost(data, myhost, &hostdataptr); | ||||
|     } | ||||
|     else { | ||||
|       if(strlen(data->set.device)>1) { | ||||
|         h = Curl_gethost(data, data->set.device, &hostdataptr); | ||||
|       } | ||||
|       if(h) { | ||||
|         /* we know data->set.device is shorter than the myhost array */ | ||||
|         strcpy(myhost, data->set.device); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if(! *myhost) { | ||||
|       /* need to fix this | ||||
|          h=Curl_gethost(data, | ||||
|          getmyhost(*myhost,sizeof(myhost)), | ||||
|          hostent_buf, | ||||
|          sizeof(hostent_buf)); | ||||
|       */ | ||||
|       printf("in here\n"); | ||||
|     } | ||||
|  | ||||
|     infof(data, "We connect from %s\n", myhost); | ||||
|  | ||||
|     if ( (in=inet_addr(myhost)) != INADDR_NONE ) { | ||||
|  | ||||
|       if ( h ) { | ||||
|         memset((char *)&sa, 0, sizeof(sa)); | ||||
|         memcpy((char *)&sa.sin_addr, | ||||
|                h->h_addr, | ||||
|                h->h_length); | ||||
|         sa.sin_family = AF_INET; | ||||
|         sa.sin_addr.s_addr = in; | ||||
|         sa.sin_port = 0; /* get any port */ | ||||
| 	 | ||||
|         if( bind(conn->firstsocket, (struct sockaddr *)&sa, sizeof(sa)) >= 0) { | ||||
|           /* we succeeded to bind */ | ||||
|           struct sockaddr_in add; | ||||
| 	 | ||||
|           size = sizeof(add); | ||||
|           if(getsockname(conn->firstsocket, (struct sockaddr *) &add, | ||||
|                          (socklen_t *)&size)<0) { | ||||
|             failf(data, "getsockname() failed"); | ||||
|             return CURLE_HTTP_PORT_FAILED; | ||||
|           } | ||||
|         } | ||||
|         else { | ||||
|           switch(errno) { | ||||
|           case EBADF: | ||||
|             failf(data, "Invalid descriptor: %d", errno); | ||||
|             break; | ||||
|           case EINVAL: | ||||
|             failf(data, "Invalid request: %d", errno); | ||||
|             break; | ||||
|           case EACCES: | ||||
|             failf(data, "Address is protected, user not superuser: %d", errno); | ||||
|             break; | ||||
|           case ENOTSOCK: | ||||
|             failf(data, | ||||
|                   "Argument is a descriptor for a file, not a socket: %d", | ||||
|                   errno); | ||||
|             break; | ||||
|           case EFAULT: | ||||
|             failf(data, "Inaccessable memory error: %d", errno); | ||||
|             break; | ||||
|           case ENAMETOOLONG: | ||||
|             failf(data, "Address too long: %d", errno); | ||||
|             break; | ||||
|           case ENOMEM: | ||||
|             failf(data, "Insufficient kernel memory was available: %d", errno); | ||||
|             break; | ||||
|           default: | ||||
|             failf(data,"errno %d\n"); | ||||
|           } /* end of switch */ | ||||
| 	 | ||||
|           return CURLE_HTTP_PORT_FAILED; | ||||
|         } /* end of else */ | ||||
| 	 | ||||
|       } /* end of if  h */ | ||||
|       else { | ||||
| 	failf(data,"could't find my own IP address (%s)", myhost); | ||||
| 	return CURLE_HTTP_PORT_FAILED; | ||||
|       } | ||||
|     } /* end of inet_addr */ | ||||
|  | ||||
|     else { | ||||
|       failf(data, "could't find my own IP address (%s)", myhost); | ||||
|       return CURLE_HTTP_PORT_FAILED; | ||||
|     } | ||||
|  | ||||
|     if(hostdataptr) | ||||
|       free(hostdataptr); /* allocated by Curl_gethost() */ | ||||
|  | ||||
|   } /* end of device selection support */ | ||||
| #endif  /* end of HAVE_INET_NTOA */ | ||||
| #endif /* end of not WIN32 */ | ||||
| #endif /*ENABLE_IPV6*/ | ||||
|   CURLcode result; | ||||
|   Curl_ipconnect *addr; | ||||
|  | ||||
|   /************************************************************* | ||||
|    * Connect to server/proxy | ||||
|    *************************************************************/ | ||||
|   result= Curl_connecthost(conn, | ||||
|                            conn->hostaddr, | ||||
|                            conn->port, | ||||
|                            &conn->firstsocket, | ||||
|                            &addr); | ||||
|   if(CURLE_OK == result) { | ||||
|     /* All is cool, then we store the current information from the hostaddr | ||||
|        struct to the serv_addr, as it might be needed later. The address | ||||
|        returned from the function above is crucial here. */ | ||||
| #ifdef ENABLE_IPV6 | ||||
|   conn->firstsocket = -1; | ||||
|   for (ai = conn->hp; ai; ai = ai->ai_next) { | ||||
|     conn->firstsocket = socket(ai->ai_family, | ||||
|                                ai->ai_socktype, | ||||
|                                ai->ai_protocol); | ||||
|     if (conn->firstsocket < 0) | ||||
|       continue; | ||||
|  | ||||
|     if (connect(conn->firstsocket, ai->ai_addr, ai->ai_addrlen) < 0) { | ||||
|       sclose(conn->firstsocket); | ||||
|       conn->firstsocket = -1; | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     break; | ||||
|   } | ||||
|   conn->ai = ai; | ||||
|   if (conn->firstsocket < 0) { | ||||
|     failf(data, strerror(errno)); | ||||
|     return CURLE_COULDNT_CONNECT; | ||||
|   } | ||||
|     conn->serv_addr = addr; | ||||
| #else | ||||
|   /* non-zero nonblock value sets socket as nonblocking under Win32 */ | ||||
| #if defined(WIN32) | ||||
|   FD_ZERO (&connectfd); | ||||
|   FD_SET(conn->firstsocket, &connectfd); | ||||
|   if (conn->data->set.connecttimeout > 0) { | ||||
|     nonblock = 1; | ||||
|   } | ||||
|   ioctlsocket(conn->firstsocket, FIONBIO, &nonblock); | ||||
|     memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr)); | ||||
|     memcpy((char *)&(conn->serv_addr.sin_addr), | ||||
|            (struct in_addr *)addr, sizeof(struct in_addr)); | ||||
|     conn->serv_addr.sin_family = conn->hostaddr->h_addrtype; | ||||
|     conn->serv_addr.sin_port = htons(conn->port); | ||||
| #endif | ||||
|   if (connect(conn->firstsocket, | ||||
|               (struct sockaddr *) &(conn->serv_addr), | ||||
|               sizeof(conn->serv_addr) | ||||
|               ) < 0) { | ||||
| #if defined(WIN32) | ||||
|     conntimeout.tv_sec = conn->data->set.connecttimeout; | ||||
|     conntimeout.tv_usec = 0;	 | ||||
|     if(-1 != select (conn->firstsocket + 1, NULL, &connectfd, NULL, &conntimeout)) { | ||||
|       if (FD_ISSET(conn->firstsocket, &connectfd)) { | ||||
|         /* shut off non-blocking again */ | ||||
|         nonblock = 0; | ||||
|         ioctlsocket(conn->firstsocket, FIONBIO, &nonblock); | ||||
|         return CURLE_OK; | ||||
|   } | ||||
|       else | ||||
|         errno = EINTR; | ||||
|     } | ||||
| #endif | ||||
|     switch(errno) { | ||||
| #ifdef ECONNREFUSED | ||||
|       /* this should be made nicer */ | ||||
|     case ECONNREFUSED: | ||||
|       failf(data, "Connection refused"); | ||||
|       break; | ||||
|     case EFAULT: | ||||
|       failf(data, "Invalid socket address: %d",errno); | ||||
|       break; | ||||
|     case EISCONN: | ||||
|       failf(data, "Socket already connected: %d",errno); | ||||
|       break; | ||||
|     case ETIMEDOUT: | ||||
|       failf(data, "Timeout while accepting connection, server busy: %d",errno); | ||||
|       break; | ||||
|     case ENETUNREACH: | ||||
|       failf(data, "Network is unreachable: %d",errno); | ||||
|       break; | ||||
|     case EADDRINUSE: | ||||
|       failf(data, "Local address already in use: %d",errno); | ||||
|       break; | ||||
|     case EINPROGRESS: | ||||
|       failf(data, "Socket is nonblocking and connection can not be completed immediately: %d",errno); | ||||
|       break; | ||||
|     case EALREADY: | ||||
|       failf(data, "Socket is nonblocking and a previous connection attempt not completed: %d",errno); | ||||
|       break; | ||||
|     case EAGAIN: | ||||
|       failf(data, "No more free local ports: %d",errno); | ||||
|       break; | ||||
|     case EACCES: | ||||
|     case EPERM: | ||||
|       failf(data, "Attempt to connect to broadcast address without socket broadcast flag or local firewall rule violated: %d",errno); | ||||
|       break; | ||||
| #endif | ||||
|     case EINTR: | ||||
|       failf(data, "Connection timed out"); | ||||
|       break; | ||||
|     default: | ||||
|       failf(data, "Can't connect to server: %d", errno); | ||||
|       break; | ||||
|     } | ||||
|     return CURLE_COULDNT_CONNECT; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   return CURLE_OK; | ||||
|   return result; | ||||
| } | ||||
|  | ||||
| static CURLcode Connect(struct SessionHandle *data, | ||||
| static CURLcode CreateConnection(struct SessionHandle *data, | ||||
|                                  struct connectdata **in_connect, | ||||
|                         bool allow_port) /* allow data->set.use_port ? */ | ||||
|                                  bool allow_port) /* allow set.use_port? */ | ||||
| { | ||||
|   char *tmp; | ||||
|   char *buf; | ||||
| @@ -1486,14 +1290,14 @@ static CURLcode Connect(struct SessionHandle *data, | ||||
|     strcpy(conn->path, "/"); | ||||
|  | ||||
|     if (2 > sscanf(data->change.url, | ||||
|                    "%64[^\n:]://%256[^\n/]%[^\n]", | ||||
|                    "%64[^\n:]://%512[^\n/]%[^\n]", | ||||
|                    conn->protostr, conn->gname, conn->path)) { | ||||
|        | ||||
|       /* | ||||
|        * The URL was badly formatted, let's try the browser-style _without_ | ||||
|        * protocol specified like 'http://'. | ||||
|        */ | ||||
|       if((1 > sscanf(data->change.url, "%256[^\n/]%[^\n]", | ||||
|       if((1 > sscanf(data->change.url, "%512[^\n/]%[^\n]", | ||||
|                      conn->gname, conn->path)) ) { | ||||
|         /* | ||||
|          * We couldn't even get this format. | ||||
| @@ -1700,12 +1504,12 @@ static CURLcode Connect(struct SessionHandle *data, | ||||
|   } /* if not using proxy */ | ||||
|  | ||||
|   /************************************************************* | ||||
|    * No protocol but proxy usage needs attention | ||||
|    * No protocol part in URL was used, add it! | ||||
|    *************************************************************/ | ||||
|   if((conn->protocol&PROT_MISSING) && data->change.proxy ) { | ||||
|     /* We're guessing prefixes here and since we're told to use a proxy, we | ||||
|        need to add the protocol prefix to the URL string before we continue! | ||||
|        */ | ||||
|   if(conn->protocol&PROT_MISSING) { | ||||
|     /* We're guessing prefixes here and if we're told to use a proxy or if | ||||
|        we're gonna follow a Location: later or... then we need the protocol | ||||
|        part added so that we have a valid URL. */ | ||||
|     char *reurl; | ||||
|  | ||||
|     reurl = aprintf("%s://%s", conn->protostr, data->change.url); | ||||
| @@ -1737,21 +1541,6 @@ static CURLcode Connect(struct SessionHandle *data, | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /************************************************************* | ||||
|    * Set timeout if that is being used | ||||
|    *************************************************************/ | ||||
|   if(data->set.timeout || data->set.connecttimeout) { | ||||
|     /* We set the timeout on the connection/resolving phase first, separately | ||||
|      * from the download/upload part to allow a maximum time on everything */ | ||||
|  | ||||
|     /* myalarm() makes a signal get sent when the timeout fires off, and that | ||||
|        will abort system calls */ | ||||
|     if(data->set.connecttimeout) | ||||
|       myalarm(data->set.connecttimeout); | ||||
|     else | ||||
|       myalarm(data->set.timeout); | ||||
|   } | ||||
|  | ||||
|   /************************************************************* | ||||
|    * Setup internals depending on protocol | ||||
|    *************************************************************/ | ||||
| @@ -1762,7 +1551,6 @@ static CURLcode Connect(struct SessionHandle *data, | ||||
|     conn->protocol |= PROT_HTTP; | ||||
|     conn->curl_do = Curl_http; | ||||
|     conn->curl_done = Curl_http_done; | ||||
|     conn->curl_close = Curl_http_close; | ||||
|   } | ||||
|   else if (strequal(conn->protostr, "HTTPS")) { | ||||
| #ifdef USE_SSLEAY | ||||
| @@ -1775,7 +1563,6 @@ static CURLcode Connect(struct SessionHandle *data, | ||||
|     conn->curl_do = Curl_http; | ||||
|     conn->curl_done = Curl_http_done; | ||||
|     conn->curl_connect = Curl_http_connect; | ||||
|     conn->curl_close = Curl_http_close; | ||||
|  | ||||
| #else /* USE_SSLEAY */ | ||||
|     failf(data, LIBCURL_NAME | ||||
| @@ -1795,7 +1582,6 @@ static CURLcode Connect(struct SessionHandle *data, | ||||
|     conn->protocol |= PROT_GOPHER; | ||||
|     conn->curl_do = Curl_http; | ||||
|     conn->curl_done = Curl_http_done; | ||||
|     conn->curl_close = Curl_http_close; | ||||
|   } | ||||
|   else if(strequal(conn->protostr, "FTP") || | ||||
|           strequal(conn->protostr, "FTPS")) { | ||||
| @@ -1827,7 +1613,6 @@ static CURLcode Connect(struct SessionHandle *data, | ||||
|       } | ||||
|       conn->curl_do = Curl_http; | ||||
|       conn->curl_done = Curl_http_done; | ||||
|       conn->curl_close = Curl_http_close; | ||||
|     } | ||||
|     else { | ||||
|       conn->curl_do = Curl_ftp; | ||||
| @@ -1996,16 +1781,13 @@ static CURLcode Connect(struct SessionHandle *data, | ||||
|    * port number of various reasons. | ||||
|    * | ||||
|    * To be able to detect port number flawlessly, we must not confuse them | ||||
|    * IPv6-specified addresses in the [0::1] style. | ||||
|    * IPv6-specified addresses in the [0::1] style. (RFC2732) | ||||
|    *************************************************************/ | ||||
|  | ||||
|   if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && | ||||
|      (']' == endbracket)) { | ||||
|     /* this is a IPv6-style specified IP-address */ | ||||
| #ifndef ENABLE_IPV6 | ||||
|     failf(data, "You haven't enabled IPv6 support"); | ||||
|     return CURLE_URL_MALFORMAT; | ||||
| #else | ||||
|     /* This is a (IPv6-style) specified IP-address. We support _any_ | ||||
|        IP within brackets to be really generic. */ | ||||
|     conn->name++; /* pass the starting bracket */ | ||||
|  | ||||
|     tmp = strchr(conn->name, ']'); | ||||
| @@ -2014,7 +1796,6 @@ static CURLcode Connect(struct SessionHandle *data, | ||||
|     tmp++; /* pass the ending bracket */ | ||||
|     if(':' != *tmp) | ||||
|       tmp = NULL; /* no port number available */ | ||||
| #endif | ||||
|   } | ||||
|   else { | ||||
|     /* traditional IPv4-style port-extracting */ | ||||
| @@ -2101,7 +1882,6 @@ static CURLcode Connect(struct SessionHandle *data, | ||||
|     conn = conn_temp;        /* use this connection from now on */ | ||||
|  | ||||
|     /* we need these pointers if we speak over a proxy */ | ||||
|     conn->name = conn->gname; | ||||
|     conn->hostname = old_conn->gname; | ||||
|  | ||||
|     free(conn->path);    /* free the previously allocated path pointer */ | ||||
| @@ -2153,6 +1933,23 @@ static CURLcode Connect(struct SessionHandle *data, | ||||
|     ConnectionStore(data, conn); | ||||
|   } | ||||
|  | ||||
|   /************************************************************* | ||||
|    * Set timeout if that is being used | ||||
|    *************************************************************/ | ||||
|   if(data->set.timeout || data->set.connecttimeout) { | ||||
|     /* We set the timeout on the name resolving phase first, separately from | ||||
|      * the download/upload part to allow a maximum time on everything. This is | ||||
|      * a signal-based timeout, why it won't work and shouldn't be used in | ||||
|      * multi-threaded environments. */ | ||||
|  | ||||
|     /* myalarm() makes a signal get sent when the timeout fires off, and that | ||||
|        will abort system calls */ | ||||
|     if(data->set.connecttimeout) | ||||
|       myalarm(data->set.connecttimeout); | ||||
|     else | ||||
|       myalarm(data->set.timeout); | ||||
|   } | ||||
|  | ||||
|   /************************************************************* | ||||
|    * Resolve the name of the server or proxy | ||||
|    *************************************************************/ | ||||
| @@ -2162,38 +1959,34 @@ static CURLcode Connect(struct SessionHandle *data, | ||||
|     conn->port =  conn->remote_port; /* it is the same port */ | ||||
|  | ||||
|     /* Resolve target host right on */ | ||||
|     if(!conn->hp) { | ||||
| #ifdef ENABLE_IPV6 | ||||
|     if(!conn->hostaddr) { | ||||
|       /* it might already be set if reusing a connection */ | ||||
|       conn->hp = Curl_getaddrinfo(data, conn->name, conn->port); | ||||
| #else | ||||
|       /* it might already be set if reusing a connection */ | ||||
|       conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf); | ||||
| #endif | ||||
|       conn->hostaddr = Curl_getaddrinfo(data, conn->name, conn->port, | ||||
|                                         &conn->hostent_buf); | ||||
|     } | ||||
|     if(!conn->hp) | ||||
|     { | ||||
|     if(!conn->hostaddr) { | ||||
|       failf(data, "Couldn't resolve host '%s'", conn->name); | ||||
|       return CURLE_COULDNT_RESOLVE_HOST; | ||||
|     } | ||||
|   } | ||||
|   else if(!conn->hp) { | ||||
|   else if(!conn->hostaddr) { | ||||
|     /* This is a proxy that hasn't been resolved yet. It may be resolved | ||||
|        if we're reusing an existing connection. */ | ||||
|  | ||||
|     /* resolve proxy */ | ||||
| #ifdef ENABLE_IPV6 | ||||
|     /* it might already be set if reusing a connection */ | ||||
|     conn->hp = Curl_getaddrinfo(data, conn->proxyhost, conn->port); | ||||
| #else | ||||
|     conn->hp = Curl_gethost(data, conn->proxyhost, &conn->hostent_buf); | ||||
| #endif | ||||
|     if(!conn->hp) { | ||||
|     conn->hostaddr = Curl_getaddrinfo(data, conn->proxyhost, conn->port, | ||||
|                                       &conn->hostent_buf); | ||||
|  | ||||
|     if(!conn->hostaddr) { | ||||
|       failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost); | ||||
|       return CURLE_COULDNT_RESOLVE_PROXY; | ||||
|     } | ||||
|   } | ||||
|   Curl_pgrsTime(data, TIMER_NAMELOOKUP); | ||||
|   if(data->set.timeout || data->set.connecttimeout) | ||||
|     /* switch off signal-based timeouts */ | ||||
|     myalarm(0); | ||||
|  | ||||
|   /************************************************************* | ||||
|    * Proxy authentication | ||||
| @@ -2227,7 +2020,7 @@ static CURLcode Connect(struct SessionHandle *data, | ||||
|  | ||||
|   if(-1 == conn->firstsocket) { | ||||
|     /* Connect only if not already connected! */ | ||||
|     result = ConnectPlease(data, conn); | ||||
|     result = ConnectPlease(conn); | ||||
|     if(CURLE_OK != result) | ||||
|       return result; | ||||
|  | ||||
| @@ -2250,6 +2043,7 @@ static CURLcode Connect(struct SessionHandle *data, | ||||
|  | ||||
|   conn->now = Curl_tvnow(); /* time this *after* the connect is done */ | ||||
|   conn->bytecount = 0; | ||||
|   conn->headerbytecount = 0; | ||||
|    | ||||
|   /* Figure out the ip-number and display the first host name it shows: */ | ||||
| #ifdef ENABLE_IPV6 | ||||
| @@ -2260,23 +2054,25 @@ static CURLcode Connect(struct SessionHandle *data, | ||||
| #else | ||||
|     const int niflags = NI_NUMERICHOST; | ||||
| #endif | ||||
|     struct addrinfo *ai = conn->ai; | ||||
|     struct addrinfo *ai = conn->serv_addr; | ||||
|  | ||||
|     if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, | ||||
| 	niflags)) { | ||||
|       snprintf(hbuf, sizeof(hbuf), "?"); | ||||
|     } | ||||
|     if (ai->ai_canonname) { | ||||
|       infof(data, "Connected to %s (%s)\n", ai->ai_canonname, hbuf); | ||||
|       infof(data, "Connected to %s (%s) port %d\n", ai->ai_canonname, hbuf, | ||||
|             conn->port); | ||||
|     } else { | ||||
|       infof(data, "Connected to %s\n", hbuf); | ||||
|       infof(data, "Connected to %s port %d\n", hbuf, conn->port); | ||||
|     } | ||||
|   } | ||||
| #else | ||||
|   { | ||||
|     struct in_addr in; | ||||
|     (void) memcpy(&in.s_addr, *conn->hp->h_addr_list, sizeof (in.s_addr)); | ||||
|     infof(data, "Connected to %s (%s)\n", conn->hp->h_name, inet_ntoa(in)); | ||||
|     (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr)); | ||||
|     infof(data, "Connected to %s (%s)\n", conn->hostaddr->h_name, | ||||
|           inet_ntoa(in)); | ||||
|   } | ||||
| #endif | ||||
|  | ||||
| @@ -2303,7 +2099,7 @@ CURLcode Curl_connect(struct SessionHandle *data, | ||||
|   struct connectdata *conn; | ||||
|  | ||||
|   /* call the stuff that needs to be called */ | ||||
|   code = Connect(data, in_connect, allow_port); | ||||
|   code = CreateConnection(data, in_connect, allow_port); | ||||
|  | ||||
|   if(CURLE_OK != code) { | ||||
|     /* We're not allowed to return failure with memory left allocated | ||||
| @@ -2354,7 +2150,7 @@ CURLcode Curl_done(struct connectdata *conn) | ||||
|      ((CURLE_OK == result) && conn->bits.close)) | ||||
|     result = Curl_disconnect(conn); /* close the connection */ | ||||
|   else | ||||
|     infof(data, "Connection (#%d) left alive\n", conn->connectindex); | ||||
|     infof(data, "Connection #%d left intact\n", conn->connectindex); | ||||
|  | ||||
|   return result; | ||||
| } | ||||
| @@ -2374,6 +2170,6 @@ CURLcode Curl_do(struct connectdata *conn) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
| @@ -26,6 +26,7 @@ | ||||
| /* This file is for lib internal stuff */ | ||||
|  | ||||
| #include "setup.h" | ||||
| #include "hostip.h" | ||||
|  | ||||
| #define PORT_FTP 21 | ||||
| #define PORT_TELNET 23 | ||||
| @@ -223,16 +224,16 @@ struct connectdata { | ||||
| #define PROT_FILE    (1<<8) | ||||
| #define PROT_FTPS    (1<<9) | ||||
|  | ||||
| #ifdef ENABLE_IPV6 | ||||
|   struct addrinfo *hp; /* host info pointer list */ | ||||
|   struct addrinfo *ai; /* the particular host we use */ | ||||
| #else | ||||
|   Curl_addrinfo *hostaddr; /* IP-protocol independent host info pointer list */ | ||||
|   char *hostent_buf; /* pointer to allocated memory for name info */ | ||||
|   struct hostent *hp; | ||||
|  | ||||
| #ifdef ENABLE_IPV6 | ||||
|   struct addrinfo *serv_addr;   /* the particular host we use */ | ||||
| #else | ||||
|   struct sockaddr_in serv_addr; | ||||
| #endif | ||||
|   char protostr[64];  /* store the protocol string in this buffer */ | ||||
|   char gname[257]; /* store the hostname in this buffer */ | ||||
|   char gname[513]; /* store the hostname in this buffer */ | ||||
|   char *name;      /* host name pointer to fool around with */ | ||||
|   char *path;      /* allocated buffer to store the URL's path part in */ | ||||
|   char *hostname;  /* hostname to connect, as parsed from url */ | ||||
| @@ -241,6 +242,7 @@ struct connectdata { | ||||
|                                  not the proxy port! */ | ||||
|   char *ppath; | ||||
|   long bytecount; | ||||
|   long headerbytecount;  /* only count received headers */ | ||||
|  | ||||
|   char *range; /* range, if used. See README for detailed specification on | ||||
|                   this syntax. */ | ||||
| @@ -351,7 +353,7 @@ struct connectdata { | ||||
| struct PureInfo { | ||||
|   int httpcode; | ||||
|   int httpversion; | ||||
|   time_t filetime; /* If requested, this is might get set. It may be 0 if | ||||
|   long filetime; /* If requested, this is might get set. Set to -1 if | ||||
|                     the time was unretrievable */ | ||||
|   long header_size;  /* size of read header(s) in bytes */ | ||||
|   long request_size; /* the amount of bytes sent in the request(s) */ | ||||
| @@ -371,7 +373,9 @@ struct Progress { | ||||
|   bool callback;  /* set when progress callback is used */ | ||||
|   int width; /* screen width at download start */ | ||||
|   int flags; /* see progress.h */ | ||||
|   double timespent; | ||||
|  | ||||
|   long timespent; | ||||
|  | ||||
|   double dlspeed; | ||||
|   double ulspeed; | ||||
|  | ||||
| @@ -381,9 +385,10 @@ struct Progress { | ||||
|  | ||||
|   struct timeval start; | ||||
|   struct timeval t_startsingle; | ||||
| #define CURR_TIME 5 | ||||
| #define CURR_TIME (5+1) /* 6 entries for 5 seconds */ | ||||
|  | ||||
|   double speeder[ CURR_TIME ]; | ||||
|   struct timeval speeder_time[ CURR_TIME ]; | ||||
|   int speeder_c; | ||||
| }; | ||||
|  | ||||
| @@ -441,6 +446,9 @@ struct UrlState { | ||||
|   long sessionage;                  /* number of the most recent session */ | ||||
|  | ||||
|   char scratch[BUFSIZE*2]; /* huge buffer when doing upload CRLF replacing */ | ||||
|   bool errorbuf; /* Set to TRUE if the error buffer is already filled in. | ||||
|                     This must be set to FALSE every time _easy_perform() is | ||||
|                     called. */ | ||||
| }; | ||||
|  | ||||
|  | ||||
| @@ -519,11 +527,13 @@ struct UserDefined { | ||||
|   struct curl_slist *quote;     /* before the transfer */ | ||||
|   struct curl_slist *postquote; /* after the transfer */ | ||||
|   struct curl_slist *telnet_options; /* linked list of telnet options */ | ||||
|   TimeCond timecondition; /* kind of time/date comparison */ | ||||
|   curl_TimeCond timecondition; /* kind of time/date comparison */ | ||||
|   time_t timevalue;       /* what time to compare with */ | ||||
|   curl_closepolicy closepolicy; /* connection cache close concept */ | ||||
|   Curl_HttpReq httpreq;   /* what kind of HTTP request (if any) is this */ | ||||
|   char *customrequest;    /* HTTP/FTP request to use */ | ||||
|   long httpversion; /* when non-zero, a specific HTTP version requested to | ||||
|                        be used in the library's request(s) */ | ||||
|   char *auth_host; /* if set, this is the allocated string to the host name | ||||
|                     * to which to send the authorization data to, and no other | ||||
|                     * host (which location-following otherwise could lead to) | ||||
|   | ||||
| @@ -108,6 +108,6 @@ char *curl_version(void) | ||||
|  * local variables: | ||||
|  * eval: (load-file "../curl-mode.el") | ||||
|  * end: | ||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker | ||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 | ||||
|  * vim600: fdm=marker | ||||
|  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||
|  */ | ||||
|   | ||||
							
								
								
									
										68
									
								
								ltmain.sh
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								ltmain.sh
									
									
									
									
									
								
							| @@ -55,8 +55,8 @@ modename="$progname" | ||||
| # Constants. | ||||
| PROGRAM=ltmain.sh | ||||
| PACKAGE=libtool | ||||
| VERSION=1.4.1 | ||||
| TIMESTAMP=" (1.922.2.34 2001/09/03 01:22:13)" | ||||
| VERSION=1.4.2 | ||||
| TIMESTAMP=" (1.922.2.54 2001/09/11 03:33:37)" | ||||
|  | ||||
| default_mode= | ||||
| help="Try \`$progname --help' for more information." | ||||
| @@ -84,6 +84,9 @@ if test "${LANG+set}" = set; then | ||||
|   save_LANG="$LANG"; LANG=C; export LANG | ||||
| fi | ||||
|  | ||||
| # Make sure IFS has a sensible default | ||||
| : ${IFS=" 	"} | ||||
|  | ||||
| if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then | ||||
|   echo "$modename: not configured to build any kind of library" 1>&2 | ||||
|   echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2 | ||||
| @@ -334,7 +337,7 @@ if test -z "$show_help"; then | ||||
|       -Wc,*) | ||||
| 	args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` | ||||
| 	lastarg= | ||||
| 	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=',' | ||||
| 	save_ifs="$IFS"; IFS=',' | ||||
| 	for arg in $args; do | ||||
| 	  IFS="$save_ifs" | ||||
|  | ||||
| @@ -1045,8 +1048,7 @@ compiler." | ||||
| 	    test "X$arg" = "X-lc" && continue | ||||
| 	    ;; | ||||
| 	  esac | ||||
| 	 fi | ||||
| 	 if test "X$arg" = "X-lc_r"; then | ||||
| 	 elif test "X$arg" = "X-lc_r"; then | ||||
| 	  case $host in | ||||
| 	  *-*-openbsd*) | ||||
| 	    # Do not include libc_r directly, use -pthread flag. | ||||
| @@ -1143,7 +1145,7 @@ compiler." | ||||
|       -Wc,*) | ||||
| 	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` | ||||
| 	arg= | ||||
| 	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=',' | ||||
| 	save_ifs="$IFS"; IFS=',' | ||||
| 	for flag in $args; do | ||||
| 	  IFS="$save_ifs" | ||||
| 	  case $flag in | ||||
| @@ -1161,7 +1163,7 @@ compiler." | ||||
|       -Wl,*) | ||||
| 	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` | ||||
| 	arg= | ||||
| 	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=',' | ||||
| 	save_ifs="$IFS"; IFS=',' | ||||
| 	for flag in $args; do | ||||
| 	  IFS="$save_ifs" | ||||
| 	  case $flag in | ||||
| @@ -1771,7 +1773,7 @@ compiler." | ||||
| 	    if test -f "$output_objdir/$soname-def"; then : | ||||
| 	    else | ||||
| 	      $show "extracting exported symbol list from \`$soname'" | ||||
| 	      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | ||||
| 	      save_ifs="$IFS"; IFS='~' | ||||
| 	      eval cmds=\"$extract_expsyms_cmds\" | ||||
| 	      for cmd in $cmds; do | ||||
| 		IFS="$save_ifs" | ||||
| @@ -1784,7 +1786,7 @@ compiler." | ||||
| 	    # Create $newlib | ||||
| 	    if test -f "$output_objdir/$newlib"; then :; else | ||||
| 	      $show "generating import library for \`$soname'" | ||||
| 	      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | ||||
| 	      save_ifs="$IFS"; IFS='~' | ||||
| 	      eval cmds=\"$old_archive_from_expsyms_cmds\" | ||||
| 	      for cmd in $cmds; do | ||||
| 		IFS="$save_ifs" | ||||
| @@ -2196,7 +2198,7 @@ compiler." | ||||
|       else | ||||
|  | ||||
| 	# Parse the version information argument. | ||||
| 	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=':' | ||||
| 	save_ifs="$IFS"; IFS=':' | ||||
| 	set dummy $vinfo 0 0 0 | ||||
| 	IFS="$save_ifs" | ||||
|  | ||||
| @@ -2818,7 +2820,7 @@ EOF | ||||
| 	    export_symbols="$output_objdir/$libname.exp" | ||||
| 	    $run $rm $export_symbols | ||||
| 	    eval cmds=\"$export_symbols_cmds\" | ||||
| 	    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | ||||
| 	    save_ifs="$IFS"; IFS='~' | ||||
| 	    for cmd in $cmds; do | ||||
| 	      IFS="$save_ifs" | ||||
| 	      $show "$cmd" | ||||
| @@ -2894,7 +2896,7 @@ EOF | ||||
| 	else | ||||
| 	  eval cmds=\"$archive_cmds\" | ||||
| 	fi | ||||
| 	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | ||||
| 	save_ifs="$IFS"; IFS='~' | ||||
| 	for cmd in $cmds; do | ||||
| 	  IFS="$save_ifs" | ||||
| 	  $show "$cmd" | ||||
| @@ -3022,7 +3024,7 @@ EOF | ||||
|  | ||||
|       output="$obj" | ||||
|       eval cmds=\"$reload_cmds\" | ||||
|       IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | ||||
|       save_ifs="$IFS"; IFS='~' | ||||
|       for cmd in $cmds; do | ||||
| 	IFS="$save_ifs" | ||||
| 	$show "$cmd" | ||||
| @@ -3058,7 +3060,7 @@ EOF | ||||
| 	reload_objs="$libobjs $reload_conv_objs" | ||||
| 	output="$libobj" | ||||
| 	eval cmds=\"$reload_cmds\" | ||||
| 	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | ||||
| 	save_ifs="$IFS"; IFS='~' | ||||
| 	for cmd in $cmds; do | ||||
| 	  IFS="$save_ifs" | ||||
| 	  $show "$cmd" | ||||
| @@ -3823,7 +3825,7 @@ fi\ | ||||
|  | ||||
| 	eval cmds=\"$old_archive_cmds\" | ||||
|       fi | ||||
|       IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | ||||
|       save_ifs="$IFS"; IFS='~' | ||||
|       for cmd in $cmds; do | ||||
| 	IFS="$save_ifs" | ||||
| 	$show "$cmd" | ||||
| @@ -4198,7 +4200,7 @@ relink_command=\"$relink_command\"" | ||||
| 	  # Do each command in the postinstall commands. | ||||
| 	  lib="$destdir/$realname" | ||||
| 	  eval cmds=\"$postinstall_cmds\" | ||||
| 	  IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | ||||
| 	  save_ifs="$IFS"; IFS='~' | ||||
| 	  for cmd in $cmds; do | ||||
| 	    IFS="$save_ifs" | ||||
| 	    $show "$cmd" | ||||
| @@ -4271,19 +4273,31 @@ relink_command=\"$relink_command\"" | ||||
| 	fi | ||||
|  | ||||
| 	# Do a test to see if this is really a libtool program. | ||||
| 	if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then | ||||
| 	#if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then | ||||
| 	case $host in | ||||
| 	*cygwin*|*mingw*) | ||||
| 	    wrapper=`echo $file | sed -e 's,.exe$,,'` | ||||
| 	    ;; | ||||
| 	*) | ||||
| 	    wrapper=$file | ||||
| 	    ;; | ||||
| 	esac | ||||
| 	if (sed -e '4q' $wrapper | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then | ||||
|  | ||||
| 	  notinst_deplibs= | ||||
| 	  relink_command= | ||||
|  | ||||
| 	  # If there is no directory component, then add one. | ||||
| 	  case $file in | ||||
| 	  */* | *\\*) . $file ;; | ||||
| 	  *) . ./$file ;; | ||||
| 	  #*/* | *\\*) . $file ;; | ||||
| 	  #*) . ./$file ;; | ||||
| 	  */* | *\\*) . $wrapper ;; | ||||
| 	  *) . ./$wrapper ;; | ||||
| 	  esac | ||||
|  | ||||
| 	  # Check the variables that should have been set. | ||||
| 	  if test -z "$notinst_deplibs"; then | ||||
| 	    $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2 | ||||
| 	    $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 | ||||
| 	    exit 1 | ||||
| 	  fi | ||||
|  | ||||
| @@ -4308,8 +4322,10 @@ relink_command=\"$relink_command\"" | ||||
| 	  relink_command= | ||||
| 	  # If there is no directory component, then add one. | ||||
| 	  case $file in | ||||
| 	  */* | *\\*) . $file ;; | ||||
| 	  *) . ./$file ;; | ||||
| 	  #*/* | *\\*) . $file ;; | ||||
| 	  #*) . ./$file ;; | ||||
| 	  */* | *\\*) . $wrapper ;; | ||||
| 	  *) . ./$wrapper ;; | ||||
| 	  esac | ||||
|  | ||||
| 	  outputname= | ||||
| @@ -4385,7 +4401,7 @@ relink_command=\"$relink_command\"" | ||||
|  | ||||
|       # Do each command in the postinstall commands. | ||||
|       eval cmds=\"$old_postinstall_cmds\" | ||||
|       IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | ||||
|       save_ifs="$IFS"; IFS='~' | ||||
|       for cmd in $cmds; do | ||||
| 	IFS="$save_ifs" | ||||
| 	$show "$cmd" | ||||
| @@ -4423,7 +4439,7 @@ relink_command=\"$relink_command\"" | ||||
| 	if test -n "$finish_cmds"; then | ||||
| 	  # Do each command in the finish commands. | ||||
| 	  eval cmds=\"$finish_cmds\" | ||||
| 	  IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | ||||
| 	  save_ifs="$IFS"; IFS='~' | ||||
| 	  for cmd in $cmds; do | ||||
| 	    IFS="$save_ifs" | ||||
| 	    $show "$cmd" | ||||
| @@ -4699,7 +4715,7 @@ relink_command=\"$relink_command\"" | ||||
| 	    if test -n "$library_names"; then | ||||
| 	      # Do each command in the postuninstall commands. | ||||
| 	      eval cmds=\"$postuninstall_cmds\" | ||||
| 	      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | ||||
| 	      save_ifs="$IFS"; IFS='~' | ||||
| 	      for cmd in $cmds; do | ||||
| 		IFS="$save_ifs" | ||||
| 		$show "$cmd" | ||||
| @@ -4714,7 +4730,7 @@ relink_command=\"$relink_command\"" | ||||
| 	    if test -n "$old_library"; then | ||||
| 	      # Do each command in the old_postuninstall commands. | ||||
| 	      eval cmds=\"$old_postuninstall_cmds\" | ||||
| 	      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | ||||
| 	      save_ifs="$IFS"; IFS='~' | ||||
| 	      for cmd in $cmds; do | ||||
| 		IFS="$save_ifs" | ||||
| 		$show "$cmd" | ||||
|   | ||||
							
								
								
									
										44
									
								
								maketgz
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								maketgz
									
									
									
									
									
								
							| @@ -61,7 +61,8 @@ findprog() | ||||
| # Enforce a rerun of configure (updates the VERSION) | ||||
| # | ||||
|  | ||||
| ./config.status --recheck | ||||
| echo "Re-running config.status" | ||||
| ./config.status --recheck >/dev/null | ||||
|  | ||||
| ############################################################################ | ||||
| # | ||||
| @@ -73,7 +74,7 @@ if { findprog automake >/dev/null 2>/dev/null; } then | ||||
|   echo "- Could not find or run automake, I hope you know what you're doing!" | ||||
| else | ||||
|   echo "Runs automake --include-deps" | ||||
|   automake --include-deps Makefile | ||||
|   automake --include-deps Makefile >/dev/null | ||||
| fi | ||||
|  | ||||
| ############################################################################ | ||||
| @@ -84,7 +85,44 @@ make html | ||||
|  | ||||
| ############################################################################ | ||||
| # | ||||
| # Now run make dist | ||||
| # Now run make dist to generate a tar.gz archive | ||||
| # | ||||
|  | ||||
| targz="curl-$version.tar.gz" | ||||
| make dist | ||||
|  | ||||
| ############################################################################ | ||||
| # | ||||
| # Now make a bz2 archive from the tar.gz original | ||||
| # | ||||
|  | ||||
| bzip2="curl-$version.tar.bz2" | ||||
| echo "Generating $bzip2" | ||||
| gzip -dc $targz | bzip2 - > $bzip2 | ||||
|  | ||||
| ############################################################################ | ||||
| # | ||||
| # Now make a zip archive from the tar.gz original | ||||
| # | ||||
| makezip () | ||||
| { | ||||
|   rm -rf $tempdir | ||||
|   mkdir $tempdir | ||||
|   cd $tempdir | ||||
|   gzip -dc ../$targz | tar -xf - | ||||
|   find . | zip $zip -@ >/dev/null | ||||
|   mv $zip ../ | ||||
|   cd .. | ||||
|   rm -rf $tempdir | ||||
| } | ||||
|  | ||||
| zip="curl-$version.zip" | ||||
| echo "Generating $zip" | ||||
| tempdir=".builddir" | ||||
| makezip | ||||
|  | ||||
| echo "------------------" | ||||
| echo "maketgz report:" | ||||
| echo "" | ||||
| ls -l $targz $bzip2 $zip | ||||
|  | ||||
|   | ||||
| @@ -167,6 +167,37 @@ while(<STDIN>) { | ||||
|                 $fopens--; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     # ADDR url.c:1282 getaddrinfo() = 0x5ddd | ||||
|     elsif($_ =~ /^ADDR ([^:]*):(\d*) (.*)/) { | ||||
|         # generic match for the filename+linenumber | ||||
|         $source = $1; | ||||
|         $linenum = $2; | ||||
|         $function = $3; | ||||
|  | ||||
|         if($function =~ /getaddrinfo\(\) = (\(nil\)|0x([0-9a-f]*))/) { | ||||
|             my $add = $2; | ||||
|             if($add eq "(nil)") { | ||||
|                 ; | ||||
|             } | ||||
|             else { | ||||
|                 $addrinfo{$add}=1; | ||||
|                 $addrinfofile{$add}="$source:$linenum"; | ||||
|                 $addrinfos++; | ||||
|             } | ||||
|         } | ||||
|         # fclose(0x1026c8) | ||||
|         elsif($function =~ /freeaddrinfo\(0x([0-9a-f]*)\)/) { | ||||
|             if(!$addrinfo{$1}) { | ||||
|                 print "freeaddrinfo() without getaddrinfo(): $line\n"; | ||||
|             } | ||||
|             else { | ||||
|                 $addrinfo{$1}=0; | ||||
|                 $addrinfos--; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|          | ||||
|     } | ||||
|     else { | ||||
|         print "Not recognized prefix line: $line\n"; | ||||
| @@ -203,6 +234,15 @@ if($fopens) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| if($addrinfos) { | ||||
|     print "IPv6-style name resolve data left at:\n"; | ||||
|     for(keys %addrinfofile) { | ||||
|         if($addrinfo{$_} == 1) { | ||||
|             print "getaddrinfo() called at ".$addrinfofile{$_}."\n"; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| if($verbose) { | ||||
|     print "Mallocs: $mallocs\n", | ||||
|     "Reallocs: $reallocs\n", | ||||
|   | ||||
| @@ -1 +1,3 @@ | ||||
| SUBDIRS = cygwin | ||||
|  | ||||
| EXTRA_DIST = README | ||||
|   | ||||
							
								
								
									
										34
									
								
								packages/Win32/cygwin/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								packages/Win32/cygwin/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| EXTRA_DIST = README | ||||
|  | ||||
| # | ||||
| # Build a Cygwin binary tar ball | ||||
| # | ||||
| # Read the README file for details on using this Makefile | ||||
| # | ||||
| # NOTE: As I'm not particularly familiar with Makefiles, this was the | ||||
| #  best I could come up with. It should probably be enhanced someday  | ||||
| #  to actually use the correct target and pre-requisite names, etc... | ||||
| #  If anyone else wants to volunteer, feel free ;-) | ||||
| # | ||||
|  | ||||
| # Cygwin build number (default to "1") | ||||
| CYGBUILD = 1 | ||||
|  | ||||
| # Cygwin tarball build dir (fully-qualified name, gets deleted when done) | ||||
| cygwintmp = $(CURDIR)/cygwinbin-builddir | ||||
|  | ||||
| cygwinbin: | ||||
| 	rm -rf $(cygwintmp) | ||||
| 	$(MAKE) -C $(top_builddir) install prefix=$(cygwintmp)/usr | ||||
| 	$(mkinstalldirs) $(cygwintmp)/usr/doc/Cygwin \ | ||||
| 	                 $(cygwintmp)/usr/doc/$(PACKAGE)-$(VERSION) | ||||
| 	cd $(top_srcdir); \ | ||||
| 	  cp packages/Win32/cygwin/README \ | ||||
| 	  $(cygwintmp)/usr/doc/Cygwin/$(PACKAGE)-$(VERSION)-$(CYGBUILD).README | ||||
| 	cd $(top_srcdir) ; \ | ||||
| 	  cp CHANGES LEGAL MPL-1.1.txt README docs/FAQ docs/FEATURES docs/TODO \ | ||||
| 	  $(cygwintmp)/usr/doc/$(PACKAGE)-$(VERSION) | ||||
| 	cd $(cygwintmp) ; \ | ||||
| 	  tar cjf $(PACKAGE)-$(VERSION)-$(CYGBUILD).tar.bz2 usr | ||||
| 	mv $(cygwintmp)/$(PACKAGE)-$(VERSION)-$(CYGBUILD).tar.bz2 . \ | ||||
| 	  && rm -rf $(cygwintmp) | ||||
							
								
								
									
										60
									
								
								packages/Win32/cygwin/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								packages/Win32/cygwin/README
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| Curl is a tool for transferring files with URL syntax, supporting FTP, FTPS, | ||||
|  HTTP, HTTPS, GOPHER, TELNET, DICT, FILE and LDAP. Curl supports HTTPS  | ||||
|  certificates, HTTP POST, HTTP PUT, FTP uploading, kerberos, HTTP form based | ||||
|  upload, proxies, cookies, user+password authentication, file transfer resume, | ||||
|  http proxy tunneling and a busload of other useful tricks. | ||||
|  See /usr/doc/curl-<version>/FEATURES for more info. | ||||
|  | ||||
| cURL (as of 7.9.1) builds 100% cleanly OOTB. | ||||
|  | ||||
| The Cygwin specific source files (README and a Makefile for | ||||
|  building binary tarballs) are not in a CYGWIN-PATCHES directory. | ||||
| They are at: <srctop>/packages/Win32/cygwin/ | ||||
|  | ||||
|  | ||||
| Direct Dependencies: | ||||
|   OpenSSL 0.9.6b  | ||||
|   (*) cURL can be built without SSL support:  ./configure --without-ssl | ||||
|  | ||||
|  | ||||
| Canonical Homepage: | ||||
|   http://curl.haxx.se/ | ||||
|  | ||||
|  | ||||
| Canonical Download: | ||||
|   http://curl.haxx.se/download.html | ||||
|  | ||||
|  | ||||
| Build Instructions: | ||||
|   Download the source, move it to a location of your choosing, and then: | ||||
|  | ||||
|   $ tar xjf curl-<ver>-X-src.tar.bz2 | ||||
|   $ cd curl-<ver>-X | ||||
|   $ ./configure --prefix=/usr  | ||||
|   $ make | ||||
|   $ make test    # optional, requires perl | ||||
|   $ make install # (*) | ||||
|  | ||||
|   (*) LibTool 1.4.2 had a bug related to cygwin's use of ".exe" extensions, | ||||
|       such that "make install" blew up at curl.exe. See this URL for details: | ||||
|         http://mail.gnu.org/pipermail/libtool/2001-September/005549.html | ||||
|       The copy of ltmain.sh that is distributed with cURL includes this patch. | ||||
|  | ||||
|  | ||||
| Packaging Instructions: | ||||
|   To create a new binary tarball for cygwin's setup.exe, the first step is to | ||||
|   do a clean build (./configure and make). The 'make install' step is optional. | ||||
|   Then do: | ||||
|  | ||||
|   $ cd curl-<ver>-X | ||||
|   $ make cygwinbin CYGBUILD=X  | ||||
|  | ||||
|   where "X" is the cygwin release number (e.g. the "-1" in curl-7.9.3-1). | ||||
|   If you leave off "CYGBUILD=X", X defaults to 1. | ||||
|    | ||||
|   Assuming everything worked properly, you'll find your cygwin | ||||
|   binary tarball in the curl-<ver>-X/packages/Win32/cygwin/ directory. | ||||
|  | ||||
|  | ||||
| Cygwin port maintained by:  | ||||
|   Kevin Roth <kproth at bigfoot dot com> | ||||
| @@ -1,84 +0,0 @@ | ||||
| Revision history for Perl extension Curl::easy. | ||||
| Check out the file README for more info. | ||||
|  | ||||
| 1.1.7  Thu Sep 13 2001: - Cris Bailiff <c.bailiff@devsecure.com> | ||||
|     - Documentation Update only - Explicitly state that Curl_easy | ||||
|       is released under the MIT-X/MPL dual licence. No code changes. | ||||
|  | ||||
| 1.1.6  Mon Sep 10 2001: - Cris Bailiff <c.bailiff@devsecure.com> | ||||
|     - Fix segfault due to changes in header callback behaviour | ||||
|       since curl-7.8.1-pre3 | ||||
|  | ||||
| 1.1.5  Fri Apr 20 2001: - Cris Bailiff <c.bailiff@devsecure.com> | ||||
|     - Add latest CURLOPT_ and CURLINFO_ constants to the constants list | ||||
|  | ||||
| 1.1.4  Fri Apr 20 2001: - Cris Bailiff <c.bailiff@devsecure.com> | ||||
|     - Fix case where curl_slists such as 'HTTPHEADERS' need to | ||||
|       be re-set over persistant requests | ||||
|  | ||||
| 1.1.3  Wed Apr 18 2001: - Cris Bailiff <c.bailiff@devsecure.com> | ||||
|     - Change/shorten module function names: Curl::easy::curl_easy_setopt | ||||
|       becomes Curl::easy::setopt etc. This requires minor changes to existing | ||||
|       scripts.... | ||||
|     - Added callback function support to pass arbitrary SV * (including | ||||
| 	  FILE globs) from perl through libcurl to the perl callback. | ||||
| 	- Make callbacks still work with existing scripts which use STDIO | ||||
| 	- Initial support for libcurl 7.7.2 HEADERFUNCTION callback feature | ||||
| 	- Minor API cleanups/changes in the callback function signatures | ||||
| 	- Added Curl::easy::version function to return curl version string | ||||
| 	- Callback documentation added in easy.pm | ||||
|     - More tests in test.pl | ||||
|  | ||||
| 1.1.2  Mon Apr 16 2001: - Georg Horn <horn@koblenz-net.de> | ||||
|     - Added support for callback functions. This is for the curl_easy_setopt() | ||||
|       options WRITEFUNCTION, READFUNCTION, PROGRESSFUNCTION and PASSWDFUNCTION. | ||||
|       Still missing, but not really neccessary: Passing a FILE * pointer, | ||||
|       that is passed in from libcurl, on to the perl callback function. | ||||
|     - Various cleanups, fixes and enhancements to easy.xs and test.pl. | ||||
|  | ||||
| 1.1.1  Thu Apr 12 2001: | ||||
|     - Made more options of curl_easy_setopt() work: Options that require | ||||
|       a list of curl_slist structs to be passed in, like CURLOPT_HTTPHEADER, | ||||
|       are now working by passing a perl array containing the list elements. | ||||
|       As always, look at the test script test.pl for an example. | ||||
|  | ||||
| 1.1.0  Wed Apr 11 2001: | ||||
|     - tested against libcurl 7.7 | ||||
|     - Added new function Curl::easy::internal_setopt(). By calling | ||||
|       Curl::easy::internal_setopt(Curl::easy::USE_INTERNAL_VARS, 1); | ||||
|       the headers and content of the fetched page are no longer stored | ||||
|       into files (or written to stdout) but are stored into internal | ||||
|       Variables $Curl::easy::headers and $Curl::easy::content. | ||||
|  | ||||
| 1.0.2  Tue Oct 10 2000: | ||||
|     - runs with libcurl 7.4 | ||||
|     - modified curl_easy_getinfo(). It now calls curl_getinfo() that has | ||||
|       been added to libcurl in version 7.4. | ||||
|  | ||||
| 1.0.1  Tue Oct 10 2000: | ||||
|     - Added some missing features of curl_easy_setopt(): | ||||
|       - CURLOPT_ERRORBUFFER now works by passing the name of a perl | ||||
|         variable that shall be crated and the errormessage (if any) | ||||
| 	be stored to. | ||||
|       - Passing filehandles (Options FILE, INFILE and WRITEHEADER) now works. | ||||
|     Have a look at test.pl to see how it works... | ||||
|  | ||||
|     - Added a new function, curl_easy_getinfo(), that for now always | ||||
|       returns the number of bytes that where written to disk during the last | ||||
|       download. If the curl_easy_getinfo() function is included in libcurl, | ||||
|       (as promised by Daniel ;-)) i will turn this into just a call to this | ||||
|       function. | ||||
|  | ||||
| 1.0  Thu Oct 5 2000: | ||||
|     - first released version | ||||
|     - runs with libcurl 7.3 | ||||
|     - some features of curl_easy_setopt() are still missing: | ||||
|       - passing function pointers doesn't work (options WRITEFUNCTION, | ||||
| 	READFUNCTION and PROGRESSFUNCTION). | ||||
|       - passing FILE * pointers doesn't work (options FILE, INFILE and | ||||
| 	WRITEHEADER). | ||||
|       - passing linked lists doesn't work (options HTTPHEADER and | ||||
| 	HTTPPOST). | ||||
|       - setting the buffer where to store error messages in doesn't work | ||||
| 	(option ERRORBUFFER). | ||||
|  | ||||
| @@ -1,7 +0,0 @@ | ||||
| Changes | ||||
| MANIFEST | ||||
| Makefile.PL | ||||
| README | ||||
| easy.pm | ||||
| easy.xs | ||||
| test.pl | ||||
| @@ -1,14 +0,0 @@ | ||||
| # Makefile.PL for Perl extension Curl::easy. | ||||
| # Check out the file README for more info. | ||||
|  | ||||
| use ExtUtils::MakeMaker; | ||||
| # See lib/ExtUtils/MakeMaker.pm for details of how to influence | ||||
| # the contents of the Makefile that is written. | ||||
| WriteMakefile( | ||||
|     'NAME'	=> 'Curl::easy', | ||||
|     'VERSION_FROM' => 'easy.pm', # finds $VERSION | ||||
|     'LIBS'	=> ['-lcurl '],   # e.g., '-lm'  | ||||
|     'DEFINE'	=> '',     # e.g., '-DHAVE_SOMETHING'  | ||||
|     'INC'	=> '',     # e.g., '-I/usr/include/other'  | ||||
|     'clean'	=> {FILES => "head.out body.out"} | ||||
| ); | ||||
| @@ -1 +0,0 @@ | ||||
| EXTRA_DIST = Changes easy.pm easy.xs Makefile.PL MANIFEST README test.pl | ||||
| @@ -1,32 +0,0 @@ | ||||
| README for Perl extension Curl::easy. | ||||
|  | ||||
| The perl module Curl::easy provides an interface to the cURL library "libcurl". | ||||
| See http://curl.haxx.se/ for more information on cURL and libcurl. | ||||
|  | ||||
| This module requires libcurl and the corresponding headerfiles to be | ||||
| installed. You then may install this module via the usual way: | ||||
|  | ||||
|     perl Makefile.PL | ||||
|     make | ||||
|     make test | ||||
|     make install | ||||
|  | ||||
| The module provides the same functionality as libcurl provides to C programs, | ||||
| please refer to the documentation of libcurl. Some examples may be found in | ||||
| test.pl. | ||||
|  | ||||
| This software is distributed AS IS, WITHOUT WARRANTY OF ANY KIND, either | ||||
| express or implied. Send praise, patches, money, beer and pizza to the author. | ||||
| Send complaints to /dev/null. ;-) | ||||
|  | ||||
| The author of this software is Georg Horn <horn@koblenz-net.de> | ||||
| Parts of the callback support have been added by Cris Bailiff | ||||
| <c.bailiff@awayweb.com> and Forrest Cahoon <forrest.cahoon@merrillcorp.com> | ||||
|  | ||||
| The latest version can be downloaded from http://koblenz-net.de/~horn/export/ | ||||
|   | ||||
| Copyright (C) 2000, Daniel Stenberg, , et al.   | ||||
| You may opt to use, copy, modify, merge, publish, distribute and/or sell | ||||
| copies of the Software, and permit persons to whom the Software is | ||||
| furnished to do so, under the terms of the MPL or the MIT/X-derivate  | ||||
| licenses. You may pick one of these licenses.                                              | ||||
| @@ -1,273 +0,0 @@ | ||||
| # Perl interface for libcurl. Check out the file README for more info. | ||||
|  | ||||
| package Curl::easy; | ||||
|  | ||||
| use strict; | ||||
| use Carp; | ||||
| use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $AUTOLOAD); | ||||
|  | ||||
| require Exporter; | ||||
| require DynaLoader; | ||||
| require AutoLoader; | ||||
|  | ||||
| @ISA = qw(Exporter DynaLoader); | ||||
| # Items to export into callers namespace by default. Note: do not export | ||||
| # names by default without a very good reason. Use EXPORT_OK instead. | ||||
| # Do not simply export all your public functions/methods/constants. | ||||
| @EXPORT = qw( | ||||
| CURLOPT_AUTOREFERER | ||||
| CURLOPT_COOKIE | ||||
| CURLOPT_COOKIEFILE | ||||
| CURLOPT_CRLF | ||||
| CURLOPT_CUSTOMREQUEST | ||||
| CURLOPT_ERRORBUFFER | ||||
| CURLOPT_FAILONERROR | ||||
| CURLOPT_FILE | ||||
| CURLOPT_FOLLOWLOCATION | ||||
| CURLOPT_FTPAPPEND | ||||
| CURLOPT_FTPASCII | ||||
| CURLOPT_FTPLISTONLY | ||||
| CURLOPT_FTPPORT | ||||
| CURLOPT_HEADER | ||||
| CURLOPT_HEADERFUNCTION | ||||
| CURLOPT_HTTPHEADER | ||||
| CURLOPT_HTTPPOST | ||||
| CURLOPT_HTTPPROXYTUNNEL | ||||
| CURLOPT_HTTPREQUEST | ||||
| CURLOPT_INFILE | ||||
| CURLOPT_INFILESIZE | ||||
| CURLOPT_INTERFACE | ||||
| CURLOPT_KRB4LEVEL | ||||
| CURLOPT_LOW_SPEED_LIMIT | ||||
| CURLOPT_LOW_SPEED_TIME | ||||
| CURLOPT_MUTE | ||||
| CURLOPT_NETRC | ||||
| CURLOPT_NOBODY | ||||
| CURLOPT_NOPROGRESS | ||||
| CURLOPT_NOTHING | ||||
| CURLOPT_PASSWDDATA | ||||
| CURLOPT_PASSWDFUNCTION | ||||
| CURLOPT_PORT | ||||
| CURLOPT_POST | ||||
| CURLOPT_POSTFIELDS | ||||
| CURLOPT_POSTFIELDSIZE | ||||
| CURLOPT_POSTQUOTE | ||||
| CURLOPT_PROGRESSDATA | ||||
| CURLOPT_PROGRESSFUNCTION | ||||
| CURLOPT_PROXY | ||||
| CURLOPT_PROXYPORT | ||||
| CURLOPT_PROXYUSERPWD | ||||
| CURLOPT_PUT | ||||
| CURLOPT_QUOTE | ||||
| CURLOPT_RANGE | ||||
| CURLOPT_READFUNCTION | ||||
| CURLOPT_REFERER | ||||
| CURLOPT_RESUME_FROM | ||||
| CURLOPT_SSLCERT | ||||
| CURLOPT_SSLCERTPASSWD | ||||
| CURLOPT_SSLVERSION | ||||
| CURLOPT_STDERR | ||||
| CURLOPT_TIMECONDITION | ||||
| CURLOPT_TIMEOUT | ||||
| CURLOPT_TIMEVALUE | ||||
| CURLOPT_TRANSFERTEXT | ||||
| CURLOPT_UPLOAD | ||||
| CURLOPT_URL | ||||
| CURLOPT_USERAGENT | ||||
| CURLOPT_USERPWD | ||||
| CURLOPT_VERBOSE | ||||
| CURLOPT_WRITEFUNCTION | ||||
| CURLOPT_WRITEHEADER | ||||
| CURLOPT_MAXREDIRS | ||||
| CURLOPT_FILETIME | ||||
| CURLOPT_TELNETOPTIONS | ||||
| CURLOPT_MAXCONNECTS | ||||
| CURLOPT_CLOSEPOLICY | ||||
| CURLOPT_CLOSEFUNCTION | ||||
| CURLOPT_FRESH_CONNECT | ||||
| CURLOPT_FORBID_REUSE | ||||
| CURLOPT_RANDOM_FILE | ||||
| CURLOPT_EGD_SOCKET | ||||
| CURLOPT_CONNECTTIMEOUT | ||||
|  | ||||
| CURLINFO_EFFECTIVE_URL | ||||
| CURLINFO_HTTP_CODE | ||||
| CURLINFO_TOTAL_TIME | ||||
| CURLINFO_NAMELOOKUP_TIME | ||||
| CURLINFO_CONNECT_TIME | ||||
| CURLINFO_PRETRANSFER_TIME | ||||
| CURLINFO_SIZE_UPLOAD | ||||
| CURLINFO_SIZE_DOWNLOAD | ||||
| CURLINFO_SPEED_DOWNLOAD | ||||
| CURLINFO_SPEED_UPLOAD | ||||
| CURLINFO_HEADER_SIZE | ||||
| CURLINFO_REQUEST_SIZE | ||||
| CURLINFO_SSL_VERIFYRESULT | ||||
| CURLINFO_FILETIME | ||||
| CURLINFO_CONTENT_LENGTH_DOWNLOAD | ||||
| CURLINFO_CONTENT_LENGTH_UPLOAD | ||||
|  | ||||
| USE_INTERNAL_VARS | ||||
| ); | ||||
|  | ||||
| $VERSION = '1.1.7'; | ||||
|  | ||||
| $Curl::easy::headers = ""; | ||||
| $Curl::easy::content = ""; | ||||
|  | ||||
| sub AUTOLOAD { | ||||
|     # This AUTOLOAD is used to 'autoload' constants from the constant() | ||||
|     # XS function. | ||||
|  | ||||
|     (my $constname = $AUTOLOAD) =~ s/.*:://; | ||||
|     return constant($constname, 0); | ||||
| } | ||||
|  | ||||
| bootstrap Curl::easy $VERSION; | ||||
|  | ||||
| # Preloaded methods go here. | ||||
|  | ||||
| # Autoload methods go after =cut, and are processed by the autosplit program. | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
| # Below is the stub of documentation for your module. You better edit it! | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| Curl::easy - Perl extension for libcurl | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|   use Curl::easy; | ||||
|   | ||||
|   $curl = Curl::easy::init(); | ||||
|   $CURLcode = Curl::easy::setopt($curl, CURLoption, Value); | ||||
|   $CURLcode = Curl::easy::perform($curl); | ||||
|   Curl::easy::cleanup($curl); | ||||
|   | ||||
| =head1 DESCRIPTION | ||||
|   | ||||
| This perl module provides an interface to the libcurl C library. See | ||||
| http://curl.haxx.se/ for more information on cURL and libcurl. | ||||
|   | ||||
| =head1 FILES and CALLBACKS | ||||
|  | ||||
| Curl::easy supports the various options of curl_easy_setopt which require either a FILE * or | ||||
| a callback function. | ||||
|  | ||||
| The perl callback functions are handled through a C wrapper which takes care of converting | ||||
| from C to perl variables and back again. This wrapper simplifies some C arguments to make | ||||
| them behave in a more 'perl' like manner. In particular, the read and write callbacks do not | ||||
| look just like the 'fread' and 'fwrite' C functions - perl variables do not need separate length | ||||
| parameters, and perl functions can return a list of variables, instead of needing a pointer | ||||
| to modify. The details are described below. | ||||
|  | ||||
| =head2 FILE handles (GLOBS) | ||||
|   | ||||
| Curl options which take a FILE, such as CURLOPT_FILE, CURLOPT_WRITEHEADER, CURLOPT_INFILE | ||||
| can be passed a perl file handle: | ||||
|   | ||||
|   open BODY,">body.out"; | ||||
|   $CURLcode = Curl::easy::setopt($curl, CURLOPT_FILE, BODY); | ||||
|  | ||||
| =head2 WRITE callback | ||||
|  | ||||
| The CUROPT_WRITEFUNCTION option may be set which will cause libcurl to callback to | ||||
| the given subroutine: | ||||
|  | ||||
|   sub chunk { my ($data,$pointer)=@_; ...; return length($data) } | ||||
|   $CURLcode = Curl::easy::setopt($curl, CURLOPT_WRITEFUNCTION, \&chunk ); | ||||
|   $CURLcode = Curl::easy::setopt($curl, CURLOPT_FILE, ); | ||||
|  | ||||
| In this case, the subroutine will be passed whatever is defined by CURLOPT_FILE. This can be | ||||
| a ref to a scalar, or a GLOB or anything else you like. | ||||
|  | ||||
| The callback function must return the number of bytes 'handled' ( length($data) ) or the transfer | ||||
| will abort. A transfer can be aborted by returning a 'length' of '-1'. | ||||
|  | ||||
| The option CURLOPT_WRITEHEADER can be set to pass a different '$pointer' into the CURLOPT_WRITEFUNCTION  | ||||
| for header values. This lets you collect the headers and body separately: | ||||
|  | ||||
|   my $headers=""; | ||||
|   my $body=""; | ||||
|   sub chunk { my ($data,$pointer)=@_; ${$pointer}.=$data; return length($data) } | ||||
|  | ||||
|   $CURLcode = Curl::easy::setopt($curl, CURLOPT_WRITEFUNCTION, \&chunk ); | ||||
|   $CURLcode = Curl::easy::setopt($curl, CURLOPT_WRITEHEADER, \$header ); | ||||
|   $CURLcode = Curl::easy::setopt($curl, CURLOPT_FILE, \$body ); | ||||
|  | ||||
| If you have libcurl > 7.7.1, then you could instead set CURLOPT_HEADERFUNCTION to a different callback, | ||||
| and have the header collected that way. | ||||
|  | ||||
| =head2 READ callback | ||||
|  | ||||
| Curl::easy supports CURLOPT_READFUNCTION. This function should look something like this: | ||||
|  | ||||
|     sub read_callback { | ||||
|         my ($maxlength,$pointer)=@_; | ||||
|  | ||||
| 		.... | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
| The subroutine must return an empty string "" at the end of the data. Note that this function | ||||
| isn't told how much data to provide - $maxlength is just the maximum size of the buffer | ||||
| provided by libcurl. If you are doing an HTTP POST or PUT for example, it is important that this | ||||
| function only returns as much data as the 'Content-Length' header specifies, followed by a | ||||
| an empty (0 length) buffer. | ||||
|  | ||||
| =head2 PROGRESS callback | ||||
|  | ||||
| Curl::easy supports CURLOPT_PROGRESSFUNCTION. This function should look something like this: | ||||
|  | ||||
|     sub prog_callb | ||||
|     { | ||||
|         my ($clientp,$dltotal,$dlnow,$ultotal,$ulnow)=@_; | ||||
| 		.... | ||||
|         return 0; | ||||
|     }                         | ||||
|  | ||||
| The function should return 0 normally, or -1 which will abort/cancel the transfer. $clientp is whatever | ||||
| value/scalar is set using the CURLOPT_PROGRESSDATA option. | ||||
|  | ||||
| =head2 PASSWD callback | ||||
|  | ||||
| Curl::easy supports CURLOPT_PASSWDFUNCTION. This function should look something like this: | ||||
|   | ||||
|     sub passwd_callb | ||||
|     { | ||||
| 		my ($clientp,$prompt,$buflen)=@_; | ||||
| 		... | ||||
|     	return (0,$data); | ||||
|     }                     | ||||
|  | ||||
| $clientp is whatever scalar is set using the CURLOPT_PASSWDDATA option. | ||||
| $prompt is a text string which can be used to prompt for a password. | ||||
| $buflen is the maximum accepted password reply. | ||||
|  | ||||
| The function must return 0 (for 'OK') and the password data as a list. Return (-1,"") to | ||||
| indicate an error. | ||||
|  | ||||
| =head1 AUTHOR | ||||
|   | ||||
| Georg Horn <horn@koblenz-net.de> | ||||
|   | ||||
| Additional callback,pod and test work by Cris Bailiff <c.bailiff@devsecure.com> | ||||
| and Forrest Cahoon <forrest.cahoon@merrillcorp.com> | ||||
|  | ||||
| =head1 Copyright | ||||
|  | ||||
| Copyright (C) 2000, Daniel Stenberg, , et al. | ||||
|   | ||||
| You may opt to use, copy, modify, merge, publish, distribute and/or sell | ||||
| copies of the Software, and permit persons to whom the Software is furnished | ||||
| to do so, under the terms of the MPL or the MIT/X-derivate licenses. You may | ||||
| pick one of these licenses. | ||||
|  | ||||
| =head1 SEE ALSO | ||||
|  | ||||
| http://curl.haxx.se/ | ||||
|  | ||||
| =cut | ||||
| @@ -1,788 +0,0 @@ | ||||
| /* Perl interface for libcurl. Check out the file README for more info. */ | ||||
| /*   | ||||
|  | ||||
| Copyright (C) 2000, Daniel Stenberg, , et al.   | ||||
| You may opt to use, copy, modify, merge, publish, distribute and/or  | ||||
| sell copies of the Software, and permit persons to whom the  | ||||
| Software is furnished to do so, under the terms of the MPL or | ||||
| the MIT/X-derivate licenses. You may pick one of these licenses.                                              | ||||
| */ | ||||
|  | ||||
| #include "EXTERN.h" | ||||
| #include "perl.h" | ||||
| #include "XSUB.h" | ||||
|  | ||||
| #include <curl/curl.h> | ||||
| #include <curl/easy.h> | ||||
|  | ||||
| #if (LIBCURL_VERSION_NUM<0x070702) | ||||
| #define CURLOPT_HEADERFUNCTION 20079 | ||||
| #define header_callback_func write_callback_func | ||||
| #else | ||||
| #define header_callback_func writeheader_callback_func | ||||
| #endif | ||||
|  | ||||
| /* Lists that can be set via curl_easy_setopt() */ | ||||
|  | ||||
| static struct curl_slist *httpheader = NULL, *quote = NULL, *postquote = NULL; | ||||
|  | ||||
|  | ||||
| /* Buffer and varname for option CURLOPT_ERRORBUFFER */ | ||||
|  | ||||
| static char errbuf[CURL_ERROR_SIZE]; | ||||
| static char *errbufvarname = NULL; | ||||
|  | ||||
|  | ||||
| /* Callback functions */ | ||||
|  | ||||
| static SV *read_callback = NULL, *write_callback = NULL, | ||||
|           *progress_callback = NULL, *passwd_callback = NULL, | ||||
| 	  *header_callback = NULL;  | ||||
| 	  /* *closepolicy_callback = NULL; */ | ||||
|  | ||||
|  | ||||
| /* For storing the content */ | ||||
|  | ||||
| static char *contbuf = NULL, *bufptr = NULL; | ||||
| static int bufsize = 32768, contlen = 0; | ||||
|  | ||||
|  | ||||
| /* Internal options for this perl module */ | ||||
|  | ||||
| #define USE_INTERNAL_VARS 0x01 | ||||
|  | ||||
| static int internal_options = 0; | ||||
|  | ||||
|  | ||||
| /* Setup these global vars */ | ||||
|  | ||||
| static void init_globals(void) | ||||
| { | ||||
|     if (httpheader) curl_slist_free_all(httpheader); | ||||
|     if (quote) curl_slist_free_all(quote); | ||||
|     if (postquote) curl_slist_free_all(postquote); | ||||
|     httpheader = quote = postquote = NULL; | ||||
|     if (errbufvarname) free(errbufvarname); | ||||
|     errbufvarname = NULL; | ||||
|     if (contbuf == NULL) { | ||||
| 	contbuf = malloc(bufsize + 1); | ||||
|     } | ||||
|     bufptr = contbuf; | ||||
|     *bufptr = '\0'; | ||||
|     contlen = 0; | ||||
|     internal_options = 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Register a callback function */ | ||||
|  | ||||
| static void register_callback(SV **callback, SV *function) | ||||
| { | ||||
|     if (*callback == NULL) { | ||||
| 	/* First time, create new SV */ | ||||
| 	*callback = newSVsv(function); | ||||
|     } else { | ||||
| 	/* Been there, done that. Just overwrite the SV */ | ||||
| 	SvSetSV(*callback, function); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* generic fwrite callback, which decides which callback to call */ | ||||
| static size_t | ||||
| fwrite_wrapper (const void *ptr, | ||||
| 		size_t size, | ||||
| 		size_t nmemb, | ||||
| 		void *stream, | ||||
| 		void *call_function) | ||||
| { | ||||
|     dSP; | ||||
|     int count, status; | ||||
|     SV *sv; | ||||
|  | ||||
|     if (call_function) { | ||||
| 	/* then we are doing a callback to perl */ | ||||
|  | ||||
| 	ENTER; | ||||
| 	SAVETMPS; | ||||
|  | ||||
| 	PUSHMARK(SP); | ||||
|  | ||||
| 	if (stream == stdout) { | ||||
| 	    sv = newSViv(0);	/* FIXME: should cast stdout to GLOB somehow? */ | ||||
| 	} else if (stream == NULL) { | ||||
|             sv = &PL_sv_undef; | ||||
|         } else {		/* its already an SV */ | ||||
| 	    sv = stream; | ||||
| 	} | ||||
|  | ||||
| 	if (ptr != NULL) { | ||||
| 	    XPUSHs(sv_2mortal(newSVpvn((char *)ptr, (STRLEN)(size * nmemb)))); | ||||
| 	} else { | ||||
| 	    XPUSHs(sv_2mortal(newSVpv("", 0))); | ||||
| 	} | ||||
| 	XPUSHs(sv_2mortal(newSVsv(sv)));	/* CURLOPT_FILE SV* */ | ||||
| 	PUTBACK; | ||||
|  | ||||
| 	count = perl_call_sv((SV *) call_function, G_SCALAR); | ||||
|  | ||||
| 	SPAGAIN; | ||||
| 	if (count != 1) | ||||
| 	    croak("Big trouble, perl_call_sv(write_callback) didn't return status\n"); | ||||
|  | ||||
| 	status = POPi; | ||||
|  | ||||
| 	PUTBACK; | ||||
|  | ||||
| 	FREETMPS; | ||||
| 	LEAVE; | ||||
| 	return status; | ||||
|  | ||||
|     } else { | ||||
| 	/* default to a normal 'fwrite' */ | ||||
| 	/* stream could be a FILE * or an SV * */ | ||||
|         /* or NULL since libcurl-7.8.1pre3  */ | ||||
| 	FILE *f; | ||||
|  | ||||
| 	if (stream == stdout || | ||||
|             stream == NULL) { /* the only possible FILE ? Think so */ | ||||
| 	    f = stream; | ||||
| 	} else {		/* its a GLOB */ | ||||
| 	    f = IoIFP(sv_2io(stream));	/* may barf if not a GLOB */ | ||||
| 	} | ||||
|  | ||||
| 	if (f) | ||||
|            return fwrite(ptr, size, nmemb, f); | ||||
| 	else | ||||
|            return (size_t) size*nmemb; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* Write callback for calling a perl callback */ | ||||
| size_t | ||||
| write_callback_func( const void *ptr, size_t size, | ||||
|                                 size_t nmemb, void *stream) | ||||
| { | ||||
|     return fwrite_wrapper(ptr,size,nmemb,stream, | ||||
|         write_callback); | ||||
| } | ||||
|  | ||||
| /* header callback for calling a perl callback */ | ||||
| size_t | ||||
| writeheader_callback_func( const void *ptr, size_t size, | ||||
|                               size_t nmemb, void *stream) | ||||
| { | ||||
|     return fwrite_wrapper(ptr,size,nmemb,stream, | ||||
|         header_callback); | ||||
| } | ||||
|  | ||||
| size_t | ||||
| read_callback_func( void *ptr, size_t size, | ||||
|                     size_t nmemb, void *stream) | ||||
| { | ||||
|     dSP ; | ||||
|  | ||||
|     int count; | ||||
|     SV *sv; | ||||
|     STRLEN len; | ||||
|     size_t maxlen,mylen; | ||||
|     char *p; | ||||
|  | ||||
|     maxlen = size*nmemb; | ||||
|  | ||||
|     if (read_callback) { | ||||
|         /* we are doing a callback to perl */ | ||||
|  | ||||
|         ENTER ; | ||||
|         SAVETMPS ; | ||||
|   | ||||
|         PUSHMARK(SP) ; | ||||
| 	 | ||||
|         if (stream == stdin) { | ||||
|             sv = newSViv(0); /* should cast stdin to GLOB somehow? */ | ||||
|         } else { /* its an SV */ | ||||
|             sv = stream; | ||||
|         } | ||||
| 	 | ||||
|         XPUSHs(sv_2mortal(newSViv(maxlen))); /* send how many bytes please */ | ||||
|         XPUSHs(sv_2mortal(newSVsv(sv))); /* CURLOPT_INFILE SV*  */ | ||||
|         PUTBACK ; | ||||
|  | ||||
|         count = perl_call_sv(read_callback, G_SCALAR); | ||||
| 	  | ||||
|         SPAGAIN; | ||||
|         if (count != 1) | ||||
|             croak("Big trouble, perl_call_sv(read_callback) didn't return data\n"); | ||||
|  | ||||
|         sv = POPs; | ||||
|         p = SvPV(sv,len); | ||||
|  | ||||
|         /* only allowed to return the number of bytes asked for */ | ||||
|         mylen = len<maxlen ? len : maxlen; | ||||
|         memcpy(ptr,p,(size_t)mylen); | ||||
|         PUTBACK ; | ||||
|   | ||||
|         FREETMPS ; | ||||
|         LEAVE ; | ||||
|         return (size_t) (mylen/size); | ||||
|     } else { | ||||
|        /* default to a normal 'fread' */ | ||||
|        /* stream could be a FILE * or an SV * */ | ||||
|        FILE *f; | ||||
|  | ||||
|        if (stream == stdin) { /* the only possible FILE ? Think so*/ | ||||
|            f = stream; | ||||
|        } else { /* its a GLOB */ | ||||
|            f = IoIFP(sv_2io(stream)); /* may barf if not a GLOB */ | ||||
|        } | ||||
|  | ||||
|        return fread(ptr,size,nmemb,f); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* Porgress callback for calling a perl callback */ | ||||
|  | ||||
| static int progress_callback_func(void *clientp, size_t dltotal, size_t dlnow, | ||||
|     size_t ultotal, size_t ulnow) | ||||
| { | ||||
|     dSP; | ||||
|     int count; | ||||
|  | ||||
|     ENTER; | ||||
|     SAVETMPS; | ||||
|     PUSHMARK(sp); | ||||
|     if (clientp != NULL) { | ||||
| 	XPUSHs(sv_2mortal(newSVpv(clientp, 0))); | ||||
|     } else { | ||||
| 	XPUSHs(sv_2mortal(newSVpv("", 0))); | ||||
|     } | ||||
|     XPUSHs(sv_2mortal(newSViv(dltotal))); | ||||
|     XPUSHs(sv_2mortal(newSViv(dlnow))); | ||||
|     XPUSHs(sv_2mortal(newSViv(ultotal))); | ||||
|     XPUSHs(sv_2mortal(newSViv(ulnow))); | ||||
|     PUTBACK; | ||||
|     count = perl_call_sv(progress_callback, G_SCALAR); | ||||
|     SPAGAIN; | ||||
|     if (count != 1) | ||||
| 	croak("Big trouble, perl_call_sv(progress_callback) didn't return 1\n"); | ||||
|     count = POPi; | ||||
|     PUTBACK; | ||||
|     FREETMPS; | ||||
|     LEAVE; | ||||
|     return count; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Password callback for calling a perl callback */ | ||||
|  | ||||
| static int passwd_callback_func(void *clientp, char *prompt, char *buffer, | ||||
|     int buflen) | ||||
| { | ||||
|     dSP; | ||||
|     int count; | ||||
|     SV *sv; | ||||
|     STRLEN len; | ||||
|     size_t mylen; | ||||
|     char *p;             | ||||
|  | ||||
|     ENTER; | ||||
|     SAVETMPS; | ||||
|     PUSHMARK(sp); | ||||
|     if (clientp != NULL) { | ||||
|         XPUSHs(sv_2mortal(newSVsv(clientp))); | ||||
|     } else { | ||||
|         XPUSHs(sv_2mortal(newSVpv("", 0))); | ||||
|     } | ||||
|     XPUSHs(sv_2mortal(newSVpv(prompt, 0))); | ||||
|     XPUSHs(sv_2mortal(newSViv(buflen))); | ||||
|     PUTBACK; | ||||
|     count = perl_call_sv(passwd_callback, G_ARRAY); | ||||
|     SPAGAIN; | ||||
|     if (count != 2) | ||||
| 	croak("Big trouble, perl_call_sv(passwd_callback) didn't return status + data\n"); | ||||
|  | ||||
|     sv = POPs; | ||||
|     count = POPi; | ||||
|  | ||||
|     p = SvPV(sv,len); | ||||
|   | ||||
|     /* only allowed to return the number of bytes asked for */ | ||||
|     mylen = len<(buflen-1) ? len : (buflen-1); | ||||
|     memcpy(buffer,p,mylen); | ||||
|     buffer[buflen]=0; /* ensure C string terminates */ | ||||
|  | ||||
|     PUTBACK; | ||||
|     FREETMPS; | ||||
|     LEAVE; | ||||
|     return count; | ||||
| } | ||||
|  | ||||
|  | ||||
| #if 0 | ||||
| /* awaiting closepolicy prototype */ | ||||
| int  | ||||
| closepolicy_callback_func(void *clientp) | ||||
| { | ||||
|    dSP; | ||||
|    int argc, status; | ||||
|    SV *pl_status; | ||||
|  | ||||
|    ENTER; | ||||
|    SAVETMPS; | ||||
|  | ||||
|    PUSHMARK(SP); | ||||
|    PUTBACK; | ||||
|  | ||||
|    argc = perl_call_sv(closepolicy_callback, G_SCALAR); | ||||
|    SPAGAIN; | ||||
|  | ||||
|    if (argc != 1) { | ||||
|       croak("Unexpected number of arguments returned from closefunction callback\n"); | ||||
|    } | ||||
|    pl_status = POPs; | ||||
|    status = SvTRUE(pl_status) ? 0 : 1; | ||||
|  | ||||
|    PUTBACK; | ||||
|    FREETMPS; | ||||
|    LEAVE; | ||||
|  | ||||
|    return status; | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Internal write callback. Only used if USE_INTERNAL_VARS was specified */ | ||||
|  | ||||
| static size_t internal_write_callback(char *data, size_t size, size_t num, | ||||
|     FILE *fp) | ||||
| { | ||||
|     int i; | ||||
|  | ||||
|     size *= num; | ||||
|     if ((contlen + size) >= bufsize) { | ||||
| 	bufsize *= 2; | ||||
| 	contbuf = realloc(contbuf, bufsize + 1); | ||||
| 	bufptr = contbuf + contlen; | ||||
|     } | ||||
|     contlen += size; | ||||
|     for (i = 0; i < size; i++) { | ||||
| 	*bufptr++ = *data++; | ||||
|     } | ||||
|     *bufptr = '\0'; | ||||
|     return size; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int | ||||
| constant(char *name, int arg) | ||||
| { | ||||
|     errno = 0; | ||||
|     if (strncmp(name, "CURLINFO_", 9) == 0) { | ||||
| 	name += 9; | ||||
| 	switch (*name) { | ||||
| 	case 'A': | ||||
| 	case 'B': | ||||
| 	case 'C': | ||||
| 	    if (strEQ(name, "CONNECT_TIME")) return CURLINFO_CONNECT_TIME; | ||||
| 	    if (strEQ(name, "CONTENT_LENGTH_DOWNLOAD")) return CURLINFO_CONTENT_LENGTH_DOWNLOAD; | ||||
| 	    if (strEQ(name, "CONTENT_LENGTH_UPLOAD")) return CURLINFO_CONTENT_LENGTH_UPLOAD; | ||||
| 	    break; | ||||
| 	case 'D': | ||||
| 	case 'E': | ||||
| 	    if (strEQ(name, "EFFECTIVE_URL")) return CURLINFO_EFFECTIVE_URL; | ||||
| 	    break; | ||||
| 	case 'F': | ||||
| 	    if (strEQ(name, "FILETIME")) return CURLINFO_FILETIME; | ||||
| 	    break; | ||||
| 	case 'G': | ||||
| 	case 'H': | ||||
| 	    if (strEQ(name, "HEADER_SIZE")) return CURLINFO_HEADER_SIZE; | ||||
| 	    if (strEQ(name, "HTTP_CODE")) return CURLINFO_HTTP_CODE; | ||||
| 	    break; | ||||
| 	case 'I': | ||||
| 	case 'J': | ||||
| 	case 'K': | ||||
| 	case 'L': | ||||
| 	case 'M': | ||||
| 	case 'N': | ||||
| 	    if (strEQ(name, "NAMELOOKUP_TIME")) return CURLINFO_NAMELOOKUP_TIME; | ||||
| 	    break; | ||||
| 	case 'O': | ||||
| 	case 'P': | ||||
| 	    if (strEQ(name, "PRETRANSFER_TIME")) return CURLINFO_PRETRANSFER_TIME; | ||||
| 	    break; | ||||
| 	case 'Q': | ||||
| 	case 'R': | ||||
| 	    if (strEQ(name, "REQUEST_SIZE")) return CURLINFO_REQUEST_SIZE; | ||||
| 	    break; | ||||
| 	case 'S': | ||||
| 	    if (strEQ(name, "SSL_VERIFYRESULT")) return CURLINFO_SSL_VERIFYRESULT; | ||||
| 	    break; | ||||
| 	case 'T': | ||||
| 	    if (strEQ(name, "SIZE_DOWNLOAD")) return CURLINFO_SIZE_DOWNLOAD; | ||||
| 	    if (strEQ(name, "SIZE_UPLOAD")) return CURLINFO_SIZE_UPLOAD; | ||||
| 	    if (strEQ(name, "SPEED_DOWNLOAD")) return CURLINFO_SPEED_DOWNLOAD; | ||||
| 	    if (strEQ(name, "SPEED_UPLOAD")) return CURLINFO_SPEED_UPLOAD; | ||||
| 	    if (strEQ(name, "TOTAL_TIME")) return CURLINFO_TOTAL_TIME; | ||||
| 	    break; | ||||
| 	case 'U': | ||||
| 	case 'V': | ||||
| 	case 'W': | ||||
| 	case 'X': | ||||
| 	case 'Y': | ||||
| 	case 'Z': | ||||
| 	    break; | ||||
| 	} | ||||
|     } | ||||
|     if (strncmp(name, "CURLOPT_", 8) == 0) { | ||||
| 	name += 8; | ||||
| 	switch (*name) { | ||||
| 	case 'A': | ||||
| 	case 'B': | ||||
| 	    if (strEQ(name, "AUTOREFERER")) return CURLOPT_AUTOREFERER; | ||||
| 	    break; | ||||
| 	case 'C': | ||||
| 	    if (strEQ(name, "CONNECTTIMEOUT")) return CURLOPT_CONNECTTIMEOUT; | ||||
| 	    if (strEQ(name, "COOKIE")) return CURLOPT_COOKIE; | ||||
| 	    if (strEQ(name, "COOKIEFILE")) return CURLOPT_COOKIEFILE; | ||||
| 	    if (strEQ(name, "CLOSEFUNCTION")) return CURLOPT_CLOSEFUNCTION; | ||||
| 	    if (strEQ(name, "CLOSEPOLICY")) return CURLOPT_CLOSEPOLICY; | ||||
| 	    if (strEQ(name, "CRLF")) return CURLOPT_CRLF; | ||||
| 	    if (strEQ(name, "CUSTOMREQUEST")) return CURLOPT_CUSTOMREQUEST; | ||||
| 	    break; | ||||
| 	case 'D': | ||||
| 	case 'E': | ||||
| 	    if (strEQ(name, "EGDSOCKET")) return CURLOPT_EGDSOCKET; | ||||
| 	    if (strEQ(name, "ERRORBUFFER")) return CURLOPT_ERRORBUFFER; | ||||
|             break; | ||||
| 	case 'F': | ||||
| 	    if (strEQ(name, "FAILONERROR")) return CURLOPT_FAILONERROR; | ||||
| 	    if (strEQ(name, "FILE")) return CURLOPT_FILE; | ||||
| 	    if (strEQ(name, "FILETIME")) return CURLOPT_FILETIME; | ||||
| 	    if (strEQ(name, "FOLLOWLOCATION")) return CURLOPT_FOLLOWLOCATION; | ||||
| 	    if (strEQ(name, "FORBID_REUSE")) return CURLOPT_FORBID_REUSE; | ||||
| 	    if (strEQ(name, "FTPAPPEND")) return CURLOPT_FTPAPPEND; | ||||
| 	    if (strEQ(name, "FTPASCII")) return CURLOPT_FTPASCII; | ||||
| 	    if (strEQ(name, "FTPLISTONLY")) return CURLOPT_FTPLISTONLY; | ||||
| 	    if (strEQ(name, "FTPPORT")) return CURLOPT_FTPPORT; | ||||
| 	    if (strEQ(name, "FRESH_CONNECT")) return CURLOPT_FRESH_CONNECT; | ||||
| 	    break; | ||||
| 	case 'G': | ||||
| 	case 'H': | ||||
| 	    if (strEQ(name, "HEADER")) return CURLOPT_HEADER; | ||||
|             if (strEQ(name, "HEADERFUNCTION")) return CURLOPT_HEADERFUNCTION; | ||||
| 	    if (strEQ(name, "HTTPHEADER")) return CURLOPT_HTTPHEADER; | ||||
| 	    if (strEQ(name, "HTTPPOST")) return CURLOPT_HTTPPOST; | ||||
| 	    if (strEQ(name, "HTTPPROXYTUNNEL")) return CURLOPT_HTTPPROXYTUNNEL; | ||||
| 	    if (strEQ(name, "HTTPREQUEST")) return CURLOPT_HTTPREQUEST; | ||||
| 	    break; | ||||
| 	case 'I': | ||||
| 	case 'J': | ||||
| 	    if (strEQ(name, "INFILE")) return CURLOPT_INFILE; | ||||
| 	    if (strEQ(name, "INFILESIZE")) return CURLOPT_INFILESIZE; | ||||
| 	    if (strEQ(name, "INTERFACE")) return CURLOPT_INTERFACE; | ||||
| 	    break; | ||||
| 	case 'K': | ||||
| 	case 'L': | ||||
| 	    if (strEQ(name, "KRB4LEVEL")) return CURLOPT_KRB4LEVEL; | ||||
| 	    if (strEQ(name, "LOW_SPEED_LIMIT")) return CURLOPT_LOW_SPEED_LIMIT; | ||||
| 	    if (strEQ(name, "LOW_SPEED_TIME")) return CURLOPT_LOW_SPEED_TIME; | ||||
| 	    break; | ||||
| 	case 'M': | ||||
| 	    if (strEQ(name, "MAXCONNECTS")) return CURLOPT_MAXCONNECTS; | ||||
| 	    if (strEQ(name, "MAXREDIRS")) return CURLOPT_MAXREDIRS; | ||||
| 	    break; | ||||
| 	case 'N': | ||||
| 	    if (strEQ(name, "MUTE")) return CURLOPT_MUTE; | ||||
| 	    if (strEQ(name, "NETRC")) return CURLOPT_NETRC; | ||||
| 	    if (strEQ(name, "NOBODY")) return CURLOPT_NOBODY; | ||||
| 	    if (strEQ(name, "NOPROGRESS")) return CURLOPT_NOPROGRESS; | ||||
| 	    if (strEQ(name, "NOTHING")) return CURLOPT_NOTHING; | ||||
| 	    break; | ||||
| 	case 'O': | ||||
| 	case 'P': | ||||
| 	    if (strEQ(name, "PASSWDDATA")) return CURLOPT_PASSWDDATA; | ||||
| 	    if (strEQ(name, "PASSWDFUNCTION")) return CURLOPT_PASSWDFUNCTION; | ||||
| 	    if (strEQ(name, "PORT")) return CURLOPT_PORT; | ||||
| 	    if (strEQ(name, "POST")) return CURLOPT_POST; | ||||
| 	    if (strEQ(name, "POSTFIELDS")) return CURLOPT_POSTFIELDS; | ||||
| 	    if (strEQ(name, "POSTFIELDSIZE")) return CURLOPT_POSTFIELDSIZE; | ||||
| 	    if (strEQ(name, "POSTQUOTE")) return CURLOPT_POSTQUOTE; | ||||
| 	    if (strEQ(name, "PROGRESSDATA")) return CURLOPT_PROGRESSDATA; | ||||
| 	    if (strEQ(name, "PROGRESSFUNCTION")) return CURLOPT_PROGRESSFUNCTION; | ||||
| 	    if (strEQ(name, "PROXY")) return CURLOPT_PROXY; | ||||
| 	    if (strEQ(name, "PROXYPORT")) return CURLOPT_PROXYPORT; | ||||
| 	    if (strEQ(name, "PROXYUSERPWD")) return CURLOPT_PROXYUSERPWD; | ||||
| 	    if (strEQ(name, "PUT")) return CURLOPT_PUT; | ||||
| 	    break; | ||||
| 	case 'Q': | ||||
| 	    if (strEQ(name, "QUOTE")) return CURLOPT_QUOTE; | ||||
|             break; | ||||
|  	case 'R': | ||||
| 	    if (strEQ(name, "RANDOM_FILE")) return CURLOPT_RANDOM_FILE; | ||||
| 	    if (strEQ(name, "RANGE")) return CURLOPT_RANGE; | ||||
| 	    if (strEQ(name, "READFUNCTION")) return CURLOPT_READFUNCTION; | ||||
| 	    if (strEQ(name, "REFERER")) return CURLOPT_REFERER; | ||||
| 	    if (strEQ(name, "RESUME_FROM")) return CURLOPT_RESUME_FROM; | ||||
| 	    break; | ||||
| 	case 'S': | ||||
| 	    if (strEQ(name, "SSLCERT")) return CURLOPT_SSLCERT; | ||||
| 	    if (strEQ(name, "SSLCERTPASSWD")) return CURLOPT_SSLCERTPASSWD; | ||||
| 	    if (strEQ(name, "SSLVERSION")) return CURLOPT_SSLVERSION; | ||||
| 	    if (strEQ(name, "STDERR")) return CURLOPT_STDERR; | ||||
|             break; | ||||
| 	case 'T': | ||||
| 	    if (strEQ(name, "TELNETOPTIONS")) return CURLOPT_TELNETOPTIONS; | ||||
| 	    if (strEQ(name, "TIMECONDITION")) return CURLOPT_TIMECONDITION; | ||||
| 	    if (strEQ(name, "TIMEOUT")) return CURLOPT_TIMEOUT; | ||||
| 	    if (strEQ(name, "TIMEVALUE")) return CURLOPT_TIMEVALUE; | ||||
| 	    if (strEQ(name, "TRANSFERTEXT")) return CURLOPT_TRANSFERTEXT; | ||||
| 	    break; | ||||
| 	case 'U': | ||||
| 	case 'V': | ||||
| 	    if (strEQ(name, "UPLOAD")) return CURLOPT_UPLOAD; | ||||
| 	    if (strEQ(name, "URL")) return CURLOPT_URL; | ||||
| 	    if (strEQ(name, "USERAGENT")) return CURLOPT_USERAGENT; | ||||
| 	    if (strEQ(name, "USERPWD")) return CURLOPT_USERPWD; | ||||
| 	    if (strEQ(name, "VERBOSE")) return CURLOPT_VERBOSE; | ||||
| 	    break; | ||||
| 	case 'W': | ||||
| 	case 'X': | ||||
| 	case 'Y': | ||||
| 	case 'Z': | ||||
| 	    if (strEQ(name, "WRITEFUNCTION")) return CURLOPT_WRITEFUNCTION; | ||||
| 	    if (strEQ(name, "WRITEHEADER")) return CURLOPT_WRITEHEADER; | ||||
| 	    if (strEQ(name, "WRITEINFO")) return CURLOPT_WRITEINFO; | ||||
| 	    break; | ||||
| 	} | ||||
|     } | ||||
|     if (strEQ(name, "USE_INTERNAL_VARS")) return USE_INTERNAL_VARS; | ||||
|     errno = EINVAL; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| MODULE = Curl::easy		PACKAGE = Curl::easy		PREFIX = curl_easy_ | ||||
|  | ||||
| int | ||||
| constant(name,arg) | ||||
|     char * name | ||||
|     int arg | ||||
|  | ||||
|  | ||||
| void * | ||||
| curl_easy_init() | ||||
| CODE: | ||||
|     init_globals(); | ||||
|     RETVAL = curl_easy_init(); | ||||
|     curl_easy_setopt(RETVAL, CURLOPT_HEADERFUNCTION, header_callback_func); | ||||
|     curl_easy_setopt(RETVAL, CURLOPT_WRITEFUNCTION, write_callback_func); | ||||
| OUTPUT: | ||||
|     RETVAL | ||||
|  | ||||
| char * | ||||
| curl_easy_version() | ||||
| CODE: | ||||
| 	RETVAL=curl_version(); | ||||
| OUTPUT: | ||||
| 	RETVAL | ||||
|  | ||||
| int | ||||
| curl_easy_setopt(curl, option, value) | ||||
| void * curl | ||||
| int option | ||||
| SV * value | ||||
| CODE: | ||||
|     if (option < CURLOPTTYPE_OBJECTPOINT) { | ||||
| 	/* This is an option specifying an integer value: */ | ||||
| 	RETVAL = curl_easy_setopt(curl, option, (long)SvIV(value)); | ||||
|     } else if (option == CURLOPT_FILE || option == CURLOPT_INFILE || | ||||
| 	    option == CURLOPT_WRITEHEADER || option == CURLOPT_PROGRESSDATA || | ||||
| 	    option == CURLOPT_PASSWDDATA) { | ||||
| 	/* This is an option specifying an SV * value: */ | ||||
| 	RETVAL = curl_easy_setopt(curl, option, newSVsv(ST(2))); | ||||
|     } else if (option == CURLOPT_ERRORBUFFER) { | ||||
| 	/* Pass in variable name for storing error messages... */ | ||||
| 	RETVAL = curl_easy_setopt(curl, option, errbuf); | ||||
| 	if (errbufvarname) free(errbufvarname); | ||||
| 	errbufvarname = strdup((char *)SvPV(value, PL_na)); | ||||
|     } else if (option == CURLOPT_WRITEFUNCTION || option == | ||||
| 	    CURLOPT_READFUNCTION || option == CURLOPT_PROGRESSFUNCTION || | ||||
| 	    option == CURLOPT_PASSWDFUNCTION || option == CURLOPT_HEADERFUNCTION) { | ||||
| 	/* This is an option specifying a callback function */ | ||||
| 	switch (option) { | ||||
| 	case CURLOPT_WRITEFUNCTION: | ||||
| 	    register_callback(&write_callback, value); | ||||
| 	    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback_func); | ||||
| 	    break; | ||||
| 	case CURLOPT_READFUNCTION: | ||||
| 	    register_callback(&read_callback, value); | ||||
| 	    curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback_func); | ||||
| 	    break; | ||||
|         case CURLOPT_HEADERFUNCTION: | ||||
|             register_callback(&header_callback, value); | ||||
| 	    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback_func);	 | ||||
| 	case CURLOPT_PROGRESSFUNCTION: | ||||
| 	    register_callback(&progress_callback, value); | ||||
| 	    curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback_func); | ||||
| 	    break; | ||||
| 	case CURLOPT_PASSWDFUNCTION: | ||||
| 	    register_callback(&passwd_callback, value); | ||||
| 	    curl_easy_setopt(curl, CURLOPT_PASSWDFUNCTION, passwd_callback_func); | ||||
| 	    break; | ||||
|         /* awaiting a prototype for the closepolicy function callback  | ||||
|         case CURLOPT_CLOSEFUNCTION: | ||||
|             register_callback(&closepolicy_callback, value); | ||||
|             curl_easy_setopt(curl, CURLOPT_CLOSEFUNCTION, closepolicy_callback_func); | ||||
|             break; | ||||
|         */ | ||||
| 	} | ||||
| 	RETVAL = -1; | ||||
|     } else if (option == CURLOPT_HTTPHEADER || option == CURLOPT_QUOTE || | ||||
| 	    option == CURLOPT_POSTQUOTE) { | ||||
| 	/* This is an option specifying a list of curl_slist structs: */ | ||||
| 	AV *array = (AV *)SvRV(value); | ||||
| 	struct curl_slist **slist = NULL; | ||||
| 	/* We have to find out which list to use... */ | ||||
| 	switch (option) { | ||||
| 	case CURLOPT_HTTPHEADER: | ||||
| 	    slist = &httpheader; break; | ||||
| 	case CURLOPT_QUOTE: | ||||
| 	    slist = "e; break; | ||||
| 	case CURLOPT_POSTQUOTE: | ||||
| 	    slist = &postquote; break; | ||||
| 	} | ||||
|         /* free any previous list */ | ||||
|         if (*slist) { | ||||
|             curl_slist_free_all(*slist); | ||||
|             *slist=NULL; | ||||
|         }                                                                        | ||||
| 	/* ...store the values into it... */ | ||||
| 	for (;;) { | ||||
| 	    SV *sv = av_shift(array); | ||||
| 	    int len = 0; | ||||
| 	    char *str = SvPV(sv, len); | ||||
| 	    if (len == 0) break; | ||||
| 	    *slist = curl_slist_append(*slist, str); | ||||
| 	} | ||||
| 	/* ...and pass the list into curl_easy_setopt() */ | ||||
| 	RETVAL = curl_easy_setopt(curl, option, *slist); | ||||
|     } else { | ||||
| 	/* This is an option specifying a char * value: */ | ||||
| 	RETVAL = curl_easy_setopt(curl, option, SvPV(value, PL_na)); | ||||
|     } | ||||
| OUTPUT: | ||||
|     RETVAL | ||||
|  | ||||
|  | ||||
| int | ||||
| internal_setopt(option, value) | ||||
| int option | ||||
| int value | ||||
| CODE: | ||||
|     if (value == 1) { | ||||
| 	internal_options |= option; | ||||
|     } else { | ||||
| 	internal_options &= !option; | ||||
|     } | ||||
|     RETVAL = 0; | ||||
| OUTPUT: | ||||
|     RETVAL | ||||
|  | ||||
|  | ||||
| int | ||||
| curl_easy_perform(curl) | ||||
| void * curl  | ||||
| CODE: | ||||
|     if (internal_options & USE_INTERNAL_VARS) { | ||||
| 	/* Use internal callback which just stores the content into a buffer. */ | ||||
| 	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, internal_write_callback); | ||||
| 	curl_easy_setopt(curl, CURLOPT_HEADER, 1); | ||||
|     } | ||||
|     RETVAL = curl_easy_perform(curl); | ||||
|     if (RETVAL && errbufvarname) { | ||||
| 	/* If an error occurred and a varname for error messages has been | ||||
| 	   specified, store the error message. */ | ||||
| 	SV *sv = perl_get_sv(errbufvarname, TRUE | GV_ADDMULTI); | ||||
| 	sv_setpv(sv, errbuf); | ||||
|     } | ||||
|     if (!RETVAL && (internal_options & USE_INTERNAL_VARS)) { | ||||
| 	/* No error and internal variable for the content are to be used: | ||||
| 	   Split the data into headers and content and store them into | ||||
| 	   perl variables. */ | ||||
| 	SV *head_sv = perl_get_sv("Curl::easy::headers", TRUE | GV_ADDMULTI); | ||||
| 	SV *cont_sv = perl_get_sv("Curl::easy::content", TRUE | GV_ADDMULTI); | ||||
| 	char *p = contbuf; | ||||
| 	int nl = 0, found = 0; | ||||
| 	while (p < bufptr) { | ||||
| 	    if (nl && (*p == '\n' || *p == '\r')) { | ||||
| 		/* found empty line, end of headers */ | ||||
| 		*p++ = '\0'; | ||||
| 		sv_setpv(head_sv, contbuf); | ||||
| 		while (*p == '\n' || *p == '\r') { | ||||
| 		    p++; | ||||
| 		} | ||||
| 		sv_setpv(cont_sv, p); | ||||
| 		found = 1; | ||||
| 		break; | ||||
| 	    } | ||||
| 	    nl = (*p == '\n'); | ||||
| 	    p++; | ||||
| 	} | ||||
| 	if (!found) { | ||||
| 	    sv_setpv(head_sv, ""); | ||||
| 	    sv_setpv(cont_sv, contbuf); | ||||
| 	} | ||||
|     } | ||||
| OUTPUT: | ||||
|     RETVAL | ||||
|  | ||||
|  | ||||
| int | ||||
| curl_easy_getinfo(curl, option, value) | ||||
| void * curl | ||||
| int option | ||||
| double value | ||||
| CODE: | ||||
| #ifdef __GNUC__ | ||||
|     /* a(void) warnig about unnused variable */ | ||||
|     (void) value; | ||||
| #endif | ||||
|     switch (option & CURLINFO_TYPEMASK) { | ||||
| 	case CURLINFO_STRING: { | ||||
| 	    char * value = (char *)SvPV(ST(2), PL_na); | ||||
| 	    RETVAL = curl_easy_getinfo(curl, option, &value); | ||||
| 	    sv_setpv(ST(2), value); | ||||
| 	    break; | ||||
| 	} | ||||
| 	case CURLINFO_LONG: { | ||||
| 	    long value = (long)SvIV(ST(2)); | ||||
| 	    RETVAL = curl_easy_getinfo(curl, option, &value); | ||||
| 	    sv_setiv(ST(2), value); | ||||
| 	    break; | ||||
| 	} | ||||
| 	case CURLINFO_DOUBLE: { | ||||
| 	    double value = (double)SvNV(ST(2)); | ||||
| 	    RETVAL = curl_easy_getinfo(curl, option, &value); | ||||
| 	    sv_setnv(ST(2), value); | ||||
| 	    break; | ||||
| 	} | ||||
| 	default: { | ||||
| 	    RETVAL = CURLE_BAD_FUNCTION_ARGUMENT; | ||||
| 	    break; | ||||
| 	} | ||||
|     } | ||||
| OUTPUT: | ||||
|     RETVAL | ||||
|  | ||||
|  | ||||
| int | ||||
| curl_easy_cleanup(curl) | ||||
| void * curl  | ||||
| CODE: | ||||
|     curl_easy_cleanup(curl); | ||||
|     init_globals(); | ||||
|     RETVAL = 0; | ||||
| OUTPUT: | ||||
|     RETVAL | ||||
|  | ||||
| @@ -1,321 +0,0 @@ | ||||
| # Test script for Perl extension Curl::easy. | ||||
| # Check out the file README for more info. | ||||
|  | ||||
| # Before `make install' is performed this script should be runnable with | ||||
| # `make test'. After `make install' it should work as `perl test.pl' | ||||
|  | ||||
| ######################### We start with some black magic to print on failure. | ||||
|  | ||||
| # Change 1..1 below to 1..last_test_to_print . | ||||
| # (It may become useful if the test is moved to ./t subdirectory.) | ||||
| use Benchmark; | ||||
| use strict; | ||||
|  | ||||
| BEGIN { $| = 1; print "1..13\n"; } | ||||
| END {print "not ok 1\n" unless $::loaded;} | ||||
| use Curl::easy; | ||||
|  | ||||
| $::loaded = 1; | ||||
| print "ok 1\n"; | ||||
|  | ||||
| ######################### End of black magic. | ||||
|  | ||||
| # Insert your test code below (better if it prints "ok 13" | ||||
| # (correspondingly "not ok 13") depending on the success of chunk 13 | ||||
| # of the test code): | ||||
|  | ||||
| print "Testing curl version ",&Curl::easy::version(),"\n"; | ||||
|  | ||||
| # Read URL to get | ||||
| my $defurl = "http://localhost/cgi-bin/printenv"; | ||||
| my $url = ""; | ||||
| print "Please enter an URL to fetch [$defurl]: "; | ||||
| $url = <STDIN>; | ||||
| if ($url =~ /^\s*\n/) { | ||||
|     $url = $defurl; | ||||
| } | ||||
|  | ||||
| # Init the curl session | ||||
| my $curl; | ||||
| if (($curl = Curl::easy::init()) != 0) { | ||||
|     print "ok 2\n"; | ||||
| } else { | ||||
|     print "ko 2\n"; | ||||
| } | ||||
|  | ||||
|  | ||||
| # No progress meter please | ||||
| # !! Need this on for all tests, as once disabled, can't re-enable it... | ||||
| #Curl::easy::setopt($curl, CURLOPT_NOPROGRESS, 1); | ||||
|  | ||||
| # Shut up completely | ||||
| Curl::easy::setopt($curl, CURLOPT_MUTE, 1); | ||||
|  | ||||
| # Follow location headers | ||||
| Curl::easy::setopt($curl, CURLOPT_FOLLOWLOCATION, 1); | ||||
|  | ||||
| # Set timeout | ||||
| Curl::easy::setopt($curl, CURLOPT_TIMEOUT, 30); | ||||
|  | ||||
| # Set file where to read cookies from | ||||
| Curl::easy::setopt($curl, CURLOPT_COOKIEFILE, "cookies"); | ||||
|  | ||||
| # Set file where to store the header | ||||
| open HEAD, ">head.out"; | ||||
| Curl::easy::setopt($curl, CURLOPT_WRITEHEADER, *HEAD); | ||||
| print "ok 3\n"; | ||||
|  | ||||
| # Set file where to store the body | ||||
| # Send body to stdout - test difference between FILE * and SV * | ||||
| #open BODY, ">body.out"; | ||||
| #Curl::easy::setopt($curl, CURLOPT_FILE,*BODY); | ||||
| print "ok 4\n"; | ||||
|  | ||||
| # Add some additional headers to the http-request: | ||||
| my @myheaders; | ||||
| $myheaders[0] = "Server: www"; | ||||
| $myheaders[1] = "User-Agent: Perl interface for libcURL"; | ||||
| Curl::easy::setopt($curl, Curl::easy::CURLOPT_HTTPHEADER, \@myheaders); | ||||
|                                                                          | ||||
| # Store error messages in variable $errbuf | ||||
| # NOTE: The name of the variable is passed as a string! | ||||
| # setopt() creates a perl variable with that name, and | ||||
| # perform() stores the errormessage into it if an error occurs. | ||||
|   | ||||
| Curl::easy::setopt($curl, CURLOPT_ERRORBUFFER, "errbuf"); | ||||
| Curl::easy::setopt($curl, CURLOPT_URL, $url); | ||||
| print "ok 5\n"; | ||||
|  | ||||
| my $bytes; | ||||
| my $realurl; | ||||
| my $httpcode; | ||||
| my $errbuf; | ||||
|  | ||||
| # Go get it | ||||
| if (Curl::easy::perform($curl) == 0) { | ||||
|     Curl::easy::getinfo($curl, CURLINFO_SIZE_DOWNLOAD, $bytes); | ||||
|     print "ok 6: $bytes bytes read\n"; | ||||
|     Curl::easy::getinfo($curl, CURLINFO_EFFECTIVE_URL, $realurl); | ||||
|     Curl::easy::getinfo($curl, CURLINFO_HTTP_CODE, $httpcode); | ||||
|     print "effective fetched url (http code: $httpcode) was: $url\n"; | ||||
| } else { | ||||
|    # We can acces the error message in $errbuf here | ||||
|     print "not ok 6: '$errbuf'\n"; | ||||
| 	die "basic url access failed"; | ||||
| } | ||||
|  | ||||
| # cleanup | ||||
| #close HEAD; | ||||
| # test here - BODY is still expected to be the output | ||||
| # Curl-easy-1.0.2.pm core dumps if we 'perform' with a closed output FD... | ||||
| #close BODY; | ||||
| #exit; | ||||
| # | ||||
| # The header callback will only be called if your libcurl has the | ||||
| # CURLOPT_HEADERFUNCTION supported, otherwise your headers | ||||
| # go to CURLOPT_WRITEFUNCTION instead... | ||||
| # | ||||
|  | ||||
| my $header_called=0; | ||||
| sub header_callback { print "header callback called\n"; $header_called=1; return length($_[0])}; | ||||
|  | ||||
| # test for sub reference and head callback | ||||
| Curl::easy::setopt($curl, CURLOPT_HEADERFUNCTION, \&header_callback); | ||||
| print "ok 7\n"; # so far so good | ||||
|  | ||||
| if (Curl::easy::perform($curl) != 0) { | ||||
| 	print "not "; | ||||
| }; | ||||
| print "ok 8\n"; | ||||
|  | ||||
| print "next test will fail on libcurl < 7.7.2\n"; | ||||
| print "not " if (!$header_called); # ok if you have a libcurl <7.7.2 | ||||
| print "ok 9\n"; | ||||
|  | ||||
| my $body_called=0; | ||||
| sub body_callback { | ||||
| 	my ($chunk,$handle)=@_; | ||||
| 	print "body callback called with ",length($chunk)," bytes\n"; | ||||
| 	print "data=$chunk\n"; | ||||
| 	$body_called++; | ||||
| 	return length($chunk); # OK | ||||
| } | ||||
|  | ||||
| # test for ref to sub and body callback | ||||
| my $body_ref=\&body_callback; | ||||
| Curl::easy::setopt($curl, CURLOPT_WRITEFUNCTION, $body_ref); | ||||
|  | ||||
| if (Curl::easy::perform($curl) != 0) { | ||||
| 	print "not "; | ||||
| }; | ||||
| print "ok 10\n"; | ||||
|  | ||||
| print "not " if (!$body_called); | ||||
| print "ok 11\n"; | ||||
|  | ||||
| my $body_abort_called=0; | ||||
| sub body_abort_callback { | ||||
| 	my ($chunk,$sv)=@_; | ||||
| 	print "body abort callback called with ",length($chunk)," bytes\n"; | ||||
| 	$body_abort_called++; | ||||
| 	return  -1; # signal a failure | ||||
| } | ||||
|  | ||||
| # test we can abort a request mid-way | ||||
| my $body_abort_ref=\&body_abort_callback; | ||||
| Curl::easy::setopt($curl, CURLOPT_WRITEFUNCTION, $body_abort_ref); | ||||
|  | ||||
| if (Curl::easy::perform($curl) == 0) { # reverse test - this should have failed | ||||
| 	print "not "; | ||||
| }; | ||||
| print "ok 12\n"; | ||||
|  | ||||
| print "not " if (!$body_abort_called); # should have been called | ||||
| print "ok 13\n"; | ||||
|  | ||||
| # reset to a working 'write' function for next tests | ||||
| Curl::easy::setopt($curl,CURLOPT_WRITEFUNCTION, sub { return length($_[0])} ); | ||||
|  | ||||
| # inline progress function | ||||
| # tests for inline subs and progress callback | ||||
| # - progress callback must return 'true' on each call. | ||||
|   | ||||
| my $progress_called=0; | ||||
| sub prog_callb | ||||
| { | ||||
|     my ($clientp,$dltotal,$dlnow,$ultotal,$ulnow)=@_; | ||||
|     print "\nperl progress_callback has been called!\n"; | ||||
|     print "clientp: $clientp, dltotal: $dltotal, dlnow: $dlnow, ultotal: $ultotal, "; | ||||
|     print "ulnow: $ulnow\n"; | ||||
| 	$progress_called++; | ||||
|     return 0; | ||||
| }                         | ||||
|  | ||||
| Curl::easy::setopt($curl, CURLOPT_PROGRESSFUNCTION, \&prog_callb); | ||||
|  | ||||
| # Turn progress meter back on - this doesn't work - once its off, its off. | ||||
| Curl::easy::setopt($curl, CURLOPT_NOPROGRESS, 0); | ||||
|  | ||||
| if (Curl::easy::perform($curl) != 0) { | ||||
| 	print "not "; | ||||
| }; | ||||
| print "ok 14\n"; | ||||
|  | ||||
| print "not " if (!$progress_called); | ||||
| print "ok 15\n"; | ||||
|  | ||||
| my $read_max=10; | ||||
|  | ||||
| sub read_callb | ||||
| { | ||||
|     my ($maxlen,$sv)=@_; | ||||
|     print "\nperl read_callback has been called!\n"; | ||||
|     print "max data size: $maxlen\n"; | ||||
| 	print "(upload needs $read_max bytes)\n"; | ||||
|     print "context: ".$sv."\n"; | ||||
| 	if ($read_max > 0) { | ||||
| 		print "\nEnter max ", $read_max, " characters to be uploaded.\n"; | ||||
| 		my $data = <STDIN>; | ||||
| 		chomp $data; | ||||
| 		$read_max=$read_max-length($data); | ||||
| 		return $data; | ||||
| 	} else { | ||||
| 		return ""; | ||||
| 	} | ||||
| }   | ||||
|  | ||||
| # | ||||
| # test post/read callback functions - requires a url which accepts posts, or it fails! | ||||
| # | ||||
|  | ||||
| Curl::easy::setopt($curl,CURLOPT_READFUNCTION,\&read_callb); | ||||
| Curl::easy::setopt($curl,CURLOPT_INFILESIZE,$read_max ); | ||||
| Curl::easy::setopt($curl,CURLOPT_UPLOAD,1 ); | ||||
| Curl::easy::setopt($curl,CURLOPT_CUSTOMREQUEST,"POST" ); | ||||
|                                                         | ||||
| if (Curl::easy::perform($curl) != 0) { | ||||
| 	print "not "; | ||||
| }; | ||||
| print "ok 16\n"; | ||||
|  | ||||
| sub passwd_callb | ||||
| { | ||||
|     my ($clientp,$prompt,$buflen)=@_; | ||||
|     print "\nperl passwd_callback has been called!\n"; | ||||
|     print "clientp: $clientp, prompt: $prompt, buflen: $buflen\n"; | ||||
|     print "\nEnter max $buflen characters for $prompt "; | ||||
|     my $data = <STDIN>; | ||||
|     chomp($data); | ||||
|     return (0,$data); | ||||
| }                                                          | ||||
|  | ||||
| Curl::easy::cleanup($curl); | ||||
|  | ||||
| # Now do an ftp upload: | ||||
|  | ||||
| $defurl = "ftp://horn\@localhost//tmp/bla"; | ||||
| print "\n\nPlease enter an URL for ftp upload [$defurl]: "; | ||||
| $url = <STDIN>; | ||||
| if ($url =~ /^\s*\n/) { | ||||
|     $url = $defurl; | ||||
| } | ||||
|  | ||||
| # Init the curl session | ||||
| if (($curl = Curl::easy::init()) != 0) { | ||||
|     print "ok 17\n"; | ||||
| } else { | ||||
|     print "not ok 17\n"; | ||||
| } | ||||
|  | ||||
| # Set URL to get | ||||
| if (Curl::easy::setopt($curl, Curl::easy::CURLOPT_URL, $url) == 0) { | ||||
|     print "ok 18\n"; | ||||
| } else { | ||||
|     print "not ok 18\n"; | ||||
|  | ||||
| } | ||||
|  | ||||
| # Tell libcurl to to an upload | ||||
| Curl::easy::setopt($curl, Curl::easy::CURLOPT_UPLOAD, 1); | ||||
|  | ||||
| # No progress meter please | ||||
| #Curl::easy::setopt($curl, Curl::easy::CURLOPT_NOPROGRESS, 1); | ||||
|  | ||||
| # Use our own progress callback | ||||
| Curl::easy::setopt($curl, Curl::easy::CURLOPT_PROGRESSFUNCTION, \&prog_callb); | ||||
|  | ||||
| # Shut up completely | ||||
| Curl::easy::setopt($curl, Curl::easy::CURLOPT_MUTE, 1); | ||||
|  | ||||
| # Store error messages in $errbuf | ||||
| Curl::easy::setopt($curl, Curl::easy::CURLOPT_ERRORBUFFER, "errbuf"); | ||||
|  | ||||
| $read_max=10; | ||||
| # Use perl read callback to read data to be uploaded | ||||
| Curl::easy::setopt($curl, Curl::easy::CURLOPT_READFUNCTION, | ||||
|     \&read_callb); | ||||
|  | ||||
| # Use perl passwd callback to read password for login to ftp server | ||||
| Curl::easy::setopt($curl, Curl::easy::CURLOPT_PASSWDFUNCTION, \&passwd_callb); | ||||
|  | ||||
| print "ok 19\n"; | ||||
|  | ||||
| # Go get it | ||||
| if (Curl::easy::perform($curl) == 0) { | ||||
|     Curl::easy::getinfo($curl, Curl::easy::CURLINFO_SIZE_UPLOAD, $bytes); | ||||
|     print "ok 20: $bytes bytes transferred\n\n"; | ||||
| } else { | ||||
|     # We can acces the error message in $errbuf here | ||||
|     print "not ok 20: '$errbuf'\n"; | ||||
| } | ||||
|  | ||||
| # Cleanup | ||||
| Curl::easy::cleanup($curl); | ||||
| print "ok 21\n"; | ||||
|  | ||||
| # Copyright (C) 2000, Daniel Stenberg, , et al. | ||||
| # You may opt to use, copy, modify, merge, publish, distribute and/or sell | ||||
| # copies of the Software, and permit persons to whom the Software is | ||||
| # furnished to do so, under the terms of the MPL or the MIT/X-derivate | ||||
| # licenses. You may pick one of these licenses. | ||||
|                                                    | ||||
| @@ -1,2 +0,0 @@ | ||||
| SUBDIRS = examples | ||||
| EXTRA_DIST = README | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user